Compare commits
1279 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c20072e940 | ||
|
|
e4c2ebfc57 | ||
|
|
587c061550 | ||
|
|
40a9f6f8e9 | ||
|
|
f0b0464cce | ||
|
|
4e803af0e6 | ||
|
|
4ccd8d3326 | ||
|
|
9768467d53 | ||
|
|
59de1e23bc | ||
|
|
f19b1e0c6b | ||
|
|
d33a3a295f | ||
|
|
f749302d25 | ||
|
|
9c47efb592 | ||
|
|
ea61046e8d | ||
|
|
3f671ea60f | ||
|
|
c1a7c3b08b | ||
|
|
d1225661d2 | ||
|
|
302eee9406 | ||
|
|
b434464b1c | ||
|
|
aabeb38c15 | ||
|
|
fe93ea56b6 | ||
|
|
b301603740 | ||
|
|
d7ba759844 | ||
|
|
8efe58bd3c | ||
|
|
6609938483 | ||
|
|
84662f2db5 | ||
|
|
da975f5a76 | ||
|
|
f34c96bf7a | ||
|
|
0f96f8e68f | ||
|
|
991962b6fd | ||
|
|
c481e27d88 | ||
|
|
56e04e0727 | ||
|
|
2244ac4d52 | ||
|
|
024b537b7f | ||
|
|
e4ee5c3f1c | ||
|
|
4b3d99d39a | ||
|
|
47a10f5a39 | ||
|
|
ecb39a5b63 | ||
|
|
39c8c9e7b0 | ||
|
|
4e7cc93af9 | ||
|
|
f8cb1a916e | ||
|
|
ab2e75e98e | ||
|
|
354892b1c6 | ||
|
|
abe69afd69 | ||
|
|
c72a89aaf8 | ||
|
|
873d98be2d | ||
|
|
f1d06b02e7 | ||
|
|
675276b802 | ||
|
|
3ed3a2d176 | ||
|
|
9e95e780da | ||
|
|
de58657537 | ||
|
|
015fa7a1d1 | ||
|
|
1ff3a6cdb8 | ||
|
|
7620efc9ad | ||
|
|
7778b480fd | ||
|
|
a17d7cea34 | ||
|
|
a9cafcb8ae | ||
|
|
bdfd0d1ff9 | ||
|
|
afc8b1a087 | ||
|
|
6c1773025b | ||
|
|
1b7d66fab6 | ||
|
|
e24365f1f4 | ||
|
|
fd334bf451 | ||
|
|
5515b1ea7f | ||
|
|
96d67f5153 | ||
|
|
8a00319962 | ||
|
|
c6136e4801 | ||
|
|
0938b5dec6 | ||
|
|
88f8fcb32e | ||
|
|
f40ce616a7 | ||
|
|
b02788b915 | ||
|
|
b094ee45d7 | ||
|
|
de0c87757a | ||
|
|
5604f987f2 | ||
|
|
9d14f0f36a | ||
|
|
a74468b353 | ||
|
|
35f81b24f1 | ||
|
|
40431cbf89 | ||
|
|
5529f14aaf | ||
|
|
54c31b498b | ||
|
|
899dba9022 | ||
|
|
7d8fa8089a | ||
|
|
ac86c5b6d1 | ||
|
|
ecc3f312b9 | ||
|
|
b65b5f43a7 | ||
|
|
c3270d7504 | ||
|
|
ea909ace01 | ||
|
|
f64d11da3c | ||
|
|
95225be93d | ||
|
|
e5d169b8d2 | ||
|
|
da4e3fb366 | ||
|
|
13ce150149 | ||
|
|
a04489a72b | ||
|
|
35cd88b09b | ||
|
|
ff56566506 | ||
|
|
01ad94bfad | ||
|
|
cfe3c54ca0 | ||
|
|
2f6a20a93a | ||
|
|
5d1543f241 | ||
|
|
c56650c773 | ||
|
|
cb11f27558 | ||
|
|
98be98816c | ||
|
|
ca2c297f72 | ||
|
|
387e1e21cb | ||
|
|
d6e49150a8 | ||
|
|
49a2729663 | ||
|
|
06baf20edd | ||
|
|
13553c2bf0 | ||
|
|
f638c1acd5 | ||
|
|
e4c659386a | ||
|
|
cd7a1661c6 | ||
|
|
96962e2101 | ||
|
|
7eedebc970 | ||
|
|
437e34accb | ||
|
|
0f2137be18 | ||
|
|
f87a622ef0 | ||
|
|
07722b835c | ||
|
|
3cd7a45c1b | ||
|
|
90b5174256 | ||
|
|
bffad26226 | ||
|
|
a578f3e23a | ||
|
|
870dd43268 | ||
|
|
ad0bd4ca92 | ||
|
|
eba480e15a | ||
|
|
4b83403a63 | ||
|
|
22c9e42f4d | ||
|
|
6ddc487fb6 | ||
|
|
3a34cadcb2 | ||
|
|
b71d1a4c7f | ||
|
|
bef80bab0d | ||
|
|
190210394c | ||
|
|
5cafcf66b0 | ||
|
|
d71e50c9fc | ||
|
|
35ebe1bf78 | ||
|
|
b14cc0417d | ||
|
|
399a3097e8 | ||
|
|
c8f5c3cdbe | ||
|
|
e83d506319 | ||
|
|
690bcd7b66 | ||
|
|
f18d285eab | ||
|
|
7887ccb441 | ||
|
|
d57b57a21d | ||
|
|
9fc0a8cbf8 | ||
|
|
5cc0531d27 | ||
|
|
0e5cdc8495 | ||
|
|
b80d892eab | ||
|
|
185af03fb2 | ||
|
|
abcbbc63d8 | ||
|
|
6871c74ce1 | ||
|
|
d0a44ca85c | ||
|
|
83db3e3ddb | ||
|
|
cc11045fd3 | ||
|
|
1b5afe737f | ||
|
|
3d65d9602e | ||
|
|
9440d080d4 | ||
|
|
9269c86339 | ||
|
|
7c82d616c9 | ||
|
|
f227379d2f | ||
|
|
eba88919c1 | ||
|
|
3408432b50 | ||
|
|
a0949158b7 | ||
|
|
ea91d2aaf1 | ||
|
|
de992abf83 | ||
|
|
5d8635a8dc | ||
|
|
7e911bae95 | ||
|
|
0676cf6d3f | ||
|
|
b74ae7aa31 | ||
|
|
0ad7db3bbd | ||
|
|
db74e316d2 | ||
|
|
1897360e4b | ||
|
|
e7fb957415 | ||
|
|
2f4567fa3c | ||
|
|
0a7abc188e | ||
|
|
5eeef7f065 | ||
|
|
7d36875d6f | ||
|
|
2fa718705a | ||
|
|
b1fdbf2335 | ||
|
|
2277922313 | ||
|
|
3e1029309c | ||
|
|
aa5deaa070 | ||
|
|
6b5d51ca22 | ||
|
|
2c114b5bb5 | ||
|
|
bd38a79e5e | ||
|
|
ccd9fd3e94 | ||
|
|
4215b3afc3 | ||
|
|
f60f111afe | ||
|
|
6fe0a3cee3 | ||
|
|
f004077734 | ||
|
|
6c5cfd2148 | ||
|
|
6c1011df92 | ||
|
|
1582a0ce78 | ||
|
|
b5b821363d | ||
|
|
399afc87ef | ||
|
|
8c842af172 | ||
|
|
bf836277f9 | ||
|
|
10d1806d81 | ||
|
|
bc41ce95fc | ||
|
|
4948d336c4 | ||
|
|
be2527d93d | ||
|
|
7f5bb1c8aa | ||
|
|
a8d40e4409 | ||
|
|
e9b4686fec | ||
|
|
5086ef2499 | ||
|
|
8a55d9a795 | ||
|
|
1caca80203 | ||
|
|
9114c26857 | ||
|
|
941a965af4 | ||
|
|
4acd431b92 | ||
|
|
fad0d566f9 | ||
|
|
e2d4079363 | ||
|
|
b9ce1f590b | ||
|
|
36463ed790 | ||
|
|
3c8838816d | ||
|
|
11e50a8eee | ||
|
|
9de4c60bd6 | ||
|
|
5288bdeabb | ||
|
|
f5804438bb | ||
|
|
6e06357dc5 | ||
|
|
28913b97b0 | ||
|
|
c59cd46391 | ||
|
|
dda239fd49 | ||
|
|
b86a6ce26a | ||
|
|
ee212e7bb5 | ||
|
|
4952c7b3b5 | ||
|
|
4e61536f50 | ||
|
|
f2886f152b | ||
|
|
b5c56f6cea | ||
|
|
80e95388f5 | ||
|
|
daed0b655a | ||
|
|
fbb994c731 | ||
|
|
10b155a486 | ||
|
|
ce6eda709b | ||
|
|
14e1d20df3 | ||
|
|
da8a02d56e | ||
|
|
16343683d9 | ||
|
|
2bdc017aff | ||
|
|
16e05c321c | ||
|
|
23d7919865 | ||
|
|
38265efc39 | ||
|
|
2d414706dc | ||
|
|
d85e4b0d46 | ||
|
|
45d03af8f6 | ||
|
|
73a3a2a131 | ||
|
|
73804580d4 | ||
|
|
259f9779db | ||
|
|
14e0e58a7d | ||
|
|
5eb373f7b5 | ||
|
|
4595c30a7b | ||
|
|
fc2dd44694 | ||
|
|
053c54017e | ||
|
|
af473d78f2 | ||
|
|
26d096aa87 | ||
|
|
476c613ba6 | ||
|
|
2348a5f592 | ||
|
|
9d8d045c66 | ||
|
|
63914dd55b | ||
|
|
93a8042f08 | ||
|
|
b2f32dac1b | ||
|
|
577a3acaac | ||
|
|
5e46ce8a50 | ||
|
|
3b7342b7b5 | ||
|
|
531077e504 | ||
|
|
147918ed66 | ||
|
|
9bbfca9226 | ||
|
|
f1a07ff105 | ||
|
|
fb6e434315 | ||
|
|
3811d96feb | ||
|
|
1017615d02 | ||
|
|
056d627f46 | ||
|
|
663bfeacf4 | ||
|
|
e918ebd721 | ||
|
|
0dc18f0102 | ||
|
|
8ddc882a66 | ||
|
|
49365d0982 | ||
|
|
50c29c7d0f | ||
|
|
bf492122f8 | ||
|
|
38d0ed9f3a | ||
|
|
248a65b37d | ||
|
|
78f86e9385 | ||
|
|
d9f3e0c275 | ||
|
|
c40451ee2e | ||
|
|
6644406185 | ||
|
|
b3a962e121 | ||
|
|
8a28ccfa2f | ||
|
|
0a75fa09ef | ||
|
|
17a16eeaf4 | ||
|
|
3d3f0bcf54 | ||
|
|
bc8b20ae3c | ||
|
|
daf344e5fd | ||
|
|
7916792f99 | ||
|
|
27e37e68b2 | ||
|
|
a538f8a24a | ||
|
|
70ec88b733 | ||
|
|
4f0e5db216 | ||
|
|
79ed124939 | ||
|
|
c0a3cd603b | ||
|
|
7c6f990cf9 | ||
|
|
7820b171d3 | ||
|
|
0cf4cc283c | ||
|
|
9a4b173b88 | ||
|
|
6d83454237 | ||
|
|
ff231b5e62 | ||
|
|
4d74216147 | ||
|
|
b7e5ad0a31 | ||
|
|
e435592d64 | ||
|
|
7ddde8dc3a | ||
|
|
fce2881de6 | ||
|
|
e96e83d557 | ||
|
|
1b2944e871 | ||
|
|
074e73a0dd | ||
|
|
8923801881 | ||
|
|
cfafe93391 | ||
|
|
6c48ef781b | ||
|
|
adeb976a1b | ||
|
|
bb19b91ef9 | ||
|
|
bfa7f171bd | ||
|
|
b96c014daf | ||
|
|
e0c83e22d9 | ||
|
|
099ad0f5e1 | ||
|
|
cf9746dd84 | ||
|
|
b70712dbba | ||
|
|
4c057fe693 | ||
|
|
ee8ff51d60 | ||
|
|
9974b16c32 | ||
|
|
9e5f319d80 | ||
|
|
4f614b4030 | ||
|
|
3d458e973e | ||
|
|
3a19a71262 | ||
|
|
29d1a1c593 | ||
|
|
3b90de558f | ||
|
|
af7e31acb3 | ||
|
|
a2c9d35efb | ||
|
|
4c058f4056 | ||
|
|
ad67b84d43 | ||
|
|
4e81e4065b | ||
|
|
81332789cb | ||
|
|
82d7c0c9eb | ||
|
|
d60235e239 | ||
|
|
9b50b0a762 | ||
|
|
21e14c4c98 | ||
|
|
16edacebc7 | ||
|
|
75027b4d54 | ||
|
|
b0bd99266d | ||
|
|
b9e04815f8 | ||
|
|
18ccc27b1b | ||
|
|
95f1fe92e2 | ||
|
|
b783f519ee | ||
|
|
996a1010cb | ||
|
|
32a9dfd983 | ||
|
|
1394509343 | ||
|
|
0f31c36b2c | ||
|
|
14ac8f71b7 | ||
|
|
6a92d51383 | ||
|
|
7c831c3fe5 | ||
|
|
778ff463af | ||
|
|
70a31d5402 | ||
|
|
48f5fa69f3 | ||
|
|
83a2d12cd2 | ||
|
|
e539297e53 | ||
|
|
bbc3d015a3 | ||
|
|
e4475c635d | ||
|
|
8370cb3e71 | ||
|
|
4073880ecf | ||
|
|
763c7a56dc | ||
|
|
556fbc487d | ||
|
|
54938d431c | ||
|
|
31c61e7eae | ||
|
|
a23151b138 | ||
|
|
11b75759d2 | ||
|
|
a2c562fea4 | ||
|
|
8950abc36f | ||
|
|
27c7226d97 | ||
|
|
1db294e837 | ||
|
|
16e943f120 | ||
|
|
9d610214cf | ||
|
|
c25681c36c | ||
|
|
1aea75261d | ||
|
|
5cd20e3d24 | ||
|
|
9968c7ef70 | ||
|
|
ca260618d8 | ||
|
|
30c5b41398 | ||
|
|
f37d4337a4 | ||
|
|
93c2adb2cd | ||
|
|
525ab0a925 | ||
|
|
a92c6886cd | ||
|
|
01d171756b | ||
|
|
930e7f5578 | ||
|
|
d14e15d432 | ||
|
|
4d3a18890b | ||
|
|
65bef02607 | ||
|
|
cb9331ddca | ||
|
|
ac0c3fb696 | ||
|
|
a844fb78bb | ||
|
|
6d02939256 | ||
|
|
e3b63f2d9c | ||
|
|
1c440b3b31 | ||
|
|
c5a0ef8399 | ||
|
|
951da0ca3d | ||
|
|
351be9ca42 | ||
|
|
4bab0a2f54 | ||
|
|
97478b746d | ||
|
|
61a591944b | ||
|
|
8e7ca41817 | ||
|
|
84e08fd534 | ||
|
|
b0e56fa1b5 | ||
|
|
e7c48ed3b0 | ||
|
|
c432270ca8 | ||
|
|
6a7f75c3e3 | ||
|
|
e9882e12ba | ||
|
|
3df10429db | ||
|
|
eee569bb20 | ||
|
|
2e07305616 | ||
|
|
2f9c36a588 | ||
|
|
907494c5d4 | ||
|
|
b14401c320 | ||
|
|
4d2520ea53 | ||
|
|
cece0c7ffe | ||
|
|
5e34383e25 | ||
|
|
b2a3f2d386 | ||
|
|
8e39ee79b0 | ||
|
|
6b679c45df | ||
|
|
e3d2643f2b | ||
|
|
fc33d5a75b | ||
|
|
6e566fb154 | ||
|
|
6675ce9036 | ||
|
|
2cf75fcca2 | ||
|
|
941f698daf | ||
|
|
48b3d1383f | ||
|
|
dc79334f1c | ||
|
|
ab74a502e2 | ||
|
|
fa18e7c21f | ||
|
|
ff7e9b6b22 | ||
|
|
00e93d1c1d | ||
|
|
45c9b1c065 | ||
|
|
dcfcd693c2 | ||
|
|
7ab4ee1d79 | ||
|
|
c017ed251d | ||
|
|
34b94aff73 | ||
|
|
65a5f85af5 | ||
|
|
52a39a00d5 | ||
|
|
ce9a9eeecc | ||
|
|
cbd433603d | ||
|
|
91fb661d12 | ||
|
|
0b74b6d98c | ||
|
|
d42326bf43 | ||
|
|
4c93f35c2b | ||
|
|
84f0cc6614 | ||
|
|
0f798dda15 | ||
|
|
629e51a8e9 | ||
|
|
4211aa41a0 | ||
|
|
5893e143f4 | ||
|
|
d91c4d3e00 | ||
|
|
3d911eba6c | ||
|
|
0c8e4335f9 | ||
|
|
247e9ffc96 | ||
|
|
3f4c3086df | ||
|
|
a84f3663dd | ||
|
|
714b3ef7f8 | ||
|
|
96bdc5834c | ||
|
|
3f4885e342 | ||
|
|
ee2bc92ab2 | ||
|
|
144f06e381 | ||
|
|
7f3f2a0f0a | ||
|
|
9e563e7b47 | ||
|
|
12ce3eefca | ||
|
|
f395b7ce11 | ||
|
|
4228adfaa7 | ||
|
|
8ad474b910 | ||
|
|
737d8e4d9f | ||
|
|
aaac7c17b8 | ||
|
|
28a975dd32 | ||
|
|
e60822b094 | ||
|
|
ac085e0f59 | ||
|
|
e8331d40f3 | ||
|
|
21b8d30c80 | ||
|
|
24989b90ba | ||
|
|
4f1bccb53d | ||
|
|
98eacdb785 | ||
|
|
8331ec7482 | ||
|
|
d43752fc4f | ||
|
|
bd03c8b28a | ||
|
|
d490933fce | ||
|
|
f65817d4c2 | ||
|
|
40a8ae2907 | ||
|
|
12b98027ee | ||
|
|
45a0ea9628 | ||
|
|
98ff85dea1 | ||
|
|
0015157cba | ||
|
|
f513531d3a | ||
|
|
4e16e9ed89 | ||
|
|
9f0ea97d85 | ||
|
|
7a435bb4f1 | ||
|
|
014346acba | ||
|
|
c90773cc85 | ||
|
|
0514e07ef4 | ||
|
|
14b8af2e65 | ||
|
|
818bacae49 | ||
|
|
6ba2e3deef | ||
|
|
bb370f3b6a | ||
|
|
f680626f53 | ||
|
|
83ca3e5563 | ||
|
|
37cb544839 | ||
|
|
ec8964dde5 | ||
|
|
913c51b1f8 | ||
|
|
cd1efb94ed | ||
|
|
d6d71e8078 | ||
|
|
4cb67339c5 | ||
|
|
4b71fe6fc1 | ||
|
|
46256cddd7 | ||
|
|
ad24069cdc | ||
|
|
3b1733bc04 | ||
|
|
43f087c99d | ||
|
|
54ca95bc6e | ||
|
|
e3f2323e14 | ||
|
|
c147667486 | ||
|
|
5ed2c06eb5 | ||
|
|
9d1e8b61fe | ||
|
|
e0ffe7a575 | ||
|
|
d676491b6e | ||
|
|
580f447bbd | ||
|
|
52f04da5f5 | ||
|
|
06927a20b2 | ||
|
|
caba531e89 | ||
|
|
7a6ab91080 | ||
|
|
e8dd4160d4 | ||
|
|
bb6b58c271 | ||
|
|
def374370f | ||
|
|
b748115609 | ||
|
|
a592a914b8 | ||
|
|
1ae48f4988 | ||
|
|
bb29d15d5a | ||
|
|
40e3d0c780 | ||
|
|
00fc600e8b | ||
|
|
f4ad37d208 | ||
|
|
79f91109cd | ||
|
|
d67cbdf725 | ||
|
|
16aba71da0 | ||
|
|
9426522159 | ||
|
|
8058832a48 | ||
|
|
fa3f22c448 | ||
|
|
cabf9c5bee | ||
|
|
4417529952 | ||
|
|
bb3f192b07 | ||
|
|
f71011aff0 | ||
|
|
df5ab4e228 | ||
|
|
b02b59b8c8 | ||
|
|
f29449ba07 | ||
|
|
bf4ceb981f | ||
|
|
84e5a4a2c2 | ||
|
|
ebd30beee4 | ||
|
|
cb067aa579 | ||
|
|
74bc2baa1d | ||
|
|
f546ab3130 | ||
|
|
35142cb206 | ||
|
|
13313b5cb6 | ||
|
|
432431f2e6 | ||
|
|
dd952146d1 | ||
|
|
237f3765e5 | ||
|
|
cca6460e65 | ||
|
|
354acf6fc9 | ||
|
|
7ce0609800 | ||
|
|
0a35effe49 | ||
|
|
95b395505f | ||
|
|
67e14a48b8 | ||
|
|
2026148dbe | ||
|
|
78b6366325 | ||
|
|
9c3535307f | ||
|
|
5e893ef8fd | ||
|
|
f72de95a38 | ||
|
|
6ab831b387 | ||
|
|
e4c434ab6f | ||
|
|
1f3310e0d1 | ||
|
|
c41a9480b8 | ||
|
|
6394f5b1a9 | ||
|
|
448c9b71c1 | ||
|
|
32a3a86a00 | ||
|
|
dcce0c86ed | ||
|
|
f4b3d30312 | ||
|
|
62aa8fa4e7 | ||
|
|
e8a52d810f | ||
|
|
5e27a759b7 | ||
|
|
c0d31ce648 | ||
|
|
eb39435481 | ||
|
|
54498452b6 | ||
|
|
821aad5281 | ||
|
|
5145b1445b | ||
|
|
e368091627 | ||
|
|
d5a08ea449 | ||
|
|
c31a1eec5b | ||
|
|
0d0f5f6c25 | ||
|
|
ab8bde0149 | ||
|
|
cf8bb668b3 | ||
|
|
f0075b9ce2 | ||
|
|
67d249eea9 | ||
|
|
c7105a1a79 | ||
|
|
f957cbd8ef | ||
|
|
5c0db8d05e | ||
|
|
200e8d971f | ||
|
|
a97e700371 | ||
|
|
4e6c52dd24 | ||
|
|
2b776e8c3a | ||
|
|
f3e1181ad9 | ||
|
|
9cbcf96aeb | ||
|
|
8ca3189f07 | ||
|
|
98e7dcfe2c | ||
|
|
cfd1b10980 | ||
|
|
f807cda375 | ||
|
|
11594c7927 | ||
|
|
509aa52efc | ||
|
|
e2c3f7ab14 | ||
|
|
fe39442c48 | ||
|
|
b21b6598f1 | ||
|
|
5e1b0014c2 | ||
|
|
cc0692d714 | ||
|
|
87f2401c1e | ||
|
|
f6ea21c8ae | ||
|
|
4436157da1 | ||
|
|
b00a2422e4 | ||
|
|
475b118fba | ||
|
|
42335fb2cb | ||
|
|
15ec1e1860 | ||
|
|
96964a4e03 | ||
|
|
e4aaa3d18f | ||
|
|
a6b597a0bd | ||
|
|
52d1ea83a0 | ||
|
|
5d64f5abd4 | ||
|
|
3e103ebffe | ||
|
|
992bc448a2 | ||
|
|
23607f91cd | ||
|
|
3a97739f83 | ||
|
|
e0ee6fe8cd | ||
|
|
a3f76fc14d | ||
|
|
c85abbfeca | ||
|
|
139ec2a64f | ||
|
|
72e1719220 | ||
|
|
3de7757ba4 | ||
|
|
7c3fad63b1 | ||
|
|
6b8145a813 | ||
|
|
688a7a7329 | ||
|
|
26201a5828 | ||
|
|
6cd59537b6 | ||
|
|
854f9895e4 | ||
|
|
4cc94df752 | ||
|
|
03eadb74ab | ||
|
|
7a4e739d6c | ||
|
|
a660464cec | ||
|
|
c9bd3f5d4a | ||
|
|
873141c1a5 | ||
|
|
8544447b19 | ||
|
|
18eb4f5015 | ||
|
|
67af99794d | ||
|
|
b5e768906a | ||
|
|
c13727adba | ||
|
|
69ccf9695c | ||
|
|
995185d02d | ||
|
|
f4de6e21fa | ||
|
|
a6db05e18d | ||
|
|
d91cefb23d | ||
|
|
e7f7416190 | ||
|
|
67cd3fb89c | ||
|
|
849b7b172a | ||
|
|
9a0c46fda7 | ||
|
|
05b56d0d08 | ||
|
|
43ffa64849 | ||
|
|
7881df2138 | ||
|
|
fd90571d49 | ||
|
|
9f7e00bb3a | ||
|
|
45b7d17ee8 | ||
|
|
859a995bd6 | ||
|
|
959bd6e9e7 | ||
|
|
9c47cae5c7 | ||
|
|
f16fefafe3 | ||
|
|
8d16e9fd6d | ||
|
|
2b8344e75c | ||
|
|
a8755af0fa | ||
|
|
ca70eaa388 | ||
|
|
1271bc4457 | ||
|
|
4d18b3f96d | ||
|
|
1279f1d430 | ||
|
|
e88b7fbcc4 | ||
|
|
8c838061f9 | ||
|
|
6c608e04bc | ||
|
|
6e4efa7edd | ||
|
|
a66ef778ec | ||
|
|
1b90207360 | ||
|
|
3f28ac3205 | ||
|
|
29817d6d8b | ||
|
|
92980e6882 | ||
|
|
b4ad175b13 | ||
|
|
b91079676d | ||
|
|
fbe37c9158 | ||
|
|
1483e9d8d2 | ||
|
|
8efd74b9b1 | ||
|
|
c2371af779 | ||
|
|
8dbd295c9b | ||
|
|
d6ff58daa1 | ||
|
|
4859b48c43 | ||
|
|
c34329284b | ||
|
|
0ad677045a | ||
|
|
c1f65dd863 | ||
|
|
b9fed3f046 | ||
|
|
35cc320e21 | ||
|
|
5a5b405a18 | ||
|
|
cd4d6a228b | ||
|
|
6c5e1c9701 | ||
|
|
627f13ea26 | ||
|
|
20fbfa2a44 | ||
|
|
3f790eae55 | ||
|
|
ddbf14adba | ||
|
|
22608ad206 | ||
|
|
60ee2ea8af | ||
|
|
bc708ee4c2 | ||
|
|
0e93352c8d | ||
|
|
a12312553b | ||
|
|
78777e141a | ||
|
|
9d9192d496 | ||
|
|
ad1638e6b6 | ||
|
|
0bab81aef9 | ||
|
|
92a1e06665 | ||
|
|
079611936f | ||
|
|
d4b92a1d20 | ||
|
|
7555d619f2 | ||
|
|
bd748bd115 | ||
|
|
85eefadada | ||
|
|
07d3261467 | ||
|
|
11586eda4c | ||
|
|
423361946d | ||
|
|
0a35277c96 | ||
|
|
16317748dd | ||
|
|
3d48a4ef65 | ||
|
|
b739264243 | ||
|
|
957971eb1d | ||
|
|
e3c161f0ea | ||
|
|
39edcbc93b | ||
|
|
beb3e35153 | ||
|
|
0416e59267 | ||
|
|
57f8dabf59 | ||
|
|
9ea4154b81 | ||
|
|
9c018fe984 | ||
|
|
faeca7cf11 | ||
|
|
f8b318aef1 | ||
|
|
93e2defc96 | ||
|
|
1c735365d0 | ||
|
|
161f63d393 | ||
|
|
8f49cf7c03 | ||
|
|
62b1cbf003 | ||
|
|
a5437cdac1 | ||
|
|
16deabef82 | ||
|
|
82ec488b99 | ||
|
|
781ddc3a25 | ||
|
|
85ff3bcd04 | ||
|
|
5b51cc86a9 | ||
|
|
d82352eacc | ||
|
|
f84c240d1c | ||
|
|
28804bfb62 | ||
|
|
5cf3a6bcd2 | ||
|
|
329a8ef9a1 | ||
|
|
9e89dcf855 | ||
|
|
344dd3793a | ||
|
|
d93f4c99e1 | ||
|
|
ffd57a0565 | ||
|
|
92c043423e | ||
|
|
d1a2ce2750 | ||
|
|
3c78ab5841 | ||
|
|
de85a3af15 | ||
|
|
cb86d597b7 | ||
|
|
9df4196597 | ||
|
|
87633d6be6 | ||
|
|
33a94a74df | ||
|
|
b5ae643b6e | ||
|
|
b0cffac79d | ||
|
|
b5f9b5de45 | ||
|
|
c772b3d86a | ||
|
|
7d7123de37 | ||
|
|
7f1e4a29c5 | ||
|
|
97ab902895 | ||
|
|
6e15f675a5 | ||
|
|
67ecce695d | ||
|
|
ac11d6ff97 | ||
|
|
4c5d7617fb | ||
|
|
7fcb3c9865 | ||
|
|
994d9075b4 | ||
|
|
649d18c4f7 | ||
|
|
cbf0cb7de7 | ||
|
|
5f0459c321 | ||
|
|
2d355c7478 | ||
|
|
4dfe19e613 | ||
|
|
1c6313679b | ||
|
|
f457bce0e7 | ||
|
|
6cc5babd2e | ||
|
|
db4ba39824 | ||
|
|
825d014616 | ||
|
|
fa576a22e3 | ||
|
|
059f1e09a8 | ||
|
|
7a7675c7ef | ||
|
|
b1e7bf16ba | ||
|
|
711e8bec3d | ||
|
|
b1c5738a67 | ||
|
|
5283e5a7d8 | ||
|
|
1a2516d4be | ||
|
|
d141cf7293 | ||
|
|
3c45c37428 | ||
|
|
d4e080be29 | ||
|
|
84fd33ea7a | ||
|
|
87e30f68b9 | ||
|
|
e8332be285 | ||
|
|
e5df7a7f01 | ||
|
|
fa0db761da | ||
|
|
5f2f955224 | ||
|
|
e26204e61d | ||
|
|
fa1cd5faff | ||
|
|
d16081c4d9 | ||
|
|
143400d444 | ||
|
|
96cb130263 | ||
|
|
0a4c824a06 | ||
|
|
b8189d7d23 | ||
|
|
4b5e89a067 | ||
|
|
f214bfcfc3 | ||
|
|
2e21e25613 | ||
|
|
d93fa2f78b | ||
|
|
75936cdde5 | ||
|
|
e73ed2afae | ||
|
|
c70d2d23a8 | ||
|
|
540a1eb6d9 | ||
|
|
d934cd105b | ||
|
|
ec05d7f8a1 | ||
|
|
345753ed19 | ||
|
|
c58e6c0dff | ||
|
|
1829bd84d3 | ||
|
|
7700c62fa8 | ||
|
|
8efbf5ef33 | ||
|
|
e8c5cb8c9a | ||
|
|
d5fd535909 | ||
|
|
b0a8d000b1 | ||
|
|
5c38488590 | ||
|
|
614fb750b7 | ||
|
|
e6cee7b41f | ||
|
|
0e57b971ad | ||
|
|
90b79fcd1f | ||
|
|
9d31705f75 | ||
|
|
059922cef1 | ||
|
|
8e4a9ba831 | ||
|
|
9b7b9b2e93 | ||
|
|
e0d7a6869c | ||
|
|
28c4bee0b1 | ||
|
|
052b5a68ed | ||
|
|
ee8b6f28b8 | ||
|
|
d5fb5d91e9 | ||
|
|
16658c14fe | ||
|
|
a96cf5b96b | ||
|
|
287fe0559e | ||
|
|
9006bba11e | ||
|
|
48d3b54e02 | ||
|
|
0c3bb75fd9 | ||
|
|
7e848b1924 | ||
|
|
8e4fcca216 | ||
|
|
fcfa42d992 | ||
|
|
5e0de79c0d | ||
|
|
8adb211216 | ||
|
|
5eea6f1b6d | ||
|
|
3f606b6c64 | ||
|
|
f31221d0d3 | ||
|
|
5220b462fd | ||
|
|
89b5e3e2ea | ||
|
|
ff2cc1626e | ||
|
|
cf6d31cefc | ||
|
|
46d64849b4 | ||
|
|
6c40079139 | ||
|
|
2c0c66e756 | ||
|
|
bc408d8d0b | ||
|
|
06cf2c7b51 | ||
|
|
37f15ea664 | ||
|
|
0da9060a80 | ||
|
|
e729516af7 | ||
|
|
4f0a42846c | ||
|
|
484b092720 | ||
|
|
ada6e5a5c4 | ||
|
|
2cf256c6d0 | ||
|
|
58692fe4d1 | ||
|
|
3a389788bf | ||
|
|
47f26b0df4 | ||
|
|
80a988c04f | ||
|
|
51f722d20f | ||
|
|
dffec8fb85 | ||
|
|
f9cae65df5 | ||
|
|
bcad536a90 | ||
|
|
d2f44006bd | ||
|
|
23cce731ab | ||
|
|
c01f4582de | ||
|
|
0e085e15bb | ||
|
|
e673a664ac | ||
|
|
57f76e936a | ||
|
|
501b2cc617 | ||
|
|
843cdbe690 | ||
|
|
df7f1c17ac | ||
|
|
1601742092 | ||
|
|
6084a3e63a | ||
|
|
adfada707d | ||
|
|
e8533d15b3 | ||
|
|
67721444b9 | ||
|
|
5f42276dbd | ||
|
|
c53efc0d6c | ||
|
|
ddd2648c1e | ||
|
|
079e640b6b | ||
|
|
bc71f737b8 | ||
|
|
c33ae0c7df | ||
|
|
e9f43251ab | ||
|
|
bc920dd2a5 | ||
|
|
9398932c47 | ||
|
|
da8adea0a9 | ||
|
|
669e789bc3 | ||
|
|
02cb347ac7 | ||
|
|
0e72a87613 | ||
|
|
8ac4643fd7 | ||
|
|
578a6db659 | ||
|
|
4aa2380de2 | ||
|
|
2adf73cca1 | ||
|
|
27b0d16422 | ||
|
|
c459fe21f8 | ||
|
|
6c7cd70202 | ||
|
|
606c601fc0 | ||
|
|
7c9652997b | ||
|
|
4e4a83bcef | ||
|
|
7cac2884ae | ||
|
|
11ada53ed5 | ||
|
|
5ba7ab0fed | ||
|
|
ebcb654649 | ||
|
|
a46af033b9 | ||
|
|
a0a18d963d | ||
|
|
4105f324f7 | ||
|
|
b7e91ee95e | ||
|
|
f1af06c00d | ||
|
|
779111d781 | ||
|
|
3e6586f58d | ||
|
|
cf2632fe59 | ||
|
|
322f3caec6 | ||
|
|
56198f40ac | ||
|
|
4a1c897b2d | ||
|
|
2b62accee0 | ||
|
|
16e543e734 | ||
|
|
1030af7b48 | ||
|
|
7f41ff26fa | ||
|
|
994f0c3d49 | ||
|
|
500e1bc9b5 | ||
|
|
23152f68f2 | ||
|
|
00778c9a1e | ||
|
|
33a21ffbdc | ||
|
|
5263b1a9c1 | ||
|
|
3fc1088d73 | ||
|
|
d12be12f72 | ||
|
|
fda8858fc3 | ||
|
|
29de86253f | ||
|
|
c7c89a5927 | ||
|
|
48f1142523 | ||
|
|
9c2459658a | ||
|
|
ca37ff8b08 | ||
|
|
e6440a75b5 | ||
|
|
2b400dc2ad | ||
|
|
860b2e2bbb | ||
|
|
f27fa5cbf3 | ||
|
|
98bec6f96b | ||
|
|
379d86f9a3 | ||
|
|
8b2dfcff29 | ||
|
|
b569930b2a | ||
|
|
061c9744af | ||
|
|
43616619ec | ||
|
|
838aeb149f | ||
|
|
37f809a1f4 | ||
|
|
32303daf63 | ||
|
|
d709f4dfdd | ||
|
|
80142af9b8 | ||
|
|
1b1b3a8fd6 | ||
|
|
afffd656f6 | ||
|
|
4f6e31eb08 | ||
|
|
9daca108b3 | ||
|
|
de5e397fd4 | ||
|
|
f5ec92c79a | ||
|
|
f654fea736 | ||
|
|
daa56ca50f | ||
|
|
c20de7b264 | ||
|
|
c5e813f9f4 | ||
|
|
3b7dd0396f | ||
|
|
c226292d8e | ||
|
|
216e5bb208 | ||
|
|
afdc0a5f59 | ||
|
|
5a9e00ce71 | ||
|
|
ca3d60c160 | ||
|
|
222b7b660e | ||
|
|
a469954ef3 | ||
|
|
be1d11f98d | ||
|
|
457515fc08 | ||
|
|
e3ac8dd5a8 | ||
|
|
14920b447c | ||
|
|
0c6177dd9a | ||
|
|
cea571fc31 | ||
|
|
d5a4c871f2 | ||
|
|
7c6c2e0ccf | ||
|
|
476d1fb334 | ||
|
|
7ca3be57df | ||
|
|
d1419edfd0 | ||
|
|
a740f750c7 | ||
|
|
610a405c85 | ||
|
|
aa1edfb6ae | ||
|
|
4864c9e96a | ||
|
|
faefeaa644 | ||
|
|
e0a7ff77df | ||
|
|
60c48fee16 | ||
|
|
1ef3dbabfc | ||
|
|
0b15755441 | ||
|
|
e9b95bbfe8 | ||
|
|
d0bf91d639 | ||
|
|
a1be6021c4 | ||
|
|
21efc93e54 | ||
|
|
fdf38dab6f | ||
|
|
5dfacf2615 | ||
|
|
613d784cfb | ||
|
|
efd426650d | ||
|
|
f62b75c731 | ||
|
|
65efd0a9a1 | ||
|
|
f08881a2b7 | ||
|
|
83da92fdcc | ||
|
|
16fa6472b3 | ||
|
|
6781f62c70 | ||
|
|
a445c39901 | ||
|
|
da490e3f53 | ||
|
|
ccd2e2496c | ||
|
|
36da171a3d | ||
|
|
e84f8b23aa | ||
|
|
864d1ea87f | ||
|
|
58ff651c6d | ||
|
|
c027563b13 | ||
|
|
f0a1735ac8 | ||
|
|
56f6d01757 | ||
|
|
3c946b2a72 | ||
|
|
1d37698d4c | ||
|
|
be50c289f8 | ||
|
|
444f956e7b | ||
|
|
b35d84156f | ||
|
|
496123a646 | ||
|
|
861747ec26 | ||
|
|
7bbaf0298e | ||
|
|
a2f5a7f3cd | ||
|
|
a5cfc59d81 | ||
|
|
da342c7855 | ||
|
|
aecddefbc8 | ||
|
|
fd05f458e1 | ||
|
|
faf176d78c | ||
|
|
151125e537 | ||
|
|
64a0eb42ed | ||
|
|
ba6cc2864a | ||
|
|
4d7c4fc0f4 | ||
|
|
e7c2f74a07 | ||
|
|
a7da6e1480 | ||
|
|
ae0d753cad | ||
|
|
31c977b906 | ||
|
|
87179346d4 | ||
|
|
d768afb80b | ||
|
|
de12a0941f | ||
|
|
987a28fc6a | ||
|
|
c5dbf0f8ad | ||
|
|
297939325a | ||
|
|
2f800521cb | ||
|
|
72a178a37e | ||
|
|
8c7b4549ed | ||
|
|
91090042d1 | ||
|
|
0693937c1e | ||
|
|
ac1a4ed576 | ||
|
|
b73d3f925d | ||
|
|
69641ddc36 | ||
|
|
36881807ed | ||
|
|
1a18b427a8 | ||
|
|
69ce97b80a | ||
|
|
9f887b436c | ||
|
|
5780163fb7 | ||
|
|
1c5fb9495e | ||
|
|
5df521bad5 | ||
|
|
be75d0265b | ||
|
|
b20de6a3ec | ||
|
|
4ee8704b99 | ||
|
|
d2e8a0a96a | ||
|
|
ff367c7b31 | ||
|
|
98d9d797fd | ||
|
|
a6fc3f6337 | ||
|
|
539f352318 | ||
|
|
e1b2b3e995 | ||
|
|
3b7bcf0f4f | ||
|
|
03ae32d937 | ||
|
|
ccf370f813 | ||
|
|
0521814dea | ||
|
|
e35841a2ea | ||
|
|
3474c273a5 | ||
|
|
3dc722b096 | ||
|
|
5002a6467d | ||
|
|
c1bfb63d96 | ||
|
|
27e295a4cb | ||
|
|
99703a95c2 | ||
|
|
f2202fc014 | ||
|
|
3761ff3522 | ||
|
|
205438669a | ||
|
|
e7f2d3179d | ||
|
|
277f4a1bfe | ||
|
|
46dc3b1442 | ||
|
|
2128c98c35 | ||
|
|
e98b326ba3 | ||
|
|
7bcd31bddb | ||
|
|
6def968c3c | ||
|
|
f2ee3cec19 | ||
|
|
589a298096 | ||
|
|
94c17bdf85 | ||
|
|
fdfea0c17b | ||
|
|
862fe60368 | ||
|
|
6a3e97a9f8 | ||
|
|
7656377f3f | ||
|
|
82029be6f9 | ||
|
|
339f75eb53 | ||
|
|
7425634692 | ||
|
|
38d5407ea1 | ||
|
|
6febfca5a6 | ||
|
|
7cba72a0b7 | ||
|
|
fb6c003c97 | ||
|
|
91016ba989 | ||
|
|
2aaf1de7fe | ||
|
|
b527e54809 | ||
|
|
c01db5fe9c | ||
|
|
534ebde638 | ||
|
|
d532d2f64f | ||
|
|
7bcd69e157 | ||
|
|
af63d053b1 | ||
|
|
d9ff118b40 | ||
|
|
be3f914acd | ||
|
|
edb9efd9a6 | ||
|
|
cdfa9a371d | ||
|
|
390efdc884 | ||
|
|
ac276a27b7 | ||
|
|
b63e99eb43 | ||
|
|
00976cfe47 | ||
|
|
6f561aa846 | ||
|
|
276386c94a | ||
|
|
0aa125304d | ||
|
|
482d29dc53 | ||
|
|
cd0aed993a | ||
|
|
f56656f6b4 | ||
|
|
fc601659f5 | ||
|
|
4a069a1e7f | ||
|
|
04badf7e6e | ||
|
|
0b31a163a3 | ||
|
|
171c00cfd6 | ||
|
|
b5cefa92fa | ||
|
|
8cead48342 | ||
|
|
1989e4fca0 | ||
|
|
880b3ef6c0 | ||
|
|
2ec93590e4 | ||
|
|
5fe69fb556 | ||
|
|
290ed09dc6 | ||
|
|
65018daebc | ||
|
|
0739937fa2 | ||
|
|
ede8ea52b0 | ||
|
|
ba83e9cfbe | ||
|
|
977331806b | ||
|
|
86207afe15 | ||
|
|
704a453b7a | ||
|
|
b7438894f6 | ||
|
|
4022586015 | ||
|
|
26fcef69c7 | ||
|
|
5036706f81 | ||
|
|
c02fbd22fa | ||
|
|
33020a63b8 | ||
|
|
eaa2e55d20 | ||
|
|
c22e11d483 | ||
|
|
41471c3b44 | ||
|
|
17e7538937 | ||
|
|
c8be8ba42c | ||
|
|
4d4df03f88 | ||
|
|
deb6e06336 | ||
|
|
c3d1d6a946 | ||
|
|
1055139c83 | ||
|
|
19d1e499c3 | ||
|
|
b161eea793 | ||
|
|
8fbe4b9c3b | ||
|
|
85479bcbc0 | ||
|
|
ec8240e890 | ||
|
|
221dec8cac | ||
|
|
9a0f6f5bb4 | ||
|
|
38dedf402b | ||
|
|
c280d0655c | ||
|
|
cdc1b640d9 | ||
|
|
37993dd713 | ||
|
|
cd25301607 | ||
|
|
4985691617 | ||
|
|
69eec9e344 | ||
|
|
a8ce570635 | ||
|
|
fab0904af7 | ||
|
|
ffc28faa51 | ||
|
|
b6843f2087 | ||
|
|
3f6606acdb | ||
|
|
7a3885863c | ||
|
|
67d8b91690 | ||
|
|
ce6977ffe6 | ||
|
|
bc7efa6da6 | ||
|
|
9198444a3b | ||
|
|
b15764ef2c | ||
|
|
abb62c76d8 | ||
|
|
51b7f322cc | ||
|
|
be99b1240c | ||
|
|
315e3b563b | ||
|
|
430d132ee0 | ||
|
|
cc37cc83cd | ||
|
|
0984f227a8 | ||
|
|
548cf96c44 | ||
|
|
0be378af6a | ||
|
|
fb988ba834 | ||
|
|
e6ddd28067 | ||
|
|
0acd3159db | ||
|
|
1897e75894 | ||
|
|
852e7cdb41 | ||
|
|
c1367d9d10 | ||
|
|
cb9bdf43f6 | ||
|
|
6b1a8e0a40 | ||
|
|
7f32cbeb06 | ||
|
|
c7253b3a37 | ||
|
|
7f03e24c55 | ||
|
|
66cecf4824 | ||
|
|
f3552ca737 | ||
|
|
3dc6a80198 | ||
|
|
e71159d6ea | ||
|
|
732a7e81a0 | ||
|
|
c3cbe2a30c | ||
|
|
9bc9b8795b | ||
|
|
d0605443fb | ||
|
|
47a8670d37 | ||
|
|
e7546e2305 | ||
|
|
ccb9826afd | ||
|
|
8de61559b0 | ||
|
|
ea4aa04cc4 | ||
|
|
a3dd72a759 | ||
|
|
62ec60188b | ||
|
|
10cb4799bc | ||
|
|
8e0438bad4 | ||
|
|
76e48b5c3f | ||
|
|
1bf9df7c85 | ||
|
|
32063bb472 | ||
|
|
f944e819e9 | ||
|
|
9c1ae09994 | ||
|
|
d82e85d099 | ||
|
|
c1d0851a56 | ||
|
|
08dd6af446 | ||
|
|
ff8f32ca80 | ||
|
|
a7c46e4d83 | ||
|
|
b15d760406 | ||
|
|
9f399f139b | ||
|
|
3b0f026522 | ||
|
|
8db94e7407 | ||
|
|
8d321446ad | ||
|
|
c783c2636f | ||
|
|
5468740042 | ||
|
|
69e4b16817 | ||
|
|
e35a1025c9 | ||
|
|
0f5601dad4 | ||
|
|
a5f35e2b3c | ||
|
|
c57d7dea8b | ||
|
|
a39cae9c2e | ||
|
|
53142f125b | ||
|
|
edf87a258f | ||
|
|
18144da755 | ||
|
|
d6007e7d9c | ||
|
|
92ce693e6f | ||
|
|
d2802cab6c | ||
|
|
177fb132b9 | ||
|
|
d811303d7b | ||
|
|
27b12ef1b6 | ||
|
|
4efc5d74d4 | ||
|
|
b5c552faf3 | ||
|
|
dec02340e8 | ||
|
|
3f80ef0648 | ||
|
|
44ae408b36 | ||
|
|
0e6554edc1 | ||
|
|
c8c5d37bcf | ||
|
|
5873e50c50 | ||
|
|
4f1371945d |
19
.travis.yml
19
.travis.yml
@@ -14,8 +14,18 @@ install:
|
||||
- sudo apt-get update
|
||||
- sudo apt-get purge -y mysql-common
|
||||
- sudo apt-get install mariadb-server mariadb-common libmariadbclient-dev
|
||||
- CFLAGS=-O0 pip install git+https://github.com/frappe/frappe.git@develop &&
|
||||
- pip install --editable .
|
||||
- ./ci/fix-mariadb.sh
|
||||
|
||||
- sudo apt-get install xfonts-75dpi xfonts-base -y
|
||||
- wget http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.2.1/wkhtmltox-0.12.2.1_linux-precise-amd64.deb
|
||||
- sudo dpkg -i wkhtmltox-0.12.2.1_linux-precise-amd64.deb
|
||||
- CFLAGS=-O0 pip install git+https://github.com/frappe/frappe.git@develop
|
||||
- CFLAGS=-O0 pip install --editable .
|
||||
|
||||
before_script:
|
||||
- mysql -e 'create database test_frappe'
|
||||
- echo "USE mysql;\nCREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe';\nFLUSH PRIVILEGES;\n" | mysql -u root
|
||||
- echo "USE mysql;\nGRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'localhost';\n" | mysql -u root
|
||||
|
||||
script:
|
||||
- cd ./test_sites/
|
||||
@@ -23,9 +33,6 @@ script:
|
||||
- frappe --reinstall
|
||||
- frappe --install_app erpnext --verbose
|
||||
- frappe -b
|
||||
- frappe --build_website
|
||||
- frappe --serve_test &
|
||||
- frappe --verbose --run_tests --app erpnext
|
||||
|
||||
before_script:
|
||||
- mysql -e 'create database test_frappe'
|
||||
- echo "USE mysql;\nCREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe';\nFLUSH PRIVILEGES;\n" | mysql -u root
|
||||
|
||||
@@ -1,16 +1,23 @@
|
||||
# Contributing to ERPNext
|
||||
# Contributing to Frappe / ERPNext
|
||||
|
||||
### Update 16-Sep-14
|
||||
|
||||
Please send pull requests to branch v5.0
|
||||
|
||||
## Reporting issues
|
||||
|
||||
We only accept issues that are bug reports or feature requests. Bugs must be isolated and reproducible problems. Please read the following guidelines before opening any issue.
|
||||
|
||||
1. **Search for existing issues.** We want to avoid duplication, and you'd help us out a lot by first checking if someone else has reported the same issue. The issue may have already been resolved with a fix available.
|
||||
1. **Search for existing issues:** We want to avoid duplication, and you'd help us out a lot by first checking if someone else has reported the same issue. The issue may have already been resolved with a fix available.
|
||||
1. **Report each issue separately:** Don't club multiple, unreleated issues in one note.
|
||||
1. **Mention the version number:** Please mention the application, browser and platform version numbers.
|
||||
|
||||
### Issues
|
||||
|
||||
1. **Share as much information as possible.** Include operating system and version, browser and version, when did you last update ERPNext, how is it customized, etc. where appropriate. Also include steps to reproduce the bug.
|
||||
1. Consider adding screenshots annotated with what goes wrong.
|
||||
1. If you are reporting an issue from the browser, Open the Javascript Console and paste us any error messages you see.
|
||||
1. **Share as much information as possible:** Include operating system and version, browser and version, when did you last update ERPNext, how is it customized, etc. where appropriate. Also include steps to reproduce the bug.
|
||||
1. **Include Screenshots if possible:** Consider adding screenshots annotated with what goes wrong.
|
||||
1. **Find and post the trace for bugs:** If you are reporting an issue from the browser, Open the Javascript Console and paste us any error messages you see.
|
||||
|
||||
|
||||
### Feature Requests
|
||||
|
||||
@@ -37,14 +44,10 @@ that function to accommodate your use case.
|
||||
|
||||
DocTypes are easy to create but hard to maintain. If you find that there is a another DocType with a similar functionality, then please try and extend that functionality. For example, by adding a "type" field to classify the new type of record.
|
||||
|
||||
#### Don't Send Trivial Requests
|
||||
|
||||
Don't send pull requests for fixing a simple typo in a code comment.
|
||||
|
||||
#### Tabs or spaces?
|
||||
|
||||
Tabs!
|
||||
|
||||
### Copyright
|
||||
|
||||
Please see README.md
|
||||
Please see README.md
|
||||
|
||||
@@ -16,4 +16,5 @@ recursive-include erpnext *.md
|
||||
recursive-include erpnext *.png
|
||||
recursive-include erpnext *.py
|
||||
recursive-include erpnext *.svg
|
||||
recursive-include erpnext/public *
|
||||
recursive-exclude * *.pyc
|
||||
|
||||
27
README.md
27
README.md
@@ -1,34 +1,31 @@
|
||||
# ERPNext - Open Source ERP for small, medium sized businesses [](https://travis-ci.org/frappe/erpnext)
|
||||
# ERPNext - Open source ERP for small and medium-size business [](https://travis-ci.org/frappe/erpnext)
|
||||
|
||||
[https://erpnext.com](https://erpnext.com)
|
||||
|
||||
Includes Accounting, Inventory, CRM, Sales, Purchase, Projects, HRMS. Built on Python / MySQL.
|
||||
Includes: Accounting, Inventory, CRM, Sales, Purchase, Projects, HRMS. Requires MariaDB.
|
||||
|
||||
ERPNext is built on [frappe](https://github.com/frappe/frappe)
|
||||
ERPNext is built on the [Frappe](https://github.com/frappe/frappe) Framework, a full-stack web app framework in Python & Javascript.
|
||||
|
||||
- [User Guide](http://erpnext.org/user-guide.html)
|
||||
- [User Guide](https://erpnext.com/user-guide)
|
||||
- [Getting Help](http://erpnext.org/getting-help.html)
|
||||
- [Developer Forum](http://groups.google.com/group/erpnext-developer-forum)
|
||||
- [User Forum](http://groups.google.com/group/erpnext-user-forum)
|
||||
- [Discussion Forum](https://discuss.frappe.io/)
|
||||
|
||||
---
|
||||
|
||||
### Development install
|
||||
### Full Install
|
||||
|
||||
Use the bench, https://github.com/frappe/frappe-bench.
|
||||
The Easy Way install script for bench will install all dependencies (e.g. MariaDB). See https://github.com/frappe/bench
|
||||
|
||||
### Admin Login
|
||||
New passwords will be created for the ERPNext "Administrator" user, the MariaDB root user, and the frappe user (the script displays the passwords and saves them to ~/frappe_passwords.txt).
|
||||
|
||||
1. go to "/login"
|
||||
1. Administrator user name: "Administrator"
|
||||
1. Administrator passowrd "admin"
|
||||
### Virtual Image
|
||||
|
||||
### Download and Install
|
||||
|
||||
##### Virtual Image:
|
||||
You can download a virtual image to run ERPNext in a virtual machine on your local system.
|
||||
|
||||
- [ERPNext Download](http://erpnext.com/download)
|
||||
|
||||
System and user credentials are listed on the download page.
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
11
ci/fix-mariadb.sh
Executable file
11
ci/fix-mariadb.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# stolen from http://cgit.drupalcode.org/octopus/commit/?id=db4f837
|
||||
includedir=`mysql_config --variable=pkgincludedir`
|
||||
thiscwd=`pwd`
|
||||
_THIS_DB_VERSION=`mysql -V 2>&1 | tr -d "\n" | cut -d" " -f6 | awk '{ print $1}' | cut -d"-" -f1 | awk '{ print $1}' | sed "s/[\,']//g"`
|
||||
if [ "$_THIS_DB_VERSION" = "5.5.40" ] && [ ! -e "$includedir-$_THIS_DB_VERSION-fixed.log" ] ; then
|
||||
cd $includedir
|
||||
sudo patch -p1 < $thiscwd/ci/my_config.h.patch &> /dev/null
|
||||
sudo touch $includedir-$_THIS_DB_VERSION-fixed.log
|
||||
fi
|
||||
22
ci/my_config.h.patch
Normal file
22
ci/my_config.h.patch
Normal file
@@ -0,0 +1,22 @@
|
||||
diff -burp a/my_config.h b/my_config.h
|
||||
--- a/my_config.h 2014-10-09 19:32:46.000000000 -0400
|
||||
+++ b/my_config.h 2014-10-09 19:35:12.000000000 -0400
|
||||
@@ -641,17 +641,4 @@
|
||||
#define SIZEOF_TIME_T 8
|
||||
/* #undef TIME_T_UNSIGNED */
|
||||
|
||||
-/*
|
||||
- stat structure (from <sys/stat.h>) is conditionally defined
|
||||
- to have different layout and size depending on the defined macros.
|
||||
- The correct macro is defined in my_config.h, which means it MUST be
|
||||
- included first (or at least before <features.h> - so, practically,
|
||||
- before including any system headers).
|
||||
-
|
||||
- __GLIBC__ is defined in <features.h>
|
||||
-*/
|
||||
-#ifdef __GLIBC__
|
||||
-#error <my_config.h> MUST be included first!
|
||||
-#endif
|
||||
-
|
||||
#endif
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = '4.0.1'
|
||||
from erpnext.__version__ import __version__
|
||||
|
||||
1
erpnext/__version__.py
Normal file
1
erpnext/__version__.py
Normal file
@@ -0,0 +1 @@
|
||||
__version__ = '4.20.0'
|
||||
@@ -49,28 +49,25 @@ cur_frm.cscript.master_type = function(doc, cdt, cdn) {
|
||||
}
|
||||
|
||||
cur_frm.add_fetch('parent_account', 'report_type', 'report_type');
|
||||
cur_frm.add_fetch('parent_account', 'root_type', 'root_type');
|
||||
|
||||
cur_frm.cscript.account_type = function(doc, cdt, cdn) {
|
||||
if(doc.group_or_ledger=='Ledger') {
|
||||
cur_frm.toggle_display(['tax_rate'], doc.account_type == 'Tax');
|
||||
cur_frm.toggle_display('master_type', cstr(doc.account_type)=='');
|
||||
cur_frm.toggle_display('master_name', doc.account_type=='Warehouse' ||
|
||||
in_list(['Customer', 'Supplier'], doc.master_type));
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.add_toolbar_buttons = function(doc) {
|
||||
cur_frm.appframe.add_button(__('Chart of Accounts'),
|
||||
cur_frm.add_custom_button(__('Chart of Accounts'),
|
||||
function() { frappe.set_route("Accounts Browser", "Account"); }, 'icon-sitemap')
|
||||
|
||||
if (cstr(doc.group_or_ledger) == 'Group') {
|
||||
cur_frm.add_custom_button(__('Convert to Ledger'),
|
||||
function() { cur_frm.cscript.convert_to_ledger(); }, 'icon-retweet')
|
||||
function() { cur_frm.cscript.convert_to_ledger(); }, 'icon-retweet', 'btn-default');
|
||||
} else if (cstr(doc.group_or_ledger) == 'Ledger') {
|
||||
cur_frm.add_custom_button(__('Convert to Group'),
|
||||
function() { cur_frm.cscript.convert_to_group(); }, 'icon-retweet')
|
||||
|
||||
cur_frm.appframe.add_button(__('View Ledger'), function() {
|
||||
cur_frm.add_custom_button(__('View Ledger'), function() {
|
||||
frappe.route_options = {
|
||||
"account": doc.name,
|
||||
"from_date": sys_defaults.year_start_date,
|
||||
@@ -79,6 +76,9 @@ cur_frm.cscript.add_toolbar_buttons = function(doc) {
|
||||
};
|
||||
frappe.set_route("query-report", "General Ledger");
|
||||
}, "icon-table");
|
||||
|
||||
cur_frm.add_custom_button(__('Convert to Group'),
|
||||
function() { cur_frm.cscript.convert_to_group(); }, 'icon-retweet', 'btn-default')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,322 +1,332 @@
|
||||
{
|
||||
"allow_copy": 1,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"creation": "2013-01-30 12:49:46",
|
||||
"description": "Heads (or groups) against which Accounting Entries are made and balances are maintained.",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Master",
|
||||
"allow_copy": 1,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"creation": "2013-01-30 12:49:46",
|
||||
"description": "Heads (or groups) against which Accounting Entries are made and balances are maintained.",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Master",
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "properties",
|
||||
"fieldtype": "Section Break",
|
||||
"in_list_view": 0,
|
||||
"label": "Account Details",
|
||||
"oldfieldtype": "Section Break",
|
||||
"fieldname": "properties",
|
||||
"fieldtype": "Section Break",
|
||||
"in_list_view": 0,
|
||||
"label": "Account Details",
|
||||
"oldfieldtype": "Section Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break0",
|
||||
"fieldtype": "Column Break",
|
||||
"in_list_view": 0,
|
||||
"permlevel": 0,
|
||||
"fieldname": "column_break0",
|
||||
"fieldtype": "Column Break",
|
||||
"in_list_view": 0,
|
||||
"permlevel": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "account_name",
|
||||
"fieldtype": "Data",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Account Name",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "account_name",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 1,
|
||||
"fieldname": "account_name",
|
||||
"fieldtype": "Data",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Account Name",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "account_name",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"default": "Ledger",
|
||||
"fieldname": "group_or_ledger",
|
||||
"fieldtype": "Select",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Group or Ledger",
|
||||
"oldfieldname": "group_or_ledger",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nLedger\nGroup",
|
||||
"permlevel": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 1,
|
||||
"default": "Ledger",
|
||||
"fieldname": "group_or_ledger",
|
||||
"fieldtype": "Select",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Group or Ledger",
|
||||
"oldfieldname": "group_or_ledger",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nLedger\nGroup",
|
||||
"permlevel": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"label": "Company",
|
||||
"oldfieldname": "company",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 1,
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"label": "Company",
|
||||
"oldfieldname": "company",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "parent_account",
|
||||
"fieldtype": "Link",
|
||||
"ignore_restrictions": 1,
|
||||
"label": "Parent Account",
|
||||
"oldfieldname": "parent_account",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"fieldname": "parent_account",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Parent Account",
|
||||
"oldfieldname": "parent_account",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "report_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Report Type",
|
||||
"options": "\nBalance Sheet\nProfit and Loss",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"description": "Setting Account Type helps in selecting this Account in transactions.",
|
||||
"fieldname": "account_type",
|
||||
"fieldtype": "Select",
|
||||
"in_filter": 1,
|
||||
"label": "Account Type",
|
||||
"oldfieldname": "account_type",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nBank\nCash\nTax\nChargeable\nWarehouse\nReceivable\nPayable\nEquity\nFixed Asset\nCost of Goods Sold\nExpense Account\nIncome Account\nStock Received But Not Billed\nExpenses Included In Valuation\nStock Adjustment",
|
||||
"permlevel": 0,
|
||||
"description": "Setting Account Type helps in selecting this Account in transactions.",
|
||||
"fieldname": "account_type",
|
||||
"fieldtype": "Select",
|
||||
"in_filter": 1,
|
||||
"label": "Account Type",
|
||||
"oldfieldname": "account_type",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nBank\nCash\nTax\nChargeable\nWarehouse\nReceivable\nPayable\nEquity\nFixed Asset\nCost of Goods Sold\nExpense Account\nIncome Account\nStock Received But Not Billed\nExpenses Included In Valuation\nStock Adjustment\nStock",
|
||||
"permlevel": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "Rate at which this tax is applied",
|
||||
"fieldname": "tax_rate",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
"label": "Rate",
|
||||
"oldfieldname": "tax_rate",
|
||||
"oldfieldtype": "Currency",
|
||||
"permlevel": 0,
|
||||
"description": "Rate at which this tax is applied",
|
||||
"fieldname": "tax_rate",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
"label": "Rate",
|
||||
"oldfieldname": "tax_rate",
|
||||
"oldfieldtype": "Currency",
|
||||
"permlevel": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "If the account is frozen, entries are allowed to restricted users.",
|
||||
"fieldname": "freeze_account",
|
||||
"fieldtype": "Select",
|
||||
"label": "Frozen",
|
||||
"oldfieldname": "freeze_account",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "No\nYes",
|
||||
"description": "If the account is frozen, entries are allowed to restricted users.",
|
||||
"fieldname": "freeze_account",
|
||||
"fieldtype": "Select",
|
||||
"label": "Frozen",
|
||||
"oldfieldname": "freeze_account",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "No\nYes",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "credit_days",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 1,
|
||||
"label": "Credit Days",
|
||||
"oldfieldname": "credit_days",
|
||||
"oldfieldtype": "Int",
|
||||
"permlevel": 0,
|
||||
"fieldname": "credit_days",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 1,
|
||||
"label": "Credit Days",
|
||||
"oldfieldname": "credit_days",
|
||||
"oldfieldtype": "Int",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "credit_limit",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 1,
|
||||
"label": "Credit Limit",
|
||||
"oldfieldname": "credit_limit",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"fieldname": "credit_limit",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 1,
|
||||
"label": "Credit Limit",
|
||||
"oldfieldname": "credit_limit",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "If this Account represents a Customer, Supplier or Employee, set it here.",
|
||||
"fieldname": "master_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Master Type",
|
||||
"oldfieldname": "master_type",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nSupplier\nCustomer\nEmployee",
|
||||
"description": "If this Account represents a Customer, Supplier or Employee, set it here.",
|
||||
"fieldname": "master_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Master Type",
|
||||
"oldfieldname": "master_type",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nSupplier\nCustomer\nEmployee",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "master_name",
|
||||
"fieldtype": "Link",
|
||||
"label": "Master Name",
|
||||
"oldfieldname": "master_name",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "[Select]",
|
||||
"fieldname": "master_name",
|
||||
"fieldtype": "Link",
|
||||
"label": "Master Name",
|
||||
"oldfieldname": "master_name",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "[Select]",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "balance_must_be",
|
||||
"fieldtype": "Select",
|
||||
"label": "Balance must be",
|
||||
"options": "\nDebit\nCredit",
|
||||
"fieldname": "balance_must_be",
|
||||
"fieldtype": "Select",
|
||||
"label": "Balance must be",
|
||||
"options": "\nDebit\nCredit",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "lft",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 1,
|
||||
"label": "Lft",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"fieldname": "root_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Root Type",
|
||||
"options": "\nAsset\nLiability\nIncome\nExpense\nEquity",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "rgt",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 1,
|
||||
"label": "Rgt",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"fieldname": "report_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Report Type",
|
||||
"options": "\nBalance Sheet\nProfit and Loss",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "old_parent",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Old Parent",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"fieldname": "lft",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 1,
|
||||
"label": "Lft",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "rgt",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 1,
|
||||
"label": "Rgt",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "old_parent",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Old Parent",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"icon": "icon-money",
|
||||
"idx": 1,
|
||||
"in_create": 1,
|
||||
"modified": "2014-05-12 17:03:19.733139",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Account",
|
||||
"owner": "Administrator",
|
||||
],
|
||||
"icon": "icon-money",
|
||||
"idx": 1,
|
||||
"in_create": 1,
|
||||
"modified": "2014-06-19 18:27:58.109303",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Account",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"import": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"submit": 0,
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"import": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Auditor",
|
||||
"submit": 0,
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Auditor",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Sales User",
|
||||
"submit": 0,
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Sales User",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Purchase User",
|
||||
"submit": 0,
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Purchase User",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"permlevel": 2,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Auditor",
|
||||
"submit": 0,
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"permlevel": 2,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Auditor",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"import": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"restrict": 1,
|
||||
"role": "Accounts Manager",
|
||||
"submit": 0,
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"import": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"set_user_permissions": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"permlevel": 2,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"submit": 0,
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"permlevel": 2,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"permlevel": 2,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"submit": 0,
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"permlevel": 2,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
}
|
||||
],
|
||||
],
|
||||
"search_fields": "group_or_ledger"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.utils import flt, cstr, cint, getdate, add_days, formatdate
|
||||
from frappe.utils import flt, cstr, cint, getdate
|
||||
from frappe import msgprint, throw, _
|
||||
from frappe.model.document import Document
|
||||
|
||||
@@ -11,11 +11,11 @@ class Account(Document):
|
||||
nsm_parent_field = 'parent_account'
|
||||
|
||||
def onload(self):
|
||||
frozen_accounts_modifier = frappe.db.get_value("Accounts Settings", "Accounts Settings", "frozen_accounts_modifier")
|
||||
if frozen_accounts_modifier in frappe.user.get_roles():
|
||||
frozen_accounts_modifier = frappe.db.get_value("Accounts Settings", "Accounts Settings",
|
||||
"frozen_accounts_modifier")
|
||||
if not frozen_accounts_modifier or frozen_accounts_modifier in frappe.user.get_roles():
|
||||
self.get("__onload").can_freeze_account = True
|
||||
|
||||
|
||||
def autoname(self):
|
||||
self.name = self.account_name.strip() + ' - ' + \
|
||||
frappe.db.get_value("Company", self.company, "abbr")
|
||||
@@ -30,6 +30,7 @@ class Account(Document):
|
||||
self.validate_mandatory()
|
||||
self.validate_warehouse_account()
|
||||
self.validate_frozen_accounts_modifier()
|
||||
self.validate_balance_must_be_debit_or_credit()
|
||||
|
||||
def validate_master_name(self):
|
||||
if self.master_type in ('Customer', 'Supplier') or self.account_type == "Warehouse":
|
||||
@@ -39,19 +40,24 @@ class Account(Document):
|
||||
throw(_("Invalid Master Name"))
|
||||
|
||||
def validate_parent(self):
|
||||
"""Fetch Parent Details and validation for account not to be created under ledger"""
|
||||
"""Fetch Parent Details and validate parent account"""
|
||||
if self.parent_account:
|
||||
par = frappe.db.get_value("Account", self.parent_account,
|
||||
["name", "group_or_ledger", "report_type"], as_dict=1)
|
||||
["name", "group_or_ledger", "report_type", "root_type", "company"], as_dict=1)
|
||||
if not par:
|
||||
throw(_("Parent account does not exist"))
|
||||
elif par["name"] == self.name:
|
||||
throw(_("You can not assign itself as parent account"))
|
||||
elif par["group_or_ledger"] != 'Group':
|
||||
throw(_("Parent account can not be a ledger"))
|
||||
throw(_("Account {0}: Parent account {1} does not exist").format(self.name, self.parent_account))
|
||||
elif par.name == self.name:
|
||||
throw(_("Account {0}: You can not assign itself as parent account").format(self.name))
|
||||
elif par.group_or_ledger != 'Group':
|
||||
throw(_("Account {0}: Parent account {1} can not be a ledger").format(self.name, self.parent_account))
|
||||
elif par.company != self.company:
|
||||
throw(_("Account {0}: Parent account {1} does not belong to company: {2}")
|
||||
.format(self.name, self.parent_account, self.company))
|
||||
|
||||
if par["report_type"]:
|
||||
self.report_type = par["report_type"]
|
||||
if par.report_type:
|
||||
self.report_type = par.report_type
|
||||
if par.root_type:
|
||||
self.root_type = par.root_type
|
||||
|
||||
def validate_root_details(self):
|
||||
#does not exists parent
|
||||
@@ -67,6 +73,16 @@ class Account(Document):
|
||||
frozen_accounts_modifier not in frappe.user.get_roles():
|
||||
throw(_("You are not authorized to set Frozen value"))
|
||||
|
||||
def validate_balance_must_be_debit_or_credit(self):
|
||||
from erpnext.accounts.utils import get_balance_on
|
||||
if not self.get("__islocal") and self.balance_must_be:
|
||||
account_balance = get_balance_on(self.name)
|
||||
|
||||
if account_balance > 0 and self.balance_must_be == "Credit":
|
||||
frappe.throw(_("Account balance already in Debit, you are not allowed to set 'Balance Must Be' as 'Credit'"))
|
||||
elif account_balance < 0 and self.balance_must_be == "Debit":
|
||||
frappe.throw(_("Account balance already in Credit, you are not allowed to set 'Balance Must Be' as 'Debit'"))
|
||||
|
||||
def convert_group_to_ledger(self):
|
||||
if self.check_if_child_exists():
|
||||
throw(_("Account with child nodes cannot be converted to ledger"))
|
||||
@@ -99,6 +115,9 @@ class Account(Document):
|
||||
if not self.report_type:
|
||||
throw(_("Report Type is mandatory"))
|
||||
|
||||
if not self.root_type:
|
||||
throw(_("Root Type is mandatory"))
|
||||
|
||||
def validate_warehouse_account(self):
|
||||
if not cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
|
||||
return
|
||||
@@ -146,28 +165,18 @@ class Account(Document):
|
||||
# If outstanding greater than credit limit and not authorized person raise exception
|
||||
if credit_limit > 0 and flt(total_outstanding) > credit_limit \
|
||||
and not self.get_authorized_user():
|
||||
throw(_("{0} Credit limit {0} crossed").format(_(credit_limit_from), credit_limit))
|
||||
throw(_("{0} Credit limit {1} crossed").format(_(credit_limit_from), credit_limit))
|
||||
|
||||
def validate_due_date(self, posting_date, due_date):
|
||||
credit_days = (self.credit_days or frappe.db.get_value("Company", self.company, "credit_days"))
|
||||
if credit_days is None:
|
||||
return
|
||||
|
||||
posting_date, due_date = getdate(posting_date), getdate(due_date)
|
||||
diff = (due_date - posting_date).days
|
||||
|
||||
if diff < 0:
|
||||
frappe.throw(_("Due Date cannot be before Posting Date"))
|
||||
elif diff > credit_days:
|
||||
is_credit_controller = frappe.db.get_value("Accounts Settings", None,
|
||||
"credit_controller") in frappe.user.get_roles()
|
||||
|
||||
if is_credit_controller:
|
||||
msgprint(_("Note: Due Date exceeds the allowed credit days by {0} day(s)").format(
|
||||
diff - credit_days))
|
||||
else:
|
||||
max_due_date = formatdate(add_days(posting_date, credit_days))
|
||||
frappe.throw(_("Due Date cannot be after {0}").format(max_due_date))
|
||||
elif credit_days is not None and diff > credit_days:
|
||||
msgprint(_("Note: Due Date exceeds the allowed credit days by {0} day(s)").format(diff - credit_days))
|
||||
|
||||
def validate_trash(self):
|
||||
"""checks gl entries and if child exists"""
|
||||
@@ -194,10 +203,10 @@ class Account(Document):
|
||||
throw(_("Account {0} does not exist").format(new))
|
||||
|
||||
val = list(frappe.db.get_value("Account", new_account,
|
||||
["group_or_ledger", "report_type", "company"]))
|
||||
["group_or_ledger", "root_type", "company"]))
|
||||
|
||||
if val != [self.group_or_ledger, self.report_type, self.company]:
|
||||
throw(_("""Merging is only possible if following properties are same in both records. Group or Ledger, Report Type, Company"""))
|
||||
if val != [self.group_or_ledger, self.root_type, self.company]:
|
||||
throw(_("""Merging is only possible if following properties are same in both records. Group or Ledger, Root Type, Company"""))
|
||||
|
||||
return new_account
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ def _make_test_records(verbose):
|
||||
["_Test Account Stock Expenses", "Direct Expenses", "Group", None],
|
||||
["_Test Account Shipping Charges", "_Test Account Stock Expenses", "Ledger", "Chargeable"],
|
||||
["_Test Account Customs Duty", "_Test Account Stock Expenses", "Ledger", "Tax"],
|
||||
["_Test Account Insurance Charges", "_Test Account Stock Expenses", "Ledger", "Chargeable"],
|
||||
|
||||
|
||||
["_Test Account Tax Assets", "Current Assets", "Group", None],
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
"icon": "icon-check",
|
||||
"idx": 1,
|
||||
"issingle": 1,
|
||||
"modified": "2014-05-06 16:26:08.984595",
|
||||
"modified": "2014-05-27 03:37:21.783216",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Reconciliation",
|
||||
@@ -93,6 +93,7 @@
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"permlevel": 0,
|
||||
|
||||
@@ -24,7 +24,8 @@ class BankReconciliation(Document):
|
||||
`tabJournal Voucher` t1, `tabJournal Voucher Detail` t2
|
||||
where
|
||||
t2.parent = t1.name and t2.account = %s
|
||||
and t1.posting_date >= %s and t1.posting_date <= %s and t1.docstatus=1 %s""" %
|
||||
and t1.posting_date >= %s and t1.posting_date <= %s and t1.docstatus=1
|
||||
and ifnull(t1.is_opening, 'No') = 'No' %s""" %
|
||||
('%s', '%s', '%s', condition), (self.bank_account, self.from_date, self.to_date), as_dict=1)
|
||||
|
||||
self.set('entries', [])
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"allow_attach": 1,
|
||||
"allow_import": 1,
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2013-03-07 11:55:06",
|
||||
"docstatus": 0,
|
||||
@@ -126,7 +126,7 @@
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"ignore_restrictions": 1,
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"options": "C-Form",
|
||||
@@ -139,13 +139,14 @@
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"max_attachments": 3,
|
||||
"modified": "2014-05-09 02:18:00.162685",
|
||||
"modified": "2014-09-05 12:58:43.333698",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "C-Form",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"apply_user_permissions": 1,
|
||||
"create": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
|
||||
@@ -17,15 +17,19 @@ class CForm(Document):
|
||||
inv = frappe.db.sql("""select c_form_applicable, c_form_no from
|
||||
`tabSales Invoice` where name = %s and docstatus = 1""", d.invoice_no)
|
||||
|
||||
if inv[0][0] != 'Yes':
|
||||
if inv and inv[0][0] != 'Yes':
|
||||
frappe.throw("C-form is not applicable for Invoice: %s" % d.invoice_no)
|
||||
|
||||
elif inv[0][1] and inv[0][1] != self.name:
|
||||
elif inv and inv[0][1] and inv[0][1] != self.name:
|
||||
frappe.throw("""Invoice %s is tagged in another C-form: %s.
|
||||
If you want to change C-form no for this invoice,
|
||||
please remove invoice no from the previous c-form and then try again""" %
|
||||
(d.invoice_no, inv[0][1]))
|
||||
|
||||
elif not inv:
|
||||
frappe.throw("Row %s: Invoice %s is invalid, it might be cancelled / does not exist. \
|
||||
Please enter a valid Invoice" % d.idx, d.invoice_no)
|
||||
|
||||
def on_update(self):
|
||||
""" Update C-Form No on invoices"""
|
||||
self.set_total_invoiced_amount()
|
||||
@@ -55,22 +59,12 @@ class CForm(Document):
|
||||
|
||||
def get_invoice_details(self, invoice_no):
|
||||
""" Pull details from invoices for referrence """
|
||||
|
||||
inv = frappe.db.get_value("Sales Invoice", invoice_no,
|
||||
["posting_date", "territory", "net_total", "grand_total"], as_dict=True)
|
||||
return {
|
||||
'invoice_date' : inv.posting_date,
|
||||
'territory' : inv.territory,
|
||||
'net_total' : inv.net_total,
|
||||
'grand_total' : inv.grand_total
|
||||
}
|
||||
|
||||
def get_invoice_nos(doctype, txt, searchfield, start, page_len, filters):
|
||||
from erpnext.utilities import build_filter_conditions
|
||||
conditions, filter_values = build_filter_conditions(filters)
|
||||
|
||||
return frappe.db.sql("""select name from `tabSales Invoice` where docstatus = 1
|
||||
and c_form_applicable = 'Yes' and ifnull(c_form_no, '') = '' %s
|
||||
and %s like %s order by name limit %s, %s""" %
|
||||
(conditions, searchfield, "%s", "%s", "%s"),
|
||||
tuple(filter_values + ["%%%s%%" % txt, start, page_len]))
|
||||
if invoice_no:
|
||||
inv = frappe.db.get_value("Sales Invoice", invoice_no,
|
||||
["posting_date", "territory", "net_total", "grand_total"], as_dict=True)
|
||||
return {
|
||||
'invoice_date' : inv.posting_date,
|
||||
'territory' : inv.territory,
|
||||
'net_total' : inv.net_total,
|
||||
'grand_total' : inv.grand_total
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ from __future__ import unicode_literals
|
||||
import os, json
|
||||
import ast
|
||||
from xml.etree import ElementTree as ET
|
||||
from frappe.utils.datautils import read_csv_content
|
||||
from frappe.utils.csvutils import read_csv_content
|
||||
from frappe.utils import cstr
|
||||
import frappe
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
||||
import frappe, os, json
|
||||
|
||||
def import_charts():
|
||||
print "Importing Chart of Accounts"
|
||||
frappe.db.sql("""delete from `tabChart of Accounts`""")
|
||||
charts_dir = os.path.join(os.path.dirname(__file__), "charts")
|
||||
for fname in os.listdir(charts_dir):
|
||||
@@ -19,8 +20,8 @@ def import_charts():
|
||||
"source_file": fname,
|
||||
"country": country
|
||||
}).insert()
|
||||
print doc.name.encode("utf-8")
|
||||
else:
|
||||
print "No chart for: " + chart.get("name").encode("utf-8")
|
||||
|
||||
frappe.db.commit()
|
||||
#print doc.name.encode("utf-8")
|
||||
#else:
|
||||
#print "No chart for: " + chart.get("name").encode("utf-8")
|
||||
|
||||
frappe.db.commit()
|
||||
|
||||
@@ -64,10 +64,12 @@ cur_frm.cscript.parent_cost_center = function(doc, cdt, cdn) {
|
||||
cur_frm.cscript.hide_unhide_group_ledger = function(doc) {
|
||||
if (cstr(doc.group_or_ledger) == 'Group') {
|
||||
cur_frm.add_custom_button(__('Convert to Ledger'),
|
||||
function() { cur_frm.cscript.convert_to_ledger(); }, 'icon-retweet')
|
||||
function() { cur_frm.cscript.convert_to_ledger(); }, 'icon-retweet',
|
||||
"btn-default")
|
||||
} else if (cstr(doc.group_or_ledger) == 'Ledger') {
|
||||
cur_frm.add_custom_button(__('Convert to Group'),
|
||||
function() { cur_frm.cscript.convert_to_group(); }, 'icon-retweet')
|
||||
function() { cur_frm.cscript.convert_to_group(); }, 'icon-retweet',
|
||||
"btn-default")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
{
|
||||
"fieldname": "parent_cost_center",
|
||||
"fieldtype": "Link",
|
||||
"ignore_restrictions": 1,
|
||||
"ignore_user_permissions": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Parent Cost Center",
|
||||
"oldfieldname": "parent_cost_center",
|
||||
@@ -131,7 +131,7 @@
|
||||
"fieldname": "old_parent",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"ignore_restrictions": 1,
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "old_parent",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "old_parent",
|
||||
@@ -144,8 +144,8 @@
|
||||
],
|
||||
"icon": "icon-money",
|
||||
"idx": 1,
|
||||
"in_create": 1,
|
||||
"modified": "2014-05-07 06:37:48.038993",
|
||||
"in_create": 0,
|
||||
"modified": "2014-08-26 12:16:11.163750",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Cost Center",
|
||||
@@ -153,7 +153,6 @@
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
@@ -167,7 +166,7 @@
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
@@ -180,16 +179,19 @@
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"apply_user_permissions": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"role": "Sales User"
|
||||
},
|
||||
{
|
||||
"apply_user_permissions": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"role": "Purchase User"
|
||||
},
|
||||
{
|
||||
"apply_user_permissions": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"role": "Material User"
|
||||
|
||||
@@ -15,5 +15,12 @@
|
||||
"doctype": "Cost Center",
|
||||
"group_or_ledger": "Ledger",
|
||||
"parent_cost_center": "_Test Company - _TC"
|
||||
},
|
||||
{
|
||||
"company": "_Test Company",
|
||||
"cost_center_name": "_Test Cost Center 2",
|
||||
"doctype": "Cost Center",
|
||||
"group_or_ledger": "Ledger",
|
||||
"parent_cost_center": "_Test Company - _TC"
|
||||
}
|
||||
]
|
||||
@@ -14,7 +14,8 @@ $.extend(cur_frm.cscript, {
|
||||
this.frm.toggle_enable('year_end_date', doc.__islocal)
|
||||
|
||||
if (!doc.__islocal && (doc.name != sys_defaults.fiscal_year)) {
|
||||
this.frm.add_custom_button(__("Set as Default"), this.frm.cscript.set_as_default);
|
||||
this.frm.add_custom_button(__("Set as Default"),
|
||||
this.frm.cscript.set_as_default, "icon-star");
|
||||
this.frm.set_intro(__("To set this Fiscal Year as Default, click on 'Set as Default'"));
|
||||
} else {
|
||||
this.frm.set_intro("");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"allow_import": 1,
|
||||
"autoname": "field:year",
|
||||
"creation": "2013-01-22 16:50:25.000000",
|
||||
"creation": "2013-01-22 16:50:25",
|
||||
"description": "**Fiscal Year** represents a Financial Year. All accounting entries and other major transactions are tracked against **Fiscal Year**.",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
@@ -11,6 +11,7 @@
|
||||
"description": "For e.g. 2012, 2012-13",
|
||||
"fieldname": "year",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Year Name",
|
||||
"oldfieldname": "year",
|
||||
"oldfieldtype": "Data",
|
||||
@@ -20,6 +21,7 @@
|
||||
{
|
||||
"fieldname": "year_start_date",
|
||||
"fieldtype": "Date",
|
||||
"in_list_view": 1,
|
||||
"label": "Year Start Date",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "year_start_date",
|
||||
@@ -30,6 +32,7 @@
|
||||
{
|
||||
"fieldname": "year_end_date",
|
||||
"fieldtype": "Date",
|
||||
"in_list_view": 1,
|
||||
"label": "Year End Date",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
@@ -40,6 +43,7 @@
|
||||
"description": "Entries are not allowed against this Fiscal Year if the year is closed.",
|
||||
"fieldname": "is_fiscal_year_closed",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Year Closed",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "is_fiscal_year_closed",
|
||||
@@ -51,14 +55,13 @@
|
||||
],
|
||||
"icon": "icon-calendar",
|
||||
"idx": 1,
|
||||
"modified": "2014-01-20 17:48:46.000000",
|
||||
"modified": "2014-07-14 05:30:56.843180",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Fiscal Year",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
@@ -71,6 +74,7 @@
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"apply_user_permissions": 1,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
@@ -78,5 +82,7 @@
|
||||
"read": 1,
|
||||
"role": "All"
|
||||
}
|
||||
]
|
||||
],
|
||||
"sort_field": "name",
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
@@ -25,15 +25,15 @@ class FiscalYear(Document):
|
||||
|
||||
if year_start_end_dates:
|
||||
if getdate(self.year_start_date) != year_start_end_dates[0][0] or getdate(self.year_end_date) != year_start_end_dates[0][1]:
|
||||
frappe.throw(_("Cannot change Year Start Date and Year End Date once the Fiscal Year is saved."))
|
||||
frappe.throw(_("Cannot change Fiscal Year Start Date and Fiscal Year End Date once the Fiscal Year is saved."))
|
||||
|
||||
def on_update(self):
|
||||
# validate year start date and year end date
|
||||
if getdate(self.year_start_date) > getdate(self.year_end_date):
|
||||
frappe.throw(_("Year Start Date should not be greater than Year End Date"))
|
||||
frappe.throw(_("Fiscal Year Start Date should not be greater than Fiscal Year End Date"))
|
||||
|
||||
if (getdate(self.year_end_date) - getdate(self.year_start_date)).days > 366:
|
||||
frappe.throw(_("Year Start Date and Year End Date are not within Fiscal Year."))
|
||||
frappe.throw(_("Fiscal Year Start Date and Fiscal Year End Date cannot be more than a year apart."))
|
||||
|
||||
year_start_end_dates = frappe.db.sql("""select name, year_start_date, year_end_date
|
||||
from `tabFiscal Year` where name!=%s""", (self.name))
|
||||
@@ -41,4 +41,4 @@ class FiscalYear(Document):
|
||||
for fiscal_year, ysd, yed in year_start_end_dates:
|
||||
if (getdate(self.year_start_date) == ysd and getdate(self.year_end_date) == yed) \
|
||||
and (not frappe.flags.in_test):
|
||||
frappe.throw(_("Year Start Date and Year End Date are already set in Fiscal Year {0}").format(fiscal_year))
|
||||
frappe.throw(_("Fiscal Year Start Date and Fiscal Year End Date are already set in Fiscal Year {0}").format(fiscal_year))
|
||||
|
||||
@@ -86,44 +86,47 @@
|
||||
"oldfieldtype": "Text",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "against_voucher",
|
||||
"fieldtype": "Data",
|
||||
"in_filter": 1,
|
||||
"label": "Against Voucher",
|
||||
"oldfieldname": "against_voucher",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "against_voucher_type",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 0,
|
||||
"label": "Against Voucher Type",
|
||||
"oldfieldname": "against_voucher_type",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "against_voucher",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"in_filter": 1,
|
||||
"label": "Against Voucher",
|
||||
"oldfieldname": "against_voucher",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "against_voucher_type",
|
||||
"permlevel": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "voucher_type",
|
||||
"fieldtype": "Select",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"label": "Voucher Type",
|
||||
"oldfieldname": "voucher_type",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Journal Voucher\nSales Invoice\nPurchase Invoice",
|
||||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "voucher_no",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"in_filter": 1,
|
||||
"label": "Voucher No",
|
||||
"oldfieldname": "voucher_no",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "voucher_type",
|
||||
"permlevel": 0,
|
||||
"search_index": 1
|
||||
},
|
||||
@@ -186,7 +189,7 @@
|
||||
"icon": "icon-list",
|
||||
"idx": 1,
|
||||
"in_create": 1,
|
||||
"modified": "2014-05-09 02:16:29.981405",
|
||||
"modified": "2014-06-23 08:07:30.678730",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "GL Entry",
|
||||
@@ -194,9 +197,10 @@
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"create": 0,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
@@ -207,9 +211,9 @@
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
@@ -217,17 +221,6 @@
|
||||
"role": "Accounts Manager",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"create": 0,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
}
|
||||
],
|
||||
"search_fields": "voucher_no,account,posting_date,against_voucher",
|
||||
|
||||
@@ -25,7 +25,8 @@ class GLEntry(Document):
|
||||
validate_balance_type(self.account, adv_adj)
|
||||
|
||||
# Update outstanding amt on against voucher
|
||||
if self.against_voucher and update_outstanding == 'Yes':
|
||||
if self.against_voucher_type in ['Journal Voucher', 'Sales Invoice', 'Purchase Invoice'] \
|
||||
and self.against_voucher and update_outstanding == 'Yes':
|
||||
update_outstanding_amt(self.account, self.against_voucher_type,
|
||||
self.against_voucher)
|
||||
|
||||
@@ -123,6 +124,10 @@ def update_outstanding_amt(account, against_voucher_type, against_voucher, on_ca
|
||||
from `tabGL Entry` where voucher_type = 'Journal Voucher' and voucher_no = %s
|
||||
and account = %s and ifnull(against_voucher, '') = ''""",
|
||||
(against_voucher, account))[0][0])
|
||||
if not against_voucher_amount:
|
||||
frappe.throw(_("Against Journal Voucher {0} is already adjusted against some other voucher")
|
||||
.format(against_voucher))
|
||||
|
||||
bal = against_voucher_amount + bal
|
||||
if against_voucher_amount < 0:
|
||||
bal = -bal
|
||||
|
||||
@@ -7,6 +7,11 @@ erpnext.accounts.JournalVoucher = frappe.ui.form.Controller.extend({
|
||||
onload: function() {
|
||||
this.load_defaults();
|
||||
this.setup_queries();
|
||||
this.setup_balance_formatter();
|
||||
},
|
||||
|
||||
onload_post_render: function() {
|
||||
cur_frm.get_field("entries").grid.set_multiple_add("account");
|
||||
},
|
||||
|
||||
load_defaults: function() {
|
||||
@@ -62,6 +67,18 @@ erpnext.accounts.JournalVoucher = frappe.ui.form.Controller.extend({
|
||||
});
|
||||
},
|
||||
|
||||
setup_balance_formatter: function() {
|
||||
var df = frappe.meta.get_docfield("Journal Voucher Detail", "balance", this.frm.doc.name);
|
||||
df.formatter = function(value, df, options, doc) {
|
||||
var currency = frappe.meta.get_field_currency(df, doc);
|
||||
var dr_or_cr = value ? ('<label>' + (value > 0.0 ? __("Dr") : __("Cr")) + '</label>') : "";
|
||||
return "<div style='text-align: right'>"
|
||||
+ ((value==null || value==="") ? "" : format_currency(Math.abs(value), currency))
|
||||
+ " " + dr_or_cr
|
||||
+ "</div>";
|
||||
}
|
||||
},
|
||||
|
||||
against_voucher: function(doc, cdt, cdn) {
|
||||
var d = frappe.get_doc(cdt, cdn);
|
||||
if (d.against_voucher && !flt(d.debit)) {
|
||||
@@ -104,7 +121,6 @@ erpnext.accounts.JournalVoucher = frappe.ui.form.Controller.extend({
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
cur_frm.script_manager.make(erpnext.accounts.JournalVoucher);
|
||||
@@ -197,10 +213,11 @@ cur_frm.cscript.voucher_type = function(doc, cdt, cdn) {
|
||||
return;
|
||||
|
||||
var update_jv_details = function(doc, r) {
|
||||
$.each(r.message, function(i, d) {
|
||||
var jvdetail = frappe.model.add_child(doc, "Journal Voucher Detail", "entries");
|
||||
jvdetail.account = d.account;
|
||||
jvdetail.balance = d.balance;
|
||||
var jvdetail = frappe.model.add_child(doc, "Journal Voucher Detail", "entries");
|
||||
$.each(r, function(i, d) {
|
||||
var row = frappe.model.add_child(doc, "Journal Voucher Detail", "entries");
|
||||
row.account = d.account;
|
||||
row.balance = d.balance;
|
||||
});
|
||||
refresh_field("entries");
|
||||
}
|
||||
@@ -215,7 +232,7 @@ cur_frm.cscript.voucher_type = function(doc, cdt, cdn) {
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
update_jv_details(doc, r);
|
||||
update_jv_details(doc, [r.message]);
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -229,7 +246,7 @@ cur_frm.cscript.voucher_type = function(doc, cdt, cdn) {
|
||||
callback: function(r) {
|
||||
frappe.model.clear_table(doc, "entries");
|
||||
if(r.message) {
|
||||
update_jv_details(doc, r);
|
||||
update_jv_details(doc, r.message);
|
||||
}
|
||||
cur_frm.set_value("is_opening", "Yes")
|
||||
}
|
||||
|
||||
@@ -123,12 +123,6 @@
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break99",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "difference",
|
||||
"fieldtype": "Currency",
|
||||
@@ -150,10 +144,8 @@
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "reference",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Reference",
|
||||
"options": "icon-pushpin",
|
||||
"fieldname": "column_break99",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
@@ -181,6 +173,31 @@
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "user_remark",
|
||||
"fieldtype": "Small Text",
|
||||
"in_filter": 1,
|
||||
"label": "User Remark",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "user_remark",
|
||||
"oldfieldtype": "Small Text",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "view_details",
|
||||
"fieldtype": "Fold",
|
||||
"label": "View Details",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "reference",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Reference",
|
||||
"options": "icon-pushpin",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "clearance_date",
|
||||
"fieldtype": "Date",
|
||||
@@ -194,23 +211,6 @@
|
||||
"read_only": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break98",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "user_remark",
|
||||
"fieldtype": "Small Text",
|
||||
"in_filter": 1,
|
||||
"label": "User Remark",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "user_remark",
|
||||
"oldfieldtype": "Small Text",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"description": "User Remark will be added to Auto Remark",
|
||||
"fieldname": "remark",
|
||||
@@ -224,6 +224,12 @@
|
||||
"read_only": 1,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break98",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "bill_no",
|
||||
"fieldtype": "Data",
|
||||
@@ -333,6 +339,7 @@
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "letter_head",
|
||||
"fieldtype": "Link",
|
||||
"label": "Letter Head",
|
||||
@@ -426,7 +433,7 @@
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"ignore_restrictions": 1,
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
@@ -440,7 +447,7 @@
|
||||
"icon": "icon-file-text",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-09 02:16:47.686703",
|
||||
"modified": "2014-09-09 05:35:31.217863",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Journal Voucher",
|
||||
@@ -448,6 +455,7 @@
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 1,
|
||||
"apply_user_permissions": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
@@ -476,6 +484,7 @@
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
from frappe.utils import cint, cstr, flt, fmt_money, formatdate, getdate
|
||||
from frappe import msgprint, _
|
||||
from frappe.utils import cstr, flt, fmt_money, formatdate, getdate
|
||||
from frappe import msgprint, _, scrub
|
||||
from erpnext.setup.utils import get_company_currency
|
||||
|
||||
from erpnext.controllers.accounts_controller import AccountsController
|
||||
@@ -13,10 +13,6 @@ from erpnext.controllers.accounts_controller import AccountsController
|
||||
class JournalVoucher(AccountsController):
|
||||
def __init__(self, arg1, arg2=None):
|
||||
super(JournalVoucher, self).__init__(arg1, arg2)
|
||||
self.master_type = {}
|
||||
self.credit_days_for = {}
|
||||
self.credit_days_global = -1
|
||||
self.is_approving_authority = -1
|
||||
|
||||
def validate(self):
|
||||
if not self.is_opening:
|
||||
@@ -35,18 +31,35 @@ class JournalVoucher(AccountsController):
|
||||
self.create_remarks()
|
||||
self.set_aging_date()
|
||||
self.set_print_format_fields()
|
||||
self.validate_against_sales_order()
|
||||
self.validate_against_purchase_order()
|
||||
|
||||
def on_submit(self):
|
||||
if self.voucher_type in ['Bank Voucher', 'Contra Voucher', 'Journal Entry']:
|
||||
self.check_credit_days()
|
||||
self.check_reference_date()
|
||||
self.make_gl_entries()
|
||||
self.check_credit_limit()
|
||||
self.update_advance_paid()
|
||||
|
||||
def update_advance_paid(self):
|
||||
advance_paid = frappe._dict()
|
||||
for d in self.get("entries"):
|
||||
if d.is_advance:
|
||||
if d.against_sales_order:
|
||||
advance_paid.setdefault("Sales Order", []).append(d.against_sales_order)
|
||||
elif d.against_purchase_order:
|
||||
advance_paid.setdefault("Purchase Order", []).append(d.against_purchase_order)
|
||||
|
||||
for voucher_type, order_list in advance_paid.items():
|
||||
for voucher_no in list(set(order_list)):
|
||||
frappe.get_doc(voucher_type, voucher_no).set_total_advance_paid()
|
||||
|
||||
def on_cancel(self):
|
||||
from erpnext.accounts.utils import remove_against_link_from_jv
|
||||
remove_against_link_from_jv(self.doctype, self.name, "against_jv")
|
||||
|
||||
self.make_gl_entries(1)
|
||||
self.update_advance_paid()
|
||||
|
||||
def validate_cheque_info(self):
|
||||
if self.voucher_type in ['Bank Voucher']:
|
||||
@@ -59,25 +72,36 @@ class JournalVoucher(AccountsController):
|
||||
|
||||
def validate_entries_for_advance(self):
|
||||
for d in self.get('entries'):
|
||||
if not d.is_advance and not d.against_voucher and \
|
||||
not d.against_invoice and not d.against_jv:
|
||||
if not (d.against_voucher and d.against_invoice and d.against_jv):
|
||||
master_type = frappe.db.get_value("Account", d.account, "master_type")
|
||||
if (master_type == 'Customer' and flt(d.credit) > 0) or \
|
||||
(master_type == 'Supplier' and flt(d.debit) > 0):
|
||||
msgprint(_("Please check 'Is Advance' against Account {0} if this is an advance entry.").format(d.account))
|
||||
if not d.is_advance:
|
||||
msgprint(_("Row {0}: Please check 'Is Advance' against Account {1} if this is an advance entry.").format(d.idx, d.account))
|
||||
elif (d.against_sales_order or d.against_purchase_order) and d.is_advance != "Yes":
|
||||
frappe.throw(_("Row {0}: Payment against Sales/Purchase Order should always be marked as advance").format(d.idx))
|
||||
|
||||
def validate_against_jv(self):
|
||||
for d in self.get('entries'):
|
||||
if d.against_jv:
|
||||
account_root_type = frappe.db.get_value("Account", d.account, "root_type")
|
||||
if account_root_type == "Asset" and flt(d.debit) > 0:
|
||||
frappe.throw(_("For {0}, only credit entries can be linked against another debit entry")
|
||||
.format(d.account))
|
||||
elif account_root_type == "Liability" and flt(d.credit) > 0:
|
||||
frappe.throw(_("For {0}, only debit entries can be linked against another credit entry")
|
||||
.format(d.account))
|
||||
|
||||
if d.against_jv == self.name:
|
||||
frappe.throw(_("You can not enter current voucher in 'Against Journal Voucher' column"))
|
||||
|
||||
against_entries = frappe.db.sql("""select * from `tabJournal Voucher Detail`
|
||||
where account = %s and docstatus = 1 and parent = %s
|
||||
and ifnull(against_jv, '') = ''""", (d.account, d.against_jv), as_dict=True)
|
||||
and ifnull(against_jv, '') = '' and ifnull(against_invoice, '') = ''
|
||||
and ifnull(against_voucher, '') = ''""", (d.account, d.against_jv), as_dict=True)
|
||||
|
||||
if not against_entries:
|
||||
frappe.throw(_("Journal Voucher {0} does not have account {1} or already matched")
|
||||
frappe.throw(_("Journal Voucher {0} does not have account {1} or already matched against other voucher")
|
||||
.format(d.against_jv, d.account))
|
||||
else:
|
||||
dr_or_cr = "debit" if d.credit > 0 else "credit"
|
||||
@@ -90,24 +114,89 @@ class JournalVoucher(AccountsController):
|
||||
.format(d.against_jv, dr_or_cr))
|
||||
|
||||
def validate_against_sales_invoice(self):
|
||||
for d in self.get("entries"):
|
||||
if d.against_invoice:
|
||||
if d.debit > 0:
|
||||
frappe.throw(_("Row {0}: Debit entry can not be linked with a Sales Invoice")
|
||||
.format(d.idx))
|
||||
if frappe.db.get_value("Sales Invoice", d.against_invoice, "debit_to") != d.account:
|
||||
frappe.throw(_("Row {0}: Account does not match with \
|
||||
Sales Invoice Debit To account").format(d.idx, d.account))
|
||||
payment_against_voucher = self.validate_account_in_against_voucher("against_invoice", "Sales Invoice")
|
||||
self.validate_against_invoice_fields("Sales Invoice", payment_against_voucher)
|
||||
|
||||
def validate_against_purchase_invoice(self):
|
||||
payment_against_voucher = self.validate_account_in_against_voucher("against_voucher", "Purchase Invoice")
|
||||
self.validate_against_invoice_fields("Purchase Invoice", payment_against_voucher)
|
||||
|
||||
def validate_against_sales_order(self):
|
||||
payment_against_voucher = self.validate_account_in_against_voucher("against_sales_order", "Sales Order")
|
||||
self.validate_against_order_fields("Sales Order", payment_against_voucher)
|
||||
|
||||
def validate_against_purchase_order(self):
|
||||
payment_against_voucher = self.validate_account_in_against_voucher("against_purchase_order", "Purchase Order")
|
||||
self.validate_against_order_fields("Purchase Order", payment_against_voucher)
|
||||
|
||||
def validate_account_in_against_voucher(self, against_field, doctype):
|
||||
payment_against_voucher = frappe._dict()
|
||||
field_dict = {'Sales Invoice': "Debit To",
|
||||
'Purchase Invoice': "Credit To",
|
||||
'Sales Order': "Customer",
|
||||
'Purchase Order': "Supplier"
|
||||
}
|
||||
|
||||
for d in self.get("entries"):
|
||||
if d.against_voucher:
|
||||
if flt(d.credit) > 0:
|
||||
frappe.throw(_("Row {0}: Credit entry can not be linked with a Purchase Invoice")
|
||||
.format(d.idx))
|
||||
if frappe.db.get_value("Purchase Invoice", d.against_voucher, "credit_to") != d.account:
|
||||
frappe.throw(_("Row {0}: Account does not match with \
|
||||
Purchase Invoice Credit To account").format(d.idx, d.account))
|
||||
if d.get(against_field):
|
||||
dr_or_cr = "credit" if against_field in ["against_invoice", "against_sales_order"] \
|
||||
else "debit"
|
||||
if against_field in ["against_invoice", "against_sales_order"] \
|
||||
and flt(d.debit) > 0:
|
||||
frappe.throw(_("Row {0}: Debit entry can not be linked with a {1}").format(d.idx, doctype))
|
||||
|
||||
if against_field in ["against_voucher", "against_purchase_order"] \
|
||||
and flt(d.credit) > 0:
|
||||
frappe.throw(_("Row {0}: Credit entry can not be linked with a {1}").format(d.idx, doctype))
|
||||
|
||||
voucher_account = frappe.db.get_value(doctype, d.get(against_field), \
|
||||
scrub(field_dict.get(doctype)))
|
||||
|
||||
account_master_name = frappe.db.get_value("Account", d.account, "master_name")
|
||||
|
||||
if against_field in ["against_invoice", "against_voucher"] \
|
||||
and voucher_account != d.account:
|
||||
frappe.throw(_("Row {0}: Account {1} does not match with {2} {3} account") \
|
||||
.format(d.idx, d.account, doctype, field_dict.get(doctype)))
|
||||
|
||||
if against_field in ["against_sales_order", "against_purchase_order"]:
|
||||
if voucher_account != account_master_name:
|
||||
frappe.throw(_("Row {0}: Account {1} does not match with {2} {3} Name") \
|
||||
.format(d.idx, d.account, doctype, field_dict.get(doctype)))
|
||||
elif d.is_advance == "Yes":
|
||||
payment_against_voucher.setdefault(d.get(against_field), []).append(flt(d.get(dr_or_cr)))
|
||||
|
||||
return payment_against_voucher
|
||||
|
||||
def validate_against_invoice_fields(self, doctype, payment_against_voucher):
|
||||
for voucher_no, payment_list in payment_against_voucher.items():
|
||||
voucher_properties = frappe.db.get_value(doctype, voucher_no,
|
||||
["docstatus", "outstanding_amount"])
|
||||
|
||||
if voucher_properties[0] != 1:
|
||||
frappe.throw(_("{0} {1} is not submitted").format(doctype, voucher_no))
|
||||
|
||||
if flt(voucher_properties[1]) < flt(sum(payment_list)):
|
||||
frappe.throw(_("Payment against {0} {1} cannot be greater \
|
||||
than Outstanding Amount {2}").format(doctype, voucher_no, voucher_properties[1]))
|
||||
|
||||
def validate_against_order_fields(self, doctype, payment_against_voucher):
|
||||
for voucher_no, payment_list in payment_against_voucher.items():
|
||||
voucher_properties = frappe.db.get_value(doctype, voucher_no,
|
||||
["docstatus", "per_billed", "status", "advance_paid", "grand_total"])
|
||||
|
||||
if voucher_properties[0] != 1:
|
||||
frappe.throw(_("{0} {1} is not submitted").format(doctype, voucher_no))
|
||||
|
||||
if flt(voucher_properties[1]) >= 100:
|
||||
frappe.throw(_("{0} {1} is fully billed").format(doctype, voucher_no))
|
||||
|
||||
if cstr(voucher_properties[2]) == "Stopped":
|
||||
frappe.throw(_("{0} {1} is stopped").format(doctype, voucher_no))
|
||||
|
||||
if flt(voucher_properties[4]) < flt(voucher_properties[3]) + flt(sum(payment_list)):
|
||||
frappe.throw(_("Advance paid against {0} {1} cannot be greater \
|
||||
than Grand Total {2}").format(doctype, voucher_no, voucher_properties[3]))
|
||||
|
||||
def set_against_account(self):
|
||||
accounts_debited, accounts_credited = [], []
|
||||
@@ -142,12 +231,18 @@ class JournalVoucher(AccountsController):
|
||||
if self.cheque_date:
|
||||
r.append(_('Reference #{0} dated {1}').format(self.cheque_no, formatdate(self.cheque_date)))
|
||||
else:
|
||||
msgprint(_("Please enter Reference date"), raise_exception=1)
|
||||
msgprint(_("Please enter Reference date"), raise_exception=frappe.MandatoryError)
|
||||
|
||||
for d in self.get('entries'):
|
||||
if d.against_invoice and d.credit:
|
||||
currency = frappe.db.get_value("Sales Invoice", d.against_invoice, "currency")
|
||||
r.append(_("{0} {1} against Invoice {1}").format(currency, fmt_money(flt(d.credit)), d.against_invoice))
|
||||
r.append(_("{0} against Sales Invoice {1}").format(fmt_money(flt(d.credit), currency = currency), \
|
||||
d.against_invoice))
|
||||
|
||||
if d.against_sales_order and d.credit:
|
||||
currency = frappe.db.get_value("Sales Order", d.against_sales_order, "currency")
|
||||
r.append(_("{0} against Sales Order {1}").format(fmt_money(flt(d.credit), currency = currency), \
|
||||
d.against_sales_order))
|
||||
|
||||
if d.against_voucher and d.debit:
|
||||
bill_no = frappe.db.sql("""select bill_no, bill_date, currency
|
||||
@@ -158,13 +253,17 @@ class JournalVoucher(AccountsController):
|
||||
fmt_money(flt(d.debit)), bill_no[0][0],
|
||||
bill_no[0][1] and formatdate(bill_no[0][1].strftime('%Y-%m-%d'))))
|
||||
|
||||
if d.against_purchase_order and d.debit:
|
||||
currency = frappe.db.get_value("Purchase Order", d.against_purchase_order, "currency")
|
||||
r.append(_("{0} against Purchase Order {1}").format(fmt_money(flt(d.credit), currency = currency), \
|
||||
d.against_purchase_order))
|
||||
|
||||
if self.user_remark:
|
||||
r.append(_("Note: {0}").format(self.user_remark))
|
||||
|
||||
if r:
|
||||
self.remark = ("\n").join(r)
|
||||
else:
|
||||
frappe.msgprint(_("User Remarks is mandatory"), raise_exception=1)
|
||||
self.remark = ("\n").join(r) #User Remarks is not mandatory
|
||||
|
||||
|
||||
def set_aging_date(self):
|
||||
if self.is_opening != 'Yes':
|
||||
@@ -186,66 +285,38 @@ class JournalVoucher(AccountsController):
|
||||
|
||||
def set_print_format_fields(self):
|
||||
for d in self.get('entries'):
|
||||
account_type, master_type = frappe.db.get_value("Account", d.account,
|
||||
["account_type", "master_type"])
|
||||
acc = frappe.db.get_value("Account", d.account, ["account_type", "master_type"], as_dict=1)
|
||||
|
||||
if master_type in ['Supplier', 'Customer']:
|
||||
if not acc: continue
|
||||
|
||||
if acc.master_type in ['Supplier', 'Customer']:
|
||||
if not self.pay_to_recd_from:
|
||||
self.pay_to_recd_from = frappe.db.get_value(master_type,
|
||||
' - '.join(d.account.split(' - ')[:-1]),
|
||||
master_type == 'Customer' and 'customer_name' or 'supplier_name')
|
||||
self.pay_to_recd_from = frappe.db.get_value(acc.master_type, ' - '.join(d.account.split(' - ')[:-1]),
|
||||
acc.master_type == 'Customer' and 'customer_name' or 'supplier_name')
|
||||
if self.voucher_type in ["Credit Note", "Debit Note"]:
|
||||
self.set_total_amount(d.debit or d.credit)
|
||||
|
||||
if account_type in ['Bank', 'Cash']:
|
||||
company_currency = get_company_currency(self.company)
|
||||
amt = flt(d.debit) and d.debit or d.credit
|
||||
self.total_amount = company_currency + ' ' + cstr(amt)
|
||||
from frappe.utils import money_in_words
|
||||
self.total_amount_in_words = money_in_words(amt, company_currency)
|
||||
if acc.account_type in ['Bank', 'Cash']:
|
||||
self.set_total_amount(d.debit or d.credit)
|
||||
|
||||
def check_credit_days(self):
|
||||
date_diff = 0
|
||||
def set_total_amount(self, amt):
|
||||
company_currency = get_company_currency(self.company)
|
||||
self.total_amount = fmt_money(amt, currency=company_currency)
|
||||
from frappe.utils import money_in_words
|
||||
self.total_amount_in_words = money_in_words(amt, company_currency)
|
||||
|
||||
def check_reference_date(self):
|
||||
if self.cheque_date:
|
||||
date_diff = (getdate(self.cheque_date)-getdate(self.posting_date)).days
|
||||
for d in self.get("entries"):
|
||||
due_date = None
|
||||
if d.against_invoice and flt(d.credit) > 0:
|
||||
due_date = frappe.db.get_value("Sales Invoice", d.against_invoice, "due_date")
|
||||
elif d.against_voucher and flt(d.debit) > 0:
|
||||
due_date = frappe.db.get_value("Purchase Invoice", d.against_voucher, "due_date")
|
||||
|
||||
if date_diff <= 0: return
|
||||
|
||||
# Get List of Customer Account
|
||||
acc_list = filter(lambda d: frappe.db.get_value("Account", d.account,
|
||||
"master_type")=='Customer', self.get('entries'))
|
||||
|
||||
for d in acc_list:
|
||||
credit_days = self.get_credit_days_for(d.account)
|
||||
# Check credit days
|
||||
if credit_days > 0 and not self.get_authorized_user() and cint(date_diff) > credit_days:
|
||||
msgprint(_("Maximum allowed credit is {0} days after posting date").format(credit_days),
|
||||
raise_exception=1)
|
||||
|
||||
def get_credit_days_for(self, ac):
|
||||
if not self.credit_days_for.has_key(ac):
|
||||
self.credit_days_for[ac] = cint(frappe.db.get_value("Account", ac, "credit_days"))
|
||||
|
||||
if not self.credit_days_for[ac]:
|
||||
if self.credit_days_global==-1:
|
||||
self.credit_days_global = cint(frappe.db.get_value("Company",
|
||||
self.company, "credit_days"))
|
||||
|
||||
return self.credit_days_global
|
||||
else:
|
||||
return self.credit_days_for[ac]
|
||||
|
||||
def get_authorized_user(self):
|
||||
if self.is_approving_authority==-1:
|
||||
self.is_approving_authority = 0
|
||||
|
||||
# Fetch credit controller role
|
||||
approving_authority = frappe.db.get_value("Accounts Settings", None,
|
||||
"credit_controller")
|
||||
|
||||
# Check logged-in user is authorized
|
||||
if approving_authority in frappe.user.get_roles():
|
||||
self.is_approving_authority = 1
|
||||
|
||||
return self.is_approving_authority
|
||||
if due_date and getdate(self.cheque_date) > getdate(due_date):
|
||||
msgprint(_("Note: Reference Date {0} is after invoice due date {1}")
|
||||
.format(formatdate(self.cheque_date), formatdate(due_date)))
|
||||
|
||||
def make_gl_entries(self, cancel=0, adv_adj=0):
|
||||
from erpnext.accounts.general_ledger import make_gl_entries
|
||||
@@ -259,14 +330,18 @@ class JournalVoucher(AccountsController):
|
||||
"against": d.against_account,
|
||||
"debit": flt(d.debit, self.precision("debit", "entries")),
|
||||
"credit": flt(d.credit, self.precision("credit", "entries")),
|
||||
"against_voucher_type": ((d.against_voucher and "Purchase Invoice")
|
||||
or (d.against_invoice and "Sales Invoice")
|
||||
or (d.against_jv and "Journal Voucher")),
|
||||
"against_voucher": d.against_voucher or d.against_invoice or d.against_jv,
|
||||
"against_voucher_type": (("Purchase Invoice" if d.against_voucher else None)
|
||||
or ("Sales Invoice" if d.against_invoice else None)
|
||||
or ("Journal Voucher" if d.against_jv else None)
|
||||
or ("Sales Order" if d.against_sales_order else None)
|
||||
or ("Purchase Order" if d.against_purchase_order else None)),
|
||||
"against_voucher": d.against_voucher or d.against_invoice or d.against_jv
|
||||
or d.against_sales_order or d.against_purchase_order,
|
||||
"remarks": self.remark,
|
||||
"cost_center": d.cost_center
|
||||
})
|
||||
)
|
||||
|
||||
if gl_map:
|
||||
make_gl_entries(gl_map, cancel=cancel, adv_adj=adv_adj)
|
||||
|
||||
@@ -274,7 +349,7 @@ class JournalVoucher(AccountsController):
|
||||
for d in self.get("entries"):
|
||||
master_type, master_name = frappe.db.get_value("Account", d.account,
|
||||
["master_type", "master_name"])
|
||||
if master_type == "Customer" and master_name:
|
||||
if master_type == "Customer" and master_name and flt(d.debit) > 0:
|
||||
super(JournalVoucher, self).check_credit_limit(d.account)
|
||||
|
||||
def get_balance(self):
|
||||
@@ -410,7 +485,7 @@ def get_opening_accounts(company):
|
||||
"""get all balance sheet accounts for opening entry"""
|
||||
from erpnext.accounts.utils import get_balance_on
|
||||
accounts = frappe.db.sql_list("""select name from tabAccount
|
||||
where group_or_ledger='Ledger' and report_type='Profit and Loss' and company=%s""", company)
|
||||
where group_or_ledger='Ledger' and report_type='Balance Sheet' and company=%s""", company)
|
||||
|
||||
return [{"account": a, "balance": get_balance_on(a)} for a in accounts]
|
||||
|
||||
@@ -429,9 +504,10 @@ def get_against_sales_invoice(doctype, txt, searchfield, start, page_len, filter
|
||||
(filters["account"], "%%%s%%" % txt, start, page_len))
|
||||
|
||||
def get_against_jv(doctype, txt, searchfield, start, page_len, filters):
|
||||
return frappe.db.sql("""select jv.name, jv.posting_date, jv.user_remark
|
||||
from `tabJournal Voucher` jv, `tabJournal Voucher Detail` jv_detail
|
||||
where jv_detail.parent = jv.name and jv_detail.account = %s and jv.docstatus = 1
|
||||
return frappe.db.sql("""select distinct jv.name, jv.posting_date, jv.user_remark
|
||||
from `tabJournal Voucher` jv, `tabJournal Voucher Detail` jvd
|
||||
where jvd.parent = jv.name and jvd.account = %s and jv.docstatus = 1
|
||||
and (ifnull(jvd.against_invoice, '') = '' and ifnull(jvd.against_voucher, '') = '' and ifnull(jvd.against_jv, '') = '' )
|
||||
and jv.%s like %s order by jv.name desc limit %s, %s""" %
|
||||
("%s", searchfield, "%s", "%s", "%s"),
|
||||
(filters["account"], "%%%s%%" % txt, start, page_len))
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<div class="row" style="max-height: 30px;">
|
||||
<div class="col-xs-10">
|
||||
<div class="text-ellipsis">
|
||||
{%= list.get_avatar_and_id(doc) %}
|
||||
<span class="text-muted" style="margin-right: 8px;">
|
||||
{%= doc.get_formatted("posting_date") %}</span>
|
||||
<span class="label label-info filterable"
|
||||
data-filter="voucher_type,=,{%= doc.voucher_type %}">
|
||||
{%= doc.voucher_type %}
|
||||
</span>
|
||||
{% if(doc.docstatus===0) { %}
|
||||
<span class="label label-danger filterable"
|
||||
data-filter="docstatus,=,0">{%= __("Draft") %}</span>
|
||||
{% } %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-2 text-right">
|
||||
{%= doc.get_formatted("total_debit") %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
frappe.listview_settings['Journal Voucher'] = {
|
||||
add_fields: ["voucher_type", "posting_date", "total_debit", "company"]
|
||||
};
|
||||
@@ -1,41 +1,88 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
import frappe
|
||||
import unittest, frappe
|
||||
from frappe.utils import flt
|
||||
|
||||
class TestJournalVoucher(unittest.TestCase):
|
||||
def test_journal_voucher_with_against_jv(self):
|
||||
self.clear_account_balance()
|
||||
|
||||
jv_invoice = frappe.copy_doc(test_records[2])
|
||||
jv_invoice.insert()
|
||||
jv_invoice.submit()
|
||||
base_jv = frappe.copy_doc(test_records[0])
|
||||
self.jv_against_voucher_testcase(base_jv, jv_invoice)
|
||||
|
||||
self.assertTrue(frappe.db.sql("""select name from `tabJournal Voucher Detail`
|
||||
where account = %s and docstatus = 1 and parent = %s""",
|
||||
("_Test Customer - _TC", jv_invoice.name)))
|
||||
def test_jv_against_sales_order(self):
|
||||
from erpnext.selling.doctype.sales_order.test_sales_order \
|
||||
import test_records as so_test_records
|
||||
|
||||
sales_order = frappe.copy_doc(so_test_records[0])
|
||||
base_jv = frappe.copy_doc(test_records[0])
|
||||
self.jv_against_voucher_testcase(base_jv, sales_order)
|
||||
|
||||
def test_jv_against_purchase_order(self):
|
||||
from erpnext.buying.doctype.purchase_order.test_purchase_order \
|
||||
import test_records as po_test_records
|
||||
|
||||
purchase_order = frappe.copy_doc(po_test_records[0])
|
||||
base_jv = frappe.copy_doc(test_records[1])
|
||||
self.jv_against_voucher_testcase(base_jv, purchase_order)
|
||||
|
||||
def jv_against_voucher_testcase(self, base_jv, test_voucher):
|
||||
dr_or_cr = "credit" if test_voucher.doctype in ["Sales Order", "Journal Voucher"] else "debit"
|
||||
field_dict = {'Journal Voucher': "against_jv",
|
||||
'Sales Order': "against_sales_order",
|
||||
'Purchase Order': "against_purchase_order"
|
||||
}
|
||||
|
||||
self.clear_account_balance()
|
||||
test_voucher.insert()
|
||||
test_voucher.submit()
|
||||
|
||||
if test_voucher.doctype == "Journal Voucher":
|
||||
self.assertTrue(frappe.db.sql("""select name from `tabJournal Voucher Detail`
|
||||
where account = %s and docstatus = 1 and parent = %s""",
|
||||
("_Test Customer - _TC", test_voucher.name)))
|
||||
|
||||
self.assertTrue(not frappe.db.sql("""select name from `tabJournal Voucher Detail`
|
||||
where against_jv=%s""", jv_invoice.name))
|
||||
where %s=%s""" % (field_dict.get(test_voucher.doctype), '%s'), (test_voucher.name)))
|
||||
|
||||
jv_payment = frappe.copy_doc(test_records[0])
|
||||
jv_payment.get("entries")[0].against_jv = jv_invoice.name
|
||||
jv_payment.insert()
|
||||
jv_payment.submit()
|
||||
base_jv.get("entries")[0].is_advance = "Yes" if (test_voucher.doctype in ["Sales Order", "Purchase Order"]) else "No"
|
||||
base_jv.get("entries")[0].set(field_dict.get(test_voucher.doctype), test_voucher.name)
|
||||
base_jv.insert()
|
||||
base_jv.submit()
|
||||
|
||||
submitted_voucher = frappe.get_doc(test_voucher.doctype, test_voucher.name)
|
||||
|
||||
self.assertTrue(frappe.db.sql("""select name from `tabJournal Voucher Detail`
|
||||
where against_jv=%s""", jv_invoice.name))
|
||||
where %s=%s""" % (field_dict.get(test_voucher.doctype), '%s'), (submitted_voucher.name)))
|
||||
|
||||
self.assertTrue(frappe.db.sql("""select name from `tabJournal Voucher Detail`
|
||||
where against_jv=%s and credit=400""", jv_invoice.name))
|
||||
where %s=%s and %s=400""" % (field_dict.get(submitted_voucher.doctype), '%s', dr_or_cr), (submitted_voucher.name)))
|
||||
|
||||
# cancel jv_invoice
|
||||
jv_invoice.cancel()
|
||||
if base_jv.get("entries")[0].is_advance == "Yes":
|
||||
self.advance_paid_testcase(base_jv, submitted_voucher, dr_or_cr)
|
||||
self.cancel_against_voucher_testcase(submitted_voucher)
|
||||
|
||||
self.assertTrue(not frappe.db.sql("""select name from `tabJournal Voucher Detail`
|
||||
where against_jv=%s""", jv_invoice.name))
|
||||
def advance_paid_testcase(self, base_jv, test_voucher, dr_or_cr):
|
||||
#Test advance paid field
|
||||
advance_paid = frappe.db.sql("""select advance_paid from `tab%s`
|
||||
where name=%s""" % (test_voucher.doctype, '%s'), (test_voucher.name))
|
||||
payment_against_order = base_jv.get("entries")[0].get(dr_or_cr)
|
||||
|
||||
self.assertTrue(flt(advance_paid[0][0]) == flt(payment_against_order))
|
||||
|
||||
def cancel_against_voucher_testcase(self, test_voucher):
|
||||
if test_voucher.doctype == "Journal Voucher":
|
||||
# if test_voucher is a Journal Voucher, test cancellation of test_voucher
|
||||
test_voucher.cancel()
|
||||
self.assertTrue(not frappe.db.sql("""select name from `tabJournal Voucher Detail`
|
||||
where against_jv=%s""", test_voucher.name))
|
||||
|
||||
elif test_voucher.doctype in ["Sales Order", "Purchase Order"]:
|
||||
# if test_voucher is a Sales Order/Purchase Order, test error on cancellation of test_voucher
|
||||
submitted_voucher = frappe.get_doc(test_voucher.doctype, test_voucher.name)
|
||||
self.assertRaises(frappe.LinkExistsError, submitted_voucher.cancel)
|
||||
|
||||
def test_jv_against_stock_account(self):
|
||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"autoname": "JVD.######",
|
||||
"creation": "2013-02-22 01:27:39.000000",
|
||||
"creation": "2013-02-22 01:27:39",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
@@ -31,6 +31,7 @@
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Cost Center",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_width": "180px",
|
||||
"search_index": 0,
|
||||
"width": "180px"
|
||||
@@ -50,6 +51,7 @@
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
@@ -115,11 +117,6 @@
|
||||
"print_hide": 0,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "col_break3",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "against_jv",
|
||||
"fieldtype": "Link",
|
||||
@@ -133,6 +130,25 @@
|
||||
"print_hide": 0,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "col_break3",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "against_sales_order",
|
||||
"fieldtype": "Link",
|
||||
"label": "Against Sales Order",
|
||||
"options": "Sales Order",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "against_purchase_order",
|
||||
"fieldtype": "Link",
|
||||
"label": "Against Purchase Order",
|
||||
"options": "Purchase Order",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "is_advance",
|
||||
"fieldtype": "Select",
|
||||
@@ -158,9 +174,10 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2014-02-03 12:44:31.000000",
|
||||
"modified": "2014-08-20 12:19:55.049973",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Journal Voucher Detail",
|
||||
"owner": "Administrator"
|
||||
"owner": "Administrator",
|
||||
"permissions": []
|
||||
}
|
||||
@@ -31,7 +31,7 @@
|
||||
"description": "Default Bank / Cash account will be automatically updated in POS Invoice when this mode is selected.",
|
||||
"fieldname": "default_account",
|
||||
"fieldtype": "Link",
|
||||
"ignore_restrictions": 1,
|
||||
"ignore_user_permissions": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Default Account",
|
||||
"options": "Account",
|
||||
@@ -41,7 +41,7 @@
|
||||
],
|
||||
"icon": "icon-credit-card",
|
||||
"idx": 1,
|
||||
"modified": "2014-05-07 05:06:13.702313",
|
||||
"modified": "2014-05-27 03:49:13.846602",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Mode of Payment",
|
||||
@@ -59,6 +59,7 @@
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"apply_user_permissions": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.provide("erpnext.accounts");
|
||||
|
||||
erpnext.accounts.PaymentReconciliationController = frappe.ui.form.Controller.extend({
|
||||
|
||||
onload: function() {
|
||||
var me = this
|
||||
this.frm.set_query('party_account', function() {
|
||||
if(!me.frm.doc.company) {
|
||||
msgprint(__("Please select company first"));
|
||||
} else {
|
||||
return{
|
||||
filters:[
|
||||
['Account', 'company', '=', me.frm.doc.company],
|
||||
['Account', 'group_or_ledger', '=', 'Ledger'],
|
||||
['Account', 'master_type', 'in', ['Customer', 'Supplier']]
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
this.frm.set_query('bank_cash_account', function() {
|
||||
if(!me.frm.doc.company) {
|
||||
msgprint(__("Please select company first"));
|
||||
} else {
|
||||
return{
|
||||
filters:[
|
||||
['Account', 'company', '=', me.frm.doc.company],
|
||||
['Account', 'group_or_ledger', '=', 'Ledger'],
|
||||
['Account', 'account_type', 'in', ['Bank', 'Cash']]
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
get_unreconciled_entries: function() {
|
||||
var me = this;
|
||||
return this.frm.call({
|
||||
doc: me.frm.doc,
|
||||
method: 'get_unreconciled_entries',
|
||||
callback: function(r, rt) {
|
||||
var invoices = [];
|
||||
|
||||
$.each(me.frm.doc.payment_reconciliation_invoices || [], function(i, row) {
|
||||
if (row.invoice_number && !inList(invoices, row.invoice_number))
|
||||
invoices.push(row.invoice_number);
|
||||
});
|
||||
|
||||
frappe.meta.get_docfield("Payment Reconciliation Payment", "invoice_number",
|
||||
me.frm.doc.name).options = invoices.join("\n");
|
||||
|
||||
$.each(me.frm.doc.payment_reconciliation_payments || [], function(i, p) {
|
||||
if(!inList(invoices, cstr(p.invoice_number))) p.invoice_number = null;
|
||||
});
|
||||
|
||||
refresh_field("payment_reconciliation_payments");
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
reconcile: function() {
|
||||
var me = this;
|
||||
return this.frm.call({
|
||||
doc: me.frm.doc,
|
||||
method: 'reconcile'
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$.extend(cur_frm.cscript, new erpnext.accounts.PaymentReconciliationController({frm: cur_frm}));
|
||||
|
||||
cur_frm.add_fetch('party_account', 'master_type', 'party_type')
|
||||
@@ -0,0 +1,156 @@
|
||||
{
|
||||
"allow_copy": 1,
|
||||
"creation": "2014-07-09 12:04:51.681583",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "",
|
||||
"fieldname": "party_account",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"label": "Party Account",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "party_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Party Type",
|
||||
"options": "\nCustomer\nSupplier",
|
||||
"permlevel": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "bank_cash_account",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Bank / Cash Account",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "col_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"label": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "from_date",
|
||||
"fieldtype": "Date",
|
||||
"in_list_view": 1,
|
||||
"label": "From Date",
|
||||
"permlevel": 0,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "to_date",
|
||||
"fieldtype": "Date",
|
||||
"in_list_view": 1,
|
||||
"label": "To Date",
|
||||
"permlevel": 0,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "minimum_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Minimum Amount",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "maximum_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Maximum Amount",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "get_unreconciled_entries",
|
||||
"fieldtype": "Button",
|
||||
"label": "Get Unreconciled Entries",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "sec_break1",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Unreconciled Payment Details",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "payment_reconciliation_payments",
|
||||
"fieldtype": "Table",
|
||||
"label": "Payment Reconciliation Payments",
|
||||
"options": "Payment Reconciliation Payment",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "reconcile",
|
||||
"fieldtype": "Button",
|
||||
"label": "Reconcile",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "sec_break2",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Invoice/Journal Voucher Details",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "payment_reconciliation_invoices",
|
||||
"fieldtype": "Table",
|
||||
"label": "Payment Reconciliation Invoices",
|
||||
"options": "Payment Reconciliation Invoice",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"hide_toolbar": 1,
|
||||
"icon": "icon-resize-horizontal",
|
||||
"issingle": 1,
|
||||
"modified": "2014-10-16 17:51:44.367107",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Reconciliation",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"role": "Accounts Manager",
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"role": "Accounts User",
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
from frappe.utils import flt
|
||||
|
||||
from frappe import msgprint, _
|
||||
|
||||
from frappe.model.document import Document
|
||||
|
||||
class PaymentReconciliation(Document):
|
||||
def get_unreconciled_entries(self):
|
||||
self.get_jv_entries()
|
||||
self.get_invoice_entries()
|
||||
|
||||
def get_jv_entries(self):
|
||||
self.check_mandatory_to_fetch()
|
||||
dr_or_cr = "credit" if self.party_type == "Customer" else "debit"
|
||||
|
||||
cond = self.check_condition(dr_or_cr)
|
||||
|
||||
bank_account_condition = "t2.against_account like %(bank_cash_account)s" \
|
||||
if self.bank_cash_account else "1=1"
|
||||
|
||||
jv_entries = frappe.db.sql("""
|
||||
select
|
||||
t1.name as voucher_no, t1.posting_date, t1.remark, t2.account,
|
||||
t2.name as voucher_detail_no, {dr_or_cr} as payment_amount, t2.is_advance
|
||||
from
|
||||
`tabJournal Voucher` t1, `tabJournal Voucher Detail` t2
|
||||
where
|
||||
t1.name = t2.parent and t1.docstatus = 1 and t2.docstatus = 1
|
||||
and t2.account = %(party_account)s and {dr_or_cr} > 0
|
||||
and ifnull(t2.against_voucher, '')='' and ifnull(t2.against_invoice, '')=''
|
||||
and ifnull(t2.against_jv, '')='' {cond}
|
||||
and (CASE
|
||||
WHEN t1.voucher_type in ('Debit Note', 'Credit Note')
|
||||
THEN 1=1
|
||||
ELSE {bank_account_condition}
|
||||
END)
|
||||
""".format(**{
|
||||
"dr_or_cr": dr_or_cr,
|
||||
"cond": cond,
|
||||
"bank_account_condition": bank_account_condition,
|
||||
}), {
|
||||
"party_account": self.party_account,
|
||||
"bank_cash_account": "%%%s%%" % self.bank_cash_account
|
||||
}, as_dict=1)
|
||||
|
||||
self.add_payment_entries(jv_entries)
|
||||
|
||||
def add_payment_entries(self, jv_entries):
|
||||
self.set('payment_reconciliation_payments', [])
|
||||
for e in jv_entries:
|
||||
ent = self.append('payment_reconciliation_payments', {})
|
||||
ent.journal_voucher = e.get('voucher_no')
|
||||
ent.posting_date = e.get('posting_date')
|
||||
ent.amount = flt(e.get('payment_amount'))
|
||||
ent.remark = e.get('remark')
|
||||
ent.voucher_detail_number = e.get('voucher_detail_no')
|
||||
ent.is_advance = e.get('is_advance')
|
||||
|
||||
def get_invoice_entries(self):
|
||||
#Fetch JVs, Sales and Purchase Invoices for 'payment_reconciliation_invoices' to reconcile against
|
||||
non_reconciled_invoices = []
|
||||
dr_or_cr = "debit" if self.party_type == "Customer" else "credit"
|
||||
cond = self.check_condition(dr_or_cr)
|
||||
|
||||
invoice_list = frappe.db.sql("""
|
||||
select
|
||||
voucher_no, voucher_type, posting_date,
|
||||
ifnull(sum({dr_or_cr}), 0) as invoice_amount
|
||||
from
|
||||
`tabGL Entry`
|
||||
where
|
||||
account = %s and {dr_or_cr} > 0 {cond}
|
||||
group by voucher_type, voucher_no
|
||||
""".format(**{
|
||||
"cond": cond,
|
||||
"dr_or_cr": dr_or_cr
|
||||
}), (self.party_account), as_dict=True)
|
||||
|
||||
for d in invoice_list:
|
||||
payment_amount = frappe.db.sql("""
|
||||
select
|
||||
ifnull(sum(ifnull({0}, 0)), 0)
|
||||
from
|
||||
`tabGL Entry`
|
||||
where
|
||||
account = %s and {0} > 0
|
||||
and against_voucher_type = %s and ifnull(against_voucher, '') = %s
|
||||
""".format("credit" if self.party_type == "Customer" else "debit"),
|
||||
(self.party_account, d.voucher_type, d.voucher_no))
|
||||
|
||||
payment_amount = payment_amount[0][0] if payment_amount else 0
|
||||
|
||||
if d.invoice_amount - payment_amount > 0.005:
|
||||
non_reconciled_invoices.append({
|
||||
'voucher_no': d.voucher_no,
|
||||
'voucher_type': d.voucher_type,
|
||||
'posting_date': d.posting_date,
|
||||
'invoice_amount': flt(d.invoice_amount),
|
||||
'outstanding_amount': flt(d.invoice_amount - payment_amount, 2)
|
||||
})
|
||||
|
||||
self.add_invoice_entries(non_reconciled_invoices)
|
||||
|
||||
def add_invoice_entries(self, non_reconciled_invoices):
|
||||
#Populate 'payment_reconciliation_invoices' with JVs and Invoices to reconcile against
|
||||
self.set('payment_reconciliation_invoices', [])
|
||||
|
||||
for e in non_reconciled_invoices:
|
||||
ent = self.append('payment_reconciliation_invoices', {})
|
||||
ent.invoice_type = e.get('voucher_type')
|
||||
ent.invoice_number = e.get('voucher_no')
|
||||
ent.invoice_date = e.get('posting_date')
|
||||
ent.amount = flt(e.get('invoice_amount'))
|
||||
ent.outstanding_amount = e.get('outstanding_amount')
|
||||
|
||||
def reconcile(self, args):
|
||||
self.get_invoice_entries()
|
||||
self.validate_invoice()
|
||||
dr_or_cr = "credit" if self.party_type == "Customer" else "debit"
|
||||
lst = []
|
||||
for e in self.get('payment_reconciliation_payments'):
|
||||
if e.invoice_type and e.invoice_number and e.allocated_amount:
|
||||
lst.append({
|
||||
'voucher_no' : e.journal_voucher,
|
||||
'voucher_detail_no' : e.voucher_detail_number,
|
||||
'against_voucher_type' : e.invoice_type,
|
||||
'against_voucher' : e.invoice_number,
|
||||
'account' : self.party_account,
|
||||
'is_advance' : e.is_advance,
|
||||
'dr_or_cr' : dr_or_cr,
|
||||
'unadjusted_amt' : flt(e.amount),
|
||||
'allocated_amt' : flt(e.allocated_amount)
|
||||
})
|
||||
|
||||
if lst:
|
||||
from erpnext.accounts.utils import reconcile_against_document
|
||||
reconcile_against_document(lst)
|
||||
msgprint(_("Successfully Reconciled"))
|
||||
self.get_unreconciled_entries()
|
||||
|
||||
def check_mandatory_to_fetch(self):
|
||||
for fieldname in ["company", "party_account"]:
|
||||
if not self.get(fieldname):
|
||||
frappe.throw(_("Please select {0} first").format(self.meta.get_label(fieldname)))
|
||||
|
||||
|
||||
def validate_invoice(self):
|
||||
if not self.get("payment_reconciliation_invoices"):
|
||||
frappe.throw(_("No records found in the Invoice table"))
|
||||
|
||||
if not self.get("payment_reconciliation_payments"):
|
||||
frappe.throw(_("No records found in the Payment table"))
|
||||
|
||||
unreconciled_invoices = frappe._dict()
|
||||
for d in self.get("payment_reconciliation_invoices"):
|
||||
unreconciled_invoices.setdefault(d.invoice_type, {}).setdefault(d.invoice_number, d.outstanding_amount)
|
||||
|
||||
invoices_to_reconcile = []
|
||||
for p in self.get("payment_reconciliation_payments"):
|
||||
if p.invoice_type and p.invoice_number and p.allocated_amount:
|
||||
invoices_to_reconcile.append(p.invoice_number)
|
||||
|
||||
if p.invoice_number not in unreconciled_invoices.get(p.invoice_type, {}):
|
||||
frappe.throw(_("{0}: {1} not found in Invoice Details table")
|
||||
.format(p.invoice_type, p.invoice_number))
|
||||
|
||||
if flt(p.allocated_amount) > flt(p.amount):
|
||||
frappe.throw(_("Row {0}: Allocated amount {1} must be less than or equals to JV amount {2}")
|
||||
.format(p.idx, p.allocated_amount, p.amount))
|
||||
|
||||
if flt(p.allocated_amount) > unreconciled_invoices.get(p.invoice_type, {}).get(p.invoice_number):
|
||||
frappe.throw(_("Row {0}: Allocated amount {1} must be less than or equals to invoice outstanding amount {2}")
|
||||
.format(p.idx, p.allocated_amount, unreconciled_invoices.get(p.invoice_type, {}).get(p.invoice_number)))
|
||||
|
||||
if not invoices_to_reconcile:
|
||||
frappe.throw(_("Please select Allocated Amount, Invoice Type and Invoice Number in atleast one row"))
|
||||
|
||||
def check_condition(self, dr_or_cr):
|
||||
cond = self.from_date and " and posting_date >= '" + self.from_date + "'" or ""
|
||||
cond += self.to_date and " and posting_date <= '" + self.to_date + "'" or ""
|
||||
|
||||
if self.minimum_amount:
|
||||
cond += " and {0} >= %s".format(dr_or_cr) % self.minimum_amount
|
||||
if self.maximum_amount:
|
||||
cond += " and {0} <= %s".format(dr_or_cr) % self.maximum_amount
|
||||
|
||||
return cond
|
||||
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"creation": "2014-07-09 16:14:23.672922",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "invoice_type",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Invoice Type",
|
||||
"options": "Sales Invoice\nPurchase Invoice\nJournal Voucher",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "invoice_number",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Invoice Number",
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "invoice_date",
|
||||
"fieldtype": "Date",
|
||||
"in_list_view": 1,
|
||||
"label": "Invoice Date",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "col_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"label": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Amount",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "outstanding_amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Outstanding Amount",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"modified": "2014-07-18 12:20:51.269974",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Reconciliation Invoice",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class PaymentReconciliationInvoice(Document):
|
||||
pass
|
||||
@@ -1,42 +1,18 @@
|
||||
{
|
||||
"creation": "2013-02-22 01:27:39",
|
||||
"creation": "2014-07-09 16:13:35.452759",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "voucher_no",
|
||||
"fieldname": "journal_voucher",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Voucher No",
|
||||
"label": "Journal Voucher",
|
||||
"options": "Journal Voucher",
|
||||
"permlevel": 0,
|
||||
"print_width": "140px",
|
||||
"read_only": 1,
|
||||
"reqd": 0,
|
||||
"width": "140px"
|
||||
},
|
||||
{
|
||||
"fieldname": "unmatched_amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Unmatched Amount",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "allocated_amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Allocated Amount",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "col_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "posting_date",
|
||||
@@ -47,41 +23,13 @@
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "total_amt",
|
||||
"fieldname": "amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Total Amount",
|
||||
"options": "Company:company:default_currency",
|
||||
"label": "Amount",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "against_account",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Against Account",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "remarks",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Remarks",
|
||||
"permlevel": 0,
|
||||
"print_width": "200px",
|
||||
"read_only": 1,
|
||||
"width": "200px"
|
||||
},
|
||||
{
|
||||
"fieldname": "voucher_detail_no",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Voucher Detail No",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "is_advance",
|
||||
"fieldtype": "Data",
|
||||
@@ -91,20 +39,78 @@
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "original_amount",
|
||||
"fieldtype": "Currency",
|
||||
"fieldname": "voucher_detail_number",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Original Amount",
|
||||
"in_list_view": 0,
|
||||
"label": "Voucher Detail Number",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "col_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"label": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "allocated_amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Allocated amount",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "Sales Invoice",
|
||||
"fieldname": "invoice_type",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 0,
|
||||
"label": "Invoice Type",
|
||||
"options": "\nSales Invoice\nPurchase Invoice\nJournal Voucher",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "invoice_number",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Invoice Number",
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "sec_break1",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "remark",
|
||||
"fieldtype": "Small Text",
|
||||
"in_list_view": 1,
|
||||
"label": "Remark",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "col_break2",
|
||||
"fieldtype": "Column Break",
|
||||
"label": "Column Break",
|
||||
"permlevel": 0
|
||||
}
|
||||
],
|
||||
"hide_toolbar": 1,
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2014-04-30 19:27:15.993641",
|
||||
"modified": "2014-10-16 17:40:54.040194",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment to Invoice Matching Tool Detail",
|
||||
"name": "Payment Reconciliation Payment",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": []
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class PaymentReconciliationPayment(Document):
|
||||
pass
|
||||
@@ -1 +0,0 @@
|
||||
Tool for mapping (cancelling) unpaid invoices and payments.
|
||||
@@ -1 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -1,51 +0,0 @@
|
||||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
cur_frm.cscript.onload_post_render = function(doc) {
|
||||
$(cur_frm.get_field("reconcile").input).addClass("btn-info");
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.voucher_no.get_query = function(doc) {
|
||||
// TO-do: check for pos, it should not come
|
||||
if (!doc.account) msgprint(__("Please select Account first"));
|
||||
else {
|
||||
return {
|
||||
doctype: doc.voucher_type,
|
||||
query: "erpnext.accounts.doctype.payment_to_invoice_matching_tool.payment_to_invoice_matching_tool.get_voucher_nos",
|
||||
filters: {
|
||||
"voucher_type": doc.voucher_type,
|
||||
"account": doc.account
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.voucher_no = function() {
|
||||
return cur_frm.call({
|
||||
doc: cur_frm.doc,
|
||||
method: "get_voucher_details"
|
||||
});
|
||||
}
|
||||
|
||||
cur_frm.cscript.get_against_entries = function() {
|
||||
return cur_frm.call({
|
||||
doc: cur_frm.doc,
|
||||
method: "get_against_entries"
|
||||
});
|
||||
}
|
||||
|
||||
cur_frm.cscript.reconcile = function() {
|
||||
return cur_frm.call({
|
||||
doc: cur_frm.doc,
|
||||
method: "reconcile"
|
||||
});
|
||||
}
|
||||
|
||||
cur_frm.cscript.allocated_amount = function(doc, cdt, cdn) {
|
||||
var total_allocated_amount = 0
|
||||
$.each(cur_frm.doc.against_entries, function(i, d) {
|
||||
if(d.allocated_amount > 0) total_allocated_amount += flt(d.allocated_amount);
|
||||
else if (d.allocated_amount < 0) frappe.throw(__("Allocated amount can not be negative"));
|
||||
})
|
||||
cur_frm.set_value("total_allocated_amount", total_allocated_amount);
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
{
|
||||
"creation": "2013-01-30 12:49:46",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Other",
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "account",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"label": "Account",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "Journal Voucher",
|
||||
"fieldname": "voucher_type",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 0,
|
||||
"label": "Voucher Type",
|
||||
"options": "Sales Invoice\nPurchase Invoice\nJournal Voucher",
|
||||
"permlevel": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "voucher_no",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Voucher No",
|
||||
"options": "[Select]",
|
||||
"permlevel": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"in_list_view": 0,
|
||||
"permlevel": 0,
|
||||
"print_width": "50%",
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"fieldname": "total_amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Total Amount",
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "unmatched_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Unmatched Amount",
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "against_entries_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Against Entries",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "from_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "From Date",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "to_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "To Date",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break3",
|
||||
"fieldtype": "Column Break",
|
||||
"label": "",
|
||||
"permlevel": 0,
|
||||
"print_width": "50%",
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"fieldname": "amt_greater_than",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Amount >=",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "amt_less_than",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Amount <=",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break0",
|
||||
"fieldtype": "Section Break",
|
||||
"options": "Simple",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "get_against_entries",
|
||||
"fieldtype": "Button",
|
||||
"label": "Get Against Entries",
|
||||
"options": "",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"description": "Update allocated amount in the above table and then click \"Allocate\" button",
|
||||
"fieldname": "against_entries",
|
||||
"fieldtype": "Table",
|
||||
"label": "Against Entries",
|
||||
"options": "Payment to Invoice Matching Tool Detail",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "sec_break1",
|
||||
"fieldtype": "Section Break",
|
||||
"options": "Simple",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "total_allocated_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Allocated Amount",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "col_breal4",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"default": "",
|
||||
"fieldname": "allocate_amount_automatically",
|
||||
"fieldtype": "Button",
|
||||
"hidden": 1,
|
||||
"label": "Allocate Amount Automatically",
|
||||
"permlevel": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "reconcile",
|
||||
"fieldtype": "Button",
|
||||
"label": "Reconcile",
|
||||
"options": "",
|
||||
"permlevel": 0
|
||||
}
|
||||
],
|
||||
"hide_toolbar": 0,
|
||||
"icon": "icon-magic",
|
||||
"idx": 1,
|
||||
"issingle": 1,
|
||||
"modified": "2014-04-30 17:11:05.908619",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment to Invoice Matching Tool",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "Accounts Manager",
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "Accounts User",
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
from frappe.utils import flt
|
||||
|
||||
from frappe import msgprint, _
|
||||
|
||||
from frappe.model.document import Document
|
||||
|
||||
class PaymenttoInvoiceMatchingTool(Document):
|
||||
def get_voucher_details(self):
|
||||
total_amount = frappe.db.sql("""select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))
|
||||
from `tabGL Entry`
|
||||
where voucher_type = %s and voucher_no = %s
|
||||
and account = %s and ifnull(against_voucher, '') != voucher_no""",
|
||||
(self.voucher_type, self.voucher_no, self.account))
|
||||
|
||||
self.total_amount = total_amount and flt(total_amount[0][0]) or 0
|
||||
|
||||
reconciled_payment = frappe.db.sql("""
|
||||
select abs(sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)))
|
||||
from `tabGL Entry`
|
||||
where against_voucher_type = %s and against_voucher = %s and account = %s
|
||||
""", (self.voucher_type, self.voucher_no, self.account))
|
||||
|
||||
reconciled_payment = reconciled_payment and flt(reconciled_payment[0][0]) or 0
|
||||
self.unmatched_amount = self.total_amount - reconciled_payment
|
||||
|
||||
def get_against_entries(self):
|
||||
self.set('against_entries', [])
|
||||
gle = self.get_gl_entries()
|
||||
self.create_against_entries_table(gle)
|
||||
|
||||
def get_gl_entries(self):
|
||||
self.validate_mandatory()
|
||||
|
||||
dr_or_cr = "credit" if self.total_amount > 0 else "debit"
|
||||
|
||||
cond = self.from_date and " and t1.posting_date >= '" + self.from_date + "'" or ""
|
||||
cond += self.to_date and " and t1.posting_date <= '" + self.to_date + "'" or ""
|
||||
|
||||
if self.amt_greater_than:
|
||||
cond += ' and abs(ifnull(t2.debit, 0) - ifnull(t2.credit, 0)) >= ' + self.amt_greater_than
|
||||
if self.amt_less_than:
|
||||
cond += ' and abs(ifnull(t2.debit, 0) - ifnull(t2.credit, 0)) >= ' + self.amt_less_than
|
||||
|
||||
gle = frappe.db.sql("""
|
||||
select
|
||||
t1.name as voucher_no, t1.posting_date, t1.total_debit as total_amt,
|
||||
abs(ifnull(t2.debit, 0) - ifnull(t2.credit, 0)) as unmatched_amount, t1.remark,
|
||||
t2.against_account, t2.name as voucher_detail_no, t2.is_advance
|
||||
from
|
||||
`tabJournal Voucher` t1, `tabJournal Voucher Detail` t2
|
||||
where
|
||||
t1.name = t2.parent and t1.docstatus = 1 and t2.account = %s
|
||||
and ifnull(t2.against_voucher, '')='' and ifnull(t2.against_invoice, '')=''
|
||||
and ifnull(t2.against_jv, '')='' and t2.%s > 0 and t1.name != %s
|
||||
and not exists (select * from `tabJournal Voucher Detail`
|
||||
where parent=%s and against_jv = t1.name) %s
|
||||
group by t1.name, t2.name """ % ('%s', dr_or_cr, '%s', '%s', cond),
|
||||
(self.account, self.voucher_no, self.voucher_no), as_dict=1)
|
||||
|
||||
return gle
|
||||
|
||||
def create_against_entries_table(self, gle):
|
||||
adjusted_jv = {}
|
||||
for d in gle:
|
||||
if not adjusted_jv.has_key(d.get("voucher_no")):
|
||||
matched_amount = frappe.db.sql("""
|
||||
select
|
||||
ifnull(abs(sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))), 0)
|
||||
from
|
||||
`tabGL Entry`
|
||||
where
|
||||
account = %s and against_voucher_type = "Journal Voucher"
|
||||
and ifnull(against_voucher, '') = %s
|
||||
""", (self.account, d.get('voucher_no')))
|
||||
matched_amount = matched_amount[0][0] if matched_amount else 0
|
||||
else:
|
||||
matched_amount = adjusted_jv.get(d.get("voucher_no"))
|
||||
|
||||
if matched_amount < flt(d.get('unmatched_amount')):
|
||||
unmatched_amount = flt(d.get('unmatched_amount')) - matched_amount
|
||||
adjusted_jv.setdefault(d.get("voucher_no"), 0)
|
||||
else:
|
||||
unmatched_amount = 0
|
||||
adjusted_jv.setdefault(d.get("voucher_no"), matched_amount - flt(d.get('unmatched_amount')))
|
||||
|
||||
if unmatched_amount:
|
||||
ch = self.append('against_entries', {})
|
||||
ch.voucher_no = d.get('voucher_no')
|
||||
ch.posting_date = d.get('posting_date')
|
||||
ch.unmatched_amount = unmatched_amount
|
||||
ch.total_amt = flt(d.get('total_amt'))
|
||||
ch.against_account = d.get('against_account')
|
||||
ch.remarks = d.get('remark')
|
||||
ch.voucher_detail_no = d.get('voucher_detail_no')
|
||||
ch.is_advance = d.get("is_advance")
|
||||
ch.original_amount = flt(d.get('unmatched_amount'))
|
||||
|
||||
def validate_mandatory(self):
|
||||
for fieldname in ["account", "voucher_type", "voucher_no"]:
|
||||
if not self.get(fieldname):
|
||||
frappe.throw(_("Please select {0} first").format(self.meta.get_label("fieldname")))
|
||||
|
||||
if not frappe.db.exists(self.voucher_type, self.voucher_no):
|
||||
frappe.throw(_("Voucher No is not valid"))
|
||||
|
||||
def reconcile(self):
|
||||
self.validate_mandatory()
|
||||
self.validate_allocated_amount()
|
||||
|
||||
dr_or_cr = "credit" if self.total_amount > 0 else "debit"
|
||||
|
||||
lst = []
|
||||
for d in self.get('against_entries'):
|
||||
if flt(d.allocated_amount) > 0:
|
||||
lst.append({
|
||||
'voucher_no' : d.voucher_no,
|
||||
'voucher_detail_no' : d.voucher_detail_no,
|
||||
'against_voucher_type' : self.voucher_type,
|
||||
'against_voucher' : self.voucher_no,
|
||||
'account' : self.account,
|
||||
'is_advance' : d.is_advance,
|
||||
'dr_or_cr' : dr_or_cr,
|
||||
'unadjusted_amt' : flt(d.original_amount),
|
||||
'allocated_amt' : flt(d.allocated_amount)
|
||||
})
|
||||
|
||||
if lst:
|
||||
from erpnext.accounts.utils import reconcile_against_document
|
||||
reconcile_against_document(lst)
|
||||
self.get_voucher_details()
|
||||
self.get_against_entries()
|
||||
msgprint(_("Successfully allocated"))
|
||||
|
||||
def validate_allocated_amount(self):
|
||||
if not self.total_allocated_amount:
|
||||
frappe.throw(_("You must allocate amount before reconcile"))
|
||||
elif self.total_allocated_amount > self.unmatched_amount:
|
||||
frappe.throw(_("Total Allocated Amount can not be greater than unmatched amount"))
|
||||
|
||||
def get_voucher_nos(doctype, txt, searchfield, start, page_len, filters):
|
||||
non_reconclied_entries = []
|
||||
entries = frappe.db.sql("""
|
||||
select
|
||||
voucher_no, posting_date, ifnull(abs(sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))), 0) as amount
|
||||
from
|
||||
`tabGL Entry`
|
||||
where
|
||||
account = %s and voucher_type = %s and voucher_no like %s
|
||||
and ifnull(against_voucher, '') = ''
|
||||
group by voucher_no
|
||||
""", (filters["account"], filters["voucher_type"], "%%%s%%" % txt), as_dict=True)
|
||||
|
||||
for d in entries:
|
||||
adjusted_amount = frappe.db.sql("""
|
||||
select
|
||||
ifnull(abs(sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))), 0)
|
||||
from
|
||||
`tabGL Entry`
|
||||
where
|
||||
account = %s and against_voucher_type = %s and ifnull(against_voucher, '') = %s
|
||||
""", (filters["account"], filters["voucher_type"], d.voucher_no))
|
||||
adjusted_amount = adjusted_amount[0][0] if adjusted_amount else 0
|
||||
|
||||
if d.amount > adjusted_amount:
|
||||
non_reconclied_entries.append([d.voucher_no, d.posting_date, d.amount])
|
||||
|
||||
return non_reconclied_entries
|
||||
@@ -1 +0,0 @@
|
||||
[]
|
||||
@@ -1 +0,0 @@
|
||||
Journal Voucher (payment) detail for matching to invoice.
|
||||
@@ -1 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
214
erpnext/accounts/doctype/payment_tool/payment_tool.js
Normal file
214
erpnext/accounts/doctype/payment_tool/payment_tool.js
Normal file
@@ -0,0 +1,214 @@
|
||||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.provide("erpnext.payment_tool");
|
||||
|
||||
// Help content
|
||||
frappe.ui.form.on("Payment Tool", "onload", function(frm) {
|
||||
frm.set_value("make_jv_help", '<i class="icon-hand-right"></i> '
|
||||
+ __("Note: If payment is not made against any reference, make Journal Voucher manually."));
|
||||
|
||||
frm.set_query("payment_account", function() {
|
||||
return {
|
||||
filters: [
|
||||
['Account', 'account_type', 'in', 'Bank, Cash'],
|
||||
['Account', 'group_or_ledger', '=', 'Ledger'],
|
||||
['Account', 'company', '=', frm.doc.company]
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
frm.set_query("against_voucher_type", "payment_tool_details", function() {
|
||||
return {
|
||||
filters: {"name": ["in", ["Sales Invoice", "Purchase Invoice", "Journal Voucher", "Sales Order", "Purchase Order"]]}
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Payment Tool", "refresh", function(frm) {
|
||||
frappe.ui.form.trigger("Payment Tool", "party_type");
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Payment Tool", "party_type", function(frm) {
|
||||
frm.toggle_reqd("customer", frm.doc.party_type == "Customer");
|
||||
frm.toggle_reqd("supplier", frm.doc.party_type == "Supplier");
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Payment Tool", "company", function(frm) {
|
||||
erpnext.payment_tool.check_mandatory_to_set_button(frm);
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Payment Tool", "received_or_paid", function(frm) {
|
||||
erpnext.payment_tool.check_mandatory_to_set_button(frm);
|
||||
});
|
||||
|
||||
// Set party account name
|
||||
frappe.ui.form.on("Payment Tool", "customer", function(frm) {
|
||||
erpnext.payment_tool.set_party_account(frm);
|
||||
erpnext.payment_tool.check_mandatory_to_set_button(frm);
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Payment Tool", "supplier", function(frm) {
|
||||
erpnext.payment_tool.set_party_account(frm);
|
||||
erpnext.payment_tool.check_mandatory_to_set_button(frm);
|
||||
});
|
||||
|
||||
erpnext.payment_tool.check_mandatory_to_set_button = function(frm) {
|
||||
if (frm.doc.company && frm.doc.party_type && frm.doc.received_or_paid && (frm.doc.customer || frm.doc.supplier)) {
|
||||
frm.fields_dict.get_outstanding_vouchers.$input.addClass("btn-primary");
|
||||
}
|
||||
}
|
||||
|
||||
//Set Button color
|
||||
erpnext.payment_tool.set_party_account = function(frm) {
|
||||
if(frm.doc.party_type == "Customer") {
|
||||
var party_name = frm.doc.customer;
|
||||
} else {
|
||||
var party_name = frm.doc.supplier;
|
||||
}
|
||||
return frappe.call({
|
||||
method: 'erpnext.accounts.doctype.payment_tool.payment_tool.get_party_account',
|
||||
args: {
|
||||
party_type: frm.doc.party_type,
|
||||
party_name: party_name
|
||||
},
|
||||
callback: function(r, rt) {
|
||||
if(!r.exc) {
|
||||
frm.set_value("party_account", r.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Get outstanding vouchers
|
||||
frappe.ui.form.on("Payment Tool", "get_outstanding_vouchers", function(frm) {
|
||||
erpnext.payment_tool.check_mandatory_to_fetch(frm.doc);
|
||||
|
||||
frm.set_value("payment_tool_details", []);
|
||||
|
||||
return frappe.call({
|
||||
method: 'erpnext.accounts.doctype.payment_tool.payment_tool.get_outstanding_vouchers',
|
||||
args: {
|
||||
args: {
|
||||
"company": frm.doc.company,
|
||||
"party_type": frm.doc.party_type,
|
||||
"received_or_paid": frm.doc.received_or_paid,
|
||||
"party_name": frm.doc.party_type == "Customer" ? frm.doc.customer : frm.doc.supplier,
|
||||
"party_account": frm.doc.party_account
|
||||
}
|
||||
},
|
||||
callback: function(r, rt) {
|
||||
if(r.message) {
|
||||
frm.fields_dict.get_outstanding_vouchers.$input.removeClass("btn-primary");
|
||||
frm.fields_dict.make_journal_voucher.$input.addClass("btn-primary");
|
||||
|
||||
frappe.model.clear_table(frm.doc, "payment_tool_details");
|
||||
$.each(r.message, function(i, d) {
|
||||
var invoice_detail = frappe.model.add_child(frm.doc, "Payment Tool Detail", "payment_tool_details");
|
||||
invoice_detail.against_voucher_type = d.voucher_type;
|
||||
invoice_detail.against_voucher_no = d.voucher_no;
|
||||
invoice_detail.total_amount = d.invoice_amount;
|
||||
invoice_detail.outstanding_amount = d.outstanding_amount;
|
||||
});
|
||||
}
|
||||
refresh_field("payment_tool_details");
|
||||
erpnext.payment_tool.set_total_payment_amount(frm);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// validate against_voucher_type
|
||||
frappe.ui.form.on("Payment Tool Detail", "against_voucher_type", function(frm) {
|
||||
erpnext.payment_tool.validate_against_voucher(frm);
|
||||
});
|
||||
|
||||
erpnext.payment_tool.validate_against_voucher = function(frm) {
|
||||
$.each(frm.doc.payment_tool_details || [], function(i, row) {
|
||||
if(frm.doc.party_type=="Customer"
|
||||
&& !in_list(["Sales Order", "Sales Invoice", "Journal Voucher"], row.against_voucher_type)) {
|
||||
frappe.model.set_value(row.doctype, row.name, "against_voucher_type", "");
|
||||
frappe.throw(__("Against Voucher Type must be one of Sales Order, Sales Invoice or Journal Voucher"))
|
||||
}
|
||||
|
||||
if(frm.doc.party_type=="Supplier"
|
||||
&& !in_list(["Purchase Order", "Purchase Invoice", "Journal Voucher"], row.against_voucher_type)) {
|
||||
frappe.model.set_value(row.doctype, row.name, "against_voucher_type", "");
|
||||
frappe.throw(__("Against Voucher Type must be one of Purchase Order, Purchase Invoice or Journal Voucher"))
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// validate against_voucher_type
|
||||
frappe.ui.form.on("Payment Tool Detail", "against_voucher_no", function(frm, cdt, cdn) {
|
||||
var row = locals[cdt][cdn];
|
||||
frappe.call({
|
||||
method: 'erpnext.accounts.doctype.payment_tool.payment_tool.get_against_voucher_amount',
|
||||
args: {
|
||||
"against_voucher_type": row.against_voucher_type,
|
||||
"against_voucher_no": row.against_voucher_no
|
||||
},
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
$.each(r.message, function(k, v) {
|
||||
frappe.model.set_value(cdt, cdn, k, v);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Set total payment amount
|
||||
frappe.ui.form.on("Payment Tool Detail", "payment_amount", function(frm) {
|
||||
erpnext.payment_tool.set_total_payment_amount(frm);
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Payment Tool Detail", "payment_tool_details_remove", function(frm) {
|
||||
erpnext.payment_tool.set_total_payment_amount(frm);
|
||||
});
|
||||
|
||||
erpnext.payment_tool.set_total_payment_amount = function(frm) {
|
||||
var total_amount = 0.00;
|
||||
$.each(frm.doc.payment_tool_details || [], function(i, row) {
|
||||
if (row.payment_amount && (row.payment_amount <= row.outstanding_amount)) {
|
||||
total_amount = total_amount + row.payment_amount;
|
||||
} else {
|
||||
if(row.payment_amount < 0)
|
||||
msgprint(__("Row {0}: Payment amount can not be negative", [row.idx]));
|
||||
else if(row.payment_amount >= row.outstanding_amount)
|
||||
msgprint(__("Row {0}: Payment Amount cannot be greater than Outstanding Amount", [__(row.idx)]));
|
||||
|
||||
frappe.model.set_value(row.doctype, row.name, "payment_amount", 0.0);
|
||||
}
|
||||
});
|
||||
frm.set_value("total_payment_amount", total_amount);
|
||||
}
|
||||
|
||||
|
||||
// Make Journal voucher
|
||||
frappe.ui.form.on("Payment Tool", "make_journal_voucher", function(frm) {
|
||||
erpnext.payment_tool.check_mandatory_to_fetch(frm.doc);
|
||||
|
||||
return frappe.call({
|
||||
method: 'make_journal_voucher',
|
||||
doc: frm.doc,
|
||||
callback: function(r) {
|
||||
frm.fields_dict.make_journal_voucher.$input.addClass("btn-primary");
|
||||
var doclist = frappe.model.sync(r.message);
|
||||
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
erpnext.payment_tool.check_mandatory_to_fetch = function(doc) {
|
||||
var check_fields = [
|
||||
['Company', doc.company],
|
||||
['Party Type', doc.party_type],
|
||||
['Received Or Paid', doc.received_or_paid],
|
||||
['Customer / Supplier', doc.party_type == "Customer" ? doc.customer : doc.supplier]
|
||||
];
|
||||
|
||||
$.each(check_fields, function(i, v) {
|
||||
if(!v[1]) frappe.throw(__("Please select {0} first", [v[0]]));
|
||||
});
|
||||
}
|
||||
381
erpnext/accounts/doctype/payment_tool/payment_tool.json
Normal file
381
erpnext/accounts/doctype/payment_tool/payment_tool.json
Normal file
@@ -0,0 +1,381 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"creation": "2014-07-23 15:12:27.746665",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "sec_break1",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Party Details",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"default": "Customer",
|
||||
"fieldname": "party_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Party Type",
|
||||
"no_copy": 0,
|
||||
"options": "Customer\nSupplier",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"depends_on": "eval:(doc.party_type == 'Customer')",
|
||||
"fieldname": "customer",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Customer",
|
||||
"no_copy": 0,
|
||||
"options": "Customer",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"depends_on": "eval:(doc.party_type == 'Supplier')",
|
||||
"fieldname": "supplier",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Supplier",
|
||||
"no_copy": 0,
|
||||
"options": "Supplier",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "party_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"label": "Party Account",
|
||||
"no_copy": 1,
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "received_or_paid",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Received Or Paid",
|
||||
"no_copy": 0,
|
||||
"options": "Received\nPaid",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "get_outstanding_vouchers",
|
||||
"fieldtype": "Button",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Get Outstanding Vouchers",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "col_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Column Break 1",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "payment_mode",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Payment Mode",
|
||||
"no_copy": 0,
|
||||
"options": "Mode of Payment",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "payment_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Payment Account",
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "reference_no",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Reference No",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "reference_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Reference Date",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"depends_on": "eval:(doc.company && doc.party_type && doc.received_or_paid && (doc.customer || doc.supplier))",
|
||||
"fieldname": "sec_break3",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Against Voucher",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "payment_tool_details",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Payment Tool Details",
|
||||
"no_copy": 0,
|
||||
"options": "Payment Tool Detail",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:(doc.company && doc.party_type && doc.received_or_paid && (doc.customer || doc.supplier))",
|
||||
"fieldname": "section_break_19",
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
{
|
||||
"fieldname": "total_payment_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Payment Amount",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "make_journal_voucher",
|
||||
"fieldtype": "Button",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Make Journal Voucher",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "data_22",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:(doc.company && doc.party_type && doc.received_or_paid && (doc.customer || doc.supplier))",
|
||||
"fieldname": "section_break_21",
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "make_jv_help",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
}
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 1,
|
||||
"icon": "icon-magic",
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"modified": "2014-09-12 04:43:05.963218",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Tool",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 0,
|
||||
"email": 0,
|
||||
"export": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 0,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "Accounts Manager",
|
||||
"set_user_permissions": 0,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 0,
|
||||
"email": 0,
|
||||
"export": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 0,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "Accounts User",
|
||||
"set_user_permissions": 0,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
119
erpnext/accounts/doctype/payment_tool/payment_tool.py
Normal file
119
erpnext/accounts/doctype/payment_tool/payment_tool.py
Normal file
@@ -0,0 +1,119 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import flt
|
||||
from frappe.model.document import Document
|
||||
import json
|
||||
|
||||
class PaymentTool(Document):
|
||||
def make_journal_voucher(self):
|
||||
from erpnext.accounts.utils import get_balance_on
|
||||
total_payment_amount = 0.00
|
||||
invoice_voucher_type = {
|
||||
'Sales Invoice': 'against_invoice',
|
||||
'Purchase Invoice': 'against_voucher',
|
||||
'Journal Voucher': 'against_jv',
|
||||
'Sales Order': 'against_sales_order',
|
||||
'Purchase Order': 'against_purchase_order',
|
||||
}
|
||||
|
||||
jv = frappe.new_doc('Journal Voucher')
|
||||
jv.voucher_type = 'Journal Entry'
|
||||
jv.company = self.company
|
||||
jv.cheque_no = self.reference_no
|
||||
jv.cheque_date = self.reference_date
|
||||
|
||||
if not self.total_payment_amount:
|
||||
frappe.throw(_("Please enter Payment Amount in atleast one row"))
|
||||
|
||||
for v in self.get("payment_tool_details"):
|
||||
if not frappe.db.get_value(v.against_voucher_type, {"name": v.against_voucher_no}):
|
||||
frappe.throw(_("Row {0}: {1} is not a valid {2}").format(v.idx, v.against_voucher_no,
|
||||
v.against_voucher_type))
|
||||
|
||||
if v.payment_amount:
|
||||
d1 = jv.append("entries")
|
||||
d1.account = self.party_account
|
||||
d1.balance = get_balance_on(self.party_account)
|
||||
d1.set("debit" if self.received_or_paid=="Paid" else "credit", flt(v.payment_amount))
|
||||
d1.set(invoice_voucher_type.get(v.against_voucher_type), v.against_voucher_no)
|
||||
d1.set('is_advance', 'Yes' if v.against_voucher_type in ['Sales Order', 'Purchase Order'] else 'No')
|
||||
total_payment_amount = flt(total_payment_amount) + flt(d1.debit) - flt(d1.credit)
|
||||
|
||||
d2 = jv.append("entries")
|
||||
d2.account = self.payment_account
|
||||
d2.set('debit' if total_payment_amount < 0 else 'credit', abs(total_payment_amount))
|
||||
if self.payment_account:
|
||||
d2.balance = get_balance_on(self.payment_account)
|
||||
|
||||
return jv.as_dict()
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_party_account(party_type, party_name):
|
||||
return frappe.db.get_value("Account", {"master_type": party_type, "master_name": party_name})
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_outstanding_vouchers(args):
|
||||
from erpnext.accounts.utils import get_outstanding_invoices
|
||||
|
||||
if not frappe.has_permission("Payment Tool"):
|
||||
frappe.throw(_("No permission to use Payment Tool"), frappe.PermissionError)
|
||||
|
||||
args = json.loads(args)
|
||||
|
||||
if args.get("party_type") == "Customer" and args.get("received_or_paid") == "Received":
|
||||
amount_query = "ifnull(debit, 0) - ifnull(credit, 0)"
|
||||
elif args.get("party_type") == "Supplier" and args.get("received_or_paid") == "Paid":
|
||||
amount_query = "ifnull(credit, 0) - ifnull(debit, 0)"
|
||||
else:
|
||||
frappe.throw(_("Please enter the Against Vouchers manually"))
|
||||
|
||||
# Get all outstanding sales /purchase invoices
|
||||
outstanding_invoices = get_outstanding_invoices(amount_query, args.get("party_account"))
|
||||
|
||||
# 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("party_type"), args.get("party_name"))
|
||||
return outstanding_invoices + orders_to_be_billed
|
||||
|
||||
def get_orders_to_be_billed(party_type, party_name):
|
||||
voucher_type = 'Sales Order' if party_type == "Customer" else 'Purchase Order'
|
||||
orders = frappe.db.sql("""
|
||||
select
|
||||
name as voucher_no,
|
||||
ifnull(grand_total, 0) as invoice_amount,
|
||||
(ifnull(grand_total, 0) - ifnull(advance_paid, 0)) as outstanding_amount,
|
||||
transaction_date as posting_date
|
||||
from
|
||||
`tab%s`
|
||||
where
|
||||
%s = %s
|
||||
and docstatus = 1
|
||||
and ifnull(status, "") != "Stopped"
|
||||
and ifnull(grand_total, 0) > ifnull(advance_paid, 0)
|
||||
and abs(100 - ifnull(per_billed, 0)) > 0.01
|
||||
""" % (voucher_type, 'customer' if party_type == "Customer" else 'supplier', '%s'),
|
||||
party_name, as_dict = True)
|
||||
|
||||
order_list = []
|
||||
for d in orders:
|
||||
d["voucher_type"] = voucher_type
|
||||
order_list.append(d)
|
||||
|
||||
return order_list
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_against_voucher_amount(against_voucher_type, against_voucher_no):
|
||||
if against_voucher_type in ["Sales Order", "Purchase Order"]:
|
||||
select_cond = "grand_total as total_amount, ifnull(grand_total, 0) - ifnull(advance_paid, 0) as outstanding_amount"
|
||||
elif against_voucher_type in ["Sales Invoice", "Purchase Invoice"]:
|
||||
select_cond = "grand_total as total_amount, outstanding_amount"
|
||||
elif against_voucher_type == "Journal Voucher":
|
||||
select_cond = "total_debit as total_amount"
|
||||
|
||||
details = frappe.db.sql("""select {0} from `tab{1}` where name = %s"""
|
||||
.format(select_cond, against_voucher_type), against_voucher_no, as_dict=1)
|
||||
|
||||
return details[0] if details else {}
|
||||
195
erpnext/accounts/doctype/payment_tool/test_payment_tool.py
Normal file
195
erpnext/accounts/doctype/payment_tool/test_payment_tool.py
Normal file
@@ -0,0 +1,195 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import unittest, frappe, json
|
||||
from frappe.utils import flt
|
||||
|
||||
test_dependencies = ["Item"]
|
||||
|
||||
class TestPaymentTool(unittest.TestCase):
|
||||
def test_make_journal_voucher(self):
|
||||
from erpnext.accounts.doctype.journal_voucher.test_journal_voucher \
|
||||
import test_records as jv_test_records
|
||||
from erpnext.selling.doctype.sales_order.test_sales_order \
|
||||
import test_records as so_test_records
|
||||
from erpnext.buying.doctype.purchase_order.test_purchase_order \
|
||||
import test_records as po_test_records
|
||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice \
|
||||
import test_records as si_test_records
|
||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice \
|
||||
import test_records as pi_test_records
|
||||
|
||||
self.clear_table_entries()
|
||||
|
||||
base_customer_jv = self.create_against_jv(jv_test_records[2], { "account": "_Test Customer 3 - _TC"})
|
||||
base_supplier_jv = self.create_against_jv(jv_test_records[1], { "account": "_Test Supplier 1 - _TC"})
|
||||
|
||||
|
||||
#Create SO with partial outstanding
|
||||
so1 = self.create_voucher(so_test_records[0], {
|
||||
"customer": "_Test Customer 3"
|
||||
})
|
||||
|
||||
jv_against_so1 = self.create_against_jv(jv_test_records[0], {
|
||||
"account": "_Test Customer 3 - _TC",
|
||||
"against_sales_order": so1.name,
|
||||
"is_advance": "Yes"
|
||||
})
|
||||
|
||||
|
||||
#Create SO with no outstanding
|
||||
so2 = self.create_voucher(so_test_records[0], {
|
||||
"customer": "_Test Customer 3"
|
||||
})
|
||||
|
||||
jv_against_so2 = self.create_against_jv(jv_test_records[0], {
|
||||
"account": "_Test Customer 3 - _TC",
|
||||
"against_sales_order": so2.name,
|
||||
"credit": 1000,
|
||||
"is_advance": "Yes"
|
||||
})
|
||||
po = self.create_voucher(po_test_records[1], {
|
||||
"supplier": "_Test Supplier 1"
|
||||
})
|
||||
|
||||
#Create SI with partial outstanding
|
||||
si1 = self.create_voucher(si_test_records[0], {
|
||||
"customer": "_Test Customer 3",
|
||||
"debit_to": "_Test Customer 3 - _TC"
|
||||
})
|
||||
|
||||
jv_against_si1 = self.create_against_jv(jv_test_records[0], {
|
||||
"account": "_Test Customer 3 - _TC",
|
||||
"against_invoice": si1.name
|
||||
})
|
||||
#Create SI with no outstanding
|
||||
si2 = self.create_voucher(si_test_records[0], {
|
||||
"customer": "_Test Customer 3",
|
||||
"debit_to": "_Test Customer 3 - _TC"
|
||||
})
|
||||
|
||||
jv_against_si2 = self.create_against_jv(jv_test_records[0], {
|
||||
"account": "_Test Customer 3 - _TC",
|
||||
"against_invoice": si2.name,
|
||||
"credit": 561.80
|
||||
})
|
||||
|
||||
pi = self.create_voucher(pi_test_records[0], {
|
||||
"supplier": "_Test Supplier 1",
|
||||
"credit_to": "_Test Supplier 1 - _TC"
|
||||
})
|
||||
|
||||
#Create a dict containing properties and expected values
|
||||
expected_outstanding = {
|
||||
"Journal Voucher" : [base_customer_jv.name, 400.00],
|
||||
"Sales Invoice" : [si1.name, 161.80],
|
||||
"Purchase Invoice" : [pi.name, 1512.30],
|
||||
"Sales Order" : [so1.name, 600.00],
|
||||
"Purchase Order" : [po.name, 5000.00]
|
||||
}
|
||||
|
||||
args = {
|
||||
"company": "_Test Company",
|
||||
"party_type": "Customer",
|
||||
"received_or_paid": "Received",
|
||||
"customer": "_Test Customer",
|
||||
"party_account": "_Test Customer 3 - _TC",
|
||||
"payment_mode": "Cheque",
|
||||
"payment_account": "_Test Account Bank Account - _TC",
|
||||
"reference_no": "123456",
|
||||
"reference_date": "2013-02-14"
|
||||
}
|
||||
|
||||
self.make_voucher_for_party(args, expected_outstanding)
|
||||
|
||||
args.update({
|
||||
"party_type": "Supplier",
|
||||
"received_or_paid": "Paid",
|
||||
"supplier": "_Test Supplier 1",
|
||||
"party_account": "_Test Supplier 1 - _TC"
|
||||
})
|
||||
expected_outstanding["Journal Voucher"] = [base_supplier_jv.name, 400.00]
|
||||
self.make_voucher_for_party(args, expected_outstanding)
|
||||
|
||||
def create_voucher(self, test_record, args):
|
||||
doc = frappe.copy_doc(test_record)
|
||||
doc.update(args)
|
||||
doc.insert()
|
||||
doc.submit()
|
||||
return doc
|
||||
|
||||
def create_against_jv(self, test_record, args):
|
||||
jv = frappe.copy_doc(test_record)
|
||||
jv.get("entries")[0].update(args)
|
||||
if args.get("debit"):
|
||||
jv.get("entries")[1].credit = args["debit"]
|
||||
elif args.get("credit"):
|
||||
jv.get("entries")[1].debit = args["credit"]
|
||||
|
||||
jv.insert()
|
||||
jv.submit()
|
||||
return jv
|
||||
|
||||
def make_voucher_for_party(self, args, expected_outstanding):
|
||||
#Make Journal Voucher for Party
|
||||
payment_tool_doc = frappe.new_doc("Payment Tool")
|
||||
|
||||
for k, v in args.items():
|
||||
payment_tool_doc.set(k, v)
|
||||
|
||||
self.check_outstanding_vouchers(payment_tool_doc, args, expected_outstanding)
|
||||
|
||||
|
||||
def check_outstanding_vouchers(self, doc, args, expected_outstanding):
|
||||
from erpnext.accounts.doctype.payment_tool.payment_tool import get_outstanding_vouchers
|
||||
|
||||
outstanding_entries = get_outstanding_vouchers(json.dumps(args))
|
||||
|
||||
for d in outstanding_entries:
|
||||
self.assertEquals(flt(d.get("outstanding_amount"), 2), expected_outstanding.get(d.get("voucher_type"))[1])
|
||||
|
||||
self.check_jv_entries(doc, outstanding_entries, expected_outstanding)
|
||||
|
||||
def check_jv_entries(self, paytool, outstanding_entries, expected_outstanding):
|
||||
for e in outstanding_entries:
|
||||
d1 = paytool.append("payment_tool_details")
|
||||
d1.against_voucher_type = e.get("voucher_type")
|
||||
d1.against_voucher_no = e.get("voucher_no")
|
||||
d1.total_amount = e.get("invoice_amount")
|
||||
d1.outstanding_amount = e.get("outstanding_amount")
|
||||
d1.payment_amount = 100.00
|
||||
paytool.total_payment_amount = 300
|
||||
|
||||
new_jv = paytool.make_journal_voucher()
|
||||
|
||||
#Create a list of expected values as [party account, payment against, against_jv, against_invoice,
|
||||
#against_voucher, against_sales_order, against_purchase_order]
|
||||
expected_values = [
|
||||
[paytool.party_account, 100.00, expected_outstanding.get("Journal Voucher")[0], None, None, None, None],
|
||||
[paytool.party_account, 100.00, None, expected_outstanding.get("Sales Invoice")[0], None, None, None],
|
||||
[paytool.party_account, 100.00, None, None, expected_outstanding.get("Purchase Invoice")[0], None, None],
|
||||
[paytool.party_account, 100.00, None, None, None, expected_outstanding.get("Sales Order")[0], None],
|
||||
[paytool.party_account, 100.00, None, None, None, None, expected_outstanding.get("Purchase Order")[0]]
|
||||
]
|
||||
|
||||
for jv_entry in new_jv.get("entries"):
|
||||
if paytool.party_account == jv_entry.get("account"):
|
||||
row = [
|
||||
jv_entry.get("account"),
|
||||
jv_entry.get("debit" if paytool.party_type=="Supplier" else "credit"),
|
||||
jv_entry.get("against_jv"),
|
||||
jv_entry.get("against_invoice"),
|
||||
jv_entry.get("against_voucher"),
|
||||
jv_entry.get("against_sales_order"),
|
||||
jv_entry.get("against_purchase_order"),
|
||||
]
|
||||
self.assertTrue(row in expected_values)
|
||||
|
||||
self.assertEquals(new_jv.get("cheque_no"), paytool.reference_no)
|
||||
self.assertEquals(new_jv.get("cheque_date"), paytool.reference_date)
|
||||
|
||||
def clear_table_entries(self):
|
||||
frappe.db.sql("""delete from `tabGL Entry` where (account = "_Test Customer 3 - _TC" or account = "_Test Supplier 1 - _TC")""")
|
||||
frappe.db.sql("""delete from `tabSales Order` where customer_name = "_Test Customer 3" """)
|
||||
frappe.db.sql("""delete from `tabPurchase Order` where supplier_name = "_Test Supplier 1" """)
|
||||
@@ -0,0 +1,130 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"creation": "2014-08-11 14:27:54.463897",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "against_voucher_type",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Against Voucher Type",
|
||||
"no_copy": 0,
|
||||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_width": "",
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"width": ""
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "against_voucher_no",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Against Voucher No",
|
||||
"no_copy": 0,
|
||||
"options": "against_voucher_type",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "total_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Total Amount",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "outstanding_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Outstanding Amount",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "payment_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Payment Amount",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
}
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"modified": "2014-09-11 08:55:34.384017",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Tool Detail",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
from frappe.model.document import Document
|
||||
|
||||
class ContactControl(Document):
|
||||
pass
|
||||
class PaymentToolDetail(Document):
|
||||
pass
|
||||
@@ -43,13 +43,14 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"ignore_restrictions": 1,
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Period Closing Voucher",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
@@ -101,7 +102,7 @@
|
||||
"icon": "icon-file-text",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-09 02:16:36.920034",
|
||||
"modified": "2014-06-23 07:55:49.946225",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Period Closing Voucher",
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
"options": "Price List",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
@@ -147,7 +147,7 @@
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "cost_center",
|
||||
@@ -171,6 +171,7 @@
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "letter_head",
|
||||
"fieldtype": "Link",
|
||||
"label": "Letter Head",
|
||||
@@ -192,6 +193,7 @@
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "select_print_heading",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 0,
|
||||
@@ -205,14 +207,13 @@
|
||||
],
|
||||
"icon": "icon-cog",
|
||||
"idx": 1,
|
||||
"modified": "2014-05-09 02:17:34.814856",
|
||||
"modified": "2014-09-09 05:35:31.969193",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Setting",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
@@ -225,7 +226,7 @@
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"cancel": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
|
||||
10
erpnext/accounts/doctype/pos_setting/test_pos_setting.py
Normal file
10
erpnext/accounts/doctype/pos_setting/test_pos_setting.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and Contributors
|
||||
# See license.txt
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
|
||||
test_records = frappe.get_test_records('POS Setting')
|
||||
|
||||
class TestPOSSetting(unittest.TestCase):
|
||||
pass
|
||||
1
erpnext/accounts/doctype/pos_setting/test_records.json
Normal file
1
erpnext/accounts/doctype/pos_setting/test_records.json
Normal file
@@ -0,0 +1 @@
|
||||
[]
|
||||
91
erpnext/accounts/doctype/pricing_rule/pricing_rule.js
Normal file
91
erpnext/accounts/doctype/pricing_rule/pricing_rule.js
Normal file
@@ -0,0 +1,91 @@
|
||||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.ui.form.on("Pricing Rule", "refresh", function(frm) {
|
||||
var help_content = ['<table class="table table-bordered" style="background-color: #f9f9f9;">',
|
||||
'<tr><td>',
|
||||
'<h4><i class="icon-hand-right"></i> ',
|
||||
__('Notes'),
|
||||
':</h4>',
|
||||
'<ul>',
|
||||
'<li>',
|
||||
__("Pricing Rule is made to overwrite Price List / define discount percentage, based on some criteria."),
|
||||
'</li>',
|
||||
'<li>',
|
||||
__("If selected Pricing Rule is made for 'Price', it will overwrite Price List. Pricing Rule price is the final price, so no further discount should be applied. Hence, in transactions like Sales Order, Purchase Order etc, it will be fetched in 'Rate' field, rather than 'Price List Rate' field."),
|
||||
'</li>',
|
||||
'<li>',
|
||||
__('Discount Percentage can be applied either against a Price List or for all Price List.'),
|
||||
'</li>',
|
||||
'<li>',
|
||||
__('To not apply Pricing Rule in a particular transaction, all applicable Pricing Rules should be disabled.'),
|
||||
'</li>',
|
||||
'</ul>',
|
||||
'</td></tr>',
|
||||
'<tr><td>',
|
||||
'<h4><i class="icon-question-sign"></i> ',
|
||||
__('How Pricing Rule is applied?'),
|
||||
'</h4>',
|
||||
'<ol>',
|
||||
'<li>',
|
||||
__("Pricing Rule is first selected based on 'Apply On' field, which can be Item, Item Group or Brand."),
|
||||
'</li>',
|
||||
'<li>',
|
||||
__("Then Pricing Rules are filtered out based on Customer, Customer Group, Territory, Supplier, Supplier Type, Campaign, Sales Partner etc."),
|
||||
'</li>',
|
||||
'<li>',
|
||||
__('Pricing Rules are further filtered based on quantity.'),
|
||||
'</li>',
|
||||
'<li>',
|
||||
__('If two or more Pricing Rules are found based on the above conditions, Priority is applied. Priority is a number between 0 to 20 while default value is zero (blank). Higher number means it will take precedence if there are multiple Pricing Rules with same conditions.'),
|
||||
'</li>',
|
||||
'<li>',
|
||||
__('Even if there are multiple Pricing Rules with highest priority, then following internal priorities are applied:'),
|
||||
'<ul>',
|
||||
'<li>',
|
||||
__('Item Code > Item Group > Brand'),
|
||||
'</li>',
|
||||
'<li>',
|
||||
__('Customer > Customer Group > Territory'),
|
||||
'</li>',
|
||||
'<li>',
|
||||
__('Supplier > Supplier Type'),
|
||||
'</li>',
|
||||
'</ul>',
|
||||
'</li>',
|
||||
'<li>',
|
||||
__('If multiple Pricing Rules continue to prevail, users are asked to set Priority manually to resolve conflict.'),
|
||||
'</li>',
|
||||
'</ol>',
|
||||
'</td></tr>',
|
||||
'</table>'].join("\n");
|
||||
|
||||
set_field_options("pricing_rule_help", help_content);
|
||||
|
||||
cur_frm.cscript.set_options_for_applicable_for();
|
||||
});
|
||||
|
||||
cur_frm.cscript.set_options_for_applicable_for = function() {
|
||||
var options = [""];
|
||||
var applicable_for = cur_frm.doc.applicable_for;
|
||||
|
||||
if(cur_frm.doc.selling) {
|
||||
options = $.merge(options, ["Customer", "Customer Group", "Territory", "Sales Partner", "Campaign"]);
|
||||
}
|
||||
if(cur_frm.doc.buying) {
|
||||
$.merge(options, ["Supplier", "Supplier Type"]);
|
||||
}
|
||||
|
||||
set_field_options("applicable_for", options.join("\n"));
|
||||
|
||||
if(!in_list(options, applicable_for)) applicable_for = null;
|
||||
cur_frm.set_value("applicable_for", applicable_for)
|
||||
}
|
||||
|
||||
cur_frm.cscript.selling = function() {
|
||||
cur_frm.cscript.set_options_for_applicable_for();
|
||||
}
|
||||
|
||||
cur_frm.cscript.buying = function() {
|
||||
cur_frm.cscript.set_options_for_applicable_for();
|
||||
}
|
||||
@@ -51,6 +51,18 @@
|
||||
"options": "Brand",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "selling",
|
||||
"fieldtype": "Check",
|
||||
"label": "Selling",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "buying",
|
||||
"fieldtype": "Check",
|
||||
"label": "Buying",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "applicable_for",
|
||||
"fieldtype": "Select",
|
||||
@@ -131,6 +143,13 @@
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"options": "Company",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"default": "Today",
|
||||
"fieldname": "valid_from",
|
||||
@@ -198,12 +217,25 @@
|
||||
"label": "For Price List",
|
||||
"options": "Price List",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "help_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "",
|
||||
"options": "Simple",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_help",
|
||||
"fieldtype": "HTML",
|
||||
"label": "Pricing Rule Help",
|
||||
"permlevel": 0
|
||||
}
|
||||
],
|
||||
"icon": "icon-gift",
|
||||
"idx": 1,
|
||||
"istable": 0,
|
||||
"modified": "2014-05-12 16:24:52.005162",
|
||||
"modified": "2014-06-20 19:36:22.502381",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Pricing Rule",
|
||||
@@ -212,8 +244,8 @@
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"export": 0,
|
||||
"import": 0,
|
||||
"export": 1,
|
||||
"import": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
@@ -258,7 +290,6 @@
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"restrict": 1,
|
||||
"role": "System Manager",
|
||||
"write": 1
|
||||
}
|
||||
|
||||
@@ -5,28 +5,46 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import json
|
||||
import copy
|
||||
from frappe import throw, _
|
||||
from frappe.utils import flt
|
||||
from frappe.utils import flt, cint
|
||||
from frappe.model.document import Document
|
||||
|
||||
class MultiplePricingRuleConflict(frappe.ValidationError): pass
|
||||
|
||||
class PricingRule(Document):
|
||||
def validate(self):
|
||||
self.validate_mandatory()
|
||||
self.validate_applicable_for_selling_or_buying()
|
||||
self.validate_min_max_qty()
|
||||
self.cleanup_fields_value()
|
||||
|
||||
self.validate_price_or_discount()
|
||||
self.validate_max_discount()
|
||||
|
||||
def validate_mandatory(self):
|
||||
for field in ["apply_on", "applicable_for", "price_or_discount"]:
|
||||
for field in ["apply_on", "applicable_for"]:
|
||||
tocheck = frappe.scrub(self.get(field) or "")
|
||||
if tocheck and not self.get(tocheck):
|
||||
throw(_("{0} is required").format(self.meta.get_label(tocheck)), frappe.MandatoryError)
|
||||
|
||||
def validate_applicable_for_selling_or_buying(self):
|
||||
if not self.selling and not self.buying:
|
||||
throw(_("Atleast one of the Selling or Buying must be selected"))
|
||||
|
||||
if not self.selling and self.applicable_for in ["Customer", "Customer Group",
|
||||
"Territory", "Sales Partner", "Campaign"]:
|
||||
throw(_("Selling must be checked, if Applicable For is selected as {0}"
|
||||
.format(self.applicable_for)))
|
||||
|
||||
if not self.buying and self.applicable_for in ["Supplier", "Supplier Type"]:
|
||||
throw(_("Buying must be checked, if Applicable For is selected as {0}"
|
||||
.format(self.applicable_for)))
|
||||
|
||||
def validate_min_max_qty(self):
|
||||
if self.min_qty and self.max_qty and flt(self.min_qty) > flt(self.max_qty):
|
||||
throw(_("Min Qty can not be greater than Max Qty"))
|
||||
|
||||
|
||||
def cleanup_fields_value(self):
|
||||
for logic_field in ["apply_on", "applicable_for", "price_or_discount"]:
|
||||
fieldname = frappe.scrub(self.get(logic_field) or "")
|
||||
@@ -39,3 +57,204 @@ class PricingRule(Document):
|
||||
f = frappe.scrub(f)
|
||||
if f!=fieldname:
|
||||
self.set(f, None)
|
||||
|
||||
def validate_price_or_discount(self):
|
||||
for field in ["Price", "Discount Percentage"]:
|
||||
if flt(self.get(frappe.scrub(field))) < 0:
|
||||
throw(_("{0} can not be negative").format(field))
|
||||
|
||||
def validate_max_discount(self):
|
||||
if self.price_or_discount == "Discount Percentage" and self.item_code:
|
||||
max_discount = frappe.db.get_value("Item", self.item_code, "max_discount")
|
||||
if max_discount and flt(self.discount_percentage) > flt(max_discount):
|
||||
throw(_("Max discount allowed for item: {0} is {1}%").format(self.item_code, max_discount))
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
@frappe.whitelist()
|
||||
def apply_pricing_rule(args):
|
||||
"""
|
||||
args = {
|
||||
"item_list": [{"doctype": "", "name": "", "item_code": "", "brand": "", "item_group": ""}, ...],
|
||||
"customer": "something",
|
||||
"customer_group": "something",
|
||||
"territory": "something",
|
||||
"supplier": "something",
|
||||
"supplier_type": "something",
|
||||
"currency": "something",
|
||||
"conversion_rate": "something",
|
||||
"price_list": "something",
|
||||
"plc_conversion_rate": "something",
|
||||
"company": "something",
|
||||
"transaction_date": "something",
|
||||
"campaign": "something",
|
||||
"sales_partner": "something",
|
||||
"ignore_pricing_rule": "something"
|
||||
}
|
||||
"""
|
||||
if isinstance(args, basestring):
|
||||
args = json.loads(args)
|
||||
|
||||
args = frappe._dict(args)
|
||||
|
||||
# list of dictionaries
|
||||
out = []
|
||||
|
||||
if args.get("parenttype") == "Material Request": return out
|
||||
|
||||
if not args.transaction_type:
|
||||
args.transaction_type = "buying" if frappe.get_meta(args.parenttype).get_field("supplier") \
|
||||
else "selling"
|
||||
|
||||
item_list = args.get("item_list")
|
||||
args.pop("item_list")
|
||||
|
||||
for item in item_list:
|
||||
args_copy = copy.deepcopy(args)
|
||||
args_copy.update(item)
|
||||
out.append(get_pricing_rule_for_item(args_copy))
|
||||
|
||||
return out
|
||||
|
||||
def get_pricing_rule_for_item(args):
|
||||
if args.get("parenttype") == "Material Request": return {}
|
||||
|
||||
item_details = frappe._dict({
|
||||
"doctype": args.doctype,
|
||||
"name": args.name,
|
||||
"pricing_rule": None
|
||||
})
|
||||
|
||||
if args.ignore_pricing_rule or not args.item_code:
|
||||
return item_details
|
||||
|
||||
if not (args.item_group and args.brand):
|
||||
args.item_group, args.brand = frappe.db.get_value("Item", args.item_code, ["item_group", "brand"])
|
||||
if not args.item_group:
|
||||
frappe.throw(_("Item Group not mentioned in item master for item {0}").format(args.item_code))
|
||||
|
||||
if args.customer and not (args.customer_group and args.territory):
|
||||
customer = frappe.db.get_value("Customer", args.customer, ["customer_group", "territory"])
|
||||
if customer:
|
||||
args.customer_group, args.territory = customer
|
||||
|
||||
elif args.supplier and not args.supplier_type:
|
||||
args.supplier_type = frappe.db.get_value("Supplier", args.supplier, "supplier_type")
|
||||
|
||||
pricing_rules = get_pricing_rules(args)
|
||||
pricing_rule = filter_pricing_rules(args, pricing_rules)
|
||||
|
||||
if pricing_rule:
|
||||
item_details.pricing_rule = pricing_rule.name
|
||||
if pricing_rule.price_or_discount == "Price":
|
||||
item_details.update({
|
||||
"price_list_rate": pricing_rule.price/flt(args.conversion_rate) \
|
||||
if args.conversion_rate else 0.0,
|
||||
"discount_percentage": 0.0
|
||||
})
|
||||
else:
|
||||
item_details.discount_percentage = pricing_rule.discount_percentage
|
||||
|
||||
return item_details
|
||||
|
||||
def get_pricing_rules(args):
|
||||
def _get_tree_conditions(parenttype, allow_blank=True):
|
||||
field = frappe.scrub(parenttype)
|
||||
condition = ""
|
||||
if args.get(field):
|
||||
lft, rgt = frappe.db.get_value(parenttype, args[field], ["lft", "rgt"])
|
||||
parent_groups = frappe.db.sql_list("""select name from `tab%s`
|
||||
where lft<=%s and rgt>=%s""" % (parenttype, '%s', '%s'), (lft, rgt))
|
||||
|
||||
if parent_groups:
|
||||
if allow_blank: parent_groups.append('')
|
||||
condition = " ifnull("+field+", '') in ('" + \
|
||||
"', '".join([d.replace("'", "\\'").replace('"', '\\"') for d in parent_groups])+"')"
|
||||
return condition
|
||||
|
||||
|
||||
conditions = ""
|
||||
for field in ["company", "customer", "supplier", "supplier_type", "campaign", "sales_partner"]:
|
||||
if args.get(field):
|
||||
conditions += " and ifnull("+field+", '') in (%("+field+")s, '')"
|
||||
else:
|
||||
conditions += " and ifnull("+field+", '') = ''"
|
||||
|
||||
for parenttype in ["Customer Group", "Territory"]:
|
||||
group_condition = _get_tree_conditions(parenttype)
|
||||
if group_condition:
|
||||
conditions += " and " + group_condition
|
||||
if not args.price_list: args.price_list = None
|
||||
conditions += " and ifnull(for_price_list, '') in (%(price_list)s, '')"
|
||||
|
||||
if args.get("transaction_date"):
|
||||
conditions += """ and %(transaction_date)s between ifnull(valid_from, '2000-01-01')
|
||||
and ifnull(valid_upto, '2500-12-31')"""
|
||||
|
||||
item_group_condition = _get_tree_conditions("Item Group", False)
|
||||
if item_group_condition: item_group_condition = " or " + item_group_condition
|
||||
|
||||
return frappe.db.sql("""select * from `tabPricing Rule`
|
||||
where (item_code=%(item_code)s {item_group_condition} or brand=%(brand)s)
|
||||
and docstatus < 2 and ifnull(disable, 0) = 0
|
||||
and ifnull({transaction_type}, 0) = 1 {conditions}
|
||||
order by priority desc, name desc""".format(
|
||||
item_group_condition=item_group_condition,
|
||||
transaction_type=args.transaction_type, conditions=conditions), args, as_dict=1)
|
||||
|
||||
def filter_pricing_rules(args, pricing_rules):
|
||||
# filter for qty
|
||||
if pricing_rules and args.get("qty"):
|
||||
pricing_rules = filter(lambda x: (args.qty>=flt(x.min_qty)
|
||||
and (args.qty<=x.max_qty if x.max_qty else True)), pricing_rules)
|
||||
|
||||
# find pricing rule with highest priority
|
||||
if pricing_rules:
|
||||
max_priority = max([cint(p.priority) for p in pricing_rules])
|
||||
if max_priority:
|
||||
pricing_rules = filter(lambda x: cint(x.priority)==max_priority, pricing_rules)
|
||||
|
||||
# apply internal priority
|
||||
all_fields = ["item_code", "item_group", "brand", "customer", "customer_group", "territory",
|
||||
"supplier", "supplier_type", "campaign", "sales_partner"]
|
||||
|
||||
if len(pricing_rules) > 1:
|
||||
for field_set in [["item_code", "item_group", "brand"],
|
||||
["customer", "customer_group", "territory"], ["supplier", "supplier_type"]]:
|
||||
remaining_fields = list(set(all_fields) - set(field_set))
|
||||
if if_all_rules_same(pricing_rules, remaining_fields):
|
||||
pricing_rules = apply_internal_priority(pricing_rules, field_set, args)
|
||||
break
|
||||
|
||||
if len(pricing_rules) > 1:
|
||||
price_or_discount = list(set([d.price_or_discount for d in pricing_rules]))
|
||||
if len(price_or_discount) == 1 and price_or_discount[0] == "Discount Percentage":
|
||||
pricing_rules = filter(lambda x: x.for_price_list==args.price_list, pricing_rules) \
|
||||
or pricing_rules
|
||||
|
||||
if len(pricing_rules) > 1:
|
||||
frappe.throw(_("Multiple Price Rule exists with same criteria, please resolve \
|
||||
conflict by assigning priority. Price Rules: {0}")
|
||||
.format("\n".join([d.name for d in pricing_rules])), MultiplePricingRuleConflict)
|
||||
elif pricing_rules:
|
||||
return pricing_rules[0]
|
||||
|
||||
def if_all_rules_same(pricing_rules, fields):
|
||||
all_rules_same = True
|
||||
val = [pricing_rules[0][k] for k in fields]
|
||||
for p in pricing_rules[1:]:
|
||||
if val != [p[k] for k in fields]:
|
||||
all_rules_same = False
|
||||
break
|
||||
|
||||
return all_rules_same
|
||||
|
||||
def apply_internal_priority(pricing_rules, field_set, args):
|
||||
filtered_rules = []
|
||||
for field in field_set:
|
||||
if args.get(field):
|
||||
filtered_rules = filter(lambda x: x[field]==args[field], pricing_rules)
|
||||
if filtered_rules: break
|
||||
|
||||
return filtered_rules or pricing_rules
|
||||
|
||||
@@ -17,9 +17,11 @@ class TestPricingRule(unittest.TestCase):
|
||||
"doctype": "Pricing Rule",
|
||||
"apply_on": "Item Code",
|
||||
"item_code": "_Test Item",
|
||||
"selling": 1,
|
||||
"price_or_discount": "Discount Percentage",
|
||||
"price": 0,
|
||||
"discount_percentage": 10,
|
||||
"company": "_Test Company"
|
||||
}
|
||||
frappe.get_doc(test_record.copy()).insert()
|
||||
|
||||
@@ -28,15 +30,16 @@ class TestPricingRule(unittest.TestCase):
|
||||
"company": "_Test Company",
|
||||
"price_list": "_Test Price List",
|
||||
"currency": "_Test Currency",
|
||||
"doctype": "Sales Order",
|
||||
"parenttype": "Sales Order",
|
||||
"conversion_rate": 1,
|
||||
"price_list_currency": "_Test Currency",
|
||||
"plc_conversion_rate": 1,
|
||||
"order_type": "Sales",
|
||||
"transaction_type": "selling",
|
||||
"customer": "_Test Customer",
|
||||
"doctype": "Sales Order Item",
|
||||
"name": None
|
||||
})
|
||||
|
||||
details = get_item_details(args)
|
||||
self.assertEquals(details.get("discount_percentage"), 10)
|
||||
|
||||
@@ -71,8 +74,8 @@ class TestPricingRule(unittest.TestCase):
|
||||
self.assertEquals(details.get("discount_percentage"), 5)
|
||||
|
||||
frappe.db.sql("update `tabPricing Rule` set priority=NULL where campaign='_Test Campaign'")
|
||||
from erpnext.stock.get_item_details import MultiplePricingRuleConflict
|
||||
self.assertRaises (MultiplePricingRuleConflict, get_item_details, args)
|
||||
from erpnext.accounts.doctype.pricing_rule.pricing_rule import MultiplePricingRuleConflict
|
||||
self.assertRaises(MultiplePricingRuleConflict, get_item_details, args)
|
||||
|
||||
args.item_code = "_Test Item 2"
|
||||
details = get_item_details(args)
|
||||
|
||||
@@ -27,7 +27,8 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
||||
|
||||
// Show / Hide button
|
||||
if(doc.docstatus==1 && doc.outstanding_amount > 0)
|
||||
this.frm.add_custom_button(__('Make Payment Entry'), this.make_bank_voucher);
|
||||
this.frm.add_custom_button(__('Make Payment Entry'), this.make_bank_voucher,
|
||||
frappe.boot.doctype_icons["Journal Voucher"]);
|
||||
|
||||
if(doc.docstatus==1) {
|
||||
cur_frm.appframe.add_button(__('View Ledger'), function() {
|
||||
@@ -56,7 +57,7 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
||||
company: cur_frm.doc.company
|
||||
}
|
||||
})
|
||||
});
|
||||
}, "icon-download", "btn-default");
|
||||
|
||||
cur_frm.add_custom_button(__('From Purchase Receipt'),
|
||||
function() {
|
||||
@@ -69,7 +70,7 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
||||
company: cur_frm.doc.company
|
||||
}
|
||||
})
|
||||
});
|
||||
}, "icon-download", "btn-default");
|
||||
|
||||
}
|
||||
|
||||
@@ -77,16 +78,19 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
||||
},
|
||||
|
||||
supplier: function() {
|
||||
var me = this;
|
||||
if(this.frm.updating_party_details)
|
||||
return;
|
||||
erpnext.utils.get_party_details(this.frm,
|
||||
"erpnext.accounts.party.get_party_details", {
|
||||
erpnext.utils.get_party_details(this.frm, "erpnext.accounts.party.get_party_details",
|
||||
{
|
||||
posting_date: this.frm.doc.posting_date,
|
||||
party: this.frm.doc.supplier,
|
||||
party_type: "Supplier",
|
||||
account: this.frm.doc.debit_to,
|
||||
price_list: this.frm.doc.buying_price_list,
|
||||
})
|
||||
}, function() {
|
||||
me.apply_pricing_rule();
|
||||
})
|
||||
},
|
||||
|
||||
credit_to: function() {
|
||||
@@ -109,7 +113,8 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
||||
|
||||
entries_add: function(doc, cdt, cdn) {
|
||||
var row = frappe.get_doc(cdt, cdn);
|
||||
this.frm.script_manager.copy_from_first_row("entries", row, ["expense_account", "cost_center"]);
|
||||
this.frm.script_manager.copy_from_first_row("entries", row,
|
||||
["expense_account", "cost_center", "project_name"]);
|
||||
},
|
||||
|
||||
on_submit: function() {
|
||||
@@ -227,7 +232,6 @@ cur_frm.fields_dict['entries'].grid.get_field('project_name').get_query = functi
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cur_frm.cscript.select_print_heading = function(doc,cdt,cdn){
|
||||
if(doc.select_print_heading){
|
||||
// print heading
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"allow_attach": 1,
|
||||
"allow_import": 1,
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2013-05-21 16:16:39",
|
||||
@@ -77,7 +76,7 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "contact_mobile",
|
||||
"fieldtype": "Text",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 1,
|
||||
"label": "Mobile No",
|
||||
"permlevel": 0,
|
||||
@@ -85,7 +84,7 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "contact_email",
|
||||
"fieldtype": "Text",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 1,
|
||||
"label": "Contact Email",
|
||||
"permlevel": 0,
|
||||
@@ -106,7 +105,7 @@
|
||||
"fieldname": "posting_date",
|
||||
"fieldtype": "Date",
|
||||
"in_filter": 1,
|
||||
"label": "Posting Date",
|
||||
"label": "Date",
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "posting_date",
|
||||
"oldfieldtype": "Date",
|
||||
@@ -117,7 +116,7 @@
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"description": "If not applicable please enter: NA",
|
||||
"description": "",
|
||||
"fieldname": "bill_no",
|
||||
"fieldtype": "Data",
|
||||
"in_filter": 1,
|
||||
@@ -127,7 +126,7 @@
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"reqd": 0,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
@@ -146,7 +145,7 @@
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"ignore_restrictions": 1,
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
@@ -231,6 +230,14 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "ignore_pricing_rule",
|
||||
"fieldtype": "Check",
|
||||
"label": "Ignore Pricing Rule",
|
||||
"no_copy": 1,
|
||||
"permlevel": 1,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "items",
|
||||
"fieldtype": "Section Break",
|
||||
@@ -256,22 +263,6 @@
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "net_total_import",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Net Total",
|
||||
"oldfieldname": "net_total_import",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_28",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"description": "Will be calculated automatically when you enter the details",
|
||||
"fieldname": "net_total",
|
||||
@@ -284,6 +275,22 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_28",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "net_total_import",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Net Total",
|
||||
"oldfieldname": "net_total_import",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "taxes",
|
||||
"fieldtype": "Section Break",
|
||||
@@ -332,6 +339,59 @@
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "other_charges_added",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Taxes and Charges Added (Company Currency)",
|
||||
"oldfieldname": "other_charges_added",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "other_charges_deducted",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Taxes and Charges Deducted (Company Currency)",
|
||||
"oldfieldname": "other_charges_deducted",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "grand_total",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Grand Total (Company Currency)",
|
||||
"oldfieldname": "grand_total",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"description": "In Words will be visible once you save the Purchase Invoice.",
|
||||
"fieldname": "in_words",
|
||||
"fieldtype": "Data",
|
||||
"label": "In Words (Company Currency)",
|
||||
"oldfieldname": "in_words",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break8",
|
||||
"fieldtype": "Column Break",
|
||||
"oldfieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"fieldname": "other_charges_added_import",
|
||||
"fieldtype": "Currency",
|
||||
@@ -401,6 +461,17 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "total_tax",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Tax (Company Currency)",
|
||||
"oldfieldname": "total_tax",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "outstanding_amount",
|
||||
"fieldtype": "Currency",
|
||||
@@ -416,70 +487,6 @@
|
||||
"read_only": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break8",
|
||||
"fieldtype": "Column Break",
|
||||
"oldfieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"fieldname": "total_tax",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Tax (Company Currency)",
|
||||
"oldfieldname": "total_tax",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "other_charges_added",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Taxes and Charges Added (Company Currency)",
|
||||
"oldfieldname": "other_charges_added",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "other_charges_deducted",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Taxes and Charges Deducted (Company Currency)",
|
||||
"oldfieldname": "other_charges_deducted",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "grand_total",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Grand Total (Company Currency)",
|
||||
"oldfieldname": "grand_total",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"description": "In Words will be visible once you save the Purchase Invoice.",
|
||||
"fieldname": "in_words",
|
||||
"fieldtype": "Data",
|
||||
"label": "In Words (Company Currency)",
|
||||
"oldfieldname": "in_words",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "write_off_amount",
|
||||
"fieldtype": "Currency",
|
||||
@@ -525,6 +532,11 @@
|
||||
"read_only": 0,
|
||||
"report_hide": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "fold",
|
||||
"fieldtype": "Fold",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "advances",
|
||||
"fieldtype": "Section Break",
|
||||
@@ -593,6 +605,7 @@
|
||||
"label": "Supplier Address",
|
||||
"options": "Address",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
@@ -686,7 +699,7 @@
|
||||
"oldfieldname": "due_date",
|
||||
"oldfieldtype": "Date",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"search_index": 1
|
||||
},
|
||||
@@ -739,21 +752,145 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.docstatus<2",
|
||||
"fieldname": "recurring_invoice",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Recurring Invoice",
|
||||
"options": "icon-time",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_77",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.docstatus<2",
|
||||
"description": "Check if recurring invoice, uncheck to stop recurring or put proper End Date",
|
||||
"fieldname": "is_recurring",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Recurring",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "Select the period when the invoice will be generated automatically",
|
||||
"fieldname": "recurring_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Recurring Type",
|
||||
"no_copy": 1,
|
||||
"options": "Monthly\nQuarterly\nHalf-yearly\nYearly",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "Start date of current invoice's period",
|
||||
"fieldname": "from_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "From Date",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "End date of current invoice's period",
|
||||
"fieldname": "to_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "To Date",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"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",
|
||||
"label": "Repeat on Day of Month",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "The date on which recurring invoice will be stop",
|
||||
"fieldname": "end_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "End Date",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_82",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"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",
|
||||
"label": "Next Date",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"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",
|
||||
"label": "Recurring Id",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "Enter email id separated by commas, invoice will be mailed automatically on particular date",
|
||||
"fieldname": "notification_email_address",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Notification Email Address",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
}
|
||||
],
|
||||
"icon": "icon-file-text",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-09 02:16:52.618986",
|
||||
"modified": "2014-11-27 17:28:20.133701",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"amend": 1,
|
||||
"apply_user_permissions": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
@@ -761,11 +898,12 @@
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
@@ -780,6 +918,7 @@
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
@@ -808,6 +947,7 @@
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
@@ -819,6 +959,12 @@
|
||||
"role": "Auditor",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"permlevel": 1,
|
||||
"read": 1,
|
||||
"role": "Accounts Manager",
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"read_only_onload": 1,
|
||||
|
||||
@@ -4,16 +4,19 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
from frappe.utils import cint, cstr, flt, formatdate
|
||||
|
||||
from frappe.utils import cint, cstr, formatdate, flt
|
||||
from frappe import msgprint, _, throw
|
||||
from erpnext.setup.utils import get_company_currency
|
||||
|
||||
import frappe.defaults
|
||||
|
||||
from erpnext.controllers.buying_controller import BuyingController
|
||||
from erpnext.accounts.party import get_party_account, get_due_date
|
||||
|
||||
form_grid_templates = {
|
||||
"entries": "templates/form_grid/item_grid.html"
|
||||
}
|
||||
|
||||
class PurchaseInvoice(BuyingController):
|
||||
tname = 'Purchase Invoice Item'
|
||||
fname = 'entries'
|
||||
@@ -30,6 +33,7 @@ class PurchaseInvoice(BuyingController):
|
||||
'target_ref_field': 'amount',
|
||||
'source_field': 'amount',
|
||||
'percent_join_field': 'purchase_order',
|
||||
'overflow_type': 'billing'
|
||||
}]
|
||||
|
||||
def validate(self):
|
||||
@@ -42,9 +46,9 @@ class PurchaseInvoice(BuyingController):
|
||||
self.pr_required()
|
||||
self.check_active_purchase_items()
|
||||
self.check_conversion_rate()
|
||||
self.validate_bill_no()
|
||||
self.validate_credit_acc()
|
||||
self.clear_unallocated_advances("Purchase Invoice Advance", "advance_allocation_details")
|
||||
self.validate_advance_jv("advance_allocation_details", "purchase_order")
|
||||
self.check_for_acc_head_of_supplier()
|
||||
self.check_for_stopped_status()
|
||||
self.validate_with_previous_doc()
|
||||
@@ -56,6 +60,14 @@ class PurchaseInvoice(BuyingController):
|
||||
self.update_valuation_rate("entries")
|
||||
self.validate_multiple_billing("Purchase Receipt", "pr_detail", "amount",
|
||||
"purchase_receipt_details")
|
||||
self.create_remarks()
|
||||
|
||||
def create_remarks(self):
|
||||
if not self.remarks:
|
||||
if self.bill_no and self.bill_date:
|
||||
self.remarks = _("Against Supplier Invoice {0} dated {1}").format(self.bill_no, formatdate(self.bill_date))
|
||||
else:
|
||||
self.remarks = _("No Remarks")
|
||||
|
||||
def set_missing_values(self, for_validate=False):
|
||||
if not self.credit_to:
|
||||
@@ -68,7 +80,7 @@ class PurchaseInvoice(BuyingController):
|
||||
|
||||
def get_advances(self):
|
||||
super(PurchaseInvoice, self).get_advances(self.credit_to,
|
||||
"Purchase Invoice Advance", "advance_allocation_details", "debit")
|
||||
"Purchase Invoice Advance", "advance_allocation_details", "debit", "purchase_order")
|
||||
|
||||
def check_active_purchase_items(self):
|
||||
for d in self.get('entries'):
|
||||
@@ -83,23 +95,6 @@ class PurchaseInvoice(BuyingController):
|
||||
if (self.currency == default_currency and flt(self.conversion_rate) != 1.00) or not self.conversion_rate or (self.currency != default_currency and flt(self.conversion_rate) == 1.00):
|
||||
throw(_("Conversion rate cannot be 0 or 1"))
|
||||
|
||||
def validate_bill_no(self):
|
||||
if self.bill_no and self.bill_no.lower().strip() \
|
||||
not in ['na', 'not applicable', 'none']:
|
||||
b_no = frappe.db.sql("""select bill_no, name, ifnull(is_opening,'') from `tabPurchase Invoice`
|
||||
where bill_no = %s and credit_to = %s and docstatus = 1 and name != %s""",
|
||||
(self.bill_no, self.credit_to, self.name))
|
||||
if b_no and cstr(b_no[0][2]) == cstr(self.is_opening):
|
||||
throw(_("Bill No {0} already booked in Purchase Invoice {1}").format(cstr(b_no[0][0]),
|
||||
cstr(b_no[0][1])))
|
||||
|
||||
if not self.remarks and self.bill_date:
|
||||
self.remarks = (self.remarks or '') + "\n" \
|
||||
+ _("Against Bill {0} dated {1}").format(self.bill_no, formatdate(self.bill_date))
|
||||
|
||||
if not self.remarks:
|
||||
self.remarks = "No Remarks"
|
||||
|
||||
def validate_credit_acc(self):
|
||||
if frappe.db.get_value("Account", self.credit_to, "report_type") != "Balance Sheet":
|
||||
frappe.throw(_("Account must be a balance sheet account"))
|
||||
@@ -254,6 +249,8 @@ class PurchaseInvoice(BuyingController):
|
||||
reconcile_against_document(lst)
|
||||
|
||||
def on_submit(self):
|
||||
super(PurchaseInvoice, self).on_submit()
|
||||
|
||||
self.check_prev_docstatus()
|
||||
|
||||
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
|
||||
@@ -269,6 +266,9 @@ class PurchaseInvoice(BuyingController):
|
||||
auto_accounting_for_stock = \
|
||||
cint(frappe.defaults.get_global_default("auto_accounting_for_stock"))
|
||||
|
||||
stock_received_but_not_billed = self.get_company_default("stock_received_but_not_billed")
|
||||
expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
|
||||
|
||||
gl_entries = []
|
||||
|
||||
# parent's gl entry
|
||||
@@ -308,30 +308,10 @@ class PurchaseInvoice(BuyingController):
|
||||
(tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.tax_amount)
|
||||
|
||||
# item gl entries
|
||||
stock_item_and_auto_accounting_for_stock = False
|
||||
negative_expense_to_be_booked = 0.0
|
||||
stock_items = self.get_stock_items()
|
||||
for item in self.get("entries"):
|
||||
if auto_accounting_for_stock and item.item_code in stock_items:
|
||||
if flt(item.valuation_rate):
|
||||
# if auto inventory accounting enabled and stock item,
|
||||
# then do stock related gl entries
|
||||
# expense will be booked in sales invoice
|
||||
stock_item_and_auto_accounting_for_stock = True
|
||||
|
||||
valuation_amt = flt(item.base_amount + item.item_tax_amount,
|
||||
self.precision("base_amount", item))
|
||||
|
||||
gl_entries.append(
|
||||
self.get_gl_dict({
|
||||
"account": item.expense_account,
|
||||
"against": self.credit_to,
|
||||
"debit": valuation_amt,
|
||||
"remarks": self.remarks or "Accounting Entry for Stock"
|
||||
})
|
||||
)
|
||||
|
||||
elif flt(item.base_amount):
|
||||
# if not a stock item or auto inventory accounting disabled, book the expense
|
||||
if flt(item.base_amount):
|
||||
gl_entries.append(
|
||||
self.get_gl_dict({
|
||||
"account": item.expense_account,
|
||||
@@ -342,23 +322,52 @@ class PurchaseInvoice(BuyingController):
|
||||
})
|
||||
)
|
||||
|
||||
if stock_item_and_auto_accounting_for_stock and valuation_tax:
|
||||
if auto_accounting_for_stock and item.item_code in stock_items and item.item_tax_amount:
|
||||
# Post reverse entry for Stock-Received-But-Not-Billed if it is booked in Purchase Receipt
|
||||
negative_expense_booked_in_pi = None
|
||||
if item.purchase_receipt:
|
||||
negative_expense_booked_in_pi = frappe.db.sql("""select name from `tabGL Entry`
|
||||
where voucher_type='Purchase Receipt' and voucher_no=%s and account=%s""",
|
||||
(item.purchase_receipt, expenses_included_in_valuation))
|
||||
|
||||
if not negative_expense_booked_in_pi:
|
||||
gl_entries.append(
|
||||
self.get_gl_dict({
|
||||
"account": stock_received_but_not_billed,
|
||||
"against": self.credit_to,
|
||||
"debit": flt(item.item_tax_amount, self.precision("item_tax_amount", item)),
|
||||
"remarks": self.remarks or "Accounting Entry for Stock"
|
||||
})
|
||||
)
|
||||
|
||||
negative_expense_to_be_booked += flt(item.item_tax_amount, self.precision("item_tax_amount", item))
|
||||
|
||||
if negative_expense_to_be_booked and valuation_tax:
|
||||
# credit valuation tax amount in "Expenses Included In Valuation"
|
||||
# this will balance out valuation amount included in cost of goods sold
|
||||
expenses_included_in_valuation = \
|
||||
self.get_company_default("expenses_included_in_valuation")
|
||||
|
||||
total_valuation_amount = sum(valuation_tax.values())
|
||||
amount_including_divisional_loss = negative_expense_to_be_booked
|
||||
i = 1
|
||||
for cost_center, amount in valuation_tax.items():
|
||||
if i == len(valuation_tax):
|
||||
applicable_amount = amount_including_divisional_loss
|
||||
else:
|
||||
applicable_amount = negative_expense_to_be_booked * (amount / total_valuation_amount)
|
||||
amount_including_divisional_loss -= applicable_amount
|
||||
|
||||
gl_entries.append(
|
||||
self.get_gl_dict({
|
||||
"account": expenses_included_in_valuation,
|
||||
"cost_center": cost_center,
|
||||
"against": self.credit_to,
|
||||
"credit": amount,
|
||||
"credit": applicable_amount,
|
||||
"remarks": self.remarks or "Accounting Entry for Stock"
|
||||
})
|
||||
)
|
||||
|
||||
i += 1
|
||||
|
||||
# writeoff account includes petty difference in the invoice amount
|
||||
# and the amount that is paid
|
||||
if self.write_off_account and flt(self.write_off_amount):
|
||||
@@ -382,7 +391,7 @@ class PurchaseInvoice(BuyingController):
|
||||
|
||||
self.update_prevdoc_status()
|
||||
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
|
||||
self.make_cancel_gl_entries()
|
||||
self.make_gl_entries_on_cancel()
|
||||
|
||||
def on_update(self):
|
||||
pass
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<div class="row" style="max-height: 30px;">
|
||||
<div class="col-xs-9">
|
||||
<div class="text-ellipsis">
|
||||
{%= list.get_avatar_and_id(doc) %}
|
||||
<span style="margin-right: 8px; display: inline-block">
|
||||
<span class="filterable"
|
||||
data-filter="supplier,=,{%= doc.supplier %}">
|
||||
{%= doc.supplier_name %}</span></span>
|
||||
{% if(doc.outstanding_amount > 0 && doc.docstatus==1) { %}
|
||||
{% if(frappe.datetime.get_diff(doc.due_date) < 0) { %}
|
||||
<span class="label label-danger filterable"
|
||||
title="{%= doc.get_formatted("due_date")%}"
|
||||
data-filter="outstanding_amount,>,0|due_date,<,Today">
|
||||
{%= __("Overdue: ") + comment_when(doc.due_date) %}
|
||||
</span>
|
||||
{% } else { %}
|
||||
<span class="label label-warning filterable"
|
||||
data-filter="outstanding_amount,>,0|due,>=,Today"
|
||||
title="{%= __("Payment Pending") %}">
|
||||
{%= doc.get_formatted("due_date") %}</span>
|
||||
{% } %}
|
||||
{% } %}
|
||||
{% if(doc.outstanding_amount==0 && doc.docstatus==1) { %}
|
||||
<span class="label label-success filterable"
|
||||
title="{%= doc.get_formatted("due_date")%}"
|
||||
data-filter="outstanding_amount,=,0">
|
||||
<i class="icon-ok-sign"></i> {%= __("Paid") %}
|
||||
</span>
|
||||
{% } %}
|
||||
{% if(doc.docstatus===0) { %}
|
||||
<span class="label label-danger filterable"
|
||||
data-filter="docstatus,=,0">{%= __("Draft") %}</span>
|
||||
{% } %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-1 text-right">
|
||||
{% var completed = cint((doc.grand_total - doc.outstanding_amount) * 100 / doc.grand_total), title = __("Outstanding Amount") + ": " + doc.get_formatted("outstanding_amount") %}
|
||||
{% include "templates/form_grid/includes/progress.html" %}
|
||||
</div>
|
||||
<div class="col-xs-2 text-right">
|
||||
<div class="text-ellipsis" title="{%= doc.get_formatted('grand_total_import') %}">
|
||||
{%= doc.get_formatted("grand_total_import") %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -3,10 +3,6 @@
|
||||
|
||||
// render
|
||||
frappe.listview_settings['Purchase Invoice'] = {
|
||||
add_fields: ["`tabPurchase Invoice`.grand_total", "`tabPurchase Invoice`.outstanding_amount"],
|
||||
add_columns: [{"content":"paid_amount", width:"10%", type:"bar-graph", label: "Paid"}],
|
||||
prepare_data: function(data) {
|
||||
data.paid_amount = flt(data.grand_total) ? (((flt(data.grand_total) -
|
||||
flt(data.outstanding_amount)) / flt(data.grand_total)) * 100) : 0;
|
||||
}
|
||||
add_fields: ["supplier", "supplier_name", "grand_total", "outstanding_amount", "due_date", "company",
|
||||
"currency"]
|
||||
};
|
||||
|
||||
@@ -9,7 +9,8 @@ import frappe.model
|
||||
import json
|
||||
from frappe.utils import cint
|
||||
import frappe.defaults
|
||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
|
||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory, \
|
||||
test_records as pr_test_records
|
||||
|
||||
test_dependencies = ["Item", "Cost Center"]
|
||||
test_ignore = ["Serial No"]
|
||||
@@ -57,9 +58,41 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
expected_values = sorted([
|
||||
["_Test Supplier - _TC", 0, 720],
|
||||
["Stock Received But Not Billed - _TC", 750.0, 0],
|
||||
["Expenses Included In Valuation - _TC", 0.0, 250.0],
|
||||
["_Test Account Shipping Charges - _TC", 100.0, 0],
|
||||
["_Test Account VAT - _TC", 120.0, 0],
|
||||
])
|
||||
|
||||
for i, gle in enumerate(gl_entries):
|
||||
self.assertEquals(expected_values[i][0], gle.account)
|
||||
self.assertEquals(expected_values[i][1], gle.debit)
|
||||
self.assertEquals(expected_values[i][2], gle.credit)
|
||||
|
||||
set_perpetual_inventory(0)
|
||||
|
||||
def test_gl_entries_with_auto_accounting_for_stock_against_pr(self):
|
||||
set_perpetual_inventory(1)
|
||||
self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 1)
|
||||
|
||||
pr = frappe.copy_doc(pr_test_records[0])
|
||||
pr.submit()
|
||||
|
||||
pi = frappe.copy_doc(test_records[1])
|
||||
for d in pi.get("entries"):
|
||||
d.purchase_receipt = pr.name
|
||||
pi.insert()
|
||||
pi.submit()
|
||||
|
||||
gl_entries = frappe.db.sql("""select account, debit, credit
|
||||
from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s
|
||||
order by account asc""", pi.name, as_dict=1)
|
||||
self.assertTrue(gl_entries)
|
||||
|
||||
expected_values = sorted([
|
||||
["_Test Supplier - _TC", 0, 720],
|
||||
["Stock Received But Not Billed - _TC", 500.0, 0],
|
||||
["_Test Account Shipping Charges - _TC", 100.0, 0],
|
||||
["_Test Account VAT - _TC", 120.0, 0],
|
||||
["Expenses Included In Valuation - _TC", 0, 250.0],
|
||||
])
|
||||
|
||||
for i, gle in enumerate(gl_entries):
|
||||
@@ -198,4 +231,8 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
self.assertTrue(not frappe.db.sql("""select name from `tabJournal Voucher Detail`
|
||||
where against_voucher=%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)
|
||||
|
||||
test_records = frappe.get_test_records('Purchase Invoice')
|
||||
|
||||
@@ -1,206 +1,208 @@
|
||||
[
|
||||
{
|
||||
"bill_no": "NA",
|
||||
"buying_price_list": "_Test Price List",
|
||||
"company": "_Test Company",
|
||||
"conversion_rate": 1,
|
||||
"credit_to": "_Test Supplier - _TC",
|
||||
"currency": "INR",
|
||||
"doctype": "Purchase Invoice",
|
||||
"bill_no": "NA",
|
||||
"buying_price_list": "_Test Price List",
|
||||
"company": "_Test Company",
|
||||
"conversion_rate": 1,
|
||||
"credit_to": "_Test Supplier - _TC",
|
||||
"currency": "INR",
|
||||
"doctype": "Purchase Invoice",
|
||||
"entries": [
|
||||
{
|
||||
"amount": 500,
|
||||
"base_amount": 500,
|
||||
"base_rate": 50,
|
||||
"conversion_factor": 1.0,
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"doctype": "Purchase Invoice Item",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"item_code": "_Test Item Home Desktop 100",
|
||||
"item_name": "_Test Item Home Desktop 100",
|
||||
"item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}",
|
||||
"parentfield": "entries",
|
||||
"qty": 10,
|
||||
"rate": 50,
|
||||
"amount": 500,
|
||||
"base_amount": 500,
|
||||
"base_rate": 50,
|
||||
"conversion_factor": 1.0,
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"doctype": "Purchase Invoice Item",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"item_code": "_Test Item Home Desktop 100",
|
||||
"item_name": "_Test Item Home Desktop 100",
|
||||
"item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}",
|
||||
"parentfield": "entries",
|
||||
"qty": 10,
|
||||
"rate": 50,
|
||||
"uom": "_Test UOM"
|
||||
},
|
||||
},
|
||||
{
|
||||
"amount": 750,
|
||||
"base_amount": 750,
|
||||
"base_rate": 150,
|
||||
"conversion_factor": 1.0,
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"doctype": "Purchase Invoice Item",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"item_code": "_Test Item Home Desktop 200",
|
||||
"item_name": "_Test Item Home Desktop 200",
|
||||
"parentfield": "entries",
|
||||
"qty": 5,
|
||||
"rate": 150,
|
||||
"amount": 750,
|
||||
"base_amount": 750,
|
||||
"base_rate": 150,
|
||||
"conversion_factor": 1.0,
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"doctype": "Purchase Invoice Item",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"item_code": "_Test Item Home Desktop 200",
|
||||
"item_name": "_Test Item Home Desktop 200",
|
||||
"parentfield": "entries",
|
||||
"qty": 5,
|
||||
"rate": 150,
|
||||
"uom": "_Test UOM"
|
||||
}
|
||||
],
|
||||
"fiscal_year": "_Test Fiscal Year 2013",
|
||||
"grand_total_import": 0,
|
||||
"naming_series": "BILL",
|
||||
],
|
||||
"fiscal_year": "_Test Fiscal Year 2013",
|
||||
"grand_total_import": 0,
|
||||
"naming_series": "_T-BILL",
|
||||
"other_charges": [
|
||||
{
|
||||
"account_head": "_Test Account Shipping Charges - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Valuation and Total",
|
||||
"charge_type": "Actual",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Shipping Charges",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account Shipping Charges - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Valuation and Total",
|
||||
"charge_type": "Actual",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Shipping Charges",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 100
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Customs Duty - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Valuation",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Customs Duty",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account Customs Duty - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Valuation",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Customs Duty",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 10
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Excise Duty - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Total",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Excise Duty",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account Excise Duty - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Total",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Excise Duty",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 12
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Education Cess - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Total",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Education Cess",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 2,
|
||||
"account_head": "_Test Account Education Cess - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Total",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Education Cess",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 2,
|
||||
"row_id": 3
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account S&H Education Cess - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Total",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "S&H Education Cess",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 1,
|
||||
"account_head": "_Test Account S&H Education Cess - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Total",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "S&H Education Cess",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 1,
|
||||
"row_id": 3
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account CST - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Total",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "CST",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 2,
|
||||
"account_head": "_Test Account CST - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Total",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "CST",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 2,
|
||||
"row_id": 5
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Total",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "VAT",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Total",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "VAT",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 12.5
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Discount - _TC",
|
||||
"add_deduct_tax": "Deduct",
|
||||
"category": "Total",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Discount",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 10,
|
||||
"account_head": "_Test Account Discount - _TC",
|
||||
"add_deduct_tax": "Deduct",
|
||||
"category": "Total",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Discount",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 10,
|
||||
"row_id": 7
|
||||
}
|
||||
],
|
||||
"posting_date": "2013-02-03",
|
||||
],
|
||||
"posting_date": "2013-02-03",
|
||||
"supplier": "_Test Supplier",
|
||||
"supplier_name": "_Test Supplier"
|
||||
},
|
||||
},
|
||||
{
|
||||
"bill_no": "NA",
|
||||
"buying_price_list": "_Test Price List",
|
||||
"company": "_Test Company",
|
||||
"conversion_rate": 1.0,
|
||||
"credit_to": "_Test Supplier - _TC",
|
||||
"currency": "INR",
|
||||
"doctype": "Purchase Invoice",
|
||||
"bill_no": "NA",
|
||||
"buying_price_list": "_Test Price List",
|
||||
"company": "_Test Company",
|
||||
"conversion_rate": 1.0,
|
||||
"credit_to": "_Test Supplier - _TC",
|
||||
"currency": "INR",
|
||||
"doctype": "Purchase Invoice",
|
||||
"entries": [
|
||||
{
|
||||
"conversion_factor": 1.0,
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"doctype": "Purchase Invoice Item",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"item_code": "_Test Item",
|
||||
"item_name": "_Test Item",
|
||||
"parentfield": "entries",
|
||||
"qty": 10.0,
|
||||
"rate": 50.0,
|
||||
"conversion_factor": 1.0,
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"doctype": "Purchase Invoice Item",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"item_code": "_Test Item",
|
||||
"item_name": "_Test Item",
|
||||
"parentfield": "entries",
|
||||
"qty": 10.0,
|
||||
"rate": 50.0,
|
||||
"uom": "_Test UOM"
|
||||
}
|
||||
],
|
||||
"fiscal_year": "_Test Fiscal Year 2013",
|
||||
"grand_total_import": 0,
|
||||
"naming_series": "_T-Purchase Invoice-",
|
||||
],
|
||||
"fiscal_year": "_Test Fiscal Year 2013",
|
||||
"grand_total_import": 0,
|
||||
"naming_series": "_T-Purchase Invoice-",
|
||||
"other_charges": [
|
||||
{
|
||||
"account_head": "_Test Account Shipping Charges - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Valuation and Total",
|
||||
"charge_type": "Actual",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Shipping Charges",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account Shipping Charges - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Valuation and Total",
|
||||
"charge_type": "Actual",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Shipping Charges",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 100.0
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Total",
|
||||
"charge_type": "Actual",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "VAT",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Total",
|
||||
"charge_type": "Actual",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "VAT",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 120.0
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Customs Duty - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Valuation",
|
||||
"charge_type": "Actual",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Customs Duty",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account Customs Duty - _TC",
|
||||
"add_deduct_tax": "Add",
|
||||
"category": "Valuation",
|
||||
"charge_type": "Actual",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Customs Duty",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 150.0
|
||||
}
|
||||
],
|
||||
"posting_date": "2013-02-03",
|
||||
],
|
||||
"posting_date": "2013-02-03",
|
||||
"supplier": "_Test Supplier",
|
||||
"supplier_name": "_Test Supplier"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"autoname": "EVD.######",
|
||||
"creation": "2013-05-22 12:43:10.000000",
|
||||
"creation": "2013-05-22 12:43:10",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
@@ -8,7 +8,7 @@
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Item",
|
||||
"oldfieldname": "item_code",
|
||||
"oldfieldtype": "Link",
|
||||
@@ -52,7 +52,6 @@
|
||||
{
|
||||
"fieldname": "quantity_and_rate",
|
||||
"fieldtype": "Section Break",
|
||||
"in_list_view": 0,
|
||||
"label": "Quantity and Rate",
|
||||
"permlevel": 0
|
||||
},
|
||||
@@ -76,7 +75,7 @@
|
||||
{
|
||||
"fieldname": "uom",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "UOM",
|
||||
"options": "UOM",
|
||||
"permlevel": 0,
|
||||
@@ -86,7 +85,6 @@
|
||||
{
|
||||
"fieldname": "conversion_factor",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 0,
|
||||
"label": "Conversion Factor",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
@@ -100,7 +98,6 @@
|
||||
{
|
||||
"fieldname": "price_list_rate",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 0,
|
||||
"label": "Price List Rate",
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
@@ -109,8 +106,8 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "discount_percentage",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 0,
|
||||
"fieldtype": "Percent",
|
||||
"in_list_view": 1,
|
||||
"label": "Discount %",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
@@ -124,7 +121,6 @@
|
||||
{
|
||||
"fieldname": "base_price_list_rate",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 0,
|
||||
"label": "Price List Rate (Company Currency)",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
@@ -169,7 +165,6 @@
|
||||
{
|
||||
"fieldname": "base_rate",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 0,
|
||||
"label": "Rate (Company Currency)",
|
||||
"oldfieldname": "rate",
|
||||
"oldfieldtype": "Currency",
|
||||
@@ -182,7 +177,6 @@
|
||||
{
|
||||
"fieldname": "base_amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 0,
|
||||
"label": "Amount (Company Currency)",
|
||||
"oldfieldname": "amount",
|
||||
"oldfieldtype": "Currency",
|
||||
@@ -193,17 +187,9 @@
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_price",
|
||||
"fieldname": "pricing_rule",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Price",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_discount",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Discount",
|
||||
"label": "Pricing Rule",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
@@ -211,14 +197,12 @@
|
||||
{
|
||||
"fieldname": "accounting",
|
||||
"fieldtype": "Section Break",
|
||||
"in_list_view": 0,
|
||||
"label": "Accounting",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "expense_account",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"label": "Expense Head",
|
||||
"oldfieldname": "expense_head",
|
||||
"oldfieldtype": "Link",
|
||||
@@ -235,11 +219,20 @@
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "project_name",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"label": "Project Name",
|
||||
"options": "Project",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"default": ":Company",
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"label": "Cost Center",
|
||||
"oldfieldname": "cost_center",
|
||||
"oldfieldtype": "Link",
|
||||
@@ -253,26 +246,13 @@
|
||||
{
|
||||
"fieldname": "reference",
|
||||
"fieldtype": "Section Break",
|
||||
"in_list_view": 0,
|
||||
"label": "Reference",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "project_name",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Project Name",
|
||||
"options": "Project",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "brand",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Brand",
|
||||
"oldfieldname": "brand",
|
||||
"oldfieldtype": "Data",
|
||||
@@ -286,7 +266,6 @@
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"in_filter": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Item Group",
|
||||
"oldfieldname": "item_group",
|
||||
"oldfieldtype": "Link",
|
||||
@@ -301,7 +280,6 @@
|
||||
"fieldname": "item_tax_rate",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Item Tax Rate",
|
||||
"oldfieldname": "item_tax_rate",
|
||||
"oldfieldtype": "Small Text",
|
||||
@@ -314,7 +292,6 @@
|
||||
"fieldname": "item_tax_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Item Tax Amount",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
@@ -325,28 +302,10 @@
|
||||
"search_index": 0,
|
||||
"width": "150px"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "page_break",
|
||||
"fieldtype": "Check",
|
||||
"in_list_view": 0,
|
||||
"label": "Page Break",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"report_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "col_break6",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "purchase_order",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Purchase Order",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "purchase_order",
|
||||
@@ -357,12 +316,16 @@
|
||||
"read_only": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "col_break6",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "po_detail",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"in_filter": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Purchase Order Item",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "po_detail",
|
||||
@@ -376,7 +339,6 @@
|
||||
"fieldname": "purchase_receipt",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Purchase Receipt",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "purchase_receipt",
|
||||
@@ -387,12 +349,22 @@
|
||||
"read_only": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "page_break",
|
||||
"fieldtype": "Check",
|
||||
"label": "Page Break",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"report_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pr_detail",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"in_filter": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "PR Detail",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "pr_detail",
|
||||
@@ -406,7 +378,6 @@
|
||||
"fieldname": "valuation_rate",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Valuation Rate",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
@@ -418,7 +389,6 @@
|
||||
"fieldname": "rm_supp_cost",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Raw Materials Supplied Cost",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
@@ -429,9 +399,12 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2014-02-28 11:27:53.000000",
|
||||
"modified": "2014-09-09 05:35:35.712453",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice Item",
|
||||
"owner": "Administrator"
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
@@ -1,431 +1,164 @@
|
||||
{
|
||||
"_last_update": null,
|
||||
"_user_tags": null,
|
||||
"allow_attach": null,
|
||||
"allow_copy": null,
|
||||
"allow_email": null,
|
||||
"allow_import": null,
|
||||
"allow_print": null,
|
||||
"allow_rename": null,
|
||||
"allow_trash": null,
|
||||
"autoname": "PVTD.######",
|
||||
"change_log": null,
|
||||
"client_script": null,
|
||||
"client_script_core": null,
|
||||
"client_string": null,
|
||||
"colour": null,
|
||||
"creation": "2013-05-21 16:16:04",
|
||||
"custom": null,
|
||||
"default_print_format": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": null,
|
||||
"dt_template": null,
|
||||
"autoname": "PVTD.######",
|
||||
"creation": "2013-05-21 16:16:04",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": "Valuation and Total",
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "category",
|
||||
"fieldtype": "Select",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": 0,
|
||||
"label": "Consider Tax or Charge for",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "category",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Valuation and Total\nValuation\nTotal",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": null,
|
||||
"reqd": 1,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
"default": "Valuation and Total",
|
||||
"fieldname": "category",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 0,
|
||||
"label": "Consider Tax or Charge for",
|
||||
"oldfieldname": "category",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Valuation and Total\nValuation\nTotal",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": "Add",
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "add_deduct_tax",
|
||||
"fieldtype": "Select",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Add or Deduct",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "add_deduct_tax",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Add\nDeduct",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": null,
|
||||
"reqd": 1,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
"default": "Add",
|
||||
"fieldname": "add_deduct_tax",
|
||||
"fieldtype": "Select",
|
||||
"label": "Add or Deduct",
|
||||
"oldfieldname": "add_deduct_tax",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Add\nDeduct",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "charge_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": 1,
|
||||
"label": "Type",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "charge_type",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nActual\nOn Net Total\nOn Previous Row Amount\nOn Previous Row Total",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": null,
|
||||
"reqd": 1,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
"fieldname": "charge_type",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Type",
|
||||
"oldfieldname": "charge_type",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nActual\nOn Net Total\nOn Previous Row Amount\nOn Previous Row Total",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": "eval:[\"On Previous Row Amount\", \"On Previous Row Total\"].indexOf(doc.charge_type)!==-1",
|
||||
"description": null,
|
||||
"fieldname": "row_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Reference Row #",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "row_id",
|
||||
"oldfieldtype": "Data",
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
"depends_on": "eval:[\"On Previous Row Amount\", \"On Previous Row Total\"].indexOf(doc.charge_type)!==-1",
|
||||
"fieldname": "row_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"label": "Reference Row #",
|
||||
"oldfieldname": "row_id",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": 1,
|
||||
"label": "Description",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Small Text",
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": "300px",
|
||||
"read_only": 0,
|
||||
"report_hide": null,
|
||||
"reqd": 1,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"in_list_view": 1,
|
||||
"label": "Description",
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Small Text",
|
||||
"permlevel": 0,
|
||||
"print_width": "300px",
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"width": "300px"
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "col_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": null,
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": null,
|
||||
"oldfieldtype": null,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": null,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
"fieldname": "col_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "account_head",
|
||||
"fieldtype": "Link",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": 0,
|
||||
"label": "Account Head",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "account_head",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": null,
|
||||
"reqd": 1,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
"fieldname": "account_head",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"label": "Account Head",
|
||||
"oldfieldname": "account_head",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": ":Company",
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": 0,
|
||||
"label": "Cost Center",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "cost_center",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Cost Center",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
"default": ":Company",
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"label": "Cost Center",
|
||||
"oldfieldname": "cost_center",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Cost Center",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "rate",
|
||||
"fieldtype": "Float",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": 1,
|
||||
"label": "Rate",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "rate",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": null,
|
||||
"reqd": 0,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
"fieldname": "rate",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Rate",
|
||||
"oldfieldname": "rate",
|
||||
"oldfieldtype": "Currency",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "tax_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": 1,
|
||||
"label": "Amount",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "tax_amount",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": null,
|
||||
"reqd": 0,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
"fieldname": "tax_amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Amount",
|
||||
"oldfieldname": "tax_amount",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "total",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Total",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "total",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
"fieldname": "total",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total",
|
||||
"oldfieldname": "total",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "item_wise_tax_detail",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 1,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Item Wise Tax Detail ",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "item_wise_tax_detail",
|
||||
"oldfieldtype": "Small Text",
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
"fieldname": "item_wise_tax_detail",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 1,
|
||||
"label": "Item Wise Tax Detail ",
|
||||
"oldfieldname": "item_wise_tax_detail",
|
||||
"oldfieldtype": "Small Text",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "parenttype",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": 1,
|
||||
"in_list_view": null,
|
||||
"label": "Parenttype",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "parenttype",
|
||||
"oldfieldtype": "Data",
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": 0,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
"fieldname": "parenttype",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"in_filter": 1,
|
||||
"label": "Parenttype",
|
||||
"oldfieldname": "parenttype",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"search_index": 0
|
||||
}
|
||||
],
|
||||
"hide_heading": 1,
|
||||
"hide_toolbar": null,
|
||||
"icon": null,
|
||||
"idx": 1,
|
||||
"in_create": null,
|
||||
"in_dialog": null,
|
||||
"is_submittable": null,
|
||||
"is_transaction_doc": null,
|
||||
"issingle": null,
|
||||
"istable": 1,
|
||||
"max_attachments": null,
|
||||
"menu_index": null,
|
||||
"modified": "2014-04-15 09:48:45.892548",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Taxes and Charges",
|
||||
"name_case": null,
|
||||
"owner": "Administrator",
|
||||
"parent": null,
|
||||
"parent_node": null,
|
||||
"parentfield": null,
|
||||
"parenttype": null,
|
||||
"permissions": [],
|
||||
"plugin": null,
|
||||
"print_outline": null,
|
||||
"read_only": null,
|
||||
"read_only_onload": null,
|
||||
"search_fields": null,
|
||||
"section_style": null,
|
||||
"server_code": null,
|
||||
"server_code_compiled": null,
|
||||
"server_code_core": null,
|
||||
"server_code_error": null,
|
||||
"show_in_menu": null,
|
||||
"smallicon": null,
|
||||
"subject": null,
|
||||
"tag_fields": null,
|
||||
"title_field": null,
|
||||
"use_template": null,
|
||||
"version": null
|
||||
}
|
||||
],
|
||||
"hide_heading": 1,
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2014-05-30 03:43:32.494112",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Taxes and Charges",
|
||||
"owner": "Administrator",
|
||||
"permissions": []
|
||||
}
|
||||
|
||||
@@ -21,9 +21,9 @@ erpnext.POS = Class.extend({
|
||||
<tr>\
|
||||
<th style="width: 40%">'+__("Item")+'</th>\
|
||||
<th style="width: 9%"></th>\
|
||||
<th style="width: 17%; text-align: right;">Qty</th>\
|
||||
<th style="width: 22%; text-align: right;">Qty</th>\
|
||||
<th style="width: 9%"></th>\
|
||||
<th style="width: 25%; text-align: right;">Rate</th>\
|
||||
<th style="width: 20%; text-align: right;">Rate</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody>\
|
||||
@@ -114,7 +114,7 @@ erpnext.POS = Class.extend({
|
||||
});
|
||||
|
||||
this.wrapper.find('input.discount-amount').on("change", function() {
|
||||
frappe.model.set_value(me.frm.doctype, me.frm.docname, "discount_amount", this.value);
|
||||
frappe.model.set_value(me.frm.doctype, me.frm.docname, "discount_amount", flt(this.value));
|
||||
});
|
||||
|
||||
this.call_function("remove-items", function() {me.remove_selected_items();});
|
||||
@@ -233,6 +233,11 @@ erpnext.POS = Class.extend({
|
||||
},
|
||||
make_item_list: function() {
|
||||
var me = this;
|
||||
if(!this.price_list) {
|
||||
msgprint(__("Price List not found or disabled"));
|
||||
return;
|
||||
}
|
||||
|
||||
me.item_timeout = null;
|
||||
frappe.call({
|
||||
method: 'erpnext.accounts.doctype.sales_invoice.pos.get_items',
|
||||
@@ -367,10 +372,8 @@ erpnext.POS = Class.extend({
|
||||
this.hide_payment_button();
|
||||
|
||||
// If quotation to is not Customer then remove party
|
||||
if (this.frm.doctype == "Quotation") {
|
||||
if (this.frm.doctype == "Quotation" && this.frm.doc.quotation_to!="Customer") {
|
||||
this.party_field.$wrapper.remove();
|
||||
if (this.frm.doc.quotation_to == "Customer")
|
||||
this.make_party();
|
||||
}
|
||||
},
|
||||
refresh_item_list: function() {
|
||||
@@ -389,14 +392,19 @@ erpnext.POS = Class.extend({
|
||||
|
||||
$(repl('<tr id="%(item_code)s" data-selected="false">\
|
||||
<td>%(item_code)s%(item_name)s</td>\
|
||||
<td style="vertical-align:middle;" align="right">\
|
||||
<td style="vertical-align:top; padding-top: 10px;" \
|
||||
align="right">\
|
||||
<div class="decrease-qty" style="cursor:pointer;">\
|
||||
<i class="icon-minus-sign icon-large text-danger"></i>\
|
||||
</div>\
|
||||
</td>\
|
||||
<td style="vertical-align:middle;"><input type="text" value="%(qty)s" \
|
||||
class="form-control qty" style="text-align: right;"></td>\
|
||||
<td style="vertical-align:middle;cursor:pointer;">\
|
||||
<td style="vertical-align:middle;">\
|
||||
<input type="text" value="%(qty)s" \
|
||||
class="form-control qty" style="text-align: right;">\
|
||||
<div class="actual-qty small text-muted">'
|
||||
+__("Stock: ")+'<span class="text-success">%(actual_qty)s</span>%(projected_qty)s</div>\
|
||||
</td>\
|
||||
<td style="vertical-align:top; padding-top: 10px;">\
|
||||
<div class="increase-qty" style="cursor:pointer;">\
|
||||
<i class="icon-plus-sign icon-large text-success"></i>\
|
||||
</div>\
|
||||
@@ -407,6 +415,9 @@ erpnext.POS = Class.extend({
|
||||
item_code: d.item_code,
|
||||
item_name: d.item_name===d.item_code ? "" : ("<br>" + d.item_name),
|
||||
qty: d.qty,
|
||||
actual_qty: d.actual_qty,
|
||||
projected_qty: d.projected_qty ? (" <span title='"+__("Projected Qty")
|
||||
+"'>(" + d.projected_qty + ")<span>") : "",
|
||||
rate: format_currency(d.rate, me.frm.doc.currency),
|
||||
amount: format_currency(d.amount, me.frm.doc.currency)
|
||||
}
|
||||
@@ -481,7 +492,11 @@ erpnext.POS = Class.extend({
|
||||
});
|
||||
|
||||
me.refresh_delete_btn();
|
||||
this.barcode.$input.focus();
|
||||
if(me.frm.doc[this.party.toLowerCase()]) {
|
||||
this.barcode.$input.focus();
|
||||
} else {
|
||||
this.party_field.$input.focus();
|
||||
}
|
||||
},
|
||||
increase_decrease_qty: function(tr, operation) {
|
||||
var item_code = tr.attr("id");
|
||||
@@ -489,7 +504,7 @@ erpnext.POS = Class.extend({
|
||||
|
||||
if (operation == "increase-qty")
|
||||
this.update_qty(item_code, item_qty + 1);
|
||||
else if (operation == "decrease-qty" && item_qty != 1)
|
||||
else if (operation == "decrease-qty" && item_qty != 0)
|
||||
this.update_qty(item_code, item_qty - 1);
|
||||
},
|
||||
disable_text_box_and_button: function() {
|
||||
|
||||
@@ -11,7 +11,6 @@ cur_frm.pformat.print_heading = 'Invoice';
|
||||
|
||||
{% include 'selling/sales_common.js' %};
|
||||
{% include 'accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js' %}
|
||||
{% include 'utilities/doctype/sms_control/sms_control.js' %}
|
||||
{% include 'accounts/doctype/sales_invoice/pos.js' %}
|
||||
|
||||
frappe.provide("erpnext.accounts");
|
||||
@@ -25,7 +24,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
}
|
||||
|
||||
// toggle to pos view if is_pos is 1 in user_defaults
|
||||
if ((cint(frappe.defaults.get_user_defaults("is_pos"))===1 || this.frm.doc.is_pos)) {
|
||||
if ((is_null(this.frm.doc.is_pos) && cint(frappe.defaults.get_user_default("is_pos"))===1) || this.frm.doc.is_pos) {
|
||||
if(this.frm.doc.__islocal && !this.frm.doc.amended_from && !this.frm.doc.customer) {
|
||||
this.frm.set_value("is_pos", 1);
|
||||
this.is_pos(function() {
|
||||
@@ -35,8 +34,9 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
}
|
||||
}
|
||||
|
||||
// if document is POS then change default print format to "POS Invoice"
|
||||
if(cur_frm.doc.is_pos && cur_frm.doc.docstatus===1) {
|
||||
// if document is POS then change default print format to "POS Invoice" if no default is specified
|
||||
if(cur_frm.doc.is_pos && cur_frm.doc.docstatus===1 && cint(frappe.defaults.get_user_defaults("fs_pos_view"))===1
|
||||
&& !locals.DocType[cur_frm.doctype].default_print_format) {
|
||||
locals.DocType[cur_frm.doctype].default_print_format = "POS Invoice";
|
||||
cur_frm.setup_print_layout();
|
||||
}
|
||||
@@ -73,12 +73,14 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
return item.delivery_note ? true : false;
|
||||
});
|
||||
|
||||
if(!from_delivery_note)
|
||||
cur_frm.appframe.add_primary_action(__('Make Delivery'), cur_frm.cscript['Make Delivery Note'])
|
||||
if(!from_delivery_note) {
|
||||
cur_frm.appframe.add_primary_action(__('Make Delivery'), cur_frm.cscript['Make Delivery Note'], "icon-truck")
|
||||
}
|
||||
}
|
||||
|
||||
if(doc.outstanding_amount!=0)
|
||||
cur_frm.appframe.add_primary_action(__('Make Payment Entry'), cur_frm.cscript.make_bank_voucher);
|
||||
if(doc.outstanding_amount!=0) {
|
||||
cur_frm.appframe.add_primary_action(__('Make Payment Entry'), cur_frm.cscript.make_bank_voucher, "icon-money");
|
||||
}
|
||||
}
|
||||
|
||||
// Show buttons only when pos view is active
|
||||
@@ -102,7 +104,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
company: cur_frm.doc.company
|
||||
}
|
||||
})
|
||||
});
|
||||
}, "icon-download", "btn-default");
|
||||
},
|
||||
|
||||
delivery_note_btn: function() {
|
||||
@@ -122,7 +124,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
}, "icon-download", "btn-default");
|
||||
},
|
||||
|
||||
tc_name: function() {
|
||||
@@ -155,8 +157,9 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
},
|
||||
|
||||
customer: function() {
|
||||
if(this.frm.updating_party_details)
|
||||
return;
|
||||
var me = this;
|
||||
if(this.frm.updating_party_details) return;
|
||||
|
||||
erpnext.utils.get_party_details(this.frm,
|
||||
"erpnext.accounts.party.get_party_details", {
|
||||
posting_date: this.frm.doc.posting_date,
|
||||
@@ -164,7 +167,9 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
party_type: "Customer",
|
||||
account: this.frm.doc.debit_to,
|
||||
price_list: this.frm.doc.selling_price_list,
|
||||
})
|
||||
}, function() {
|
||||
me.apply_pricing_rule();
|
||||
})
|
||||
},
|
||||
|
||||
debit_to: function() {
|
||||
@@ -181,8 +186,9 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
frappe.model.round_floats_in(this.frm.doc, ["grand_total", "paid_amount"]);
|
||||
// this will make outstanding amount 0
|
||||
this.frm.set_value("write_off_amount",
|
||||
flt(this.frm.doc.grand_total - this.frm.doc.paid_amount),
|
||||
precision("write_off_amount"));
|
||||
flt(this.frm.doc.grand_total - this.frm.doc.paid_amount,
|
||||
precision("write_off_amount"))
|
||||
);
|
||||
}
|
||||
|
||||
this.calculate_outstanding_amount(false);
|
||||
@@ -219,10 +225,9 @@ $.extend(cur_frm.cscript, new erpnext.accounts.SalesInvoiceController({frm: cur_
|
||||
// Hide Fields
|
||||
// ------------
|
||||
cur_frm.cscript.hide_fields = function(doc) {
|
||||
par_flds = ['project_name', 'due_date', 'is_opening', 'source', 'total_advance', 'gross_profit',
|
||||
'gross_profit_percent', 'get_advances_received',
|
||||
par_flds = ['project_name', 'due_date', 'is_opening', 'source', 'total_advance', 'get_advances_received',
|
||||
'advance_adjustment_details', 'sales_partner', 'commission_rate',
|
||||
'total_commission', 'advances'];
|
||||
'total_commission', 'advances', 'from_date', 'to_date'];
|
||||
|
||||
item_flds_normal = ['sales_order', 'delivery_note']
|
||||
|
||||
@@ -393,33 +398,8 @@ cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
|
||||
})
|
||||
}
|
||||
|
||||
cur_frm.cscript.convert_into_recurring_invoice = function(doc, dt, dn) {
|
||||
// set default values for recurring invoices
|
||||
if(doc.convert_into_recurring_invoice) {
|
||||
var owner_email = doc.owner=="Administrator"
|
||||
? frappe.user_info("Administrator").email
|
||||
: doc.owner;
|
||||
|
||||
doc.notification_email_address = $.map([cstr(owner_email),
|
||||
cstr(doc.contact_email)], function(v) { return v || null; }).join(", ");
|
||||
doc.repeat_on_day_of_month = frappe.datetime.str_to_obj(doc.posting_date).getDate();
|
||||
}
|
||||
|
||||
refresh_many(["notification_email_address", "repeat_on_day_of_month"]);
|
||||
cur_frm.cscript.send_sms = function() {
|
||||
frappe.require("assets/erpnext/js/sms_manager.js");
|
||||
var sms_man = new SMSManager(cur_frm.doc);
|
||||
}
|
||||
|
||||
cur_frm.cscript.invoice_period_from_date = function(doc, dt, dn) {
|
||||
// set invoice_period_to_date
|
||||
if(doc.invoice_period_from_date) {
|
||||
var recurring_type_map = {'Monthly': 1, 'Quarterly': 3, 'Half-yearly': 6,
|
||||
'Yearly': 12};
|
||||
|
||||
var months = recurring_type_map[doc.recurring_type];
|
||||
if(months) {
|
||||
var to_date = frappe.datetime.add_months(doc.invoice_period_from_date,
|
||||
months);
|
||||
doc.invoice_period_to_date = frappe.datetime.add_days(to_date, -1);
|
||||
refresh_field('invoice_period_to_date');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"allow_attach": 1,
|
||||
"allow_import": 1,
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2013-05-24 19:29:05",
|
||||
@@ -71,7 +70,7 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "contact_mobile",
|
||||
"fieldtype": "Text",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 1,
|
||||
"label": "Mobile No",
|
||||
"permlevel": 0,
|
||||
@@ -79,13 +78,24 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "contact_email",
|
||||
"fieldtype": "Text",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 1,
|
||||
"label": "Contact Email",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "mode_of_payment",
|
||||
"fieldtype": "Link",
|
||||
"label": "Mode of Payment",
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "mode_of_payment",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Mode of Payment",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
@@ -103,19 +113,6 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"ignore_restrictions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Sales Invoice",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
@@ -130,12 +127,25 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Sales Invoice",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"default": "Today",
|
||||
"fieldname": "posting_date",
|
||||
"fieldtype": "Date",
|
||||
"in_filter": 1,
|
||||
"label": "Posting Date",
|
||||
"label": "Date",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "posting_date",
|
||||
"oldfieldtype": "Date",
|
||||
@@ -159,15 +169,25 @@
|
||||
"search_index": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "mode_of_payment",
|
||||
"fieldname": "shipping_address_name",
|
||||
"fieldtype": "Link",
|
||||
"label": "Mode of Payment",
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "mode_of_payment",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Mode of Payment",
|
||||
"hidden": 1,
|
||||
"in_filter": 1,
|
||||
"label": "Shipping Address Name",
|
||||
"options": "Address",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
"precision": "",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "shipping_address",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 1,
|
||||
"label": "Shipping Address",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "currency_section",
|
||||
@@ -241,6 +261,14 @@
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "ignore_pricing_rule",
|
||||
"fieldtype": "Check",
|
||||
"label": "Ignore Pricing Rule",
|
||||
"no_copy": 1,
|
||||
"permlevel": 1,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "items",
|
||||
"fieldtype": "Section Break",
|
||||
@@ -303,20 +331,6 @@
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "net_total_export",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Net Total",
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_32",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "net_total",
|
||||
"fieldtype": "Currency",
|
||||
@@ -329,6 +343,20 @@
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_32",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "net_total_export",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Net Total",
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "taxes",
|
||||
"fieldtype": "Section Break",
|
||||
@@ -403,11 +431,6 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_45",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "other_charges_total",
|
||||
"fieldtype": "Currency",
|
||||
@@ -419,14 +442,29 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_45",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "discount_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Discount Amount",
|
||||
"options": "Company:company:default_currency",
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "base_discount_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Discount Amount (Company Currency)",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "totals",
|
||||
"fieldtype": "Section Break",
|
||||
@@ -437,70 +475,6 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "grand_total_export",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Grand Total",
|
||||
"oldfieldname": "grand_total_export",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "rounded_total_export",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Rounded Total",
|
||||
"oldfieldname": "rounded_total_export",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "in_words_export",
|
||||
"fieldtype": "Data",
|
||||
"label": "In Words",
|
||||
"oldfieldname": "in_words_export",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "gross_profit",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Gross Profit",
|
||||
"oldfieldname": "gross_profit",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "gross_profit_percent",
|
||||
"fieldtype": "Float",
|
||||
"label": "Gross Profit (%)",
|
||||
"oldfieldname": "gross_profit_percent",
|
||||
"oldfieldtype": "Currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break5",
|
||||
"fieldtype": "Column Break",
|
||||
"oldfieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"fieldname": "grand_total",
|
||||
"fieldtype": "Currency",
|
||||
@@ -561,6 +535,49 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break5",
|
||||
"fieldtype": "Column Break",
|
||||
"oldfieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"fieldname": "grand_total_export",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Grand Total",
|
||||
"oldfieldname": "grand_total_export",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "rounded_total_export",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Rounded Total",
|
||||
"oldfieldname": "rounded_total_export",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "in_words_export",
|
||||
"fieldtype": "Data",
|
||||
"label": "In Words",
|
||||
"oldfieldname": "in_words_export",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "advances",
|
||||
"fieldtype": "Section Break",
|
||||
@@ -682,6 +699,11 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "fold",
|
||||
"fieldtype": "Fold",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "terms_section_break",
|
||||
"fieldtype": "Section Break",
|
||||
@@ -1051,9 +1073,9 @@
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.docstatus<2",
|
||||
"description": "Check if recurring invoice, uncheck to stop recurring or put proper End Date",
|
||||
"fieldname": "convert_into_recurring_invoice",
|
||||
"fieldname": "is_recurring",
|
||||
"fieldtype": "Check",
|
||||
"label": "Convert into Recurring Invoice",
|
||||
"label": "Is Recurring",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
@@ -1061,7 +1083,7 @@
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.convert_into_recurring_invoice==1",
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "Select the period when the invoice will be generated automatically",
|
||||
"fieldname": "recurring_type",
|
||||
"fieldtype": "Select",
|
||||
@@ -1074,7 +1096,31 @@
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.convert_into_recurring_invoice==1",
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "Start date of current invoice's period",
|
||||
"fieldname": "from_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "From Date",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "End date of current invoice's period",
|
||||
"fieldname": "to_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "To Date",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"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",
|
||||
@@ -1086,23 +1132,11 @@
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.convert_into_recurring_invoice==1",
|
||||
"description": "Start date of current invoice's period",
|
||||
"fieldname": "invoice_period_from_date",
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "The date on which recurring invoice will be stop",
|
||||
"fieldname": "end_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Invoice Period From Date",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.convert_into_recurring_invoice==1",
|
||||
"description": "End date of current invoice's period",
|
||||
"fieldname": "invoice_period_to_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Invoice Period To Date",
|
||||
"label": "End Date",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
@@ -1118,30 +1152,7 @@
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.convert_into_recurring_invoice==1",
|
||||
"description": "Enter email id separated by commas, invoice will be mailed automatically on particular date",
|
||||
"fieldname": "notification_email_address",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Notification Email Address",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.convert_into_recurring_invoice==1",
|
||||
"description": "The unique id for tracking all recurring invoices.\u00a0It is generated on submit.",
|
||||
"fieldname": "recurring_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "Recurring Id",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.convert_into_recurring_invoice==1",
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "The date on which next invoice will be generated. It is generated on submit.\n",
|
||||
"fieldname": "next_date",
|
||||
"fieldtype": "Date",
|
||||
@@ -1151,13 +1162,24 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "The unique id for tracking all recurring invoices.\u00a0It is generated on submit.",
|
||||
"fieldname": "recurring_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "Recurring Id",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.convert_into_recurring_invoice==1",
|
||||
"description": "The date on which recurring invoice will be stop",
|
||||
"fieldname": "end_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "End Date",
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "Enter email id separated by commas, invoice will be mailed automatically on particular date",
|
||||
"fieldname": "notification_email_address",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Notification Email Address",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
@@ -1180,7 +1202,7 @@
|
||||
"icon": "icon-file-text",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-09 02:17:00.217556",
|
||||
"modified": "2015-01-12 17:34:36.353241",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice",
|
||||
@@ -1202,6 +1224,7 @@
|
||||
},
|
||||
{
|
||||
"amend": 1,
|
||||
"apply_user_permissions": 1,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 0,
|
||||
@@ -1215,6 +1238,7 @@
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"apply_user_permissions": 1,
|
||||
"cancel": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
@@ -1223,6 +1247,12 @@
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Customer"
|
||||
},
|
||||
{
|
||||
"permlevel": 1,
|
||||
"read": 1,
|
||||
"role": "Accounts Manager",
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"read_only_onload": 1,
|
||||
|
||||
@@ -4,20 +4,18 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import frappe.defaults
|
||||
|
||||
from frappe.utils import add_days, cint, cstr, date_diff, flt, getdate, nowdate, \
|
||||
get_first_day, get_last_day
|
||||
from frappe.model.naming import make_autoname
|
||||
from frappe.utils import cint, cstr, flt
|
||||
from frappe import _, msgprint, throw
|
||||
|
||||
from erpnext.accounts.party import get_party_account, get_due_date
|
||||
from erpnext.controllers.stock_controller import update_gl_entries_after
|
||||
from frappe.model.mapper import get_mapped_doc
|
||||
|
||||
month_map = {'Monthly': 1, 'Quarterly': 3, 'Half-yearly': 6, 'Yearly': 12}
|
||||
|
||||
from erpnext.controllers.selling_controller import SellingController
|
||||
|
||||
form_grid_templates = {
|
||||
"entries": "templates/form_grid/item_grid.html"
|
||||
}
|
||||
|
||||
class SalesInvoice(SellingController):
|
||||
tname = 'Sales Invoice Item'
|
||||
fname = 'entries'
|
||||
@@ -36,7 +34,8 @@ class SalesInvoice(SellingController):
|
||||
'join_field': 'so_detail',
|
||||
'percent_join_field': 'sales_order',
|
||||
'status_field': 'billing_status',
|
||||
'keyword': 'Billed'
|
||||
'keyword': 'Billed',
|
||||
'overflow_type': 'billing'
|
||||
}]
|
||||
|
||||
def validate(self):
|
||||
@@ -51,6 +50,7 @@ class SalesInvoice(SellingController):
|
||||
self.validate_debit_acc()
|
||||
self.validate_fixed_asset_account()
|
||||
self.clear_unallocated_advances("Sales Invoice Advance", "advance_adjustment_details")
|
||||
self.validate_advance_jv("advance_adjustment_details", "sales_order")
|
||||
self.add_remarks()
|
||||
|
||||
if cint(self.is_pos):
|
||||
@@ -66,15 +66,18 @@ class SalesInvoice(SellingController):
|
||||
self.is_opening = 'No'
|
||||
|
||||
self.set_aging_date()
|
||||
|
||||
frappe.get_doc("Account", self.debit_to).validate_due_date(self.posting_date, self.due_date)
|
||||
|
||||
self.set_against_income_account()
|
||||
self.validate_c_form()
|
||||
self.validate_time_logs_are_submitted()
|
||||
self.validate_recurring_invoice()
|
||||
self.validate_multiple_billing("Delivery Note", "dn_detail", "amount",
|
||||
"delivery_note_details")
|
||||
|
||||
def on_submit(self):
|
||||
super(SalesInvoice, self).on_submit()
|
||||
|
||||
if cint(self.update_stock) == 1:
|
||||
self.update_stock_ledger()
|
||||
else:
|
||||
@@ -96,9 +99,7 @@ class SalesInvoice(SellingController):
|
||||
if not cint(self.is_pos) == 1:
|
||||
self.update_against_document_in_jv()
|
||||
|
||||
self.update_c_form()
|
||||
self.update_time_log_batch(self.name)
|
||||
self.convert_to_recurring()
|
||||
|
||||
def before_cancel(self):
|
||||
self.update_time_log_batch(None)
|
||||
@@ -115,8 +116,9 @@ class SalesInvoice(SellingController):
|
||||
self.update_status_updater_args()
|
||||
self.update_prevdoc_status()
|
||||
self.update_billing_status_for_zero_amount_refdoc("Sales Order")
|
||||
self.validate_c_form_on_cancel()
|
||||
|
||||
self.make_cancel_gl_entries()
|
||||
self.make_gl_entries_on_cancel()
|
||||
|
||||
def update_status_updater_args(self):
|
||||
if cint(self.update_stock):
|
||||
@@ -134,13 +136,10 @@ class SalesInvoice(SellingController):
|
||||
'keyword':'Delivered',
|
||||
'second_source_dt': 'Delivery Note Item',
|
||||
'second_source_field': 'qty',
|
||||
'second_join_field': 'prevdoc_detail_docname'
|
||||
'second_join_field': 'prevdoc_detail_docname',
|
||||
'overflow_type': 'delivery'
|
||||
})
|
||||
|
||||
def on_update_after_submit(self):
|
||||
self.validate_recurring_invoice()
|
||||
self.convert_to_recurring()
|
||||
|
||||
def get_portal_page(self):
|
||||
return "invoice" if self.docstatus==1 else None
|
||||
|
||||
@@ -210,7 +209,7 @@ class SalesInvoice(SellingController):
|
||||
|
||||
def get_advances(self):
|
||||
super(SalesInvoice, self).get_advances(self.debit_to,
|
||||
"Sales Invoice Advance", "advance_adjustment_details", "credit")
|
||||
"Sales Invoice Advance", "advance_adjustment_details", "credit", "sales_order")
|
||||
|
||||
def get_company_abbr(self):
|
||||
return frappe.db.sql("select abbr from tabCompany where name=%s", self.company)[0][0]
|
||||
@@ -262,11 +261,11 @@ class SalesInvoice(SellingController):
|
||||
"""Validate Fixed Asset and whether Income Account Entered Exists"""
|
||||
for d in self.get('entries'):
|
||||
item = frappe.db.sql("""select name,is_asset_item,is_sales_item from `tabItem`
|
||||
where name = %s and (ifnull(end_of_life,'')='' or end_of_life > now())""", d.item_code)
|
||||
acc = frappe.db.sql("""select account_type from `tabAccount`
|
||||
where name = %s""", d.item_code)
|
||||
acc = frappe.db.sql("""select account_type from `tabAccount`
|
||||
where name = %s and docstatus != 2""", d.income_account)
|
||||
if item and item[0][1] == 'Yes' and not acc[0][0] == 'Fixed Asset':
|
||||
msgprint(_("Account {0} must be of type 'Fixed Asset' as Item {1} is an Asset Item").format(d.item_code), raise_exception=True)
|
||||
if item and item[0][1] == 'Yes' and acc and acc[0][0] != 'Fixed Asset':
|
||||
msgprint(_("Account {0} must be of type 'Fixed Asset' as Item {1} is an Asset Item").format(acc[0][0], d.item_code), raise_exception=True)
|
||||
|
||||
def validate_with_previous_doc(self):
|
||||
super(SalesInvoice, self).validate_with_previous_doc(self.tname, {
|
||||
@@ -339,8 +338,8 @@ class SalesInvoice(SellingController):
|
||||
|
||||
def validate_pos(self):
|
||||
if not self.cash_bank_account and flt(self.paid_amount):
|
||||
msgprint(_("Cash or Bank Account is mandatory for making payment entry"))
|
||||
raise Exception
|
||||
frappe.throw(_("Cash or Bank Account is mandatory for making payment entry"))
|
||||
|
||||
if flt(self.paid_amount) + flt(self.write_off_amount) \
|
||||
- flt(self.grand_total) > 1/(10**(self.precision("grand_total") + 1)):
|
||||
frappe.throw(_("""Paid amount + Write Off Amount can not be greater than Grand Total"""))
|
||||
@@ -370,6 +369,12 @@ class SalesInvoice(SellingController):
|
||||
|
||||
frappe.db.set(self, 'c_form_no', '')
|
||||
|
||||
def validate_c_form_on_cancel(self):
|
||||
""" Display message if C-Form no exists on cancellation of Sales Invoice"""
|
||||
if self.c_form_applicable == 'Yes' and self.c_form_no:
|
||||
msgprint(_("Please remove this Invoice {0} from C-Form {1}")
|
||||
.format(self.name, self.c_form_no), raise_exception = 1)
|
||||
|
||||
def update_current_stock(self):
|
||||
for d in self.get('entries'):
|
||||
if d.item_code and d.warehouse:
|
||||
@@ -383,20 +388,20 @@ class SalesInvoice(SellingController):
|
||||
|
||||
|
||||
def get_warehouse(self):
|
||||
w = frappe.db.sql("""select warehouse from `tabPOS Setting`
|
||||
where ifnull(user,'') = %s and company = %s""",
|
||||
(frappe.session['user'], self.company))
|
||||
w = w and w[0][0] or ''
|
||||
if not w:
|
||||
ps = frappe.db.sql("""select name, warehouse from `tabPOS Setting`
|
||||
user_pos_setting = frappe.db.sql("""select name, warehouse from `tabPOS Setting`
|
||||
where ifnull(user,'') = %s and company = %s""", (frappe.session['user'], self.company))
|
||||
warehouse = user_pos_setting[0][1] if user_pos_setting else None
|
||||
|
||||
if not warehouse:
|
||||
global_pos_setting = frappe.db.sql("""select name, warehouse from `tabPOS Setting`
|
||||
where ifnull(user,'') = '' and company = %s""", self.company)
|
||||
if not ps:
|
||||
|
||||
if global_pos_setting:
|
||||
warehouse = global_pos_setting[0][1]
|
||||
elif not user_pos_setting:
|
||||
msgprint(_("POS Setting required to make POS Entry"), raise_exception=True)
|
||||
elif not ps[0][1]:
|
||||
msgprint(_("Warehouse required in POS Setting"))
|
||||
else:
|
||||
w = ps[0][1]
|
||||
return w
|
||||
|
||||
return warehouse
|
||||
|
||||
def on_update(self):
|
||||
if cint(self.update_stock) == 1:
|
||||
@@ -431,8 +436,7 @@ class SalesInvoice(SellingController):
|
||||
submitted = frappe.db.sql("""select name from `tabSales Order`
|
||||
where docstatus = 1 and name = %s""", d.sales_order)
|
||||
if not submitted:
|
||||
msgprint(_("Sales Order {0} is not submitted").format(d.sales_order))
|
||||
raise Exception
|
||||
frappe.throw(_("Sales Order {0} is not submitted").format(d.sales_order))
|
||||
|
||||
if d.delivery_note:
|
||||
submitted = frappe.db.sql("""select name from `tabDelivery Note`
|
||||
@@ -469,9 +473,8 @@ class SalesInvoice(SellingController):
|
||||
|
||||
if repost_future_gle and cint(self.update_stock) \
|
||||
and cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
|
||||
items, warehouse_account = self.get_items_and_warehouse_accounts()
|
||||
update_gl_entries_after(self.posting_date, self.posting_time,
|
||||
warehouse_account, items)
|
||||
items, warehouses = self.get_items_and_warehouses()
|
||||
update_gl_entries_after(self.posting_date, self.posting_time, warehouses, items)
|
||||
|
||||
def get_gl_entries(self, warehouse_account=None):
|
||||
from erpnext.accounts.general_ledger import merge_similar_entries
|
||||
@@ -579,178 +582,6 @@ class SalesInvoice(SellingController):
|
||||
})
|
||||
)
|
||||
|
||||
def update_c_form(self):
|
||||
"""Update amended id in C-form"""
|
||||
if self.c_form_no and self.amended_from:
|
||||
frappe.db.sql("""update `tabC-Form Invoice Detail` set invoice_no = %s,
|
||||
invoice_date = %s, territory = %s, net_total = %s,
|
||||
grand_total = %s where invoice_no = %s and parent = %s""",
|
||||
(self.name, self.amended_from, self.c_form_no))
|
||||
|
||||
def validate_recurring_invoice(self):
|
||||
if self.convert_into_recurring_invoice:
|
||||
self.validate_notification_email_id()
|
||||
|
||||
if not self.recurring_type:
|
||||
msgprint(_("Please select {0}").format(self.meta.get_label("recurring_type")),
|
||||
raise_exception=1)
|
||||
|
||||
elif not (self.invoice_period_from_date and \
|
||||
self.invoice_period_to_date):
|
||||
throw(_("Invoice Period From and Invoice Period To dates mandatory for recurring invoice"))
|
||||
|
||||
def convert_to_recurring(self):
|
||||
if self.convert_into_recurring_invoice:
|
||||
if not self.recurring_id:
|
||||
frappe.db.set(self, "recurring_id",
|
||||
make_autoname("RECINV/.#####"))
|
||||
|
||||
self.set_next_date()
|
||||
|
||||
elif self.recurring_id:
|
||||
frappe.db.sql("""update `tabSales Invoice`
|
||||
set convert_into_recurring_invoice = 0
|
||||
where recurring_id = %s""", (self.recurring_id,))
|
||||
|
||||
def validate_notification_email_id(self):
|
||||
if self.notification_email_address:
|
||||
email_list = filter(None, [cstr(email).strip() for email in
|
||||
self.notification_email_address.replace("\n", "").split(",")])
|
||||
|
||||
from frappe.utils import validate_email_add
|
||||
for email in email_list:
|
||||
if not validate_email_add(email):
|
||||
throw(_("{0} is an invalid email address in 'Notification Email Address'").format(email))
|
||||
|
||||
else:
|
||||
throw(_("'Notification Email Addresses' not specified for recurring invoice"))
|
||||
|
||||
def set_next_date(self):
|
||||
""" Set next date on which auto invoice will be created"""
|
||||
if not self.repeat_on_day_of_month:
|
||||
msgprint(_("Please enter 'Repeat on Day of Month' field value"), raise_exception=1)
|
||||
|
||||
next_date = get_next_date(self.posting_date,
|
||||
month_map[self.recurring_type], cint(self.repeat_on_day_of_month))
|
||||
|
||||
frappe.db.set(self, 'next_date', next_date)
|
||||
|
||||
def get_next_date(dt, mcount, day=None):
|
||||
dt = getdate(dt)
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
dt += relativedelta(months=mcount, day=day)
|
||||
|
||||
return dt
|
||||
|
||||
def manage_recurring_invoices(next_date=None, commit=True):
|
||||
"""
|
||||
Create recurring invoices on specific date by copying the original one
|
||||
and notify the concerned people
|
||||
"""
|
||||
next_date = next_date or nowdate()
|
||||
recurring_invoices = frappe.db.sql("""select name, recurring_id
|
||||
from `tabSales Invoice` where ifnull(convert_into_recurring_invoice, 0)=1
|
||||
and docstatus=1 and next_date=%s
|
||||
and next_date <= ifnull(end_date, '2199-12-31')""", next_date)
|
||||
|
||||
exception_list = []
|
||||
for ref_invoice, recurring_id in recurring_invoices:
|
||||
if not frappe.db.sql("""select name from `tabSales Invoice`
|
||||
where posting_date=%s and recurring_id=%s and docstatus=1""",
|
||||
(next_date, recurring_id)):
|
||||
try:
|
||||
ref_wrapper = frappe.get_doc('Sales Invoice', ref_invoice)
|
||||
new_invoice_wrapper = make_new_invoice(ref_wrapper, next_date)
|
||||
send_notification(new_invoice_wrapper)
|
||||
if commit:
|
||||
frappe.db.commit()
|
||||
except:
|
||||
if commit:
|
||||
frappe.db.rollback()
|
||||
|
||||
frappe.db.begin()
|
||||
frappe.db.sql("update `tabSales Invoice` set \
|
||||
convert_into_recurring_invoice = 0 where name = %s", ref_invoice)
|
||||
notify_errors(ref_invoice, ref_wrapper.customer, ref_wrapper.owner)
|
||||
frappe.db.commit()
|
||||
|
||||
exception_list.append(frappe.get_traceback())
|
||||
finally:
|
||||
if commit:
|
||||
frappe.db.begin()
|
||||
|
||||
if exception_list:
|
||||
exception_message = "\n\n".join([cstr(d) for d in exception_list])
|
||||
raise Exception, exception_message
|
||||
|
||||
def make_new_invoice(ref_wrapper, posting_date):
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
new_invoice = frappe.copy_doc(ref_wrapper)
|
||||
|
||||
mcount = month_map[ref_wrapper.recurring_type]
|
||||
|
||||
invoice_period_from_date = get_next_date(ref_wrapper.invoice_period_from_date, mcount)
|
||||
|
||||
# get last day of the month to maintain period if the from date is first day of its own month
|
||||
# and to date is the last day of its own month
|
||||
if (cstr(get_first_day(ref_wrapper.invoice_period_from_date)) == \
|
||||
cstr(ref_wrapper.invoice_period_from_date)) and \
|
||||
(cstr(get_last_day(ref_wrapper.invoice_period_to_date)) == \
|
||||
cstr(ref_wrapper.invoice_period_to_date)):
|
||||
invoice_period_to_date = get_last_day(get_next_date(ref_wrapper.invoice_period_to_date,
|
||||
mcount))
|
||||
else:
|
||||
invoice_period_to_date = get_next_date(ref_wrapper.invoice_period_to_date, mcount)
|
||||
|
||||
new_invoice.update({
|
||||
"posting_date": posting_date,
|
||||
"aging_date": posting_date,
|
||||
"due_date": add_days(posting_date, cint(date_diff(ref_wrapper.due_date,
|
||||
ref_wrapper.posting_date))),
|
||||
"invoice_period_from_date": invoice_period_from_date,
|
||||
"invoice_period_to_date": invoice_period_to_date,
|
||||
"fiscal_year": get_fiscal_year(posting_date)[0],
|
||||
"owner": ref_wrapper.owner,
|
||||
})
|
||||
|
||||
new_invoice.submit()
|
||||
|
||||
return new_invoice
|
||||
|
||||
def send_notification(new_rv):
|
||||
"""Notify concerned persons about recurring invoice generation"""
|
||||
|
||||
from frappe.core.doctype.print_format.print_format import get_html
|
||||
frappe.sendmail(new_rv.notification_email_address,
|
||||
subject="New Invoice : " + new_rv.name,
|
||||
message = get_html(new_rv, new_rv, "SalesInvoice"))
|
||||
|
||||
def notify_errors(inv, customer, owner):
|
||||
from frappe.utils.user import get_system_managers
|
||||
recipients=get_system_managers()
|
||||
|
||||
frappe.sendmail(recipients + [frappe.db.get_value("User", owner, "email")],
|
||||
subject="[Urgent] Error while creating recurring invoice for %s" % inv,
|
||||
message = frappe.get_template("template/emails/recurring_invoice_failed.html").render({
|
||||
"name": inv,
|
||||
"customer": customer
|
||||
}))
|
||||
|
||||
assign_task_to_owner(inv, "Recurring Invoice Failed", recipients)
|
||||
|
||||
def assign_task_to_owner(inv, msg, users):
|
||||
for d in users:
|
||||
from frappe.widgets.form import assign_to
|
||||
args = {
|
||||
'assign_to' : d,
|
||||
'doctype' : 'Sales Invoice',
|
||||
'name' : inv,
|
||||
'description' : msg,
|
||||
'priority' : 'Urgent'
|
||||
}
|
||||
assign_to.add(args)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_bank_cash_account(mode_of_payment):
|
||||
val = frappe.db.get_value("Mode of Payment", mode_of_payment, "default_account")
|
||||
@@ -783,6 +614,7 @@ def get_income_account(doctype, txt, searchfield, start, page_len, filters):
|
||||
@frappe.whitelist()
|
||||
def make_delivery_note(source_name, target_doc=None):
|
||||
def set_missing_values(source, target):
|
||||
target.ignore_pricing_rule = 1
|
||||
target.run_method("set_missing_values")
|
||||
target.run_method("calculate_taxes_and_totals")
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<div class="row" style="max-height: 30px;">
|
||||
<div class="col-xs-9">
|
||||
<div class="text-ellipsis">
|
||||
{%= list.get_avatar_and_id(doc) %}
|
||||
<span style="margin-right: 8px; display: inline-block">
|
||||
<span class="filterable"
|
||||
data-filter="customer,=,{%= doc.customer %}">
|
||||
{%= doc.customer_name %}</span></span>
|
||||
{% if(doc.outstanding_amount > 0 && doc.docstatus==1) { %}
|
||||
{% if(frappe.datetime.get_diff(doc.due_date) < 0) { %}
|
||||
<span class="label label-danger filterable"
|
||||
title="{%= doc.get_formatted("due_date")%}"
|
||||
data-filter="outstanding_amount,>,0|due_date,<,Today">
|
||||
{%= __("Overdue: ") + comment_when(doc.due_date) %}
|
||||
</span>
|
||||
{% } else { %}
|
||||
<span class="label label-warning filterable"
|
||||
data-filter="outstanding_amount,>,0|due_date,>=,Today"
|
||||
title="{%= __("Payment Pending") %}">
|
||||
{%= doc.get_formatted("due_date") %}</span>
|
||||
{% } %}
|
||||
{% } %}
|
||||
{% if(doc.outstanding_amount==0 && doc.docstatus==1) { %}
|
||||
<span class="label label-success filterable"
|
||||
title="{%= doc.get_formatted("due_date")%}"
|
||||
data-filter="outstanding_amount,=,0">
|
||||
<i class="icon-ok-sign"></i> {%= __("Paid") %}
|
||||
</span>
|
||||
{% } %}
|
||||
{% if(doc.docstatus===0) { %}
|
||||
<span class="label label-danger filterable"
|
||||
data-filter="docstatus,=,0">{%= __("Draft") %}</span>
|
||||
{% } %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-1 text-right">
|
||||
{% var completed = cint((doc.grand_total - doc.outstanding_amount) * 100 / doc.grand_total), title = __("Outstanding Amount") + ": " + doc.get_formatted("outstanding_amount") %}
|
||||
{% include "templates/form_grid/includes/progress.html" %}
|
||||
</div>
|
||||
<div class="col-xs-2 text-right">
|
||||
<div class="text-ellipsis" title="{%= doc.get_formatted("grand_total_export") %}">
|
||||
{%= doc.get_formatted("grand_total_export") %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -3,12 +3,7 @@
|
||||
|
||||
// render
|
||||
frappe.listview_settings['Sales Invoice'] = {
|
||||
add_fields: ["`tabSales Invoice`.grand_total", "`tabSales Invoice`.outstanding_amount"],
|
||||
add_columns: [{"content":"Percent Paid", width:"10%", type:"bar-graph",
|
||||
label: "Payment Received"}],
|
||||
prepare_data: function(data) {
|
||||
data["Percent Paid"] = (data.docstatus===1 && flt(data.grand_total))
|
||||
? (((flt(data.grand_total) - flt(data.outstanding_amount)) / flt(data.grand_total)) * 100)
|
||||
: 0;
|
||||
}
|
||||
add_fields: ["customer", "customer_name", "grand_total", "outstanding_amount", "due_date", "company",
|
||||
"currency"],
|
||||
filters: [["outstanding_amount", ">", "0"]]
|
||||
};
|
||||
|
||||
@@ -1,385 +1,390 @@
|
||||
[
|
||||
{
|
||||
"company": "_Test Company",
|
||||
"conversion_rate": 1.0,
|
||||
"currency": "INR",
|
||||
"customer": "_Test Customer",
|
||||
"customer_name": "_Test Customer",
|
||||
"debit_to": "_Test Customer - _TC",
|
||||
"doctype": "Sales Invoice",
|
||||
"due_date": "2013-01-23",
|
||||
"company": "_Test Company",
|
||||
"conversion_rate": 1.0,
|
||||
"currency": "INR",
|
||||
"customer": "_Test Customer",
|
||||
"customer_name": "_Test Customer",
|
||||
"debit_to": "_Test Customer - _TC",
|
||||
"doctype": "Sales Invoice",
|
||||
"due_date": "2013-01-23",
|
||||
"entries": [
|
||||
{
|
||||
"amount": 500.0,
|
||||
"base_amount": 500.0,
|
||||
"base_rate": 500.0,
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "138-CMS Shoe",
|
||||
"doctype": "Sales Invoice Item",
|
||||
"income_account": "Sales - _TC",
|
||||
"item_name": "138-CMS Shoe",
|
||||
"parentfield": "entries",
|
||||
"qty": 1.0,
|
||||
"amount": 500.0,
|
||||
"base_amount": 500.0,
|
||||
"base_rate": 500.0,
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "138-CMS Shoe",
|
||||
"doctype": "Sales Invoice Item",
|
||||
"income_account": "Sales - _TC",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"item_name": "138-CMS Shoe",
|
||||
"parentfield": "entries",
|
||||
"qty": 1.0,
|
||||
"rate": 500.0
|
||||
}
|
||||
],
|
||||
"fiscal_year": "_Test Fiscal Year 2013",
|
||||
"grand_total": 561.8,
|
||||
"grand_total_export": 561.8,
|
||||
"is_pos": 0,
|
||||
"naming_series": "_T-Sales Invoice-",
|
||||
"net_total": 500.0,
|
||||
],
|
||||
"fiscal_year": "_Test Fiscal Year 2013",
|
||||
"grand_total": 561.8,
|
||||
"grand_total_export": 561.8,
|
||||
"is_pos": 0,
|
||||
"naming_series": "_T-Sales Invoice-",
|
||||
"net_total": 500.0,
|
||||
"other_charges": [
|
||||
{
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"description": "VAT",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"description": "VAT",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 6
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Service Tax - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"description": "Service Tax",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account Service Tax - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"description": "Service Tax",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 6.36
|
||||
}
|
||||
],
|
||||
"plc_conversion_rate": 1.0,
|
||||
"posting_date": "2013-01-23",
|
||||
"price_list_currency": "INR",
|
||||
],
|
||||
"plc_conversion_rate": 1.0,
|
||||
"posting_date": "2013-01-23",
|
||||
"price_list_currency": "INR",
|
||||
"sales_team": [
|
||||
{
|
||||
"allocated_percentage": 65.5,
|
||||
"doctype": "Sales Team",
|
||||
"parentfield": "sales_team",
|
||||
"allocated_percentage": 65.5,
|
||||
"doctype": "Sales Team",
|
||||
"parentfield": "sales_team",
|
||||
"sales_person": "_Test Sales Person 1"
|
||||
},
|
||||
},
|
||||
{
|
||||
"allocated_percentage": 34.5,
|
||||
"doctype": "Sales Team",
|
||||
"parentfield": "sales_team",
|
||||
"allocated_percentage": 34.5,
|
||||
"doctype": "Sales Team",
|
||||
"parentfield": "sales_team",
|
||||
"sales_person": "_Test Sales Person 2"
|
||||
}
|
||||
],
|
||||
"selling_price_list": "_Test Price List",
|
||||
],
|
||||
"selling_price_list": "_Test Price List",
|
||||
"territory": "_Test Territory"
|
||||
},
|
||||
},
|
||||
{
|
||||
"company": "_Test Company",
|
||||
"conversion_rate": 1.0,
|
||||
"currency": "INR",
|
||||
"customer": "_Test Customer",
|
||||
"customer_name": "_Test Customer",
|
||||
"debit_to": "_Test Customer - _TC",
|
||||
"doctype": "Sales Invoice",
|
||||
"due_date": "2013-01-23",
|
||||
"company": "_Test Company",
|
||||
"conversion_rate": 1.0,
|
||||
"currency": "INR",
|
||||
"customer": "_Test Customer",
|
||||
"customer_name": "_Test Customer",
|
||||
"debit_to": "_Test Customer - _TC",
|
||||
"doctype": "Sales Invoice",
|
||||
"due_date": "2013-03-07",
|
||||
"entries": [
|
||||
{
|
||||
"amount": 500.0,
|
||||
"base_amount": 500.0,
|
||||
"base_rate": 500.0,
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "_Test Item",
|
||||
"doctype": "Sales Invoice Item",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"income_account": "Sales - _TC",
|
||||
"item_code": "_Test Item",
|
||||
"item_name": "_Test Item",
|
||||
"parentfield": "entries",
|
||||
"price_list_rate": 500.0,
|
||||
"amount": 500.0,
|
||||
"base_amount": 500.0,
|
||||
"base_rate": 500.0,
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "_Test Item",
|
||||
"doctype": "Sales Invoice Item",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"income_account": "Sales - _TC",
|
||||
"item_code": "_Test Item",
|
||||
"item_name": "_Test Item",
|
||||
"parentfield": "entries",
|
||||
"price_list_rate": 500.0,
|
||||
"qty": 1.0
|
||||
}
|
||||
],
|
||||
"fiscal_year": "_Test Fiscal Year 2013",
|
||||
"grand_total": 630.0,
|
||||
"grand_total_export": 630.0,
|
||||
"is_pos": 0,
|
||||
"naming_series": "_T-Sales Invoice-",
|
||||
"net_total": 500.0,
|
||||
],
|
||||
"fiscal_year": "_Test Fiscal Year 2013",
|
||||
"grand_total": 630.0,
|
||||
"grand_total_export": 630.0,
|
||||
"is_pos": 0,
|
||||
"naming_series": "_T-Sales Invoice-",
|
||||
"net_total": 500.0,
|
||||
"other_charges": [
|
||||
{
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"description": "VAT",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"description": "VAT",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 16
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Service Tax - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"description": "Service Tax",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account Service Tax - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"description": "Service Tax",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 10
|
||||
}
|
||||
],
|
||||
"plc_conversion_rate": 1.0,
|
||||
"posting_date": "2013-03-07",
|
||||
"price_list_currency": "INR",
|
||||
"selling_price_list": "_Test Price List",
|
||||
],
|
||||
"plc_conversion_rate": 1.0,
|
||||
"posting_date": "2013-03-07",
|
||||
"price_list_currency": "INR",
|
||||
"selling_price_list": "_Test Price List",
|
||||
"territory": "_Test Territory"
|
||||
},
|
||||
},
|
||||
{
|
||||
"company": "_Test Company",
|
||||
"conversion_rate": 1.0,
|
||||
"currency": "INR",
|
||||
"customer": "_Test Customer",
|
||||
"customer_name": "_Test Customer",
|
||||
"debit_to": "_Test Customer - _TC",
|
||||
"doctype": "Sales Invoice",
|
||||
"due_date": "2013-01-23",
|
||||
"company": "_Test Company",
|
||||
"conversion_rate": 1.0,
|
||||
"currency": "INR",
|
||||
"customer": "_Test Customer",
|
||||
"customer_name": "_Test Customer",
|
||||
"debit_to": "_Test Customer - _TC",
|
||||
"doctype": "Sales Invoice",
|
||||
"due_date": "2013-01-23",
|
||||
"entries": [
|
||||
{
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"doctype": "Sales Invoice Item",
|
||||
"income_account": "Sales - _TC",
|
||||
"item_code": "_Test Item Home Desktop 100",
|
||||
"item_name": "_Test Item Home Desktop 100",
|
||||
"item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}",
|
||||
"parentfield": "entries",
|
||||
"price_list_rate": 50,
|
||||
"qty": 10,
|
||||
"rate": 50,
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"doctype": "Sales Invoice Item",
|
||||
"income_account": "Sales - _TC",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"item_code": "_Test Item Home Desktop 100",
|
||||
"item_name": "_Test Item Home Desktop 100",
|
||||
"item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}",
|
||||
"parentfield": "entries",
|
||||
"price_list_rate": 50,
|
||||
"qty": 10,
|
||||
"rate": 50,
|
||||
"stock_uom": "_Test UOM"
|
||||
},
|
||||
},
|
||||
{
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"doctype": "Sales Invoice Item",
|
||||
"income_account": "Sales - _TC",
|
||||
"item_code": "_Test Item Home Desktop 200",
|
||||
"item_name": "_Test Item Home Desktop 200",
|
||||
"parentfield": "entries",
|
||||
"price_list_rate": 150,
|
||||
"qty": 5,
|
||||
"rate": 150,
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"doctype": "Sales Invoice Item",
|
||||
"income_account": "Sales - _TC",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"item_code": "_Test Item Home Desktop 200",
|
||||
"item_name": "_Test Item Home Desktop 200",
|
||||
"parentfield": "entries",
|
||||
"price_list_rate": 150,
|
||||
"qty": 5,
|
||||
"rate": 150,
|
||||
"stock_uom": "_Test UOM"
|
||||
}
|
||||
],
|
||||
"fiscal_year": "_Test Fiscal Year 2013",
|
||||
"grand_total_export": 0,
|
||||
"is_pos": 0,
|
||||
"naming_series": "_T-Sales Invoice-",
|
||||
],
|
||||
"fiscal_year": "_Test Fiscal Year 2013",
|
||||
"grand_total_export": 0,
|
||||
"is_pos": 0,
|
||||
"naming_series": "_T-Sales Invoice-",
|
||||
"other_charges": [
|
||||
{
|
||||
"account_head": "_Test Account Shipping Charges - _TC",
|
||||
"charge_type": "Actual",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Shipping Charges",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account Shipping Charges - _TC",
|
||||
"charge_type": "Actual",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Shipping Charges",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 100
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Customs Duty - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Customs Duty",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account Customs Duty - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Customs Duty",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 10
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Excise Duty - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Excise Duty",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account Excise Duty - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Excise Duty",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 12
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Education Cess - _TC",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Education Cess",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 2,
|
||||
"account_head": "_Test Account Education Cess - _TC",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Education Cess",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 2,
|
||||
"row_id": 3
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account S&H Education Cess - _TC",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "S&H Education Cess",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 1,
|
||||
"account_head": "_Test Account S&H Education Cess - _TC",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "S&H Education Cess",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 1,
|
||||
"row_id": 3
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account CST - _TC",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "CST",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 2,
|
||||
"account_head": "_Test Account CST - _TC",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "CST",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 2,
|
||||
"row_id": 5
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "VAT",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "VAT",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": 12.5
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Discount - _TC",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Discount",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": -10,
|
||||
"account_head": "_Test Account Discount - _TC",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Discount",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "other_charges",
|
||||
"rate": -10,
|
||||
"row_id": 7
|
||||
}
|
||||
],
|
||||
"plc_conversion_rate": 1.0,
|
||||
"posting_date": "2013-01-23",
|
||||
"price_list_currency": "INR",
|
||||
"selling_price_list": "_Test Price List",
|
||||
],
|
||||
"plc_conversion_rate": 1.0,
|
||||
"posting_date": "2013-01-23",
|
||||
"price_list_currency": "INR",
|
||||
"selling_price_list": "_Test Price List",
|
||||
"territory": "_Test Territory"
|
||||
},
|
||||
},
|
||||
{
|
||||
"company": "_Test Company",
|
||||
"conversion_rate": 1.0,
|
||||
"currency": "INR",
|
||||
"customer": "_Test Customer",
|
||||
"customer_name": "_Test Customer",
|
||||
"debit_to": "_Test Customer - _TC",
|
||||
"doctype": "Sales Invoice",
|
||||
"due_date": "2013-01-23",
|
||||
"company": "_Test Company",
|
||||
"conversion_rate": 1.0,
|
||||
"currency": "INR",
|
||||
"customer": "_Test Customer",
|
||||
"customer_name": "_Test Customer",
|
||||
"debit_to": "_Test Customer - _TC",
|
||||
"doctype": "Sales Invoice",
|
||||
"due_date": "2013-01-23",
|
||||
"entries": [
|
||||
{
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"doctype": "Sales Invoice Item",
|
||||
"income_account": "Sales - _TC",
|
||||
"item_code": "_Test Item Home Desktop 100",
|
||||
"item_name": "_Test Item Home Desktop 100",
|
||||
"item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}",
|
||||
"parentfield": "entries",
|
||||
"price_list_rate": 62.5,
|
||||
"qty": 10,
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"doctype": "Sales Invoice Item",
|
||||
"income_account": "Sales - _TC",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"item_code": "_Test Item Home Desktop 100",
|
||||
"item_name": "_Test Item Home Desktop 100",
|
||||
"item_tax_rate": "{\"_Test Account Excise Duty - _TC\": 10}",
|
||||
"parentfield": "entries",
|
||||
"price_list_rate": 62.5,
|
||||
"qty": 10,
|
||||
"stock_uom": "_Test UOM"
|
||||
},
|
||||
},
|
||||
{
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"doctype": "Sales Invoice Item",
|
||||
"income_account": "Sales - _TC",
|
||||
"item_code": "_Test Item Home Desktop 200",
|
||||
"item_name": "_Test Item Home Desktop 200",
|
||||
"parentfield": "entries",
|
||||
"price_list_rate": 190.66,
|
||||
"qty": 5,
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"doctype": "Sales Invoice Item",
|
||||
"income_account": "Sales - _TC",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"item_code": "_Test Item Home Desktop 200",
|
||||
"item_name": "_Test Item Home Desktop 200",
|
||||
"parentfield": "entries",
|
||||
"price_list_rate": 190.66,
|
||||
"qty": 5,
|
||||
"stock_uom": "_Test UOM"
|
||||
}
|
||||
],
|
||||
"fiscal_year": "_Test Fiscal Year 2013",
|
||||
"grand_total_export": 0,
|
||||
"is_pos": 0,
|
||||
"naming_series": "_T-Sales Invoice-",
|
||||
],
|
||||
"fiscal_year": "_Test Fiscal Year 2013",
|
||||
"grand_total_export": 0,
|
||||
"is_pos": 0,
|
||||
"naming_series": "_T-Sales Invoice-",
|
||||
"other_charges": [
|
||||
{
|
||||
"account_head": "_Test Account Excise Duty - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Excise Duty",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"idx": 1,
|
||||
"included_in_print_rate": 1,
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account Excise Duty - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Excise Duty",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"idx": 1,
|
||||
"included_in_print_rate": 1,
|
||||
"parentfield": "other_charges",
|
||||
"rate": 12
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Education Cess - _TC",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Education Cess",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"idx": 2,
|
||||
"included_in_print_rate": 1,
|
||||
"parentfield": "other_charges",
|
||||
"rate": 2,
|
||||
"account_head": "_Test Account Education Cess - _TC",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Education Cess",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"idx": 2,
|
||||
"included_in_print_rate": 1,
|
||||
"parentfield": "other_charges",
|
||||
"rate": 2,
|
||||
"row_id": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account S&H Education Cess - _TC",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "S&H Education Cess",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"idx": 3,
|
||||
"included_in_print_rate": 1,
|
||||
"parentfield": "other_charges",
|
||||
"rate": 1,
|
||||
"account_head": "_Test Account S&H Education Cess - _TC",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "S&H Education Cess",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"idx": 3,
|
||||
"included_in_print_rate": 1,
|
||||
"parentfield": "other_charges",
|
||||
"rate": 1,
|
||||
"row_id": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account CST - _TC",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "CST",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"idx": 4,
|
||||
"included_in_print_rate": 1,
|
||||
"parentfield": "other_charges",
|
||||
"rate": 2,
|
||||
"account_head": "_Test Account CST - _TC",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "CST",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"idx": 4,
|
||||
"included_in_print_rate": 1,
|
||||
"parentfield": "other_charges",
|
||||
"rate": 2,
|
||||
"row_id": 3
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "VAT",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"idx": 5,
|
||||
"included_in_print_rate": 1,
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "VAT",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"idx": 5,
|
||||
"included_in_print_rate": 1,
|
||||
"parentfield": "other_charges",
|
||||
"rate": 12.5
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Customs Duty - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Customs Duty",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"idx": 6,
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account Customs Duty - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Customs Duty",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"idx": 6,
|
||||
"parentfield": "other_charges",
|
||||
"rate": 10
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Shipping Charges - _TC",
|
||||
"charge_type": "Actual",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Shipping Charges",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"idx": 7,
|
||||
"parentfield": "other_charges",
|
||||
"account_head": "_Test Account Shipping Charges - _TC",
|
||||
"charge_type": "Actual",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Shipping Charges",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"idx": 7,
|
||||
"parentfield": "other_charges",
|
||||
"rate": 100
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Discount - _TC",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Discount",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"idx": 8,
|
||||
"parentfield": "other_charges",
|
||||
"rate": -10,
|
||||
"account_head": "_Test Account Discount - _TC",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Discount",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"idx": 8,
|
||||
"parentfield": "other_charges",
|
||||
"rate": -10,
|
||||
"row_id": 7
|
||||
}
|
||||
],
|
||||
"plc_conversion_rate": 1.0,
|
||||
"posting_date": "2013-01-23",
|
||||
"price_list_currency": "INR",
|
||||
"selling_price_list": "_Test Price List",
|
||||
],
|
||||
"plc_conversion_rate": 1.0,
|
||||
"posting_date": "2013-01-23",
|
||||
"price_list_currency": "INR",
|
||||
"selling_price_list": "_Test Price List",
|
||||
"territory": "_Test Territory"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -502,7 +502,8 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
"warehouse": "_Test Warehouse - _TC"
|
||||
})
|
||||
|
||||
pos_setting.insert()
|
||||
if not frappe.db.exists("POS Setting", "_Test POS Setting"):
|
||||
pos_setting.insert()
|
||||
|
||||
def test_si_gl_entry_with_aii_and_update_stock_with_warehouse_but_no_account(self):
|
||||
self.clear_stock_account_balance()
|
||||
@@ -664,142 +665,9 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
where against_invoice=%s""", si.name))
|
||||
|
||||
def test_recurring_invoice(self):
|
||||
from frappe.utils import get_first_day, get_last_day, add_to_date, nowdate, getdate
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
today = nowdate()
|
||||
base_si = frappe.copy_doc(test_records[0])
|
||||
base_si.update({
|
||||
"convert_into_recurring_invoice": 1,
|
||||
"recurring_type": "Monthly",
|
||||
"notification_email_address": "test@example.com, test1@example.com, test2@example.com",
|
||||
"repeat_on_day_of_month": getdate(today).day,
|
||||
"posting_date": today,
|
||||
"fiscal_year": get_fiscal_year(today)[0],
|
||||
"invoice_period_from_date": get_first_day(today),
|
||||
"invoice_period_to_date": get_last_day(today)
|
||||
})
|
||||
from erpnext.controllers.tests.test_recurring_document import test_recurring_document
|
||||
|
||||
# monthly
|
||||
si1 = frappe.copy_doc(base_si)
|
||||
si1.insert()
|
||||
si1.submit()
|
||||
self._test_recurring_invoice(si1, True)
|
||||
|
||||
# monthly without a first and last day period
|
||||
si2 = frappe.copy_doc(base_si)
|
||||
si2.update({
|
||||
"invoice_period_from_date": today,
|
||||
"invoice_period_to_date": add_to_date(today, days=30)
|
||||
})
|
||||
si2.insert()
|
||||
si2.submit()
|
||||
self._test_recurring_invoice(si2, False)
|
||||
|
||||
# quarterly
|
||||
si3 = frappe.copy_doc(base_si)
|
||||
si3.update({
|
||||
"recurring_type": "Quarterly",
|
||||
"invoice_period_from_date": get_first_day(today),
|
||||
"invoice_period_to_date": get_last_day(add_to_date(today, months=3))
|
||||
})
|
||||
si3.insert()
|
||||
si3.submit()
|
||||
self._test_recurring_invoice(si3, True)
|
||||
|
||||
# quarterly without a first and last day period
|
||||
si4 = frappe.copy_doc(base_si)
|
||||
si4.update({
|
||||
"recurring_type": "Quarterly",
|
||||
"invoice_period_from_date": today,
|
||||
"invoice_period_to_date": add_to_date(today, months=3)
|
||||
})
|
||||
si4.insert()
|
||||
si4.submit()
|
||||
self._test_recurring_invoice(si4, False)
|
||||
|
||||
# yearly
|
||||
si5 = frappe.copy_doc(base_si)
|
||||
si5.update({
|
||||
"recurring_type": "Yearly",
|
||||
"invoice_period_from_date": get_first_day(today),
|
||||
"invoice_period_to_date": get_last_day(add_to_date(today, years=1))
|
||||
})
|
||||
si5.insert()
|
||||
si5.submit()
|
||||
self._test_recurring_invoice(si5, True)
|
||||
|
||||
# yearly without a first and last day period
|
||||
si6 = frappe.copy_doc(base_si)
|
||||
si6.update({
|
||||
"recurring_type": "Yearly",
|
||||
"invoice_period_from_date": today,
|
||||
"invoice_period_to_date": add_to_date(today, years=1)
|
||||
})
|
||||
si6.insert()
|
||||
si6.submit()
|
||||
self._test_recurring_invoice(si6, False)
|
||||
|
||||
# change posting date but keep recuring day to be today
|
||||
si7 = frappe.copy_doc(base_si)
|
||||
si7.update({
|
||||
"posting_date": add_to_date(today, days=-1)
|
||||
})
|
||||
si7.insert()
|
||||
si7.submit()
|
||||
|
||||
# setting so that _test function works
|
||||
si7.posting_date = today
|
||||
self._test_recurring_invoice(si7, True)
|
||||
|
||||
def _test_recurring_invoice(self, base_si, first_and_last_day):
|
||||
from frappe.utils import add_months, get_last_day
|
||||
from erpnext.accounts.doctype.sales_invoice.sales_invoice \
|
||||
import manage_recurring_invoices, get_next_date
|
||||
|
||||
no_of_months = ({"Monthly": 1, "Quarterly": 3, "Yearly": 12})[base_si.recurring_type]
|
||||
|
||||
def _test(i):
|
||||
self.assertEquals(i+1, frappe.db.sql("""select count(*) from `tabSales Invoice`
|
||||
where recurring_id=%s and docstatus=1""", base_si.recurring_id)[0][0])
|
||||
|
||||
next_date = get_next_date(base_si.posting_date, no_of_months,
|
||||
base_si.repeat_on_day_of_month)
|
||||
|
||||
manage_recurring_invoices(next_date=next_date, commit=False)
|
||||
|
||||
recurred_invoices = frappe.db.sql("""select name from `tabSales Invoice`
|
||||
where recurring_id=%s and docstatus=1 order by name desc""",
|
||||
base_si.recurring_id)
|
||||
|
||||
self.assertEquals(i+2, len(recurred_invoices))
|
||||
|
||||
new_si = frappe.get_doc("Sales Invoice", recurred_invoices[0][0])
|
||||
|
||||
for fieldname in ["convert_into_recurring_invoice", "recurring_type",
|
||||
"repeat_on_day_of_month", "notification_email_address"]:
|
||||
self.assertEquals(base_si.get(fieldname),
|
||||
new_si.get(fieldname))
|
||||
|
||||
self.assertEquals(new_si.posting_date, unicode(next_date))
|
||||
|
||||
self.assertEquals(new_si.invoice_period_from_date,
|
||||
unicode(add_months(base_si.invoice_period_from_date, no_of_months)))
|
||||
|
||||
if first_and_last_day:
|
||||
self.assertEquals(new_si.invoice_period_to_date,
|
||||
unicode(get_last_day(add_months(base_si.invoice_period_to_date,
|
||||
no_of_months))))
|
||||
else:
|
||||
self.assertEquals(new_si.invoice_period_to_date,
|
||||
unicode(add_months(base_si.invoice_period_to_date, no_of_months)))
|
||||
|
||||
|
||||
return new_si
|
||||
|
||||
# if yearly, test 1 repetition, else test 5 repetitions
|
||||
count = 1 if (no_of_months == 12) else 5
|
||||
for i in xrange(count):
|
||||
base_si = _test(i)
|
||||
test_recurring_document(self, test_records)
|
||||
|
||||
def clear_stock_account_balance(self):
|
||||
frappe.db.sql("delete from `tabStock Ledger Entry`")
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
{
|
||||
"autoname": "INVD.######",
|
||||
"creation": "2013-06-04 11:02:19.000000",
|
||||
"creation": "2013-06-04 11:02:19",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "barcode",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 0,
|
||||
"label": "Barcode",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
@@ -32,7 +31,7 @@
|
||||
"fieldname": "item_name",
|
||||
"fieldtype": "Data",
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Item Name",
|
||||
"oldfieldname": "item_name",
|
||||
"oldfieldtype": "Data",
|
||||
@@ -51,7 +50,6 @@
|
||||
"fieldname": "customer_item_code",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Customer's Item Code",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
@@ -73,7 +71,6 @@
|
||||
{
|
||||
"fieldname": "quantity_and_rate",
|
||||
"fieldtype": "Section Break",
|
||||
"in_list_view": 0,
|
||||
"label": "Quantity and Rate",
|
||||
"permlevel": 0
|
||||
},
|
||||
@@ -91,7 +88,6 @@
|
||||
{
|
||||
"fieldname": "price_list_rate",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 0,
|
||||
"label": "Price List Rate",
|
||||
"oldfieldname": "ref_rate",
|
||||
"oldfieldtype": "Currency",
|
||||
@@ -103,8 +99,8 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "discount_percentage",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 0,
|
||||
"fieldtype": "Percent",
|
||||
"in_list_view": 1,
|
||||
"label": "Discount (%)",
|
||||
"oldfieldname": "adj_rate",
|
||||
"oldfieldtype": "Float",
|
||||
@@ -120,7 +116,7 @@
|
||||
{
|
||||
"fieldname": "stock_uom",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "UOM",
|
||||
"options": "UOM",
|
||||
"permlevel": 0,
|
||||
@@ -129,7 +125,6 @@
|
||||
{
|
||||
"fieldname": "base_price_list_rate",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 0,
|
||||
"label": "Price List Rate (Company Currency)",
|
||||
"oldfieldname": "base_ref_rate",
|
||||
"oldfieldtype": "Currency",
|
||||
@@ -176,7 +171,6 @@
|
||||
"fieldname": "base_rate",
|
||||
"fieldtype": "Currency",
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Rate (Company Currency)",
|
||||
"oldfieldname": "basic_rate",
|
||||
"oldfieldtype": "Currency",
|
||||
@@ -190,7 +184,6 @@
|
||||
{
|
||||
"fieldname": "base_amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 0,
|
||||
"label": "Amount (Company Currency)",
|
||||
"oldfieldname": "amount",
|
||||
"oldfieldtype": "Currency",
|
||||
@@ -201,17 +194,9 @@
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_price",
|
||||
"fieldname": "pricing_rule",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Price",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_discount",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Discount",
|
||||
"label": "Pricing Rule",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
@@ -219,7 +204,6 @@
|
||||
{
|
||||
"fieldname": "accounting",
|
||||
"fieldtype": "Section Break",
|
||||
"in_list_view": 0,
|
||||
"label": "Accounting",
|
||||
"permlevel": 0
|
||||
},
|
||||
@@ -227,7 +211,6 @@
|
||||
"fieldname": "income_account",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Income Account",
|
||||
"oldfieldname": "income_account",
|
||||
"oldfieldtype": "Link",
|
||||
@@ -244,7 +227,6 @@
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"in_filter": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Expense Account",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
@@ -262,7 +244,6 @@
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Cost Center",
|
||||
"oldfieldname": "cost_center",
|
||||
"oldfieldtype": "Link",
|
||||
@@ -271,13 +252,12 @@
|
||||
"print_hide": 1,
|
||||
"print_width": "120px",
|
||||
"read_only": 0,
|
||||
"reqd": 0,
|
||||
"reqd": 1,
|
||||
"width": "120px"
|
||||
},
|
||||
{
|
||||
"fieldname": "warehouse_and_reference",
|
||||
"fieldtype": "Section Break",
|
||||
"in_list_view": 0,
|
||||
"label": "Warehouse and Reference",
|
||||
"permlevel": 0
|
||||
},
|
||||
@@ -285,7 +265,7 @@
|
||||
"fieldname": "warehouse",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"in_list_view": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Warehouse",
|
||||
"oldfieldname": "warehouse",
|
||||
"oldfieldtype": "Link",
|
||||
@@ -310,6 +290,7 @@
|
||||
{
|
||||
"fieldname": "batch_no",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Batch No",
|
||||
"options": "Batch",
|
||||
"permlevel": 0,
|
||||
@@ -359,6 +340,7 @@
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "actual_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Available Qty at Warehouse",
|
||||
@@ -380,6 +362,7 @@
|
||||
"fieldname": "sales_order",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Sales Order",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "sales_order",
|
||||
@@ -456,9 +439,12 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2014-02-28 11:04:19.000000",
|
||||
"modified": "2014-09-09 05:35:36.019576",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice Item",
|
||||
"owner": "Administrator"
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
@@ -1,431 +1,156 @@
|
||||
{
|
||||
"_last_update": null,
|
||||
"_user_tags": null,
|
||||
"allow_attach": null,
|
||||
"allow_copy": null,
|
||||
"allow_email": null,
|
||||
"allow_import": null,
|
||||
"allow_print": null,
|
||||
"allow_rename": null,
|
||||
"allow_trash": null,
|
||||
"autoname": "INVTD.######",
|
||||
"change_log": null,
|
||||
"client_script": null,
|
||||
"client_script_core": null,
|
||||
"client_string": null,
|
||||
"colour": null,
|
||||
"creation": "2013-04-24 11:39:32",
|
||||
"custom": null,
|
||||
"default_print_format": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": null,
|
||||
"dt_template": null,
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "charge_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": 1,
|
||||
"label": "Type",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "charge_type",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nActual\nOn Net Total\nOn Previous Row Amount\nOn Previous Row Total",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": null,
|
||||
"report_hide": null,
|
||||
"reqd": 1,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": "eval:[\"On Previous Row Amount\", \"On Previous Row Total\"].indexOf(doc.charge_type)!==-1",
|
||||
"description": null,
|
||||
"fieldname": "row_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Reference Row #",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "row_id",
|
||||
"oldfieldtype": "Data",
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": null,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": 1,
|
||||
"label": "Description",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Small Text",
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": "300px",
|
||||
"read_only": null,
|
||||
"report_hide": null,
|
||||
"reqd": 1,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": "300px"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "col_break_1",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": null,
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": null,
|
||||
"oldfieldtype": null,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": null,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "account_head",
|
||||
"fieldtype": "Link",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": 0,
|
||||
"label": "Account Head",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "account_head",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": null,
|
||||
"report_hide": null,
|
||||
"reqd": 1,
|
||||
"search_index": 1,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": ":Company",
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": 0,
|
||||
"label": "Cost Center",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "cost_center_other_charges",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Cost Center",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": null,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "rate",
|
||||
"fieldtype": "Float",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": 1,
|
||||
"label": "Rate",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "rate",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": null,
|
||||
"report_hide": null,
|
||||
"reqd": 1,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "tax_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": 1,
|
||||
"label": "Amount",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "tax_amount",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": null,
|
||||
"reqd": 0,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "total",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Total",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "total",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": "If checked, the tax amount will be considered as already included in the Print Rate / Print Amount",
|
||||
"fieldname": "included_in_print_rate",
|
||||
"fieldtype": "Check",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Is this Tax included in Basic Rate?",
|
||||
"no_column": null,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": null,
|
||||
"oldfieldtype": null,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_width": "150px",
|
||||
"read_only": null,
|
||||
"report_hide": 1,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": "150px"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"depends_on": "eval:parent.discount_amount",
|
||||
"fieldname": "tax_amount_after_discount_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 1,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"hidden": 0,
|
||||
"label": "Tax Amount After Discount Amount",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": null,
|
||||
"oldfieldtype": null,
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "item_wise_tax_detail",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 1,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Item Wise Tax Detail",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "item_wise_tax_detail",
|
||||
"oldfieldtype": "Small Text",
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "parenttype",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": 1,
|
||||
"in_list_view": null,
|
||||
"label": "Parenttype",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "parenttype",
|
||||
"oldfieldtype": "Data",
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_width": null,
|
||||
"read_only": null,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": 1,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
"search_index": 1
|
||||
}
|
||||
],
|
||||
"hide_heading": 1,
|
||||
"hide_toolbar": null,
|
||||
"icon": null,
|
||||
"idx": 1,
|
||||
"in_create": null,
|
||||
"in_dialog": null,
|
||||
"is_submittable": null,
|
||||
"is_transaction_doc": null,
|
||||
"issingle": null,
|
||||
"istable": 1,
|
||||
"max_attachments": null,
|
||||
"menu_index": null,
|
||||
"modified": "2014-04-14 18:40:48.450796",
|
||||
"modified": "2014-12-10 12:26:41.222471",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Taxes and Charges",
|
||||
"name_case": null,
|
||||
"owner": "Administrator",
|
||||
"parent": null,
|
||||
"parent_node": null,
|
||||
"parentfield": null,
|
||||
"parenttype": null,
|
||||
"permissions": [],
|
||||
"plugin": null,
|
||||
"print_outline": null,
|
||||
"read_only": null,
|
||||
"read_only_onload": null,
|
||||
"search_fields": null,
|
||||
"section_style": null,
|
||||
"server_code": null,
|
||||
"server_code_compiled": null,
|
||||
"server_code_core": null,
|
||||
"server_code_error": null,
|
||||
"show_in_menu": null,
|
||||
"smallicon": null,
|
||||
"subject": null,
|
||||
"tag_fields": null,
|
||||
"title_field": null,
|
||||
"use_template": null,
|
||||
"version": null
|
||||
"permissions": []
|
||||
}
|
||||
@@ -46,17 +46,17 @@ cur_frm.pformat.other_charges= function(doc){
|
||||
var new_val = flt(val)/flt(doc.conversion_rate);
|
||||
return new_val;
|
||||
}
|
||||
|
||||
|
||||
function print_hide(fieldname) {
|
||||
var doc_field = frappe.meta.get_docfield(doc.doctype, fieldname, doc.name);
|
||||
return doc_field.print_hide;
|
||||
}
|
||||
|
||||
|
||||
out ='';
|
||||
if (!doc.print_without_amount) {
|
||||
var cl = doc.other_charges || [];
|
||||
|
||||
// outer table
|
||||
// outer table
|
||||
var out='<div><table class="noborder" style="width:100%"><tr><td style="width: 60%"></td><td>';
|
||||
|
||||
// main table
|
||||
@@ -77,12 +77,12 @@ cur_frm.pformat.other_charges= function(doc){
|
||||
|
||||
// Discount Amount
|
||||
if(!print_hide('discount_amount') && doc.discount_amount)
|
||||
out += make_row('Discount Amount', convert_rate(doc.discount_amount), 0);
|
||||
out += make_row('Discount Amount', doc.discount_amount, 0);
|
||||
|
||||
// grand total
|
||||
if(!print_hide('grand_total_export'))
|
||||
out += make_row('Grand Total', doc.grand_total_export, 1);
|
||||
|
||||
|
||||
if(!print_hide('rounded_total_export'))
|
||||
out += make_row('Rounded Total', doc.rounded_total_export, 1);
|
||||
|
||||
@@ -92,7 +92,7 @@ cur_frm.pformat.other_charges= function(doc){
|
||||
out += '<table><tr><td style="width:25%;"><b>In Words</b></td>';
|
||||
out += '<td style="width:50%;">' + doc.in_words_export + '</td></tr>';
|
||||
}
|
||||
out += '</table></td></tr></table></div>';
|
||||
out += '</table></td></tr></table></div>';
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -139,14 +139,14 @@ cur_frm.fields_dict['other_charges'].grid.get_field("account_head").get_query =
|
||||
"account_type": ["Tax", "Chargeable", "Income Account"],
|
||||
"company": doc.company
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['other_charges'].grid.get_field("cost_center").get_query = function(doc) {
|
||||
return{
|
||||
'company': doc.company,
|
||||
'group_or_ledger': "Ledger"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.rate = function(doc, cdt, cdn) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:title",
|
||||
"creation": "2013-01-10 16:34:09.000000",
|
||||
"creation": "2013-01-10 16:34:09",
|
||||
"description": "Standard tax template that can be applied to all Sales Transactions. This template can contain list of tax heads and also other expense / income heads like \"Shipping\", \"Insurance\", \"Handling\" etc.\n\n#### Note\n\nThe tax rate you define here will be the standard tax rate for all **Items**. If there are **Items** that have different rates, they must be added in the **Item Tax** table in the **Item** master.\n\n#### Description of Columns\n\n1. Calculation Type: \n - This can be on **Net Total** (that is the sum of basic amount).\n - **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.\n - **Actual** (as mentioned).\n2. Account Head: The Account ledger under which this tax will be booked\n3. Cost Center: If the tax / charge is an income (like shipping) or expense it needs to be booked against a Cost Center.\n4. Description: Description of the tax (that will be printed in invoices / quotes).\n5. Rate: Tax rate.\n6. Amount: Tax amount.\n7. Total: Cumulative total to this point.\n8. Enter Row: If based on \"Previous Row Total\" you can select the row number which will be taken as a base for this calculation (default is the previous row).\n9. Is this Tax included in Basic Rate?: If you check this, it means that this tax will not be shown below the item table, but will be included in the Basic Rate in your main item table. This is useful where you want give a flat price (inclusive of all taxes) price to customers.",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
@@ -12,6 +12,7 @@
|
||||
"fieldname": "title",
|
||||
"fieldtype": "Data",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Title",
|
||||
"oldfieldname": "title",
|
||||
"oldfieldtype": "Data",
|
||||
@@ -22,6 +23,7 @@
|
||||
{
|
||||
"fieldname": "is_default",
|
||||
"fieldtype": "Check",
|
||||
"in_list_view": 1,
|
||||
"label": "Default",
|
||||
"permlevel": 0
|
||||
},
|
||||
@@ -34,6 +36,7 @@
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Company",
|
||||
"oldfieldname": "company",
|
||||
"oldfieldtype": "Link",
|
||||
@@ -69,7 +72,7 @@
|
||||
],
|
||||
"icon": "icon-money",
|
||||
"idx": 1,
|
||||
"modified": "2014-01-28 12:28:27.000000",
|
||||
"modified": "2014-05-27 03:49:19.023941",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Taxes and Charges Master",
|
||||
@@ -77,7 +80,7 @@
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
@@ -91,7 +94,6 @@
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
@@ -105,7 +107,6 @@
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"autoname": "Prompt",
|
||||
"creation": "2013-06-25 11:48:03.000000",
|
||||
"creation": "2013-06-25 11:48:03",
|
||||
"description": "Specify conditions to calculate shipping amount",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
@@ -102,13 +102,14 @@
|
||||
],
|
||||
"icon": "icon-truck",
|
||||
"idx": 1,
|
||||
"modified": "2014-01-20 17:49:27.000000",
|
||||
"modified": "2014-05-27 03:49:19.387875",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Shipping Rule",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"apply_user_permissions": 1,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
@@ -118,6 +119,7 @@
|
||||
"role": "Accounts User"
|
||||
},
|
||||
{
|
||||
"apply_user_permissions": 1,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
@@ -127,7 +129,6 @@
|
||||
"role": "Sales User"
|
||||
},
|
||||
{
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
@@ -139,7 +140,6 @@
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
|
||||
@@ -15,7 +15,10 @@ def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True,
|
||||
if gl_map:
|
||||
if not cancel:
|
||||
gl_map = process_gl_map(gl_map, merge_entries)
|
||||
save_entries(gl_map, adv_adj, update_outstanding)
|
||||
if gl_map and len(gl_map) > 1:
|
||||
save_entries(gl_map, adv_adj, update_outstanding)
|
||||
else:
|
||||
frappe.throw(_("Incorrect number of General Ledger Entries found. You might have selected a wrong Account in the transaction."))
|
||||
else:
|
||||
delete_gl_entries(gl_map, adv_adj=adv_adj, update_outstanding=update_outstanding)
|
||||
|
||||
@@ -94,8 +97,7 @@ def validate_account_for_auto_accounting_for_stock(gl_map):
|
||||
|
||||
for entry in gl_map:
|
||||
if entry.account in aii_accounts:
|
||||
frappe.throw(_("Account: {0} can only be updated via \
|
||||
Stock Transactions").format(entry.account), StockAccountInvalidTransaction)
|
||||
frappe.throw(_("Account: {0} can only be updated via Stock Transactions").format(entry.account), StockAccountInvalidTransaction)
|
||||
|
||||
|
||||
def delete_gl_entries(gl_entries=None, voucher_type=None, voucher_no=None,
|
||||
|
||||
@@ -25,16 +25,16 @@ pscript['onload_Accounts Browser'] = function(wrapper){
|
||||
'<li>'+__('To add child nodes, explore tree and click on the node under which you want to add more nodes.')+'</li>'+
|
||||
'<li>'+
|
||||
__('Accounting Entries can be made against leaf nodes, called')+
|
||||
'<b>' +__('Ledgers')+'</b>.'+ __('Entries against') +
|
||||
'<b>' +__('Groups') + '</b>'+ __('are not allowed.')+
|
||||
' <b>' +__('Ledgers')+'</b>. '+ __('Entries against ') +
|
||||
'<b>' +__('Groups') + '</b> '+ __('are not allowed.')+
|
||||
'</li>'+
|
||||
'<li>'+__('Please do NOT create Account (Ledgers) for Customers and Suppliers. They are created directly from the Customer / Supplier masters.')+'</li>'+
|
||||
'<li>'+
|
||||
'<b>'+__('To create a Bank Account:')+'</b>'+
|
||||
'<b>'+__('To create a Bank Account')+'</b>: '+
|
||||
__('Go to the appropriate group (usually Application of Funds > Current Assets > Bank Accounts and create a new Account Ledger (by clicking on Add Child) of type "Bank"')+
|
||||
'</li>'+
|
||||
'<li>'+
|
||||
'<b>'+__('To create a Tax Account:')+'</b>'+
|
||||
'<b>'+__('To create a Tax Account') +'</b>: '+
|
||||
__('Go to the appropriate group (usually Source of Funds > Current Liabilities > Taxes and Duties and create a new Account Ledger (by clicking on Add Child) of type "Tax" and do mention the Tax rate.')+
|
||||
'</li>'+
|
||||
'</ol>'+
|
||||
@@ -45,7 +45,7 @@ pscript['onload_Accounts Browser'] = function(wrapper){
|
||||
'icon-plus');
|
||||
}
|
||||
|
||||
wrapper.appframe.set_title_right('Refresh', function() {
|
||||
wrapper.appframe.set_title_right(__('Refresh'), function() {
|
||||
wrapper.$company_select.change();
|
||||
});
|
||||
|
||||
@@ -66,7 +66,7 @@ pscript['onload_Accounts Browser'] = function(wrapper){
|
||||
$.each(r.message, function(i, v) {
|
||||
$('<option>').html(v).attr('value', v).appendTo(wrapper.$company_select);
|
||||
});
|
||||
wrapper.$company_select.val(frappe.defaults.get_user_default("company") || r[0]).change();
|
||||
wrapper.$company_select.val(frappe.defaults.get_user_default("company") || r.message[0]).change();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -238,6 +238,9 @@ erpnext.AccountsChart = Class.extend({
|
||||
method: 'erpnext.accounts.utils.add_ac',
|
||||
callback: function(r) {
|
||||
d.hide();
|
||||
if(node.expanded) {
|
||||
node.toggle_node();
|
||||
}
|
||||
node.reload();
|
||||
}
|
||||
});
|
||||
@@ -281,6 +284,9 @@ erpnext.AccountsChart = Class.extend({
|
||||
method: 'erpnext.accounts.utils.add_cc',
|
||||
callback: function(r) {
|
||||
d.hide();
|
||||
if(node.expanded) {
|
||||
node.toggle_node();
|
||||
}
|
||||
node.reload();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -17,8 +17,9 @@ frappe.pages['financial-analytics'].onload = function(wrapper) {
|
||||
erpnext.FinancialAnalytics = erpnext.AccountTreeGrid.extend({
|
||||
filters: [
|
||||
{
|
||||
fieldtype:"Select", label: __("PL or BS"),
|
||||
options:["Profit and Loss", "Balance Sheet"],
|
||||
fieldtype:"Select", label: __("PL or BS"), fieldname: "pl_or_bs",
|
||||
options:[{"label": __("Profit and Loss"), "value": "Profit and Loss"},
|
||||
{"label": __("Balance Sheet"), "value": "Balance Sheet"}],
|
||||
filter: function(val, item, opts, me) {
|
||||
if(item._show) return true;
|
||||
|
||||
@@ -31,21 +32,23 @@ erpnext.FinancialAnalytics = erpnext.AccountTreeGrid.extend({
|
||||
}
|
||||
},
|
||||
{
|
||||
fieldtype:"Select", label: __("Company"),
|
||||
link:"Company", default_value: "Select Company...",
|
||||
fieldtype:"Select", label: __("Company"), fieldname: "company",
|
||||
link:"Company", default_value: __("Select Company..."),
|
||||
filter: function(val, item, opts) {
|
||||
return item.company == val || val == opts.default_value || item._show;
|
||||
}
|
||||
},
|
||||
{fieldtype:"Select", label: __("Fiscal Year"), link:"Fiscal Year",
|
||||
default_value: "Select Fiscal Year..."},
|
||||
{fieldtype:"Date", label: __("From Date")},
|
||||
{fieldtype:"Select", label: __("Fiscal Year"), link:"Fiscal Year", fieldname: "fiscal_year",
|
||||
default_value: __("Select Fiscal Year...")},
|
||||
{fieldtype:"Date", label: __("From Date"), fieldname: "from_date"},
|
||||
{fieldtype:"Label", label: __("To")},
|
||||
{fieldtype:"Date", label: __("To Date")},
|
||||
{fieldtype:"Select", label: __("Range"),
|
||||
options:["Daily", "Weekly", "Monthly", "Quarterly", "Yearly"]},
|
||||
{fieldtype:"Date", label: __("To Date"), fieldname: "to_date"},
|
||||
{fieldtype:"Select", label: __("Range"), fieldname: "range",
|
||||
options:[{label: __("Daily"), value: "Daily"}, {label: __("Weekly"), value: "Weekly"},
|
||||
{label: __("Monthly"), value: "Monthly"}, {label: __("Quarterly"), value: "Quarterly"},
|
||||
{label: __("Yearly"), value: "Yearly"}]},
|
||||
{fieldtype:"Button", label: __("Refresh"), icon:"icon-refresh icon-white"},
|
||||
{fieldtype:"Button", label: __("Reset Filters")}
|
||||
{fieldtype:"Button", label: __("Reset Filters"), icon: "icon-filter"}
|
||||
],
|
||||
setup_columns: function() {
|
||||
var std_columns = [
|
||||
@@ -203,11 +206,11 @@ erpnext.FinancialAnalytics = erpnext.AccountTreeGrid.extend({
|
||||
if(me.pl_or_bs=='Balance Sheet') {
|
||||
$.each(me.data, function(i, ac) {
|
||||
if((ac.rgt - ac.lft)==1 && ac.report_type=='Balance Sheet') {
|
||||
var opening = 0;
|
||||
var opening = flt(ac["opening_dr"]) - flt(ac["opening_cr"]);
|
||||
//if(opening) throw opening;
|
||||
$.each(me.columns, function(i, col) {
|
||||
if(col.formatter==me.currency_formatter) {
|
||||
if(col.balance_type=="Dr") {
|
||||
if(col.balance_type=="Dr" && !in_list(["opening_dr", "opening_cr"], col.field)) {
|
||||
opening = opening + flt(ac[col.date + "_dr"]) -
|
||||
flt(ac[col.date + "_cr"]);
|
||||
me.set_debit_or_credit(ac, col.date, opening);
|
||||
@@ -229,7 +232,7 @@ erpnext.FinancialAnalytics = erpnext.AccountTreeGrid.extend({
|
||||
indent: 0,
|
||||
opening: 0,
|
||||
checked: false,
|
||||
report_type: me.pl_or_bs,
|
||||
report_type: me.pl_or_bs=="Balance Sheet"? "Balance Sheet" : "Profit and Loss",
|
||||
};
|
||||
me.item_by_name[net_profit.name] = net_profit;
|
||||
|
||||
@@ -241,7 +244,7 @@ erpnext.FinancialAnalytics = erpnext.AccountTreeGrid.extend({
|
||||
|
||||
$.each(me.data, function(i, ac) {
|
||||
if(!ac.parent_account && me.apply_filter(ac, "company") &&
|
||||
ac.report_type==me.pl_or_bs) {
|
||||
ac.report_type==net_profit.report_type) {
|
||||
$.each(me.columns, function(i, col) {
|
||||
if(col.formatter==me.currency_formatter && col.balance_type=="Dr") {
|
||||
var bal = net_profit[col.date+"_dr"] -
|
||||
@@ -253,9 +256,6 @@ erpnext.FinancialAnalytics = erpnext.AccountTreeGrid.extend({
|
||||
}
|
||||
});
|
||||
this.data.push(net_profit);
|
||||
// $.each(me.data, function(i, v) {
|
||||
// if(v.report_type=="Profit and Loss") console.log(v)
|
||||
// })
|
||||
}
|
||||
},
|
||||
add_balance: function(field, account, gl) {
|
||||
|
||||
0
erpnext/accounts/page/pos/__init__.py
Normal file
0
erpnext/accounts/page/pos/__init__.py
Normal file
52
erpnext/accounts/page/pos/pos.js
Normal file
52
erpnext/accounts/page/pos/pos.js
Normal file
@@ -0,0 +1,52 @@
|
||||
frappe.pages['pos'].onload = function(wrapper) {
|
||||
frappe.ui.make_app_page({
|
||||
parent: wrapper,
|
||||
title: __('Start POS'),
|
||||
single_column: true
|
||||
});
|
||||
|
||||
wrapper.body.html('<div class="text-center" style="margin: 40px">\
|
||||
<p>' + __("Select type of transaction") + '</p>\
|
||||
<p class="select-type" style="margin: auto; max-width: 300px; margin-bottom: 15px;"></p>\
|
||||
<p class="alert alert-warning pos-setting-message hide">'
|
||||
+ __("Please setup your POS Preferences")
|
||||
+ ': <a class="btn btn-default" onclick="newdoc(\'POS Setting\')">'
|
||||
+ __("Make new POS Setting") + '</a></p>\
|
||||
<p><button class="btn btn-primary">' + __("Start") + '</button></p>\
|
||||
</div>');
|
||||
|
||||
var pos_type = frappe.ui.form.make_control({
|
||||
parent: wrapper.body.find(".select-type"),
|
||||
df: {
|
||||
fieldtype: "Select",
|
||||
options: [
|
||||
{label: __("Billing (Sales Invoice)"), value:"Sales Invoice"},
|
||||
{value:"Sales Order"},
|
||||
{value:"Delivery Note"},
|
||||
{value:"Quotation"},
|
||||
{value:"Purchase Order"},
|
||||
{value:"Purchase Receipt"},
|
||||
{value:"Purchase Invoice"},
|
||||
],
|
||||
fieldname: "pos_type"
|
||||
},
|
||||
only_input: true
|
||||
});
|
||||
|
||||
pos_type.refresh();
|
||||
|
||||
wrapper.body.find(".btn-primary").on("click", function() {
|
||||
erpnext.open_as_pos = true;
|
||||
new_doc(pos_type.get_value());
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: "/api/resource/POS Setting",
|
||||
success: function(data) {
|
||||
if(!data.data.length) {
|
||||
wrapper.body.find(".pos-setting-message").removeClass('hide');
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
28
erpnext/accounts/page/pos/pos.json
Normal file
28
erpnext/accounts/page/pos/pos.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"content": null,
|
||||
"creation": "2014-08-08 02:45:55.931022",
|
||||
"docstatus": 0,
|
||||
"doctype": "Page",
|
||||
"icon": "icon-th",
|
||||
"modified": "2014-08-08 05:59:33.045012",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "pos",
|
||||
"owner": "Administrator",
|
||||
"page_name": "pos",
|
||||
"roles": [
|
||||
{
|
||||
"role": "Sales User"
|
||||
},
|
||||
{
|
||||
"role": "Purchase User"
|
||||
},
|
||||
{
|
||||
"role": "Accounts User"
|
||||
}
|
||||
],
|
||||
"script": null,
|
||||
"standard": "Yes",
|
||||
"style": null,
|
||||
"title": "POS"
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
Period wise opening and closing balance of all transactions.
|
||||
@@ -1 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -1,51 +0,0 @@
|
||||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.require("assets/erpnext/js/account_tree_grid.js");
|
||||
|
||||
frappe.pages['trial-balance'].onload = function(wrapper) {
|
||||
frappe.ui.make_app_page({
|
||||
parent: wrapper,
|
||||
title: __('Trial Balance'),
|
||||
single_column: true
|
||||
});
|
||||
var TrialBalance = erpnext.AccountTreeGrid.extend({
|
||||
init: function(wrapper, title) {
|
||||
var me = this;
|
||||
this._super(wrapper, title);
|
||||
|
||||
// period closing entry checkbox
|
||||
this.wrapper.bind("make", function() {
|
||||
$('<div style="margin: 10px 0px; "\
|
||||
class="with_period_closing_entry"><input type="checkbox" checked="checked">' +
|
||||
__("With period closing entry") + '</div>')
|
||||
.appendTo(me.wrapper)
|
||||
.find("input").click(function() { me.refresh(); });
|
||||
});
|
||||
},
|
||||
|
||||
prepare_balances: function() {
|
||||
// store value of with closing entry
|
||||
this.with_period_closing_entry = this.wrapper
|
||||
.find(".with_period_closing_entry input:checked").length;
|
||||
this._super();
|
||||
},
|
||||
|
||||
update_balances: function(account, posting_date, v) {
|
||||
// for period closing voucher,
|
||||
// only consider them when adding "With Closing Entry is checked"
|
||||
if(v.voucher_type === "Period Closing Voucher") {
|
||||
if(this.with_period_closing_entry) {
|
||||
this._super(account, posting_date, v);
|
||||
}
|
||||
} else {
|
||||
this._super(account, posting_date, v);
|
||||
}
|
||||
},
|
||||
})
|
||||
erpnext.trial_balance = new TrialBalance(wrapper, 'Trial Balance');
|
||||
|
||||
|
||||
wrapper.appframe.add_module_icon("Accounts")
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"creation": "2013-01-27 16:30:52.000000",
|
||||
"docstatus": 0,
|
||||
"doctype": "Page",
|
||||
"icon": "icon-table",
|
||||
"idx": 1,
|
||||
"modified": "2013-07-11 14:44:49.000000",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "trial-balance",
|
||||
"owner": "Administrator",
|
||||
"page_name": "trial-balance",
|
||||
"roles": [
|
||||
{
|
||||
"role": "Analytics"
|
||||
},
|
||||
{
|
||||
"role": "Accounts Manager"
|
||||
}
|
||||
],
|
||||
"standard": "Yes",
|
||||
"title": "Trial Balance"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user