Compare commits
738 Commits
v13.0.0-be
...
v13.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b77793763a | ||
|
|
88b3c52533 | ||
|
|
ece4c16d8f | ||
|
|
ce6c3b5b74 | ||
|
|
dbb76a7d00 | ||
|
|
913845e4ce | ||
|
|
bda4c5cc52 | ||
|
|
c39720db50 | ||
|
|
e0222723f0 | ||
|
|
547fd31a37 | ||
|
|
aa809ceffe | ||
|
|
d05686d27d | ||
|
|
e7b3047eca | ||
|
|
87dea3923b | ||
|
|
f9b9298a6d | ||
|
|
c01b2caaa3 | ||
|
|
5921f434b6 | ||
|
|
c5347c4a34 | ||
|
|
db5f0f79b1 | ||
|
|
0773d6772d | ||
|
|
f4e7e72f67 | ||
|
|
98d250995d | ||
|
|
a3da206b64 | ||
|
|
6717773c28 | ||
|
|
7f7b3608bb | ||
|
|
11eb30d082 | ||
|
|
bee9c73730 | ||
|
|
58ca5a7329 | ||
|
|
d765b21825 | ||
|
|
8617c0ab99 | ||
|
|
2fef245607 | ||
|
|
85a7ec91a1 | ||
|
|
35415fa575 | ||
|
|
9920d4062c | ||
|
|
526497bc43 | ||
|
|
e9236ab60f | ||
|
|
ad520e08ba | ||
|
|
bcd63f04da | ||
|
|
5cdb1cb7a9 | ||
|
|
56ab3fb132 | ||
|
|
b5843dbdcd | ||
|
|
b6ce868199 | ||
|
|
75ce336c84 | ||
|
|
c814aab0b6 | ||
|
|
c5ae9ee0e1 | ||
|
|
c482c9592f | ||
|
|
fb4051bddd | ||
|
|
4d0939de8d | ||
|
|
968885af26 | ||
|
|
94c145f3c3 | ||
|
|
f239dbdd03 | ||
|
|
f4426c825e | ||
|
|
df1ef6f8e5 | ||
|
|
83b3e87497 | ||
|
|
59bff8a2f1 | ||
|
|
1b903e39c8 | ||
|
|
1999ae0a91 | ||
|
|
e50324aed7 | ||
|
|
368cb45147 | ||
|
|
410d36beca | ||
|
|
91a8a74d54 | ||
|
|
08eaf3c6b8 | ||
|
|
41229ba705 | ||
|
|
a5de6c779b | ||
|
|
ba3578929e | ||
|
|
c0ba6eafd5 | ||
|
|
a21e347bf1 | ||
|
|
7e442c74b6 | ||
|
|
6be78db62c | ||
|
|
469ef122aa | ||
|
|
04c0296558 | ||
|
|
9be11afbde | ||
|
|
a54eecb230 | ||
|
|
146cbb10f8 | ||
|
|
5f4a2bfc61 | ||
|
|
170d2efd35 | ||
|
|
7f43c051df | ||
|
|
237033704f | ||
|
|
c2548ddc75 | ||
|
|
7366b5d3eb | ||
|
|
ceb026c5ab | ||
|
|
b38ea0cc8b | ||
|
|
f4901b4f22 | ||
|
|
d429138dcc | ||
|
|
6c7f029597 | ||
|
|
4adaf7ed2e | ||
|
|
5d994d8aa1 | ||
|
|
e825d2ab51 | ||
|
|
256b9c7bf9 | ||
|
|
0486276789 | ||
|
|
fce552b811 | ||
|
|
cd8422a840 | ||
|
|
2c191c105f | ||
|
|
44853da7c2 | ||
|
|
4cd68cdecb | ||
|
|
d74ff72527 | ||
|
|
28a885a3a9 | ||
|
|
efe2b425b1 | ||
|
|
f66aab6d98 | ||
|
|
5243eea532 | ||
|
|
0ae0368d34 | ||
|
|
eeb3121622 | ||
|
|
e9c801e4bd | ||
|
|
2a39b74ad2 | ||
|
|
f29c075bc3 | ||
|
|
d4499277b4 | ||
|
|
91026e026f | ||
|
|
d7d7df2fdd | ||
|
|
244f3eeedc | ||
|
|
3c490088c4 | ||
|
|
9165327cf6 | ||
|
|
5c172044d7 | ||
|
|
d26ed25c3e | ||
|
|
d7b139182b | ||
|
|
940c75f8ac | ||
|
|
5c7138c86b | ||
|
|
2ba198576c | ||
|
|
2a391298a7 | ||
|
|
6a534ea82b | ||
|
|
4ccda9f799 | ||
|
|
d1f15b2a88 | ||
|
|
c7c921495b | ||
|
|
dffa647071 | ||
|
|
98a40d81d5 | ||
|
|
67d94ac0cc | ||
|
|
23af1ed372 | ||
|
|
b75cbeee4d | ||
|
|
a5de22cb8e | ||
|
|
95e9b2fd6e | ||
|
|
bacfaa4396 | ||
|
|
438d9cad90 | ||
|
|
f9519c7e13 | ||
|
|
a5987782bd | ||
|
|
00cce433a5 | ||
|
|
65165fcc80 | ||
|
|
d4a3cf1395 | ||
|
|
635c480771 | ||
|
|
3f14aafa67 | ||
|
|
dd7d71ca2e | ||
|
|
7f2e45e0f4 | ||
|
|
e838d1c7f0 | ||
|
|
00a0e8da10 | ||
|
|
51c500d446 | ||
|
|
9ab3bedd0a | ||
|
|
90ea17fbd6 | ||
|
|
fe3529b194 | ||
|
|
b5792872e9 | ||
|
|
6e3668dc30 | ||
|
|
2b61491adb | ||
|
|
0b29f87fa2 | ||
|
|
d1e331f77f | ||
|
|
be2c1fca7b | ||
|
|
63eb6bdb3c | ||
|
|
a780306ec7 | ||
|
|
6f0fabc54e | ||
|
|
a2063b1337 | ||
|
|
59fdee4dfa | ||
|
|
c7fff34cf5 | ||
|
|
000fa824d3 | ||
|
|
a0e7787f7b | ||
|
|
77eaf2939a | ||
|
|
20cc2bb0d8 | ||
|
|
6ccd64c2ec | ||
|
|
0623a34210 | ||
|
|
fe0f46c5b3 | ||
|
|
06e99dfe7b | ||
|
|
358153b04b | ||
|
|
894cff5aa4 | ||
|
|
27bcb2a064 | ||
|
|
832098f042 | ||
|
|
ec829786e9 | ||
|
|
db2d196296 | ||
|
|
535406cb0c | ||
|
|
d7ac2394e8 | ||
|
|
78777d6ed4 | ||
|
|
e314b8b209 | ||
|
|
9f6015a4e9 | ||
|
|
261c42186f | ||
|
|
fa73074250 | ||
|
|
79b5be1830 | ||
|
|
06a6ee37cb | ||
|
|
47c6d2e00f | ||
|
|
6249798d84 | ||
|
|
79005a4a76 | ||
|
|
dfc5c45e50 | ||
|
|
e1ee9034ef | ||
|
|
916b75a3a3 | ||
|
|
5accf8adf5 | ||
|
|
9b4e5bfa87 | ||
|
|
9d0a93dd92 | ||
|
|
5471265f92 | ||
|
|
be98ee26cd | ||
|
|
baa406e99f | ||
|
|
d1fb363a37 | ||
|
|
98cc7b1751 | ||
|
|
d95b59e90c | ||
|
|
afc766bbf1 | ||
|
|
5571b988dd | ||
|
|
cc46866cd9 | ||
|
|
1002e36c53 | ||
|
|
fa932e2a3e | ||
|
|
48b0f0da96 | ||
|
|
15c0199e07 | ||
|
|
4c089b5852 | ||
|
|
45870317f2 | ||
|
|
92b0691c68 | ||
|
|
36a0085905 | ||
|
|
3e0a9383b4 | ||
|
|
9cbdfe17e4 | ||
|
|
9b4a258c89 | ||
|
|
27ea23223d | ||
|
|
f1d13a4ff3 | ||
|
|
1521b31795 | ||
|
|
53d261702a | ||
|
|
7c4c42ad67 | ||
|
|
7c78220eac | ||
|
|
9b3f5d5f67 | ||
|
|
a44df63a91 | ||
|
|
82c6223196 | ||
|
|
ecde26409b | ||
|
|
846500e8bc | ||
|
|
a5c4558f8b | ||
|
|
7a5b6021b9 | ||
|
|
7d892438f0 | ||
|
|
f06c166ee4 | ||
|
|
b27d4f6095 | ||
|
|
190106a8b8 | ||
|
|
bd10d7c028 | ||
|
|
47ce85484b | ||
|
|
810a36105c | ||
|
|
f45756d821 | ||
|
|
236a232de0 | ||
|
|
2efdfa26b4 | ||
|
|
10e4b9d4e8 | ||
|
|
eb6b3cfe6d | ||
|
|
8755339cba | ||
|
|
fa777555b7 | ||
|
|
d7a81be56d | ||
|
|
6fdd859a10 | ||
|
|
b5819c74c8 | ||
|
|
28da945ecd | ||
|
|
56f6dbb666 | ||
|
|
aa09628358 | ||
|
|
630ce6e531 | ||
|
|
c603fd638b | ||
|
|
3dfa017f1d | ||
|
|
2a1b1537f9 | ||
|
|
9803835436 | ||
|
|
28ca4ec79d | ||
|
|
f8a7e000f5 | ||
|
|
27da2bb63a | ||
|
|
027db0b41e | ||
|
|
b85fb0c3a4 | ||
|
|
dca307e7cc | ||
|
|
286e00bdf2 | ||
|
|
1be997beb4 | ||
|
|
2d0b277ce0 | ||
|
|
02f50a93e5 | ||
|
|
118a4ffb08 | ||
|
|
8cdba8ab64 | ||
|
|
6af3c3fa2a | ||
|
|
2e320cfdc3 | ||
|
|
7a837170ea | ||
|
|
b990e71b4c | ||
|
|
834a8b740d | ||
|
|
409c37ebeb | ||
|
|
325a461c34 | ||
|
|
d3e122259d | ||
|
|
e11ce57f3c | ||
|
|
684fc4e27b | ||
|
|
6bd2bbc953 | ||
|
|
d0baa90b50 | ||
|
|
84184559bc | ||
|
|
1dba7d2161 | ||
|
|
402fcbd489 | ||
|
|
23c30e43f0 | ||
|
|
c04ed62863 | ||
|
|
bc8c9de26d | ||
|
|
231aec9257 | ||
|
|
1e2772d389 | ||
|
|
d5656f4b76 | ||
|
|
eb1233425e | ||
|
|
85c91ca2db | ||
|
|
2fb3647a4c | ||
|
|
c532b99a4c | ||
|
|
ae63d66b8f | ||
|
|
3dd0e49525 | ||
|
|
8f8d9744f1 | ||
|
|
b5a2320b33 | ||
|
|
19f8fa59d3 | ||
|
|
07f40596bc | ||
|
|
866cf70d3a | ||
|
|
f5d6bd77e5 | ||
|
|
c839177f8e | ||
|
|
214951a9c6 | ||
|
|
69a6bed106 | ||
|
|
58399f6524 | ||
|
|
0ca74ce04b | ||
|
|
98a0feab89 | ||
|
|
bb8cd1cdaa | ||
|
|
8676bedd18 | ||
|
|
14472f6bab | ||
|
|
fdafb55fba | ||
|
|
28c834ac95 | ||
|
|
311bb6452f | ||
|
|
0c15f75524 | ||
|
|
d780f56ba8 | ||
|
|
133ebc1d51 | ||
|
|
ed1c7649cd | ||
|
|
4a1ffcf742 | ||
|
|
01b4ee8a3c | ||
|
|
aa46def745 | ||
|
|
e4964a0c6c | ||
|
|
e53fd87669 | ||
|
|
cbb4fe2cce | ||
|
|
a6d0610730 | ||
|
|
e12398e75e | ||
|
|
75b01e3d72 | ||
|
|
bbadebcf64 | ||
|
|
6f29f67a83 | ||
|
|
43f126ed13 | ||
|
|
ab149f196e | ||
|
|
1aad27a539 | ||
|
|
8c7c682f17 | ||
|
|
6a5ef261f2 | ||
|
|
811ff5c397 | ||
|
|
7efbbcf3aa | ||
|
|
a43aea0dc1 | ||
|
|
bc857522ad | ||
|
|
4858b40813 | ||
|
|
77d72d59ef | ||
|
|
f3ca4bcb70 | ||
|
|
ccc80927f6 | ||
|
|
d44e60f17c | ||
|
|
e7bf87cc84 | ||
|
|
ef5c714de2 | ||
|
|
c697cb8b2d | ||
|
|
d826bee13a | ||
|
|
c5b94adc87 | ||
|
|
03a1484aed | ||
|
|
208d1942c3 | ||
|
|
a9de890993 | ||
|
|
7de7bb5202 | ||
|
|
b43c2e5d7c | ||
|
|
4441cebbb3 | ||
|
|
3f16902b00 | ||
|
|
f9d4d9a095 | ||
|
|
9c36dc3798 | ||
|
|
7166b6740f | ||
|
|
9b178bcd10 | ||
|
|
f1c0f680f4 | ||
|
|
7e8113c7e8 | ||
|
|
29878e5c3b | ||
|
|
9a40c1b2e1 | ||
|
|
d60ff83b6f | ||
|
|
79f63526cb | ||
|
|
e2324c77fe | ||
|
|
243661b37b | ||
|
|
8cc6a2d62c | ||
|
|
b0735732f9 | ||
|
|
df4eed4c0d | ||
|
|
47f5f4757a | ||
|
|
b6cd97e5fc | ||
|
|
535dc4aea2 | ||
|
|
57c3d373a7 | ||
|
|
e963362dfd | ||
|
|
429fb3bba8 | ||
|
|
9bf05ad927 | ||
|
|
fd4e7bdbb1 | ||
|
|
45db1c5d74 | ||
|
|
164ffac4ef | ||
|
|
85252e7aef | ||
|
|
c44d6b9546 | ||
|
|
87fcae4efd | ||
|
|
ad1f2b41f4 | ||
|
|
138e98fef2 | ||
|
|
1e6cce3593 | ||
|
|
bb0d8f8038 | ||
|
|
7e1dcf911d | ||
|
|
ee87484134 | ||
|
|
0a7939277c | ||
|
|
e2d0715cdf | ||
|
|
8615227090 | ||
|
|
f25ab6f826 | ||
|
|
6756d3b561 | ||
|
|
819b8d0266 | ||
|
|
0681a480c2 | ||
|
|
a46a83b476 | ||
|
|
aa235b36e0 | ||
|
|
a5039e8f85 | ||
|
|
47f784aa9c | ||
|
|
aa00eb9898 | ||
|
|
e37a5c2646 | ||
|
|
e07eb86498 | ||
|
|
15f4672ffa | ||
|
|
30c8873f24 | ||
|
|
bb05acb60d | ||
|
|
9d3f242f39 | ||
|
|
b58b8ec2fb | ||
|
|
e816ed89e6 | ||
|
|
e3c72a3d71 | ||
|
|
8609d31430 | ||
|
|
df6e20887d | ||
|
|
79ba299abc | ||
|
|
969d37da4c | ||
|
|
7b2afaf349 | ||
|
|
161e3954a8 | ||
|
|
3237f5bb88 | ||
|
|
a751b6bb7a | ||
|
|
fd0e8a4e23 | ||
|
|
5f27c9e100 | ||
|
|
6fa44fefc3 | ||
|
|
bb87950e96 | ||
|
|
1ab95413be | ||
|
|
516b3ae1bc | ||
|
|
45cec6928b | ||
|
|
5006a2065e | ||
|
|
5164223b99 | ||
|
|
637ddff6e9 | ||
|
|
e56daeb347 | ||
|
|
1016ff48fc | ||
|
|
6330e20d16 | ||
|
|
236c9ae453 | ||
|
|
fbc3988037 | ||
|
|
8991d4ed0b | ||
|
|
dcc9947d10 | ||
|
|
c5248b30eb | ||
|
|
ba26020a82 | ||
|
|
723e6dd73f | ||
|
|
c4d67c2afe | ||
|
|
5a7ddba9a3 | ||
|
|
53dbe39d12 | ||
|
|
9490122abb | ||
|
|
0aef0fd764 | ||
|
|
a97eb6a052 | ||
|
|
f29b811a56 | ||
|
|
ffb36aac8f | ||
|
|
c4a1bb0e1c | ||
|
|
4742a25942 | ||
|
|
91b41db9e3 | ||
|
|
ec337f64d9 | ||
|
|
d7f4aefd00 | ||
|
|
b8f4cdfbce | ||
|
|
a7820f310c | ||
|
|
b814b002ce | ||
|
|
8c3da162ba | ||
|
|
0f2dc0eb73 | ||
|
|
eff675f45b | ||
|
|
dce73d1881 | ||
|
|
0701f08ab6 | ||
|
|
7177579051 | ||
|
|
ef65d6463e | ||
|
|
7d64a291b8 | ||
|
|
91a02868cb | ||
|
|
54a253616a | ||
|
|
f9642eb333 | ||
|
|
d4d639c7ed | ||
|
|
d809de6579 | ||
|
|
852e67c5ee | ||
|
|
6f1664223d | ||
|
|
44a055b52f | ||
|
|
0ea2587679 | ||
|
|
73d60aa498 | ||
|
|
cfb5f58141 | ||
|
|
9dcb286c31 | ||
|
|
723bd9676d | ||
|
|
62442d1c52 | ||
|
|
bf7317d4e2 | ||
|
|
9a69c0e21e | ||
|
|
526ea46ae2 | ||
|
|
159063db29 | ||
|
|
8586c08639 | ||
|
|
f57efd1150 | ||
|
|
fb016edb7a | ||
|
|
53225f5cbb | ||
|
|
11eae6d51a | ||
|
|
8fef3a3814 | ||
|
|
1ab79da7d1 | ||
|
|
ba54c4f1b3 | ||
|
|
a3585e40f7 | ||
|
|
8030abe1bd | ||
|
|
f67bf7ae98 | ||
|
|
1d346702ed | ||
|
|
7863118994 | ||
|
|
cee3670167 | ||
|
|
13d48a0c20 | ||
|
|
055b81da7b | ||
|
|
beebaf6e1e | ||
|
|
ab88ec208e | ||
|
|
2aebf99968 | ||
|
|
fb75f0935f | ||
|
|
77d5f59376 | ||
|
|
cf3e0cf271 | ||
|
|
3b2327ba8d | ||
|
|
ba599f7676 | ||
|
|
0a8939e1c1 | ||
|
|
989c853e3b | ||
|
|
7e3f5e04ab | ||
|
|
675a8330a4 | ||
|
|
3234df5581 | ||
|
|
62dfff5dde | ||
|
|
4d9b6066a2 | ||
|
|
ac9e6ff704 | ||
|
|
e6f925e5e6 | ||
|
|
56c6805d79 | ||
|
|
55e7c5644c | ||
|
|
31eb740aef | ||
|
|
ae9a9a2167 | ||
|
|
ff12f91486 | ||
|
|
74feaf85dc | ||
|
|
6db14d02d2 | ||
|
|
58250aac10 | ||
|
|
6f718a31f0 | ||
|
|
2d1d900c88 | ||
|
|
72053cc4ab | ||
|
|
e1e4810a46 | ||
|
|
8541d9738f | ||
|
|
2aa1efb70e | ||
|
|
dfa78eb27d | ||
|
|
988ea8d61d | ||
|
|
ea30e0a37d | ||
|
|
ae3a9c1ead | ||
|
|
f0ff23eac3 | ||
|
|
bed55bb7ba | ||
|
|
5f52f8d473 | ||
|
|
8670dda5b7 | ||
|
|
2dcdeb8231 | ||
|
|
17ed3fc270 | ||
|
|
f3d321fb82 | ||
|
|
0c0155e885 | ||
|
|
8b1a720ae8 | ||
|
|
164fe37fa0 | ||
|
|
9f1a156307 | ||
|
|
f110759897 | ||
|
|
b00eb1b0cc | ||
|
|
706eae7cac | ||
|
|
ac7bc78afe | ||
|
|
599322871a | ||
|
|
2e67a41c27 | ||
|
|
c858bb8122 | ||
|
|
bbc6bfd3c3 | ||
|
|
e560d7428e | ||
|
|
cde1566606 | ||
|
|
f75d1bb043 | ||
|
|
22cdfbea87 | ||
|
|
3d00e25232 | ||
|
|
56c7b554a6 | ||
|
|
b6c7ba2eea | ||
|
|
37aa81526a | ||
|
|
7619d3d6d6 | ||
|
|
f8a6dde8d8 | ||
|
|
3c55463b4b | ||
|
|
b864b09d40 | ||
|
|
45a56288bb | ||
|
|
31a651365d | ||
|
|
355943c3a0 | ||
|
|
2a6c4ec26e | ||
|
|
565b178721 | ||
|
|
7055969ef3 | ||
|
|
425bae8bf6 | ||
|
|
298608ef40 | ||
|
|
ed21350871 | ||
|
|
2dd26f7551 | ||
|
|
b06ed4908f | ||
|
|
134f6b1b6c | ||
|
|
aa42886851 | ||
|
|
dfe8f7601b | ||
|
|
c640065a66 | ||
|
|
c54aca3f44 | ||
|
|
a90b6a73dd | ||
|
|
419c889a9a | ||
|
|
293f483cb4 | ||
|
|
d0437cfb59 | ||
|
|
bba2726333 | ||
|
|
eb0e596d43 | ||
|
|
7a38f41350 | ||
|
|
79c3d6f71d | ||
|
|
ab1c2b7631 | ||
|
|
3278d02cd2 | ||
|
|
1446749b63 | ||
|
|
eb065d6d40 | ||
|
|
4da7a15ac0 | ||
|
|
b71611dd3d | ||
|
|
4cc333996c | ||
|
|
ba6ff6e227 | ||
|
|
708065cb85 | ||
|
|
af9f172be8 | ||
|
|
66b697cd05 | ||
|
|
550e60a69d | ||
|
|
b88af3a3f7 | ||
|
|
78fdd5d9b4 | ||
|
|
46e1c09b45 | ||
|
|
4d6c3c9449 | ||
|
|
493eea19e8 | ||
|
|
25c356894d | ||
|
|
f63df91186 | ||
|
|
e1464a7bf0 | ||
|
|
34a7250a2d | ||
|
|
0761301c2e | ||
|
|
47f3a3a5bd | ||
|
|
6f1538026a | ||
|
|
30299c6f49 | ||
|
|
dedc0015c0 | ||
|
|
49b326fc08 | ||
|
|
fc2cb3a85e | ||
|
|
46bc7ca69f | ||
|
|
64fa0e8729 | ||
|
|
1725fbc59a | ||
|
|
7574a14d57 | ||
|
|
5f53b140e2 | ||
|
|
7d848b1785 | ||
|
|
ec959bc3b9 | ||
|
|
59a2029c87 | ||
|
|
7d3876d51a | ||
|
|
721251f09f | ||
|
|
b4946c31b4 | ||
|
|
e40926b4cc | ||
|
|
09c8aaa87a | ||
|
|
fa102e4713 | ||
|
|
2cd41bca06 | ||
|
|
70cfc4df15 | ||
|
|
3ebe511eb9 | ||
|
|
c634e24b60 | ||
|
|
fd044b032f | ||
|
|
34fc528500 | ||
|
|
23f638a47c | ||
|
|
d050816e17 | ||
|
|
f2511c84b5 | ||
|
|
ada5facdf5 | ||
|
|
dc13d4b0fc | ||
|
|
c9209237da | ||
|
|
39154e5296 | ||
|
|
fec8dba16c | ||
|
|
be9550955f | ||
|
|
dea6a90a1f | ||
|
|
f4d645f87a | ||
|
|
a6a37b7c81 | ||
|
|
2fa3cac814 | ||
|
|
2895645f86 | ||
|
|
9aaca25edb | ||
|
|
de68f74b4c | ||
|
|
0b774e8ea5 | ||
|
|
188e0ecbcb | ||
|
|
02d1491e39 | ||
|
|
27e7c264f2 | ||
|
|
3e6cdea51f | ||
|
|
61388d412b | ||
|
|
9707b4789e | ||
|
|
7e2d8ca916 | ||
|
|
1466ed4579 | ||
|
|
c8b5f982ac | ||
|
|
8c3b2d0a0d | ||
|
|
beb1811523 | ||
|
|
d0ee615c2c | ||
|
|
8e2ce641c3 | ||
|
|
58a3fea1b7 | ||
|
|
896e4b1722 | ||
|
|
39102e68df | ||
|
|
10c168e257 | ||
|
|
59be7ff144 | ||
|
|
1ea12079da | ||
|
|
ecce3bca2f | ||
|
|
d6a2b390dc | ||
|
|
7b16c55c9a | ||
|
|
a81e872cdb | ||
|
|
94ebbc550e | ||
|
|
ac164c66ed | ||
|
|
7f1d7894c2 | ||
|
|
c1afc95e3c | ||
|
|
96feae608d | ||
|
|
937dc467a0 | ||
|
|
eeee7e9427 | ||
|
|
69ef766a93 | ||
|
|
fa0ef218dd | ||
|
|
f719380a0d | ||
|
|
fada84cc47 | ||
|
|
d0d6fc2e17 | ||
|
|
b0b6aa9124 | ||
|
|
7202e9f658 | ||
|
|
fc3315a6d7 | ||
|
|
cc208839cf | ||
|
|
210baafad4 | ||
|
|
0fb2e02b56 | ||
|
|
1a74dd4237 | ||
|
|
ca3809831c | ||
|
|
3bec3cfef1 | ||
|
|
8cf3bdd044 | ||
|
|
542bc01718 | ||
|
|
f9e4f6b57a | ||
|
|
e0b2e31f86 | ||
|
|
dc1e240642 | ||
|
|
bed717b442 | ||
|
|
922432616f | ||
|
|
e3b71b9b24 | ||
|
|
1183980e0e | ||
|
|
c2d97e9d9c | ||
|
|
2d1f8341f9 | ||
|
|
18ef17f3ba | ||
|
|
71e5b60df1 | ||
|
|
bc6a2b2f9c | ||
|
|
13c6e2f320 | ||
|
|
d7b704c90f | ||
|
|
b57b3c9f6c | ||
|
|
5e00ed926c | ||
|
|
9d468a8daf | ||
|
|
2c2e7297ae | ||
|
|
8261df29c4 | ||
|
|
5418818683 | ||
|
|
5ee7bca185 | ||
|
|
12d4be7f3f | ||
|
|
cb8457b9ae | ||
|
|
55f52e8135 | ||
|
|
6a506b63bf | ||
|
|
1323a9a990 | ||
|
|
9a4d603403 | ||
|
|
67095d239f | ||
|
|
2b405b9bb3 | ||
|
|
9cc87f8b9a | ||
|
|
df00c5c846 | ||
|
|
fa400820bb | ||
|
|
a6cb27cb8e | ||
|
|
f39bb116cc | ||
|
|
a324e9bd12 | ||
|
|
a49af09705 | ||
|
|
b6ebcd7559 | ||
|
|
744169833c | ||
|
|
99dfb9556d | ||
|
|
314551ceb2 | ||
|
|
a43e760703 | ||
|
|
ecc7eedd10 | ||
|
|
6f9f40992c | ||
|
|
de80553d89 | ||
|
|
11111cd9a9 | ||
|
|
b6fb13258f | ||
|
|
f59d927f73 | ||
|
|
840550e25f | ||
|
|
be5e129259 | ||
|
|
1358efe896 |
@@ -92,6 +92,7 @@
|
||||
"cur_page": true,
|
||||
"cur_list": true,
|
||||
"cur_tree": true,
|
||||
"cur_pos": true,
|
||||
"msg_dialog": true,
|
||||
"is_null": true,
|
||||
"in_list": true,
|
||||
@@ -149,6 +150,7 @@
|
||||
"it": true,
|
||||
"context": true,
|
||||
"before": true,
|
||||
"beforeEach": true
|
||||
"beforeEach": true,
|
||||
"onScan": true
|
||||
}
|
||||
}
|
||||
|
||||
32
.flake8
Normal file
32
.flake8
Normal file
@@ -0,0 +1,32 @@
|
||||
[flake8]
|
||||
ignore =
|
||||
E121,
|
||||
E126,
|
||||
E127,
|
||||
E128,
|
||||
E203,
|
||||
E225,
|
||||
E226,
|
||||
E231,
|
||||
E241,
|
||||
E251,
|
||||
E261,
|
||||
E265,
|
||||
E302,
|
||||
E303,
|
||||
E305,
|
||||
E402,
|
||||
E501,
|
||||
E741,
|
||||
W291,
|
||||
W292,
|
||||
W293,
|
||||
W391,
|
||||
W503,
|
||||
W504,
|
||||
F403,
|
||||
B007,
|
||||
B950,
|
||||
W191,
|
||||
|
||||
max-line-length = 200
|
||||
10
.github/helper/translation.py
vendored
10
.github/helper/translation.py
vendored
@@ -2,7 +2,7 @@ import re
|
||||
import sys
|
||||
|
||||
errors_encounter = 0
|
||||
pattern = re.compile(r"_\(([\"']{,3})(?P<message>((?!\1).)*)\1(\s*,\s*context\s*=\s*([\"'])(?P<py_context>((?!\5).)*)\5)*(\s*,\s*(.)*?\s*(,\s*([\"'])(?P<js_context>((?!\11).)*)\11)*)*\)")
|
||||
pattern = re.compile(r"_\(([\"']{,3})(?P<message>((?!\1).)*)\1(\s*,\s*context\s*=\s*([\"'])(?P<py_context>((?!\5).)*)\5)*(\s*,(\s*?.*?\n*?)*(,\s*([\"'])(?P<js_context>((?!\11).)*)\11)*)*\)")
|
||||
words_pattern = re.compile(r"_{1,2}\([\"'`]{1,3}.*?[a-zA-Z]")
|
||||
start_pattern = re.compile(r"_{1,2}\([f\"'`]{1,3}")
|
||||
f_string_pattern = re.compile(r"_\(f[\"']")
|
||||
@@ -28,7 +28,7 @@ for _file in files_to_scan:
|
||||
has_f_string = f_string_pattern.search(line)
|
||||
if has_f_string:
|
||||
errors_encounter += 1
|
||||
print(f'\nF-strings are not supported for translations at line number {line_number + 1}\n{line.strip()[:100]}')
|
||||
print(f'\nF-strings are not supported for translations at line number {line_number}\n{line.strip()[:100]}')
|
||||
continue
|
||||
else:
|
||||
continue
|
||||
@@ -36,7 +36,7 @@ for _file in files_to_scan:
|
||||
match = pattern.search(line)
|
||||
error_found = False
|
||||
|
||||
if not match and line.endswith(',\n'):
|
||||
if not match and line.endswith((',\n', '[\n')):
|
||||
# concat remaining text to validate multiline pattern
|
||||
line = "".join(file_lines[line_number - 1:])
|
||||
line = line[start_matches.start() + 1:]
|
||||
@@ -44,11 +44,11 @@ for _file in files_to_scan:
|
||||
|
||||
if not match:
|
||||
error_found = True
|
||||
print(f'\nTranslation syntax error at line number {line_number + 1}\n{line.strip()[:100]}')
|
||||
print(f'\nTranslation syntax error at line number {line_number}\n{line.strip()[:100]}')
|
||||
|
||||
if not error_found and not words_pattern.search(line):
|
||||
error_found = True
|
||||
print(f'\nTranslation is useless because it has no words at line number {line_number + 1}\n{line.strip()[:100]}')
|
||||
print(f'\nTranslation is useless because it has no words at line number {line_number}\n{line.strip()[:100]}')
|
||||
|
||||
if error_found:
|
||||
errors_encounter += 1
|
||||
|
||||
9
erpnext/.stylelintrc
Normal file
9
erpnext/.stylelintrc
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": ["stylelint-config-recommended"],
|
||||
"plugins": ["stylelint-scss"],
|
||||
"rules": {
|
||||
"at-rule-no-unknown": null,
|
||||
"scss/at-rule-no-unknown": true,
|
||||
"no-descending-specificity": null
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
from frappe.utils import getdate
|
||||
|
||||
__version__ = '13.0.0-beta.13'
|
||||
__version__ = '13.0.2'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
@@ -109,7 +109,7 @@ def get_region(company=None):
|
||||
'''
|
||||
if company or frappe.flags.company:
|
||||
return frappe.get_cached_value('Company',
|
||||
company or frappe.flags.company, 'country')
|
||||
company or frappe.flags.company, 'country')
|
||||
elif frappe.flags.country:
|
||||
return frappe.flags.country
|
||||
else:
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
{
|
||||
"cards": [
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Accounting Masters",
|
||||
"links": "[\n {\n \"description\": \"Company (not Customer or Supplier) master.\",\n \"label\": \"Company\",\n \"name\": \"Company\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tree of financial accounts.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Chart of Accounts\",\n \"name\": \"Account\",\n \"onboard\": 1,\n \"route\": \"#Tree/Account\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounts Settings\",\n \"name\": \"Accounts Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Financial / accounting year.\",\n \"label\": \"Fiscal Year\",\n \"name\": \"Fiscal Year\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounting Dimension\",\n \"name\": \"Accounting Dimension\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Finance Book\",\n \"name\": \"Finance Book\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounting Period\",\n \"name\": \"Accounting Period\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Payment Terms based on conditions\",\n \"label\": \"Payment Term\",\n \"name\": \"Payment Term\",\n \"type\": \"doctype\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "General Ledger",
|
||||
"links": "[\n {\n \"description\": \"Accounting journal entries.\",\n \"label\": \"Journal Entry\",\n \"name\": \"Journal Entry\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Make journal entries from a template.\",\n \"label\": \"Journal Entry Template\",\n \"name\": \"Journal Entry Template\",\n \"type\": \"doctype\"\n },\n \n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"General Ledger\",\n \"name\": \"General Ledger\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Customer Ledger Summary\",\n \"name\": \"Customer Ledger Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Supplier Ledger Summary\",\n \"name\": \"Supplier Ledger Summary\",\n \"type\": \"report\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Accounts Receivable",
|
||||
"links": "[\n {\n \"description\": \"Bills raised to Customers.\",\n \"label\": \"Sales Invoice\",\n \"name\": \"Sales Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Customer database.\",\n \"label\": \"Customer\",\n \"name\": \"Customer\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bank/Cash transactions against party or for internal transfer\",\n \"label\": \"Payment Entry\",\n \"name\": \"Payment Entry\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Payment Request\",\n \"label\": \"Payment Request\",\n \"name\": \"Payment Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable\",\n \"name\": \"Accounts Receivable\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Receivable Summary\",\n \"name\": \"Accounts Receivable Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Register\",\n \"name\": \"Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Sales Register\",\n \"name\": \"Item-wise Sales Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Order\",\n \"is_query_report\": true,\n \"label\": \"Sales Order Analysis\",\n \"name\": \"Sales Order Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Delivered Items To Be Billed\",\n \"name\": \"Delivered Items To Be Billed\",\n \"type\": \"report\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Accounts Payable",
|
||||
"links": "[\n {\n \"description\": \"Bills raised by Suppliers.\",\n \"label\": \"Purchase Invoice\",\n \"name\": \"Purchase Invoice\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Supplier database.\",\n \"label\": \"Supplier\",\n \"name\": \"Supplier\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Bank/Cash transactions against party or for internal transfer\",\n \"label\": \"Payment Entry\",\n \"name\": \"Payment Entry\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Payable\",\n \"name\": \"Accounts Payable\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Accounts Payable Summary\",\n \"name\": \"Accounts Payable Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Purchase Register\",\n \"name\": \"Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Item-wise Purchase Register\",\n \"name\": \"Item-wise Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Order\"\n ],\n \"doctype\": \"Purchase Order\",\n \"is_query_report\": true,\n \"label\": \"Purchase Order Analysis\",\n \"name\": \"Purchase Order Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Received Items To Be Billed\",\n \"name\": \"Received Items To Be Billed\",\n \"type\": \"report\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Reports",
|
||||
"links": "[\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Trial Balance for Party\",\n \"name\": \"Trial Balance for Party\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Journal Entry\"\n ],\n \"doctype\": \"Journal Entry\",\n \"is_query_report\": true,\n \"label\": \"Payment Period Based On Invoice Date\",\n \"name\": \"Payment Period Based On Invoice Date\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Partners Commission\",\n \"name\": \"Sales Partners Commission\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customer Credit Balance\",\n \"name\": \"Customer Credit Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Payment Summary\",\n \"name\": \"Sales Payment Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Address\"\n ],\n \"doctype\": \"Address\",\n \"is_query_report\": true,\n \"label\": \"Address And Contacts\",\n \"name\": \"Address And Contacts\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"DATEV Export\",\n \"name\": \"DATEV\",\n \"type\": \"report\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Financial Statements",
|
||||
"links": "[\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Trial Balance\",\n \"name\": \"Trial Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Profit and Loss Statement\",\n \"name\": \"Profit and Loss Statement\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Balance Sheet\",\n \"name\": \"Balance Sheet\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Cash Flow\",\n \"name\": \"Cash Flow\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Consolidated Financial Statement\",\n \"name\": \"Consolidated Financial Statement\",\n \"type\": \"report\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Multi Currency",
|
||||
"links": "[\n {\n \"description\": \"Enable / disable currencies.\",\n \"label\": \"Currency\",\n \"name\": \"Currency\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Currency exchange rate master.\",\n \"label\": \"Currency Exchange\",\n \"name\": \"Currency Exchange\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Exchange Rate Revaluation master.\",\n \"label\": \"Exchange Rate Revaluation\",\n \"name\": \"Exchange Rate Revaluation\",\n \"type\": \"doctype\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Settings",
|
||||
"links": "[\n {\n \"description\": \"Setup Gateway accounts.\",\n \"label\": \"Payment Gateway Account\",\n \"name\": \"Payment Gateway Account\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Template of terms or contract.\",\n \"label\": \"Terms and Conditions Template\",\n \"name\": \"Terms and Conditions\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"e.g. Bank, Cash, Credit Card\",\n \"label\": \"Mode of Payment\",\n \"name\": \"Mode of Payment\",\n \"type\": \"doctype\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Bank Statement",
|
||||
"links": "[\n {\n \"label\": \"Bank\",\n \"name\": \"Bank\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Bank Account\",\n \"name\": \"Bank Account\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Bank Clearance\",\n \"name\": \"Bank Clearance\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Bank Reconciliation\",\n \"name\": \"bank-reconciliation\",\n \"type\": \"page\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Bank Reconciliation Statement\",\n \"name\": \"Bank Reconciliation Statement\",\n \"type\": \"report\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Subscription Management",
|
||||
"links": "[\n {\n \"label\": \"Subscription Plan\",\n \"name\": \"Subscription Plan\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Subscription\",\n \"name\": \"Subscription\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Subscription Settings\",\n \"name\": \"Subscription Settings\",\n \"type\": \"doctype\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Goods and Services Tax (GST India)",
|
||||
"links": "[\n {\n \"label\": \"GST Settings\",\n \"name\": \"GST Settings\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"GST HSN Code\",\n \"name\": \"GST HSN Code\",\n \"type\": \"doctype\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GSTR-1\",\n \"name\": \"GSTR-1\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GSTR-2\",\n \"name\": \"GSTR-2\",\n \"type\": \"report\"\n },\n {\n \"label\": \"GSTR 3B Report\",\n \"name\": \"GSTR 3B Report\",\n \"type\": \"doctype\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Sales Register\",\n \"name\": \"GST Sales Register\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Purchase Register\",\n \"name\": \"GST Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Itemised Sales Register\",\n \"name\": \"GST Itemised Sales Register\",\n \"type\": \"report\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"GST Itemised Purchase Register\",\n \"name\": \"GST Itemised Purchase Register\",\n \"type\": \"report\"\n },\n {\n \"country\": \"India\",\n \"description\": \"C-Form records\",\n \"label\": \"C-Form\",\n \"name\": \"C-Form\",\n \"type\": \"doctype\"\n },\n {\n \"country\": \"India\",\n \"label\": \"Lower Deduction Certificate\",\n \"name\": \"Lower Deduction Certificate\",\n \"type\": \"doctype\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Share Management",
|
||||
"links": "[\n {\n \"description\": \"List of available Shareholders with folio numbers\",\n \"label\": \"Shareholder\",\n \"name\": \"Shareholder\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"List of all share transactions\",\n \"label\": \"Share Transfer\",\n \"name\": \"Share Transfer\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Share Transfer\"\n ],\n \"doctype\": \"Share Transfer\",\n \"is_query_report\": true,\n \"label\": \"Share Ledger\",\n \"name\": \"Share Ledger\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Share Transfer\"\n ],\n \"doctype\": \"Share Transfer\",\n \"is_query_report\": true,\n \"label\": \"Share Balance\",\n \"name\": \"Share Balance\",\n \"type\": \"report\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Cost Center and Budgeting",
|
||||
"links": "[\n {\n \"description\": \"Tree of financial Cost Centers.\",\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Chart of Cost Centers\",\n \"name\": \"Cost Center\",\n \"route\": \"#Tree/Cost Center\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Define budget for a financial year.\",\n \"label\": \"Budget\",\n \"name\": \"Budget\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Accounting Dimension\",\n \"name\": \"Accounting Dimension\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Cost Center\"\n ],\n \"doctype\": \"Cost Center\",\n \"is_query_report\": true,\n \"label\": \"Budget Variance Report\",\n \"name\": \"Budget Variance Report\",\n \"type\": \"report\"\n },\n {\n \"description\": \"Seasonality for setting budgets, targets etc.\",\n \"label\": \"Monthly Distribution\",\n \"name\": \"Monthly Distribution\",\n \"type\": \"doctype\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Opening and Closing",
|
||||
"links": "[\n {\n \"label\": \"Opening Invoice Creation Tool\",\n \"name\": \"Opening Invoice Creation Tool\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Chart of Accounts Importer\",\n \"name\": \"Chart of Accounts Importer\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Close Balance Sheet and book Profit or Loss.\",\n \"label\": \"Period Closing Voucher\",\n \"name\": \"Period Closing Voucher\",\n \"type\": \"doctype\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Taxes",
|
||||
"links": "[\n {\n \"description\": \"Tax template for selling transactions.\",\n \"label\": \"Sales Taxes and Charges Template\",\n \"name\": \"Sales Taxes and Charges Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for buying transactions.\",\n \"label\": \"Purchase Taxes and Charges Template\",\n \"name\": \"Purchase Taxes and Charges Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax template for item tax rates.\",\n \"label\": \"Item Tax Template\",\n \"name\": \"Item Tax Template\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax Category for overriding tax rates.\",\n \"label\": \"Tax Category\",\n \"name\": \"Tax Category\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax Rule for transactions.\",\n \"label\": \"Tax Rule\",\n \"name\": \"Tax Rule\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Tax Withholding rates to be applied on transactions.\",\n \"label\": \"Tax Withholding Category\",\n \"name\": \"Tax Withholding Category\",\n \"type\": \"doctype\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Profitability",
|
||||
"links": "[\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Gross Profit\",\n \"name\": \"Gross Profit\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Profitability Analysis\",\n \"name\": \"Profitability Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Invoice Trends\",\n \"name\": \"Sales Invoice Trends\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Invoice\"\n ],\n \"doctype\": \"Purchase Invoice\",\n \"is_query_report\": true,\n \"label\": \"Purchase Invoice Trends\",\n \"name\": \"Purchase Invoice Trends\",\n \"type\": \"report\"\n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Value-Added Tax (VAT UAE)",
|
||||
"links": "[\n {\n \"country\": \"United Arab Emirates\",\n \"label\": \"UAE VAT Settings\",\n \"name\": \"UAE VAT Settings\",\n \"type\": \"doctype\"\n },\n {\n \"country\": \"United Arab Emirates\",\n \"is_query_report\": true,\n \"label\": \"UAE VAT 201\",\n \"name\": \"UAE VAT 201\",\n \"type\": \"report\"\n }\n\n]"
|
||||
}
|
||||
],
|
||||
"category": "Modules",
|
||||
"charts": [
|
||||
{
|
||||
"chart_name": "Profit and Loss",
|
||||
"label": "Profit and Loss"
|
||||
}
|
||||
],
|
||||
"creation": "2020-03-02 15:41:59.515192",
|
||||
"developer_mode_only": 0,
|
||||
"disable_user_customization": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Desk Page",
|
||||
"extends_another_page": 0,
|
||||
"hide_custom": 0,
|
||||
"idx": 0,
|
||||
"is_standard": 1,
|
||||
"label": "Accounting",
|
||||
"modified": "2020-11-11 18:35:11.542909",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Accounting",
|
||||
"onboarding": "Accounts",
|
||||
"owner": "Administrator",
|
||||
"pin_to_bottom": 0,
|
||||
"pin_to_top": 0,
|
||||
"shortcuts": [
|
||||
{
|
||||
"label": "Chart Of Accounts",
|
||||
"link_to": "Account",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"label": "Sales Invoice",
|
||||
"link_to": "Sales Invoice",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"label": "Purchase Invoice",
|
||||
"link_to": "Purchase Invoice",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"label": "Journal Entry",
|
||||
"link_to": "Journal Entry",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"label": "Payment Entry",
|
||||
"link_to": "Payment Entry",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"label": "Accounts Receivable",
|
||||
"link_to": "Accounts Receivable",
|
||||
"type": "Report"
|
||||
},
|
||||
{
|
||||
"label": "General Ledger",
|
||||
"link_to": "General Ledger",
|
||||
"type": "Report"
|
||||
},
|
||||
{
|
||||
"label": "Trial Balance",
|
||||
"link_to": "Trial Balance",
|
||||
"type": "Report"
|
||||
},
|
||||
{
|
||||
"label": "Dashboard",
|
||||
"link_to": "Accounts",
|
||||
"type": "Dashboard"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -120,17 +120,17 @@ frappe.treeview_settings["Account"] = {
|
||||
} else {
|
||||
treeview.new_node();
|
||||
}
|
||||
}, "octicon octicon-plus");
|
||||
}, "add");
|
||||
},
|
||||
onrender: function(node) {
|
||||
if(frappe.boot.user.can_read.indexOf("GL Entry") !== -1){
|
||||
if (frappe.boot.user.can_read.indexOf("GL Entry") !== -1) {
|
||||
|
||||
// show Dr if positive since balance is calculated as debit - credit else show Cr
|
||||
let balance = node.data.balance_in_account_currency || node.data.balance;
|
||||
let dr_or_cr = balance > 0 ? "Dr": "Cr";
|
||||
|
||||
if (node.data && node.data.balance!==undefined) {
|
||||
$('<span class="balance-area pull-right text-muted small">'
|
||||
$('<span class="balance-area pull-right">'
|
||||
+ (node.data.balance_in_account_currency ?
|
||||
(format_currency(Math.abs(node.data.balance_in_account_currency),
|
||||
node.data.account_currency) + " / ") : "")
|
||||
|
||||
@@ -63,17 +63,21 @@
|
||||
"Gewinnermittlung \u00a74/3 nicht Ergebniswirksam": {
|
||||
"account_number": "1371"
|
||||
},
|
||||
"Abziehbare VSt. 7%": {
|
||||
"account_number": "1571"
|
||||
},
|
||||
"Abziehbare VSt. 19%": {
|
||||
"account_number": "1576"
|
||||
},
|
||||
"Abziehbare VStr. nach \u00a713b UStG 19%": {
|
||||
"account_number": "1577"
|
||||
},
|
||||
"Leistungen \u00a713b UStG 19% Vorsteuer, 19% Umsatzsteuer": {
|
||||
"account_number": "3120"
|
||||
"Abziehbare Vorsteuer": {
|
||||
"account_type": "Tax",
|
||||
"is_group": 1,
|
||||
"Abziehbare Vorsteuer 7%": {
|
||||
"account_number": "1571"
|
||||
},
|
||||
"Abziehbare Vorsteuer 19%": {
|
||||
"account_number": "1576"
|
||||
},
|
||||
"Abziehbare Vorsteuer nach \u00a713b UStG 19%": {
|
||||
"account_number": "1577"
|
||||
},
|
||||
"Leistungen \u00a713b UStG 19% Vorsteuer, 19% Umsatzsteuer": {
|
||||
"account_number": "3120"
|
||||
}
|
||||
}
|
||||
},
|
||||
"III. Wertpapiere": {
|
||||
@@ -196,6 +200,7 @@
|
||||
},
|
||||
"Umsatzsteuer": {
|
||||
"is_group": 1,
|
||||
"account_type": "Tax",
|
||||
"Umsatzsteuer 7%": {
|
||||
"account_number": "1771"
|
||||
},
|
||||
|
||||
@@ -292,18 +292,21 @@
|
||||
"Umsatzsteuerforderungen fr\u00fchere Jahre": {}
|
||||
},
|
||||
"Sonstige Verm\u00f6gensgegenst\u00e4nde oder sonstige Verbindlichkeiten": {
|
||||
"Abziehbare Vorsteuer": {},
|
||||
"Abziehbare Vorsteuer 16%": {},
|
||||
"Abziehbare Vorsteuer 19%": {},
|
||||
"Abziehbare Vorsteuer 7%": {},
|
||||
"Abziehbare Vorsteuer aus der Auslagerung von Gegenst\u00e4nden aus einem Unsatzsteuerlager": {},
|
||||
"Abziehbare Vorsteuer aus innergemeinschaftlichem Erwerb": {},
|
||||
"Abziehbare Vorsteuer aus innergemeinschaftlichem Erwerb 16%": {},
|
||||
"Abziehbare Vorsteuer aus innergemeinschaftlichem Erwerb 19%": {},
|
||||
"Abziehbare Vorsteuer aus innergemeinschaftlichem Erwerb von Neufahrzeugen von Lieferanten ohne Ust-Identifikationsnummer": {},
|
||||
"Abziehbare Vorsteuer nach \u00a7 13b UStG ": {},
|
||||
"Abziehbare Vorsteuer nach \u00a7 13b UStG 16%": {},
|
||||
"Abziehbare Vorsteuer nach \u00a7 13b UStG 19%": {},
|
||||
"Abziehbare Vorsteuer": {
|
||||
"account_type": "Tax",
|
||||
"is_group": 1,
|
||||
"Abziehbare Vorsteuer 16%": {},
|
||||
"Abziehbare Vorsteuer 19%": {},
|
||||
"Abziehbare Vorsteuer 7%": {},
|
||||
"Abziehbare Vorsteuer aus der Auslagerung von Gegenst\u00e4nden aus einem Unsatzsteuerlager": {},
|
||||
"Abziehbare Vorsteuer aus innergemeinschaftlichem Erwerb": {},
|
||||
"Abziehbare Vorsteuer aus innergemeinschaftlichem Erwerb 16%": {},
|
||||
"Abziehbare Vorsteuer aus innergemeinschaftlichem Erwerb 19%": {},
|
||||
"Abziehbare Vorsteuer aus innergemeinschaftlichem Erwerb von Neufahrzeugen von Lieferanten ohne Ust-Identifikationsnummer": {},
|
||||
"Abziehbare Vorsteuer nach \u00a7 13b UStG ": {},
|
||||
"Abziehbare Vorsteuer nach \u00a7 13b UStG 16%": {},
|
||||
"Abziehbare Vorsteuer nach \u00a7 13b UStG 19%": {}
|
||||
},
|
||||
"Aufl\u00f6sung Vorsteuer aus Vorjahr \u00a7 4/3 EStG": {},
|
||||
"Aufzuteilende Vorsteuer": {},
|
||||
"Aufzuteilende Vorsteuer 16%": {},
|
||||
@@ -673,23 +676,26 @@
|
||||
"Sonstige Verrechnungskonten (Interimskonto)": {
|
||||
"account_type": "Stock Received But Not Billed"
|
||||
},
|
||||
"Umsatzsteuer": {},
|
||||
"Umsatzsteuer 16%": {},
|
||||
"Umsatzsteuer 19%": {},
|
||||
"Umsatzsteuer 7%": {},
|
||||
"Umsatzsteuer Vorjahr": {},
|
||||
"Umsatzsteuer aus der Auslagerung von Gegenst\u00e4nden aus einem Umsatzsteuerlager": {},
|
||||
"Umsatzsteuer aus im Inland steuerpflichtigen EG-Lieferungen": {},
|
||||
"Umsatzsteuer aus im Inland steuerpflichtigen EG-Lieferungen 19%": {},
|
||||
"Umsatzsteuer aus innergemeinschaftlichem Erwerb ": {},
|
||||
"Umsatzsteuer aus innergemeinschaftlichem Erwerb 16%": {},
|
||||
"Umsatzsteuer aus innergemeinschaftlichem Erwerb 19%": {},
|
||||
"Umsatzsteuer aus innergemeinschaftlichem Erwerb ohne Vorsteuerabzug": {},
|
||||
"Umsatzsteuer fr\u00fchere Jahre": {},
|
||||
"Umsatzsteuer laufendes Jahr": {},
|
||||
"Umsatzsteuer nach \u00a713b UStG": {},
|
||||
"Umsatzsteuer nach \u00a713b UStG 16%": {},
|
||||
"Umsatzsteuer nach \u00a713b UStG 19%": {},
|
||||
"Umsatzsteuer": {
|
||||
"account_type": "Tax",
|
||||
"is_group": 1,
|
||||
"Umsatzsteuer 16%": {},
|
||||
"Umsatzsteuer 19%": {},
|
||||
"Umsatzsteuer 7%": {},
|
||||
"Umsatzsteuer Vorjahr": {},
|
||||
"Umsatzsteuer aus der Auslagerung von Gegenst\u00e4nden aus einem Umsatzsteuerlager": {},
|
||||
"Umsatzsteuer aus im Inland steuerpflichtigen EG-Lieferungen": {},
|
||||
"Umsatzsteuer aus im Inland steuerpflichtigen EG-Lieferungen 19%": {},
|
||||
"Umsatzsteuer aus innergemeinschaftlichem Erwerb ": {},
|
||||
"Umsatzsteuer aus innergemeinschaftlichem Erwerb 16%": {},
|
||||
"Umsatzsteuer aus innergemeinschaftlichem Erwerb 19%": {},
|
||||
"Umsatzsteuer aus innergemeinschaftlichem Erwerb ohne Vorsteuerabzug": {},
|
||||
"Umsatzsteuer fr\u00fchere Jahre": {},
|
||||
"Umsatzsteuer laufendes Jahr": {},
|
||||
"Umsatzsteuer nach \u00a713b UStG": {},
|
||||
"Umsatzsteuer nach \u00a713b UStG 16%": {},
|
||||
"Umsatzsteuer nach \u00a713b UStG 19%": {}
|
||||
},
|
||||
"Umsatzsteuer- Vorauszahlungen": {},
|
||||
"Umsatzsteuer- Vorauszahlungen 1/11": {},
|
||||
"Verbindlichkeiten aus Lohn- und Kirchensteuer": {}
|
||||
|
||||
@@ -659,6 +659,7 @@
|
||||
},
|
||||
"Abziehbare Vorsteuer (Gruppe)": {
|
||||
"is_group": 1,
|
||||
"account_type": "Tax",
|
||||
"Abziehbare Vorsteuer": {
|
||||
"account_number": "1400"
|
||||
},
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
"fieldtype": "Link",
|
||||
"label": "Reference Document Type",
|
||||
"options": "DocType",
|
||||
"read_only_depends_on": "eval:!doc.__islocal",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -48,7 +49,7 @@
|
||||
}
|
||||
],
|
||||
"links": [],
|
||||
"modified": "2020-03-22 20:34:39.805728",
|
||||
"modified": "2021-02-08 16:37:53.936656",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Accounting Dimension",
|
||||
|
||||
@@ -29,6 +29,16 @@ class AccountingDimension(Document):
|
||||
if exists and self.is_new():
|
||||
frappe.throw("Document Type already used as a dimension")
|
||||
|
||||
if not self.is_new():
|
||||
self.validate_document_type_change()
|
||||
|
||||
def validate_document_type_change(self):
|
||||
doctype_before_save = frappe.db.get_value("Accounting Dimension", self.name, "document_type")
|
||||
if doctype_before_save != self.document_type:
|
||||
message = _("Cannot change Reference Document Type.")
|
||||
message += _("Please create a new Accounting Dimension if required.")
|
||||
frappe.throw(message)
|
||||
|
||||
def after_insert(self):
|
||||
if frappe.flags.in_test:
|
||||
make_dimension_in_accounting_doctypes(doc=self)
|
||||
@@ -51,8 +61,10 @@ class AccountingDimension(Document):
|
||||
def on_update(self):
|
||||
frappe.flags.accounting_dimensions = None
|
||||
|
||||
def make_dimension_in_accounting_doctypes(doc):
|
||||
doclist = get_doctypes_with_dimensions()
|
||||
def make_dimension_in_accounting_doctypes(doc, doclist=None):
|
||||
if not doclist:
|
||||
doclist = get_doctypes_with_dimensions()
|
||||
|
||||
doc_count = len(get_accounting_dimensions())
|
||||
count = 0
|
||||
|
||||
@@ -72,13 +84,13 @@ def make_dimension_in_accounting_doctypes(doc):
|
||||
"owner": "Administrator"
|
||||
}
|
||||
|
||||
if doctype == "Budget":
|
||||
add_dimension_to_budget_doctype(df, doc)
|
||||
else:
|
||||
meta = frappe.get_meta(doctype, cached=False)
|
||||
fieldnames = [d.fieldname for d in meta.get("fields")]
|
||||
meta = frappe.get_meta(doctype, cached=False)
|
||||
fieldnames = [d.fieldname for d in meta.get("fields")]
|
||||
|
||||
if df['fieldname'] not in fieldnames:
|
||||
if df['fieldname'] not in fieldnames:
|
||||
if doctype == "Budget":
|
||||
add_dimension_to_budget_doctype(df.copy(), doc)
|
||||
else:
|
||||
create_custom_field(doctype, df)
|
||||
|
||||
count += 1
|
||||
@@ -168,15 +180,7 @@ def toggle_disabling(doc):
|
||||
frappe.clear_cache(doctype=doctype)
|
||||
|
||||
def get_doctypes_with_dimensions():
|
||||
doclist = ["GL Entry", "Sales Invoice", "POS Invoice", "Purchase Invoice", "Payment Entry", "Asset",
|
||||
"Expense Claim", "Expense Claim Detail", "Expense Taxes and Charges", "Stock Entry", "Budget", "Payroll Entry", "Delivery Note",
|
||||
"Sales Invoice Item", "POS Invoice Item", "Purchase Invoice Item", "Purchase Order Item", "Journal Entry Account", "Material Request Item", "Delivery Note Item",
|
||||
"Purchase Receipt Item", "Stock Entry Detail", "Payment Entry Deduction", "Sales Taxes and Charges", "Purchase Taxes and Charges", "Shipping Rule",
|
||||
"Landed Cost Item", "Asset Value Adjustment", "Loyalty Program", "Fee Schedule", "Fee Structure", "Stock Reconciliation",
|
||||
"Travel Request", "Fees", "POS Profile", "Opening Invoice Creation Tool", "Opening Invoice Creation Tool Item", "Subscription",
|
||||
"Subscription Plan"]
|
||||
|
||||
return doclist
|
||||
return frappe.get_hooks("accounting_dimension_doctypes")
|
||||
|
||||
def get_accounting_dimensions(as_list=True):
|
||||
if frappe.flags.accounting_dimensions is None:
|
||||
|
||||
@@ -6,3 +6,46 @@ frappe.ui.form.on('Accounts Settings', {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
frappe.tour['Accounts Settings'] = [
|
||||
{
|
||||
fieldname: "acc_frozen_upto",
|
||||
title: "Accounts Frozen Upto",
|
||||
description: __("Freeze accounting transactions up to specified date, nobody can make/modify entry except the specified Role."),
|
||||
},
|
||||
{
|
||||
fieldname: "frozen_accounts_modifier",
|
||||
title: "Role Allowed to Set Frozen Accounts & Edit Frozen Entries",
|
||||
description: __("Users with this Role are allowed to set frozen accounts and create/modify accounting entries against frozen accounts.")
|
||||
},
|
||||
{
|
||||
fieldname: "determine_address_tax_category_from",
|
||||
title: "Determine Address Tax Category From",
|
||||
description: __("Tax category can be set on Addresses. An address can be Shipping or Billing address. Set which addres to select when applying Tax Category.")
|
||||
},
|
||||
{
|
||||
fieldname: "over_billing_allowance",
|
||||
title: "Over Billing Allowance Percentage",
|
||||
description: __("The percentage by which you can overbill transactions. For example, if the order value is $100 for an Item and percentage here is set as 10% then you are allowed to bill for $110.")
|
||||
},
|
||||
{
|
||||
fieldname: "credit_controller",
|
||||
title: "Credit Controller",
|
||||
description: __("Select the role that is allowed to submit transactions that exceed credit limits set. The credit limit can be set in the Customer form.")
|
||||
},
|
||||
{
|
||||
fieldname: "make_payment_via_journal_entry",
|
||||
title: "Make Payment via Journal Entry",
|
||||
description: __("When checked, if user proceeds to make payment from an invoice, the system will open a Journal Entry instead of a Payment Entry.")
|
||||
},
|
||||
{
|
||||
fieldname: "unlink_payment_on_cancellation_of_invoice",
|
||||
title: "Unlink Payment on Cancellation of Invoice",
|
||||
description: __("If checked, system will unlink the payment against the respective invoice.")
|
||||
},
|
||||
{
|
||||
fieldname: "unlink_advance_payment_on_cancelation_of_order",
|
||||
title: "Unlink Advance Payment on Cancellation of Order",
|
||||
description: __("Similar to the previous option, this unlinks any advance payments made against Purchase/Sales Orders.")
|
||||
}
|
||||
];
|
||||
@@ -86,6 +86,7 @@
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Setting the account as a Company Account is necessary for Bank Reconciliation",
|
||||
"fieldname": "is_company_account",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Company Account"
|
||||
@@ -207,7 +208,7 @@
|
||||
}
|
||||
],
|
||||
"links": [],
|
||||
"modified": "2020-07-17 13:59:50.795412",
|
||||
"modified": "2020-10-23 16:48:06.303658",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Account",
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
frappe.provide("erpnext.accounts.bank_reconciliation");
|
||||
|
||||
frappe.ui.form.on("Bank Reconciliation Tool", {
|
||||
setup: function (frm) {
|
||||
frm.set_query("bank_account", function () {
|
||||
return {
|
||||
filters: {
|
||||
company: ["in", frm.doc.company],
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
refresh: function (frm) {
|
||||
frappe.require("assets/js/bank-reconciliation-tool.min.js", () =>
|
||||
frm.trigger("make_reconciliation_tool")
|
||||
);
|
||||
frm.upload_statement_button = frm.page.set_secondary_action(
|
||||
__("Upload Bank Statement"),
|
||||
() =>
|
||||
frappe.call({
|
||||
method:
|
||||
"erpnext.accounts.doctype.bank_statement_import.bank_statement_import.upload_bank_statement",
|
||||
args: {
|
||||
dt: frm.doc.doctype,
|
||||
dn: frm.doc.name,
|
||||
company: frm.doc.company,
|
||||
bank_account: frm.doc.bank_account,
|
||||
},
|
||||
callback: function (r) {
|
||||
if (!r.exc) {
|
||||
var doc = frappe.model.sync(r.message);
|
||||
frappe.set_route(
|
||||
"Form",
|
||||
doc[0].doctype,
|
||||
doc[0].name
|
||||
);
|
||||
}
|
||||
},
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
after_save: function (frm) {
|
||||
frm.trigger("make_reconciliation_tool");
|
||||
},
|
||||
|
||||
bank_account: function (frm) {
|
||||
frappe.db.get_value(
|
||||
"Bank Account",
|
||||
frm.bank_account,
|
||||
"account",
|
||||
(r) => {
|
||||
frappe.db.get_value(
|
||||
"Account",
|
||||
r.account,
|
||||
"account_currency",
|
||||
(r) => {
|
||||
frm.currency = r.account_currency;
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
frm.trigger("get_account_opening_balance");
|
||||
},
|
||||
|
||||
bank_statement_from_date: function (frm) {
|
||||
frm.trigger("get_account_opening_balance");
|
||||
},
|
||||
|
||||
make_reconciliation_tool(frm) {
|
||||
frm.get_field("reconciliation_tool_cards").$wrapper.empty();
|
||||
if (frm.doc.bank_account && frm.doc.bank_statement_to_date) {
|
||||
frm.trigger("get_cleared_balance").then(() => {
|
||||
if (
|
||||
frm.doc.bank_account &&
|
||||
frm.doc.bank_statement_from_date &&
|
||||
frm.doc.bank_statement_to_date &&
|
||||
frm.doc.bank_statement_closing_balance
|
||||
) {
|
||||
frm.trigger("render_chart");
|
||||
frm.trigger("render");
|
||||
frappe.utils.scroll_to(
|
||||
frm.get_field("reconciliation_tool_cards").$wrapper,
|
||||
true,
|
||||
30
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
get_account_opening_balance(frm) {
|
||||
if (frm.doc.bank_account && frm.doc.bank_statement_from_date) {
|
||||
frappe.call({
|
||||
method:
|
||||
"erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_account_balance",
|
||||
args: {
|
||||
bank_account: frm.doc.bank_account,
|
||||
till_date: frm.doc.bank_statement_from_date,
|
||||
},
|
||||
callback: (response) => {
|
||||
frm.set_value("account_opening_balance", response.message);
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
get_cleared_balance(frm) {
|
||||
if (frm.doc.bank_account && frm.doc.bank_statement_to_date) {
|
||||
return frappe.call({
|
||||
method:
|
||||
"erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_account_balance",
|
||||
args: {
|
||||
bank_account: frm.doc.bank_account,
|
||||
till_date: frm.doc.bank_statement_to_date,
|
||||
},
|
||||
callback: (response) => {
|
||||
frm.cleared_balance = response.message;
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
render_chart(frm) {
|
||||
frm.cards_manager = new erpnext.accounts.bank_reconciliation.NumberCardManager(
|
||||
{
|
||||
$reconciliation_tool_cards: frm.get_field(
|
||||
"reconciliation_tool_cards"
|
||||
).$wrapper,
|
||||
bank_statement_closing_balance:
|
||||
frm.doc.bank_statement_closing_balance,
|
||||
cleared_balance: frm.cleared_balance,
|
||||
currency: frm.currency,
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
render(frm) {
|
||||
if (frm.doc.bank_account) {
|
||||
frm.bank_reconciliation_data_table_manager = new erpnext.accounts.bank_reconciliation.DataTableManager(
|
||||
{
|
||||
company: frm.doc.company,
|
||||
bank_account: frm.doc.bank_account,
|
||||
$reconciliation_tool_dt: frm.get_field(
|
||||
"reconciliation_tool_dt"
|
||||
).$wrapper,
|
||||
$no_bank_transactions: frm.get_field(
|
||||
"no_bank_transactions"
|
||||
).$wrapper,
|
||||
bank_statement_from_date: frm.doc.bank_statement_from_date,
|
||||
bank_statement_to_date: frm.doc.bank_statement_to_date,
|
||||
bank_statement_closing_balance:
|
||||
frm.doc.bank_statement_closing_balance,
|
||||
cards_manager: frm.cards_manager,
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2020-12-02 10:13:02.148040",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"company",
|
||||
"bank_account",
|
||||
"column_break_1",
|
||||
"bank_statement_from_date",
|
||||
"bank_statement_to_date",
|
||||
"column_break_2",
|
||||
"account_opening_balance",
|
||||
"bank_statement_closing_balance",
|
||||
"section_break_1",
|
||||
"reconciliation_tool_cards",
|
||||
"reconciliation_tool_dt",
|
||||
"no_bank_transactions"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"options": "Company"
|
||||
},
|
||||
{
|
||||
"fieldname": "bank_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Bank Account",
|
||||
"options": "Bank Account"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_1",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.bank_account",
|
||||
"fieldname": "bank_statement_from_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Bank Statement From Date"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.bank_statement_from_date",
|
||||
"fieldname": "bank_statement_to_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Bank Statement To Date"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_2",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.bank_statement_from_date",
|
||||
"fieldname": "account_opening_balance",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Account Opening Balance",
|
||||
"options": "Currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.bank_statement_to_date",
|
||||
"fieldname": "bank_statement_closing_balance",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Bank Statement Closing Balance",
|
||||
"options": "Currency"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.bank_statement_closing_balance",
|
||||
"fieldname": "section_break_1",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Reconcile"
|
||||
},
|
||||
{
|
||||
"fieldname": "reconciliation_tool_cards",
|
||||
"fieldtype": "HTML"
|
||||
},
|
||||
{
|
||||
"fieldname": "reconciliation_tool_dt",
|
||||
"fieldtype": "HTML"
|
||||
},
|
||||
{
|
||||
"fieldname": "no_bank_transactions",
|
||||
"fieldtype": "HTML",
|
||||
"options": "<div class=\"text-muted text-center\">No Matching Bank Transactions Found</div>"
|
||||
}
|
||||
],
|
||||
"hide_toolbar": 1,
|
||||
"index_web_pages_for_search": 1,
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2021-02-02 01:35:53.043578",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Reconciliation Tool",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
@@ -0,0 +1,452 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import json
|
||||
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from frappe import _
|
||||
from frappe.utils import flt
|
||||
|
||||
from erpnext import get_company_currency
|
||||
from erpnext.accounts.utils import get_balance_on
|
||||
from erpnext.accounts.report.bank_reconciliation_statement.bank_reconciliation_statement import get_entries, get_amounts_not_reflected_in_system
|
||||
from erpnext.accounts.doctype.bank_transaction.bank_transaction import get_paid_amount
|
||||
|
||||
|
||||
class BankReconciliationTool(Document):
|
||||
pass
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_bank_transactions(bank_account, from_date = None, to_date = None):
|
||||
# returns bank transactions for a bank account
|
||||
filters = []
|
||||
filters.append(['bank_account', '=', bank_account])
|
||||
filters.append(['docstatus', '=', 1])
|
||||
filters.append(['unallocated_amount', '>', 0])
|
||||
if to_date:
|
||||
filters.append(['date', '<=', to_date])
|
||||
if from_date:
|
||||
filters.append(['date', '>=', from_date])
|
||||
transactions = frappe.get_all(
|
||||
'Bank Transaction',
|
||||
fields = ['date', 'deposit', 'withdrawal', 'currency',
|
||||
'description', 'name', 'bank_account', 'company',
|
||||
'unallocated_amount', 'reference_number', 'party_type', 'party'],
|
||||
filters = filters
|
||||
)
|
||||
return transactions
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_account_balance(bank_account, till_date):
|
||||
# returns account balance till the specified date
|
||||
account = frappe.db.get_value('Bank Account', bank_account, 'account')
|
||||
filters = frappe._dict({
|
||||
"account": account,
|
||||
"report_date": till_date,
|
||||
"include_pos_transactions": 1
|
||||
})
|
||||
data = get_entries(filters)
|
||||
|
||||
balance_as_per_system = get_balance_on(filters["account"], filters["report_date"])
|
||||
|
||||
total_debit, total_credit = 0,0
|
||||
for d in data:
|
||||
total_debit += flt(d.debit)
|
||||
total_credit += flt(d.credit)
|
||||
|
||||
amounts_not_reflected_in_system = get_amounts_not_reflected_in_system(filters)
|
||||
|
||||
bank_bal = flt(balance_as_per_system) - flt(total_debit) + flt(total_credit) \
|
||||
+ amounts_not_reflected_in_system
|
||||
|
||||
return bank_bal
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_bank_transaction(bank_transaction_name, reference_number, party_type=None, party=None):
|
||||
# updates bank transaction based on the new parameters provided by the user from Vouchers
|
||||
bank_transaction = frappe.get_doc("Bank Transaction", bank_transaction_name)
|
||||
bank_transaction.reference_number = reference_number
|
||||
bank_transaction.party_type = party_type
|
||||
bank_transaction.party = party
|
||||
bank_transaction.save()
|
||||
return frappe.db.get_all('Bank Transaction',
|
||||
filters={
|
||||
'name': bank_transaction_name
|
||||
},
|
||||
fields=['date', 'deposit', 'withdrawal', 'currency',
|
||||
'description', 'name', 'bank_account', 'company',
|
||||
'unallocated_amount', 'reference_number',
|
||||
'party_type', 'party'],
|
||||
)[0]
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def create_journal_entry_bts( bank_transaction_name, reference_number=None, reference_date=None, posting_date=None, entry_type=None,
|
||||
second_account=None, mode_of_payment=None, party_type=None, party=None, allow_edit=None):
|
||||
# Create a new journal entry based on the bank transaction
|
||||
bank_transaction = frappe.db.get_values(
|
||||
"Bank Transaction", bank_transaction_name,
|
||||
fieldname=["name", "deposit", "withdrawal", "bank_account"] ,
|
||||
as_dict=True
|
||||
)[0]
|
||||
company_account = frappe.get_value("Bank Account", bank_transaction.bank_account, "account")
|
||||
account_type = frappe.db.get_value("Account", second_account, "account_type")
|
||||
if account_type in ["Receivable", "Payable"]:
|
||||
if not (party_type and party):
|
||||
frappe.throw(_("Party Type and Party is required for Receivable / Payable account {0}").format( second_account))
|
||||
accounts = []
|
||||
# Multi Currency?
|
||||
accounts.append({
|
||||
"account": second_account,
|
||||
"credit_in_account_currency": bank_transaction.deposit
|
||||
if bank_transaction.deposit > 0
|
||||
else 0,
|
||||
"debit_in_account_currency":bank_transaction.withdrawal
|
||||
if bank_transaction.withdrawal > 0
|
||||
else 0,
|
||||
"party_type":party_type,
|
||||
"party":party,
|
||||
})
|
||||
|
||||
accounts.append({
|
||||
"account": company_account,
|
||||
"bank_account": bank_transaction.bank_account,
|
||||
"credit_in_account_currency": bank_transaction.withdrawal
|
||||
if bank_transaction.withdrawal > 0
|
||||
else 0,
|
||||
"debit_in_account_currency":bank_transaction.deposit
|
||||
if bank_transaction.deposit > 0
|
||||
else 0,
|
||||
})
|
||||
|
||||
company = frappe.get_value("Account", company_account, "company")
|
||||
|
||||
journal_entry_dict = {
|
||||
"voucher_type" : entry_type,
|
||||
"company" : company,
|
||||
"posting_date" : posting_date,
|
||||
"cheque_date" : reference_date,
|
||||
"cheque_no" : reference_number,
|
||||
"mode_of_payment" : mode_of_payment
|
||||
}
|
||||
journal_entry = frappe.new_doc('Journal Entry')
|
||||
journal_entry.update(journal_entry_dict)
|
||||
journal_entry.set("accounts", accounts)
|
||||
|
||||
|
||||
if allow_edit:
|
||||
return journal_entry
|
||||
|
||||
journal_entry.insert()
|
||||
journal_entry.submit()
|
||||
|
||||
if bank_transaction.deposit > 0:
|
||||
paid_amount = bank_transaction.deposit
|
||||
else:
|
||||
paid_amount = bank_transaction.withdrawal
|
||||
|
||||
vouchers = json.dumps([{
|
||||
"payment_doctype":"Journal Entry",
|
||||
"payment_name":journal_entry.name,
|
||||
"amount":paid_amount}])
|
||||
|
||||
return reconcile_vouchers(bank_transaction.name, vouchers)
|
||||
|
||||
@frappe.whitelist()
|
||||
def create_payment_entry_bts( bank_transaction_name, reference_number=None, reference_date=None, party_type=None, party=None, posting_date=None,
|
||||
mode_of_payment=None, project=None, cost_center=None, allow_edit=None):
|
||||
# Create a new payment entry based on the bank transaction
|
||||
bank_transaction = frappe.db.get_values(
|
||||
"Bank Transaction", bank_transaction_name,
|
||||
fieldname=["name", "unallocated_amount", "deposit", "bank_account"] ,
|
||||
as_dict=True
|
||||
)[0]
|
||||
paid_amount = bank_transaction.unallocated_amount
|
||||
payment_type = "Receive" if bank_transaction.deposit > 0 else "Pay"
|
||||
|
||||
company_account = frappe.get_value("Bank Account", bank_transaction.bank_account, "account")
|
||||
company = frappe.get_value("Account", company_account, "company")
|
||||
payment_entry_dict = {
|
||||
"company" : company,
|
||||
"payment_type" : payment_type,
|
||||
"reference_no" : reference_number,
|
||||
"reference_date" : reference_date,
|
||||
"party_type" : party_type,
|
||||
"party" : party,
|
||||
"posting_date" : posting_date,
|
||||
"paid_amount": paid_amount,
|
||||
"received_amount": paid_amount
|
||||
}
|
||||
payment_entry = frappe.new_doc("Payment Entry")
|
||||
|
||||
|
||||
payment_entry.update(payment_entry_dict)
|
||||
|
||||
if mode_of_payment:
|
||||
payment_entry.mode_of_payment = mode_of_payment
|
||||
if project:
|
||||
payment_entry.project = project
|
||||
if cost_center:
|
||||
payment_entry.cost_center = cost_center
|
||||
if payment_type == "Receive":
|
||||
payment_entry.paid_to = company_account
|
||||
else:
|
||||
payment_entry.paid_from = company_account
|
||||
|
||||
payment_entry.validate()
|
||||
|
||||
if allow_edit:
|
||||
return payment_entry
|
||||
|
||||
payment_entry.insert()
|
||||
|
||||
payment_entry.submit()
|
||||
vouchers = json.dumps([{
|
||||
"payment_doctype":"Payment Entry",
|
||||
"payment_name":payment_entry.name,
|
||||
"amount":paid_amount}])
|
||||
return reconcile_vouchers(bank_transaction.name, vouchers)
|
||||
|
||||
@frappe.whitelist()
|
||||
def reconcile_vouchers(bank_transaction_name, vouchers):
|
||||
# updated clear date of all the vouchers based on the bank transaction
|
||||
vouchers = json.loads(vouchers)
|
||||
transaction = frappe.get_doc("Bank Transaction", bank_transaction_name)
|
||||
if transaction.unallocated_amount == 0:
|
||||
frappe.throw(_("This bank transaction is already fully reconciled"))
|
||||
total_amount = 0
|
||||
for voucher in vouchers:
|
||||
voucher['payment_entry'] = frappe.get_doc(voucher['payment_doctype'], voucher['payment_name'])
|
||||
total_amount += get_paid_amount(frappe._dict({
|
||||
'payment_document': voucher['payment_doctype'],
|
||||
'payment_entry': voucher['payment_name'],
|
||||
}), transaction.currency)
|
||||
|
||||
if total_amount > transaction.unallocated_amount:
|
||||
frappe.throw(_("The Sum Total of Amounts of All Selected Vouchers Should be Less than the Unallocated Amount of the Bank Transaction"))
|
||||
account = frappe.db.get_value("Bank Account", transaction.bank_account, "account")
|
||||
|
||||
for voucher in vouchers:
|
||||
gl_entry = frappe.db.get_value("GL Entry", dict(account=account, voucher_type=voucher['payment_doctype'], voucher_no=voucher['payment_name']), ['credit', 'debit'], as_dict=1)
|
||||
gl_amount, transaction_amount = (gl_entry.credit, transaction.deposit) if gl_entry.credit > 0 else (gl_entry.debit, transaction.withdrawal)
|
||||
allocated_amount = gl_amount if gl_amount >= transaction_amount else transaction_amount
|
||||
|
||||
transaction.append("payment_entries", {
|
||||
"payment_document": voucher['payment_entry'].doctype,
|
||||
"payment_entry": voucher['payment_entry'].name,
|
||||
"allocated_amount": allocated_amount
|
||||
})
|
||||
|
||||
transaction.save()
|
||||
transaction.update_allocations()
|
||||
return frappe.get_doc("Bank Transaction", bank_transaction_name)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_linked_payments(bank_transaction_name, document_types = None):
|
||||
# get all matching payments for a bank transaction
|
||||
transaction = frappe.get_doc("Bank Transaction", bank_transaction_name)
|
||||
bank_account = frappe.db.get_values(
|
||||
"Bank Account",
|
||||
transaction.bank_account,
|
||||
["account", "company"],
|
||||
as_dict=True)[0]
|
||||
(account, company) = (bank_account.account, bank_account.company)
|
||||
matching = check_matching(account, company, transaction, document_types)
|
||||
return matching
|
||||
|
||||
def check_matching(bank_account, company, transaction, document_types):
|
||||
# combine all types of vocuhers
|
||||
subquery = get_queries(bank_account, company, transaction, document_types)
|
||||
filters = {
|
||||
"amount": transaction.unallocated_amount,
|
||||
"payment_type" : "Receive" if transaction.deposit > 0 else "Pay",
|
||||
"reference_no": transaction.reference_number,
|
||||
"party_type": transaction.party_type,
|
||||
"party": transaction.party,
|
||||
"bank_account": bank_account
|
||||
}
|
||||
|
||||
matching_vouchers = []
|
||||
for query in subquery:
|
||||
matching_vouchers.extend(
|
||||
frappe.db.sql(query, filters,)
|
||||
)
|
||||
|
||||
return sorted(matching_vouchers, key = lambda x: x[0], reverse=True) if matching_vouchers else []
|
||||
|
||||
def get_queries(bank_account, company, transaction, document_types):
|
||||
# get queries to get matching vouchers
|
||||
amount_condition = "=" if "exact_match" in document_types else "<="
|
||||
account_from_to = "paid_to" if transaction.deposit > 0 else "paid_from"
|
||||
queries = []
|
||||
|
||||
if "payment_entry" in document_types:
|
||||
pe_amount_matching = get_pe_matching_query(amount_condition, account_from_to, transaction)
|
||||
queries.extend([pe_amount_matching])
|
||||
|
||||
if "journal_entry" in document_types:
|
||||
je_amount_matching = get_je_matching_query(amount_condition, transaction)
|
||||
queries.extend([je_amount_matching])
|
||||
|
||||
if transaction.deposit > 0 and "sales_invoice" in document_types:
|
||||
si_amount_matching = get_si_matching_query(amount_condition)
|
||||
queries.extend([si_amount_matching])
|
||||
|
||||
if transaction.withdrawal > 0:
|
||||
if "purchase_invoice" in document_types:
|
||||
pi_amount_matching = get_pi_matching_query(amount_condition)
|
||||
queries.extend([pi_amount_matching])
|
||||
|
||||
if "expense_claim" in document_types:
|
||||
ec_amount_matching = get_ec_matching_query(bank_account, company, amount_condition)
|
||||
queries.extend([ec_amount_matching])
|
||||
|
||||
return queries
|
||||
|
||||
def get_pe_matching_query(amount_condition, account_from_to, transaction):
|
||||
# get matching payment entries query
|
||||
if transaction.deposit > 0:
|
||||
currency_field = "paid_to_account_currency as currency"
|
||||
else:
|
||||
currency_field = "paid_from_account_currency as currency"
|
||||
return f"""
|
||||
SELECT
|
||||
(CASE WHEN reference_no=%(reference_no)s THEN 1 ELSE 0 END
|
||||
+ CASE WHEN (party_type = %(party_type)s AND party = %(party)s ) THEN 1 ELSE 0 END
|
||||
+ 1 ) AS rank,
|
||||
'Payment Entry' as doctype,
|
||||
name,
|
||||
paid_amount,
|
||||
reference_no,
|
||||
reference_date,
|
||||
party,
|
||||
party_type,
|
||||
posting_date,
|
||||
{currency_field}
|
||||
FROM
|
||||
`tabPayment Entry`
|
||||
WHERE
|
||||
paid_amount {amount_condition} %(amount)s
|
||||
AND docstatus = 1
|
||||
AND payment_type IN (%(payment_type)s, 'Internal Transfer')
|
||||
AND ifnull(clearance_date, '') = ""
|
||||
AND {account_from_to} = %(bank_account)s
|
||||
"""
|
||||
|
||||
|
||||
def get_je_matching_query(amount_condition, transaction):
|
||||
# get matching journal entry query
|
||||
cr_or_dr = "credit" if transaction.withdrawal > 0 else "debit"
|
||||
return f"""
|
||||
|
||||
SELECT
|
||||
(CASE WHEN je.cheque_no=%(reference_no)s THEN 1 ELSE 0 END
|
||||
+ 1) AS rank ,
|
||||
'Journal Entry' as doctype,
|
||||
je.name,
|
||||
jea.{cr_or_dr}_in_account_currency as paid_amount,
|
||||
je.cheque_no as reference_no,
|
||||
je.cheque_date as reference_date,
|
||||
je.pay_to_recd_from as party,
|
||||
jea.party_type,
|
||||
je.posting_date,
|
||||
jea.account_currency as currency
|
||||
FROM
|
||||
`tabJournal Entry Account` as jea
|
||||
JOIN
|
||||
`tabJournal Entry` as je
|
||||
ON
|
||||
jea.parent = je.name
|
||||
WHERE
|
||||
(je.clearance_date is null or je.clearance_date='0000-00-00')
|
||||
AND jea.account = %(bank_account)s
|
||||
AND jea.{cr_or_dr}_in_account_currency {amount_condition} %(amount)s
|
||||
AND je.docstatus = 1
|
||||
"""
|
||||
|
||||
|
||||
def get_si_matching_query(amount_condition):
|
||||
# get matchin sales invoice query
|
||||
return f"""
|
||||
SELECT
|
||||
( CASE WHEN si.customer = %(party)s THEN 1 ELSE 0 END
|
||||
+ 1 ) AS rank,
|
||||
'Sales Invoice' as doctype,
|
||||
si.name,
|
||||
sip.amount as paid_amount,
|
||||
'' as reference_no,
|
||||
'' as reference_date,
|
||||
si.customer as party,
|
||||
'Customer' as party_type,
|
||||
si.posting_date,
|
||||
si.currency
|
||||
|
||||
FROM
|
||||
`tabSales Invoice Payment` as sip
|
||||
JOIN
|
||||
`tabSales Invoice` as si
|
||||
ON
|
||||
sip.parent = si.name
|
||||
WHERE (sip.clearance_date is null or sip.clearance_date='0000-00-00')
|
||||
AND sip.account = %(bank_account)s
|
||||
AND sip.amount {amount_condition} %(amount)s
|
||||
AND si.docstatus = 1
|
||||
"""
|
||||
|
||||
def get_pi_matching_query(amount_condition):
|
||||
# get matching purchase invoice query
|
||||
return f"""
|
||||
SELECT
|
||||
( CASE WHEN supplier = %(party)s THEN 1 ELSE 0 END
|
||||
+ 1 ) AS rank,
|
||||
'Purchase Invoice' as doctype,
|
||||
name,
|
||||
paid_amount,
|
||||
'' as reference_no,
|
||||
'' as reference_date,
|
||||
supplier as party,
|
||||
'Supplier' as party_type,
|
||||
posting_date,
|
||||
currency
|
||||
FROM
|
||||
`tabPurchase Invoice`
|
||||
WHERE
|
||||
paid_amount {amount_condition} %(amount)s
|
||||
AND docstatus = 1
|
||||
AND is_paid = 1
|
||||
AND ifnull(clearance_date, '') = ""
|
||||
AND cash_bank_account = %(bank_account)s
|
||||
"""
|
||||
|
||||
def get_ec_matching_query(bank_account, company, amount_condition):
|
||||
# get matching Expense Claim query
|
||||
mode_of_payments = [x["parent"] for x in frappe.db.get_list("Mode of Payment Account",
|
||||
filters={"default_account": bank_account}, fields=["parent"])]
|
||||
mode_of_payments = '(\'' + '\', \''.join(mode_of_payments) + '\' )'
|
||||
company_currency = get_company_currency(company)
|
||||
return f"""
|
||||
SELECT
|
||||
( CASE WHEN employee = %(party)s THEN 1 ELSE 0 END
|
||||
+ 1 ) AS rank,
|
||||
'Expense Claim' as doctype,
|
||||
name,
|
||||
total_sanctioned_amount as paid_amount,
|
||||
'' as reference_no,
|
||||
'' as reference_date,
|
||||
employee as party,
|
||||
'Employee' as party_type,
|
||||
posting_date,
|
||||
'{company_currency}' as currency
|
||||
FROM
|
||||
`tabExpense Claim`
|
||||
WHERE
|
||||
total_sanctioned_amount {amount_condition} %(amount)s
|
||||
AND docstatus = 1
|
||||
AND is_paid = 1
|
||||
AND ifnull(clearance_date, '') = ""
|
||||
AND mode_of_payment in {mode_of_payments}
|
||||
"""
|
||||
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
class TestBankReconciliationTool(unittest.TestCase):
|
||||
pass
|
||||
3
erpnext/accounts/doctype/bank_statement_import/bank_statement_import.css
vendored
Normal file
3
erpnext/accounts/doctype/bank_statement_import/bank_statement_import.css
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.warnings .warning {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
@@ -0,0 +1,574 @@
|
||||
// Copyright (c) 2019, Frappe Technologies and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on("Bank Statement Import", {
|
||||
setup(frm) {
|
||||
frappe.realtime.on("data_import_refresh", ({ data_import }) => {
|
||||
frm.import_in_progress = false;
|
||||
if (data_import !== frm.doc.name) return;
|
||||
frappe.model.clear_doc("Bank Statement Import", frm.doc.name);
|
||||
frappe.model
|
||||
.with_doc("Bank Statement Import", frm.doc.name)
|
||||
.then(() => {
|
||||
frm.refresh();
|
||||
});
|
||||
});
|
||||
frappe.realtime.on("data_import_progress", (data) => {
|
||||
frm.import_in_progress = true;
|
||||
if (data.data_import !== frm.doc.name) {
|
||||
return;
|
||||
}
|
||||
let percent = Math.floor((data.current * 100) / data.total);
|
||||
let seconds = Math.floor(data.eta);
|
||||
let minutes = Math.floor(data.eta / 60);
|
||||
let eta_message =
|
||||
// prettier-ignore
|
||||
seconds < 60
|
||||
? __('About {0} seconds remaining', [seconds])
|
||||
: minutes === 1
|
||||
? __('About {0} minute remaining', [minutes])
|
||||
: __('About {0} minutes remaining', [minutes]);
|
||||
|
||||
let message;
|
||||
if (data.success) {
|
||||
let message_args = [data.current, data.total, eta_message];
|
||||
message =
|
||||
frm.doc.import_type === "Insert New Records"
|
||||
? __("Importing {0} of {1}, {2}", message_args)
|
||||
: __("Updating {0} of {1}, {2}", message_args);
|
||||
}
|
||||
if (data.skipping) {
|
||||
message = __(
|
||||
"Skipping {0} of {1}, {2}",
|
||||
[
|
||||
data.current,
|
||||
data.total,
|
||||
eta_message,
|
||||
]
|
||||
);
|
||||
}
|
||||
frm.dashboard.show_progress(
|
||||
__("Import Progress"),
|
||||
percent,
|
||||
message
|
||||
);
|
||||
frm.page.set_indicator(__("In Progress"), "orange");
|
||||
|
||||
// hide progress when complete
|
||||
if (data.current === data.total) {
|
||||
setTimeout(() => {
|
||||
frm.dashboard.hide();
|
||||
frm.refresh();
|
||||
}, 2000);
|
||||
}
|
||||
});
|
||||
|
||||
frm.set_query("reference_doctype", () => {
|
||||
return {
|
||||
filters: {
|
||||
name: ["in", frappe.boot.user.can_import],
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
frm.get_field("import_file").df.options = {
|
||||
restrictions: {
|
||||
allowed_file_types: [".csv", ".xls", ".xlsx"],
|
||||
},
|
||||
};
|
||||
|
||||
frm.has_import_file = () => {
|
||||
return frm.doc.import_file || frm.doc.google_sheets_url;
|
||||
};
|
||||
},
|
||||
|
||||
refresh(frm) {
|
||||
frm.page.hide_icon_group();
|
||||
frm.trigger("update_indicators");
|
||||
frm.trigger("import_file");
|
||||
frm.trigger("show_import_log");
|
||||
frm.trigger("show_import_warnings");
|
||||
frm.trigger("toggle_submit_after_import");
|
||||
frm.trigger("show_import_status");
|
||||
frm.trigger("show_report_error_button");
|
||||
|
||||
if (frm.doc.status === "Partial Success") {
|
||||
frm.add_custom_button(__("Export Errored Rows"), () =>
|
||||
frm.trigger("export_errored_rows")
|
||||
);
|
||||
}
|
||||
|
||||
if (frm.doc.status.includes("Success")) {
|
||||
frm.add_custom_button(
|
||||
__("Go to {0} List", [frm.doc.reference_doctype]),
|
||||
() => frappe.set_route("List", frm.doc.reference_doctype)
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
onload_post_render(frm) {
|
||||
frm.trigger("update_primary_action");
|
||||
},
|
||||
|
||||
update_primary_action(frm) {
|
||||
if (frm.is_dirty()) {
|
||||
frm.enable_save();
|
||||
return;
|
||||
}
|
||||
frm.disable_save();
|
||||
if (frm.doc.status !== "Success") {
|
||||
if (!frm.is_new() && frm.has_import_file()) {
|
||||
let label =
|
||||
frm.doc.status === "Pending"
|
||||
? __("Start Import")
|
||||
: __("Retry");
|
||||
frm.page.set_primary_action(label, () =>
|
||||
frm.events.start_import(frm)
|
||||
);
|
||||
} else {
|
||||
frm.page.set_primary_action(__("Save"), () => frm.save());
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
update_indicators(frm) {
|
||||
const indicator = frappe.get_indicator(frm.doc);
|
||||
if (indicator) {
|
||||
frm.page.set_indicator(indicator[0], indicator[1]);
|
||||
} else {
|
||||
frm.page.clear_indicator();
|
||||
}
|
||||
},
|
||||
|
||||
show_import_status(frm) {
|
||||
let import_log = JSON.parse(frm.doc.import_log || "[]");
|
||||
let successful_records = import_log.filter((log) => log.success);
|
||||
let failed_records = import_log.filter((log) => !log.success);
|
||||
if (successful_records.length === 0) return;
|
||||
|
||||
let message;
|
||||
if (failed_records.length === 0) {
|
||||
let message_args = [successful_records.length];
|
||||
if (frm.doc.import_type === "Insert New Records") {
|
||||
message =
|
||||
successful_records.length > 1
|
||||
? __("Successfully imported {0} records.", message_args)
|
||||
: __("Successfully imported {0} record.", message_args);
|
||||
} else {
|
||||
message =
|
||||
successful_records.length > 1
|
||||
? __("Successfully updated {0} records.", message_args)
|
||||
: __("Successfully updated {0} record.", message_args);
|
||||
}
|
||||
} else {
|
||||
let message_args = [successful_records.length, import_log.length];
|
||||
if (frm.doc.import_type === "Insert New Records") {
|
||||
message =
|
||||
successful_records.length > 1
|
||||
? __(
|
||||
"Successfully imported {0} records out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
||||
message_args
|
||||
)
|
||||
: __(
|
||||
"Successfully imported {0} record out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
||||
message_args
|
||||
);
|
||||
} else {
|
||||
message =
|
||||
successful_records.length > 1
|
||||
? __(
|
||||
"Successfully updated {0} records out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
||||
message_args
|
||||
)
|
||||
: __(
|
||||
"Successfully updated {0} record out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
||||
message_args
|
||||
);
|
||||
}
|
||||
}
|
||||
frm.dashboard.set_headline(message);
|
||||
},
|
||||
|
||||
show_report_error_button(frm) {
|
||||
if (frm.doc.status === "Error") {
|
||||
frappe.db
|
||||
.get_list("Error Log", {
|
||||
filters: { method: frm.doc.name },
|
||||
fields: ["method", "error"],
|
||||
order_by: "creation desc",
|
||||
limit: 1,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result.length > 0) {
|
||||
frm.add_custom_button("Report Error", () => {
|
||||
let fake_xhr = {
|
||||
responseText: JSON.stringify({
|
||||
exc: result[0].error,
|
||||
}),
|
||||
};
|
||||
frappe.request.report_error(fake_xhr, {});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
start_import(frm) {
|
||||
frm.call({
|
||||
method: "form_start_import",
|
||||
args: { data_import: frm.doc.name },
|
||||
btn: frm.page.btn_primary,
|
||||
}).then((r) => {
|
||||
if (r.message === true) {
|
||||
frm.disable_save();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
download_template() {
|
||||
let method =
|
||||
"/api/method/frappe.core.doctype.data_import.data_import.download_template";
|
||||
|
||||
open_url_post(method, {
|
||||
doctype: "Bank Transaction",
|
||||
export_records: "5_records",
|
||||
export_fields: {
|
||||
"Bank Transaction": [
|
||||
"date",
|
||||
"deposit",
|
||||
"withdrawal",
|
||||
"description",
|
||||
"reference_number",
|
||||
],
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
reference_doctype(frm) {
|
||||
frm.trigger("toggle_submit_after_import");
|
||||
},
|
||||
|
||||
toggle_submit_after_import(frm) {
|
||||
frm.toggle_display("submit_after_import", false);
|
||||
let doctype = frm.doc.reference_doctype;
|
||||
if (doctype) {
|
||||
frappe.model.with_doctype(doctype, () => {
|
||||
let meta = frappe.get_meta(doctype);
|
||||
frm.toggle_display("submit_after_import", meta.is_submittable);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
google_sheets_url(frm) {
|
||||
if (!frm.is_dirty()) {
|
||||
frm.trigger("import_file");
|
||||
} else {
|
||||
frm.trigger("update_primary_action");
|
||||
}
|
||||
},
|
||||
|
||||
refresh_google_sheet(frm) {
|
||||
frm.trigger("import_file");
|
||||
},
|
||||
|
||||
import_file(frm) {
|
||||
frm.toggle_display("section_import_preview", frm.has_import_file());
|
||||
if (!frm.has_import_file()) {
|
||||
frm.get_field("import_preview").$wrapper.empty();
|
||||
return;
|
||||
} else {
|
||||
frm.trigger("update_primary_action");
|
||||
}
|
||||
|
||||
// load import preview
|
||||
frm.get_field("import_preview").$wrapper.empty();
|
||||
$('<span class="text-muted">')
|
||||
.html(__("Loading import file..."))
|
||||
.appendTo(frm.get_field("import_preview").$wrapper);
|
||||
|
||||
frm.call({
|
||||
method: "get_preview_from_template",
|
||||
args: {
|
||||
data_import: frm.doc.name,
|
||||
import_file: frm.doc.import_file,
|
||||
google_sheets_url: frm.doc.google_sheets_url,
|
||||
},
|
||||
error_handlers: {
|
||||
TimestampMismatchError() {
|
||||
// ignore this error
|
||||
},
|
||||
},
|
||||
}).then((r) => {
|
||||
let preview_data = r.message;
|
||||
frm.events.show_import_preview(frm, preview_data);
|
||||
frm.events.show_import_warnings(frm, preview_data);
|
||||
});
|
||||
},
|
||||
// method: 'frappe.core.doctype.data_import.data_import.get_preview_from_template',
|
||||
|
||||
show_import_preview(frm, preview_data) {
|
||||
let import_log = JSON.parse(frm.doc.import_log || "[]");
|
||||
|
||||
if (
|
||||
frm.import_preview &&
|
||||
frm.import_preview.doctype === frm.doc.reference_doctype
|
||||
) {
|
||||
frm.import_preview.preview_data = preview_data;
|
||||
frm.import_preview.import_log = import_log;
|
||||
frm.import_preview.refresh();
|
||||
return;
|
||||
}
|
||||
|
||||
frappe.require("/assets/js/data_import_tools.min.js", () => {
|
||||
frm.import_preview = new frappe.data_import.ImportPreview({
|
||||
wrapper: frm.get_field("import_preview").$wrapper,
|
||||
doctype: frm.doc.reference_doctype,
|
||||
preview_data,
|
||||
import_log,
|
||||
frm,
|
||||
events: {
|
||||
remap_column(changed_map) {
|
||||
let template_options = JSON.parse(
|
||||
frm.doc.template_options || "{}"
|
||||
);
|
||||
template_options.column_to_field_map =
|
||||
template_options.column_to_field_map || {};
|
||||
Object.assign(
|
||||
template_options.column_to_field_map,
|
||||
changed_map
|
||||
);
|
||||
frm.set_value(
|
||||
"template_options",
|
||||
JSON.stringify(template_options)
|
||||
);
|
||||
frm.save().then(() => frm.trigger("import_file"));
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
export_errored_rows(frm) {
|
||||
open_url_post(
|
||||
"/api/method/frappe.core.doctype.data_import.data_import.download_errored_template",
|
||||
{
|
||||
data_import_name: frm.doc.name,
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
show_import_warnings(frm, preview_data) {
|
||||
let columns = preview_data.columns;
|
||||
let warnings = JSON.parse(frm.doc.template_warnings || "[]");
|
||||
warnings = warnings.concat(preview_data.warnings || []);
|
||||
|
||||
frm.toggle_display("import_warnings_section", warnings.length > 0);
|
||||
if (warnings.length === 0) {
|
||||
frm.get_field("import_warnings").$wrapper.html("");
|
||||
return;
|
||||
}
|
||||
|
||||
// group warnings by row
|
||||
let warnings_by_row = {};
|
||||
let other_warnings = [];
|
||||
for (let warning of warnings) {
|
||||
if (warning.row) {
|
||||
warnings_by_row[warning.row] =
|
||||
warnings_by_row[warning.row] || [];
|
||||
warnings_by_row[warning.row].push(warning);
|
||||
} else {
|
||||
other_warnings.push(warning);
|
||||
}
|
||||
}
|
||||
|
||||
let html = "";
|
||||
html += Object.keys(warnings_by_row)
|
||||
.map((row_number) => {
|
||||
let message = warnings_by_row[row_number]
|
||||
.map((w) => {
|
||||
if (w.field) {
|
||||
let label =
|
||||
w.field.label +
|
||||
(w.field.parent !== frm.doc.reference_doctype
|
||||
? ` (${w.field.parent})`
|
||||
: "");
|
||||
return `<li>${label}: ${w.message}</li>`;
|
||||
}
|
||||
return `<li>${w.message}</li>`;
|
||||
})
|
||||
.join("");
|
||||
return `
|
||||
<div class="warning" data-row="${row_number}">
|
||||
<h5 class="text-uppercase">${__("Row {0}", [row_number])}</h5>
|
||||
<div class="body"><ul>${message}</ul></div>
|
||||
</div>
|
||||
`;
|
||||
})
|
||||
.join("");
|
||||
|
||||
html += other_warnings
|
||||
.map((warning) => {
|
||||
let header = "";
|
||||
if (warning.col) {
|
||||
let column_number = `<span class="text-uppercase">${__(
|
||||
"Column {0}",
|
||||
[warning.col]
|
||||
)}</span>`;
|
||||
let column_header = columns[warning.col].header_title;
|
||||
header = `${column_number} (${column_header})`;
|
||||
}
|
||||
return `
|
||||
<div class="warning" data-col="${warning.col}">
|
||||
<h5>${header}</h5>
|
||||
<div class="body">${warning.message}</div>
|
||||
</div>
|
||||
`;
|
||||
})
|
||||
.join("");
|
||||
frm.get_field("import_warnings").$wrapper.html(`
|
||||
<div class="row">
|
||||
<div class="col-sm-10 warnings">${html}</div>
|
||||
</div>
|
||||
`);
|
||||
},
|
||||
|
||||
show_failed_logs(frm) {
|
||||
frm.trigger("show_import_log");
|
||||
},
|
||||
|
||||
show_import_log(frm) {
|
||||
let import_log = JSON.parse(frm.doc.import_log || "[]");
|
||||
let logs = import_log;
|
||||
frm.toggle_display("import_log", false);
|
||||
frm.toggle_display("import_log_section", logs.length > 0);
|
||||
|
||||
if (logs.length === 0) {
|
||||
frm.get_field("import_log_preview").$wrapper.empty();
|
||||
return;
|
||||
}
|
||||
|
||||
let rows = logs
|
||||
.map((log) => {
|
||||
let html = "";
|
||||
if (log.success) {
|
||||
if (frm.doc.import_type === "Insert New Records") {
|
||||
html = __(
|
||||
"Successfully imported {0}", [
|
||||
`<span class="underline">${frappe.utils.get_form_link(
|
||||
frm.doc.reference_doctype,
|
||||
log.docname,
|
||||
true
|
||||
)}<span>`,
|
||||
]
|
||||
);
|
||||
} else {
|
||||
html = __(
|
||||
"Successfully updated {0}", [
|
||||
`<span class="underline">${frappe.utils.get_form_link(
|
||||
frm.doc.reference_doctype,
|
||||
log.docname,
|
||||
true
|
||||
)}<span>`,
|
||||
]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
let messages = log.messages
|
||||
.map(JSON.parse)
|
||||
.map((m) => {
|
||||
let title = m.title
|
||||
? `<strong>${m.title}</strong>`
|
||||
: "";
|
||||
let message = m.message
|
||||
? `<div>${m.message}</div>`
|
||||
: "";
|
||||
return title + message;
|
||||
})
|
||||
.join("");
|
||||
let id = frappe.dom.get_unique_id();
|
||||
html = `${messages}
|
||||
<button class="btn btn-default btn-xs" type="button" data-toggle="collapse" data-target="#${id}" aria-expanded="false" aria-controls="${id}" style="margin-top: 15px;">
|
||||
${__("Show Traceback")}
|
||||
</button>
|
||||
<div class="collapse" id="${id}" style="margin-top: 15px;">
|
||||
<div class="well">
|
||||
<pre>${log.exception}</pre>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
let indicator_color = log.success ? "green" : "red";
|
||||
let title = log.success ? __("Success") : __("Failure");
|
||||
|
||||
if (frm.doc.show_failed_logs && log.success) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return `<tr>
|
||||
<td>${log.row_indexes.join(", ")}</td>
|
||||
<td>
|
||||
<div class="indicator ${indicator_color}">${title}</div>
|
||||
</td>
|
||||
<td>
|
||||
${html}
|
||||
</td>
|
||||
</tr>`;
|
||||
})
|
||||
.join("");
|
||||
|
||||
if (!rows && frm.doc.show_failed_logs) {
|
||||
rows = `<tr><td class="text-center text-muted" colspan=3>
|
||||
${__("No failed logs")}
|
||||
</td></tr>`;
|
||||
}
|
||||
|
||||
frm.get_field("import_log_preview").$wrapper.html(`
|
||||
<table class="table table-bordered">
|
||||
<tr class="text-muted">
|
||||
<th width="10%">${__("Row Number")}</th>
|
||||
<th width="10%">${__("Status")}</th>
|
||||
<th width="80%">${__("Message")}</th>
|
||||
</tr>
|
||||
${rows}
|
||||
</table>
|
||||
`);
|
||||
},
|
||||
|
||||
show_missing_link_values(frm, missing_link_values) {
|
||||
let can_be_created_automatically = missing_link_values.every(
|
||||
(d) => d.has_one_mandatory_field
|
||||
);
|
||||
|
||||
let html = missing_link_values
|
||||
.map((d) => {
|
||||
let doctype = d.doctype;
|
||||
let values = d.missing_values;
|
||||
return `
|
||||
<h5>${doctype}</h5>
|
||||
<ul>${values.map((v) => `<li>${v}</li>`).join("")}</ul>
|
||||
`;
|
||||
})
|
||||
.join("");
|
||||
|
||||
if (can_be_created_automatically) {
|
||||
// prettier-ignore
|
||||
let message = __('There are some linked records which needs to be created before we can import your file. Do you want to create the following missing records automatically?');
|
||||
frappe.confirm(message + html, () => {
|
||||
frm.call("create_missing_link_values", {
|
||||
missing_link_values,
|
||||
}).then((r) => {
|
||||
let records = r.message;
|
||||
frappe.msgprint(__(
|
||||
"Created {0} records successfully.", [
|
||||
records.length,
|
||||
]
|
||||
));
|
||||
});
|
||||
});
|
||||
} else {
|
||||
frappe.msgprint(
|
||||
// prettier-ignore
|
||||
__('The following records needs to be created before we can import your file.') + html
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,227 @@
|
||||
{
|
||||
"actions": [],
|
||||
"autoname": "format:Bank Statement Import on {creation}",
|
||||
"beta": 1,
|
||||
"creation": "2019-08-04 14:16:08.318714",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"company",
|
||||
"bank_account",
|
||||
"bank",
|
||||
"column_break_4",
|
||||
"google_sheets_url",
|
||||
"refresh_google_sheet",
|
||||
"html_5",
|
||||
"import_file",
|
||||
"download_template",
|
||||
"status",
|
||||
"template_options",
|
||||
"import_warnings_section",
|
||||
"template_warnings",
|
||||
"import_warnings",
|
||||
"section_import_preview",
|
||||
"import_preview",
|
||||
"import_log_section",
|
||||
"import_log",
|
||||
"show_failed_logs",
|
||||
"import_log_preview",
|
||||
"reference_doctype",
|
||||
"import_type",
|
||||
"submit_after_import",
|
||||
"mute_emails"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"options": "Company",
|
||||
"reqd": 1,
|
||||
"set_only_once": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "bank_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Bank Account",
|
||||
"options": "Bank Account",
|
||||
"reqd": 1,
|
||||
"set_only_once": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.bank_account",
|
||||
"fetch_from": "bank_account.bank",
|
||||
"fieldname": "bank",
|
||||
"fieldtype": "Link",
|
||||
"label": "Bank",
|
||||
"options": "Bank",
|
||||
"read_only": 1,
|
||||
"set_only_once": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:!doc.__islocal",
|
||||
"fieldname": "download_template",
|
||||
"fieldtype": "Button",
|
||||
"label": "Download Template"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:!doc.__islocal",
|
||||
"fieldname": "import_file",
|
||||
"fieldtype": "Attach",
|
||||
"in_list_view": 1,
|
||||
"label": "Import File"
|
||||
},
|
||||
{
|
||||
"fieldname": "import_preview",
|
||||
"fieldtype": "HTML",
|
||||
"label": "Import Preview"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_import_preview",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Preview"
|
||||
},
|
||||
{
|
||||
"fieldname": "template_options",
|
||||
"fieldtype": "Code",
|
||||
"hidden": 1,
|
||||
"label": "Template Options",
|
||||
"options": "JSON",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "import_log",
|
||||
"fieldtype": "Code",
|
||||
"label": "Import Log",
|
||||
"options": "JSON"
|
||||
},
|
||||
{
|
||||
"fieldname": "import_log_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Import Log"
|
||||
},
|
||||
{
|
||||
"fieldname": "import_log_preview",
|
||||
"fieldtype": "HTML",
|
||||
"label": "Import Log Preview"
|
||||
},
|
||||
{
|
||||
"default": "Pending",
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 1,
|
||||
"label": "Status",
|
||||
"options": "Pending\nSuccess\nPartial Success\nError",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "template_warnings",
|
||||
"fieldtype": "Code",
|
||||
"hidden": 1,
|
||||
"label": "Template Warnings",
|
||||
"options": "JSON"
|
||||
},
|
||||
{
|
||||
"fieldname": "import_warnings_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Import File Errors and Warnings"
|
||||
},
|
||||
{
|
||||
"fieldname": "import_warnings",
|
||||
"fieldtype": "HTML",
|
||||
"label": "Import Warnings"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "show_failed_logs",
|
||||
"fieldtype": "Check",
|
||||
"label": "Show Failed Logs"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:!doc.__islocal && !doc.import_file",
|
||||
"fieldname": "html_5",
|
||||
"fieldtype": "HTML",
|
||||
"options": "<h5 class=\"text-muted uppercase\">Or</h5>"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:!doc.__islocal && !doc.import_file\n",
|
||||
"description": "Must be a publicly accessible Google Sheets URL",
|
||||
"fieldname": "google_sheets_url",
|
||||
"fieldtype": "Data",
|
||||
"label": "Import from Google Sheets"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.google_sheets_url && !doc.__unsaved",
|
||||
"fieldname": "refresh_google_sheet",
|
||||
"fieldtype": "Button",
|
||||
"label": "Refresh Google Sheet"
|
||||
},
|
||||
{
|
||||
"default": "Bank Transaction",
|
||||
"fieldname": "reference_doctype",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Document Type",
|
||||
"options": "DocType",
|
||||
"reqd": 1,
|
||||
"set_only_once": 1
|
||||
},
|
||||
{
|
||||
"default": "Insert New Records",
|
||||
"fieldname": "import_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Import Type",
|
||||
"options": "\nInsert New Records\nUpdate Existing Records",
|
||||
"reqd": 1,
|
||||
"set_only_once": 1
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "submit_after_import",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 1,
|
||||
"label": "Submit After Import",
|
||||
"set_only_once": 1
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "mute_emails",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 1,
|
||||
"label": "Don't Send Emails",
|
||||
"set_only_once": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_4",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"hide_toolbar": 1,
|
||||
"links": [],
|
||||
"modified": "2021-02-10 19:29:59.027325",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Statement Import",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2019, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import csv
|
||||
import json
|
||||
import re
|
||||
|
||||
import openpyxl
|
||||
from openpyxl.styles import Font
|
||||
from openpyxl.utils import get_column_letter
|
||||
from six import string_types
|
||||
|
||||
import frappe
|
||||
from frappe.core.doctype.data_import.importer import Importer, ImportFile
|
||||
from frappe.utils.background_jobs import enqueue
|
||||
from frappe.utils.xlsxutils import handle_html, ILLEGAL_CHARACTERS_RE
|
||||
from frappe import _
|
||||
|
||||
from frappe.core.doctype.data_import.data_import import DataImport
|
||||
|
||||
class BankStatementImport(DataImport):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(BankStatementImport, self).__init__(*args, **kwargs)
|
||||
|
||||
def validate(self):
|
||||
doc_before_save = self.get_doc_before_save()
|
||||
if (
|
||||
not (self.import_file or self.google_sheets_url)
|
||||
or (doc_before_save and doc_before_save.import_file != self.import_file)
|
||||
or (doc_before_save and doc_before_save.google_sheets_url != self.google_sheets_url)
|
||||
):
|
||||
|
||||
template_options_dict = {}
|
||||
column_to_field_map = {}
|
||||
bank = frappe.get_doc("Bank", self.bank)
|
||||
for i in bank.bank_transaction_mapping:
|
||||
column_to_field_map[i.file_field] = i.bank_transaction_field
|
||||
template_options_dict["column_to_field_map"] = column_to_field_map
|
||||
self.template_options = json.dumps(template_options_dict)
|
||||
|
||||
self.template_warnings = ""
|
||||
|
||||
self.validate_import_file()
|
||||
self.validate_google_sheets_url()
|
||||
|
||||
def start_import(self):
|
||||
|
||||
from frappe.core.page.background_jobs.background_jobs import get_info
|
||||
from frappe.utils.scheduler import is_scheduler_inactive
|
||||
|
||||
if is_scheduler_inactive() and not frappe.flags.in_test:
|
||||
frappe.throw(
|
||||
_("Scheduler is inactive. Cannot import data."), title=_("Scheduler Inactive")
|
||||
)
|
||||
|
||||
enqueued_jobs = [d.get("job_name") for d in get_info()]
|
||||
|
||||
if self.name not in enqueued_jobs:
|
||||
enqueue(
|
||||
start_import,
|
||||
queue="default",
|
||||
timeout=6000,
|
||||
event="data_import",
|
||||
job_name=self.name,
|
||||
data_import=self.name,
|
||||
bank_account=self.bank_account,
|
||||
import_file_path=self.import_file,
|
||||
bank=self.bank,
|
||||
template_options=self.template_options,
|
||||
now=frappe.conf.developer_mode or frappe.flags.in_test,
|
||||
)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_preview_from_template(data_import, import_file=None, google_sheets_url=None):
|
||||
return frappe.get_doc("Bank Statement Import", data_import).get_preview_from_template(
|
||||
import_file, google_sheets_url
|
||||
)
|
||||
|
||||
@frappe.whitelist()
|
||||
def form_start_import(data_import):
|
||||
return frappe.get_doc("Bank Statement Import", data_import).start_import()
|
||||
|
||||
@frappe.whitelist()
|
||||
def download_errored_template(data_import_name):
|
||||
data_import = frappe.get_doc("Bank Statement Import", data_import_name)
|
||||
data_import.export_errored_rows()
|
||||
|
||||
def start_import(data_import, bank_account, import_file_path, bank, template_options):
|
||||
"""This method runs in background job"""
|
||||
|
||||
update_mapping_db(bank, template_options)
|
||||
|
||||
data_import = frappe.get_doc("Bank Statement Import", data_import)
|
||||
|
||||
import_file = ImportFile("Bank Transaction", file = import_file_path, import_type="Insert New Records")
|
||||
data = import_file.raw_data
|
||||
|
||||
add_bank_account(data, bank_account)
|
||||
write_files(import_file, data)
|
||||
|
||||
try:
|
||||
i = Importer(data_import.reference_doctype, data_import=data_import)
|
||||
i.import_data()
|
||||
except Exception:
|
||||
frappe.db.rollback()
|
||||
data_import.db_set("status", "Error")
|
||||
frappe.log_error(title=data_import.name)
|
||||
finally:
|
||||
frappe.flags.in_import = False
|
||||
|
||||
frappe.publish_realtime("data_import_refresh", {"data_import": data_import.name})
|
||||
|
||||
def update_mapping_db(bank, template_options):
|
||||
bank = frappe.get_doc("Bank", bank)
|
||||
for d in bank.bank_transaction_mapping:
|
||||
d.delete()
|
||||
|
||||
for d in json.loads(template_options)["column_to_field_map"].items():
|
||||
bank.append("bank_transaction_mapping", {"bank_transaction_field": d[1] ,"file_field": d[0]} )
|
||||
|
||||
bank.save()
|
||||
|
||||
def add_bank_account(data, bank_account):
|
||||
bank_account_loc = None
|
||||
if "Bank Account" not in data[0]:
|
||||
data[0].append("Bank Account")
|
||||
else:
|
||||
for loc, header in enumerate(data[0]):
|
||||
if header == "Bank Account":
|
||||
bank_account_loc = loc
|
||||
|
||||
for row in data[1:]:
|
||||
if bank_account_loc:
|
||||
row[bank_account_loc] = bank_account
|
||||
else:
|
||||
row.append(bank_account)
|
||||
|
||||
def write_files(import_file, data):
|
||||
full_file_path = import_file.file_doc.get_full_path()
|
||||
parts = import_file.file_doc.get_extension()
|
||||
extension = parts[1]
|
||||
extension = extension.lstrip(".")
|
||||
|
||||
if extension == "csv":
|
||||
with open(full_file_path, 'w', newline='') as file:
|
||||
writer = csv.writer(file)
|
||||
writer.writerows(data)
|
||||
elif extension == "xlsx" or "xls":
|
||||
write_xlsx(data, "trans", file_path = full_file_path)
|
||||
|
||||
def write_xlsx(data, sheet_name, wb=None, column_widths=None, file_path=None):
|
||||
# from xlsx utils with changes
|
||||
column_widths = column_widths or []
|
||||
if wb is None:
|
||||
wb = openpyxl.Workbook(write_only=True)
|
||||
|
||||
ws = wb.create_sheet(sheet_name, 0)
|
||||
|
||||
for i, column_width in enumerate(column_widths):
|
||||
if column_width:
|
||||
ws.column_dimensions[get_column_letter(i + 1)].width = column_width
|
||||
|
||||
row1 = ws.row_dimensions[1]
|
||||
row1.font = Font(name='Calibri', bold=True)
|
||||
|
||||
for row in data:
|
||||
clean_row = []
|
||||
for item in row:
|
||||
if isinstance(item, string_types) and (sheet_name not in ['Data Import Template', 'Data Export']):
|
||||
value = handle_html(item)
|
||||
else:
|
||||
value = item
|
||||
|
||||
if isinstance(item, string_types) and next(ILLEGAL_CHARACTERS_RE.finditer(value), None):
|
||||
# Remove illegal characters from the string
|
||||
value = re.sub(ILLEGAL_CHARACTERS_RE, '', value)
|
||||
|
||||
clean_row.append(value)
|
||||
|
||||
ws.append(clean_row)
|
||||
|
||||
wb.save(file_path)
|
||||
return True
|
||||
|
||||
@frappe.whitelist()
|
||||
def upload_bank_statement(**args):
|
||||
args = frappe._dict(args)
|
||||
bsi = frappe.new_doc("Bank Statement Import")
|
||||
|
||||
if args.company:
|
||||
bsi.update({
|
||||
"company": args.company,
|
||||
})
|
||||
|
||||
if args.bank_account:
|
||||
bsi.update({
|
||||
"bank_account": args.bank_account
|
||||
})
|
||||
|
||||
return bsi
|
||||
@@ -0,0 +1,36 @@
|
||||
let imports_in_progress = [];
|
||||
|
||||
frappe.listview_settings['Bank Statement Import'] = {
|
||||
onload(listview) {
|
||||
frappe.realtime.on('data_import_progress', data => {
|
||||
if (!imports_in_progress.includes(data.data_import)) {
|
||||
imports_in_progress.push(data.data_import);
|
||||
}
|
||||
});
|
||||
frappe.realtime.on('data_import_refresh', data => {
|
||||
imports_in_progress = imports_in_progress.filter(
|
||||
d => d !== data.data_import
|
||||
);
|
||||
listview.refresh();
|
||||
});
|
||||
},
|
||||
get_indicator: function(doc) {
|
||||
var colors = {
|
||||
'Pending': 'orange',
|
||||
'Not Started': 'orange',
|
||||
'Partial Success': 'orange',
|
||||
'Success': 'green',
|
||||
'In Progress': 'orange',
|
||||
'Error': 'red'
|
||||
};
|
||||
let status = doc.status;
|
||||
if (imports_in_progress.includes(doc.name)) {
|
||||
status = 'In Progress';
|
||||
}
|
||||
if (status == 'Pending') {
|
||||
status = 'Not Started';
|
||||
}
|
||||
return [__(status), colors[status], 'status,=,' + doc.status];
|
||||
},
|
||||
hide_name_column: true
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
class TestBankStatementImport(unittest.TestCase):
|
||||
pass
|
||||
@@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2017, sathishpy@gmail.com and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Bank Statement Settings', {
|
||||
refresh: function(frm) {
|
||||
|
||||
}
|
||||
});
|
||||
@@ -1,272 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 1,
|
||||
"beta": 0,
|
||||
"creation": "2017-11-13 13:38:10.863592",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "bank",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Bank Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Bank",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "'%d/%m/%Y'",
|
||||
"fieldname": "date_format",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Date Format",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "statement_header_mapping",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Statement Header Mapping",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "header_items",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Statement Headers",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Bank Statement Settings Item",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "transaction_data_mapping",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Transaction Data Mapping",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "mapped_items",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Mapped Items",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Bank Statement Transaction Settings Item",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-04-07 18:57:04.048423",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Statement Settings",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, sathishpy@gmail.com and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class BankStatementSettings(Document):
|
||||
def autoname(self):
|
||||
self.name = self.bank + "-Statement-Settings"
|
||||
@@ -1,23 +0,0 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Bank Statement Settings", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Bank Statement Settings
|
||||
() => frappe.tests.make('Bank Statement Settings', [
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, sathishpy@gmail.com and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
|
||||
class TestBankStatementSettings(unittest.TestCase):
|
||||
pass
|
||||
@@ -1,101 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2018-01-08 00:16:42.762980",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "mapped_header",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Mapped Header",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "stmt_header",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Bank Header",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-01-08 00:19:14.841134",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Statement Settings Item",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
// Copyright (c) 2017, sathishpy@gmail.com and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Bank Statement Transaction Entry', {
|
||||
setup: function(frm) {
|
||||
frm.events.account_filters(frm)
|
||||
frm.events.invoice_filter(frm)
|
||||
},
|
||||
refresh: function(frm) {
|
||||
frm.set_df_property("bank_account", "read_only", frm.doc.__islocal ? 0 : 1);
|
||||
frm.set_df_property("from_date", "read_only", frm.doc.__islocal ? 0 : 1);
|
||||
frm.set_df_property("to_date", "read_only", frm.doc.__islocal ? 0 : 1);
|
||||
},
|
||||
invoke_doc_function(frm, method) {
|
||||
frappe.call({
|
||||
doc: frm.doc,
|
||||
method: method,
|
||||
callback: function(r) {
|
||||
if(!r.exe) {
|
||||
frm.refresh_fields();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
account_filters: function(frm) {
|
||||
frm.fields_dict['bank_account'].get_query = function(doc, dt, dn) {
|
||||
return {
|
||||
filters:[
|
||||
["Account", "account_type", "in", ["Bank"]]
|
||||
]
|
||||
}
|
||||
};
|
||||
frm.fields_dict['receivable_account'].get_query = function(doc, dt, dn) {
|
||||
return {
|
||||
filters: {"account_type": "Receivable"}
|
||||
}
|
||||
};
|
||||
frm.fields_dict['payable_account'].get_query = function(doc, dt, dn) {
|
||||
return {
|
||||
filters: {"account_type": "Payable"}
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
invoice_filter: function(frm) {
|
||||
frm.set_query("invoice", "payment_invoice_items", function(doc, cdt, cdn) {
|
||||
let row = locals[cdt][cdn]
|
||||
if (row.party_type == "Customer") {
|
||||
return {
|
||||
filters:[[row.invoice_type, "customer", "in", [row.party]],
|
||||
[row.invoice_type, "status", "!=", "Cancelled" ],
|
||||
[row.invoice_type, "posting_date", "<", row.transaction_date ],
|
||||
[row.invoice_type, "outstanding_amount", ">", 0 ]]
|
||||
}
|
||||
} else if (row.party_type == "Supplier") {
|
||||
return {
|
||||
filters:[[row.invoice_type, "supplier", "in", [row.party]],
|
||||
[row.invoice_type, "status", "!=", "Cancelled" ],
|
||||
[row.invoice_type, "posting_date", "<", row.transaction_date ],
|
||||
[row.invoice_type, "outstanding_amount", ">", 0 ]]
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
match_invoices: function(frm) {
|
||||
frm.events.invoke_doc_function(frm, "populate_matching_invoices");
|
||||
},
|
||||
create_payments: function(frm) {
|
||||
frm.events.invoke_doc_function(frm, "create_payment_entries");
|
||||
},
|
||||
submit_payments: function(frm) {
|
||||
frm.events.invoke_doc_function(frm, "submit_payment_entries");
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
frappe.ui.form.on('Bank Statement Transaction Invoice Item', {
|
||||
party_type: function(frm, cdt, cdn) {
|
||||
let row = locals[cdt][cdn];
|
||||
if (row.party_type == "Customer") {
|
||||
row.invoice_type = "Sales Invoice";
|
||||
} else if (row.party_type == "Supplier") {
|
||||
row.invoice_type = "Purchase Invoice";
|
||||
} else if (row.party_type == "Account") {
|
||||
row.invoice_type = "Journal Entry";
|
||||
}
|
||||
refresh_field("invoice_type", row.name, "payment_invoice_items");
|
||||
|
||||
},
|
||||
invoice_type: function(frm, cdt, cdn) {
|
||||
let row = locals[cdt][cdn];
|
||||
if (row.invoice_type == "Purchase Invoice") {
|
||||
row.party_type = "Supplier";
|
||||
} else if (row.invoice_type == "Sales Invoice") {
|
||||
row.party_type = "Customer";
|
||||
}
|
||||
refresh_field("party_type", row.name, "payment_invoice_items");
|
||||
}
|
||||
});
|
||||
@@ -1,792 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 1,
|
||||
"beta": 0,
|
||||
"creation": "2017-11-07 13:48:13.123185",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "bank_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Bank Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "from_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "From Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "to_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "To Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "bank_settings",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Bank Statement Settings",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Bank Statement Settings",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "bank",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Bank",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Bank",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "receivable_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Receivable Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "payable_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Payable Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "bank_statement",
|
||||
"fieldtype": "Attach",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Bank Statement",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "section_break_6",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Bank Transaction Entries",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "new_transaction_items",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "New Transactions",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Bank Statement Transaction Payment Item",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.new_transaction_items && doc.new_transaction_items.length",
|
||||
"fieldname": "section_break_9",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "match_invoices",
|
||||
"fieldtype": "Button",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Match Transaction to Invoices",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_14",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "create_payments",
|
||||
"fieldtype": "Button",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Create New Payment/Journal Entry",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_16",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "submit_payments",
|
||||
"fieldtype": "Button",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Submit/Reconcile Payments",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.new_transaction_items && doc.new_transaction_items.length",
|
||||
"fieldname": "section_break_18",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Matching Invoices",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "payment_invoice_items",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Payment Invoice Items",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Bank Statement Transaction Invoice Item",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "reconciled_transactions",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reconciled Transactions",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "reconciled_transaction_items",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reconciled Transactions",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Bank Statement Transaction Payment Item",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Amended From",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Bank Statement Transaction Entry",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 1,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-09-14 18:04:44.170455",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Statement Transaction Entry",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -1,443 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, sathishpy@gmail.com and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from erpnext.accounts.utils import get_outstanding_invoices
|
||||
from frappe.utils import nowdate
|
||||
from datetime import datetime
|
||||
import csv, os, re, io
|
||||
import difflib
|
||||
import copy
|
||||
|
||||
class BankStatementTransactionEntry(Document):
|
||||
def autoname(self):
|
||||
self.name = self.bank_account + "-" + self.from_date + "-" + self.to_date
|
||||
if self.bank:
|
||||
mapper_name = self.bank + "-Statement-Settings"
|
||||
if not frappe.db.exists("Bank Statement Settings", mapper_name):
|
||||
self.create_settings(self.bank)
|
||||
self.bank_settings = mapper_name
|
||||
|
||||
def create_settings(self, bank):
|
||||
mapper = frappe.new_doc("Bank Statement Settings")
|
||||
mapper.bank = bank
|
||||
mapper.date_format = "%Y-%m-%d"
|
||||
mapper.bank_account = self.bank_account
|
||||
for header in ["Date", "Particulars", "Withdrawals", "Deposits", "Balance"]:
|
||||
header_item = mapper.append("header_items", {})
|
||||
header_item.mapped_header = header_item.stmt_header = header
|
||||
mapper.save()
|
||||
|
||||
def on_update(self):
|
||||
if (not self.bank_statement):
|
||||
self.reconciled_transaction_items = self.new_transaction_items = []
|
||||
return
|
||||
|
||||
if len(self.new_transaction_items + self.reconciled_transaction_items) == 0:
|
||||
self.populate_payment_entries()
|
||||
else:
|
||||
self.match_invoice_to_payment()
|
||||
|
||||
def validate(self):
|
||||
if not self.new_transaction_items:
|
||||
self.populate_payment_entries()
|
||||
|
||||
def get_statement_headers(self):
|
||||
if not self.bank_settings:
|
||||
frappe.throw(_("Bank Data mapper doesn't exist"))
|
||||
mapper_doc = frappe.get_doc("Bank Statement Settings", self.bank_settings)
|
||||
headers = {entry.mapped_header:entry.stmt_header for entry in mapper_doc.header_items}
|
||||
return headers
|
||||
|
||||
def populate_payment_entries(self):
|
||||
if self.bank_statement is None: return
|
||||
file_url = self.bank_statement
|
||||
if (len(self.new_transaction_items + self.reconciled_transaction_items) > 0):
|
||||
frappe.throw(_("Transactions already retreived from the statement"))
|
||||
|
||||
date_format = frappe.get_value("Bank Statement Settings", self.bank_settings, "date_format")
|
||||
if (date_format is None):
|
||||
date_format = '%Y-%m-%d'
|
||||
if self.bank_settings:
|
||||
mapped_items = frappe.get_doc("Bank Statement Settings", self.bank_settings).mapped_items
|
||||
statement_headers = self.get_statement_headers()
|
||||
transactions = get_transaction_entries(file_url, statement_headers)
|
||||
for entry in transactions:
|
||||
date = entry[statement_headers["Date"]].strip()
|
||||
#print("Processing entry DESC:{0}-W:{1}-D:{2}-DT:{3}".format(entry["Particulars"], entry["Withdrawals"], entry["Deposits"], entry["Date"]))
|
||||
if (not date): continue
|
||||
transaction_date = datetime.strptime(date, date_format).date()
|
||||
if (self.from_date and transaction_date < datetime.strptime(self.from_date, '%Y-%m-%d').date()): continue
|
||||
if (self.to_date and transaction_date > datetime.strptime(self.to_date, '%Y-%m-%d').date()): continue
|
||||
bank_entry = self.append('new_transaction_items', {})
|
||||
bank_entry.transaction_date = transaction_date
|
||||
bank_entry.description = entry[statement_headers["Particulars"]]
|
||||
|
||||
mapped_item = next((entry for entry in mapped_items if entry.mapping_type == "Transaction" and frappe.safe_decode(entry.bank_data.lower()) in frappe.safe_decode(bank_entry.description.lower())), None)
|
||||
if (mapped_item is not None):
|
||||
bank_entry.party_type = mapped_item.mapped_data_type
|
||||
bank_entry.party = mapped_item.mapped_data
|
||||
else:
|
||||
bank_entry.party_type = "Supplier" if not entry[statement_headers["Deposits"]].strip() else "Customer"
|
||||
party_list = frappe.get_all(bank_entry.party_type, fields=["name"])
|
||||
parties = [party.name for party in party_list]
|
||||
matches = difflib.get_close_matches(frappe.safe_decode(bank_entry.description.lower()), parties, 1, 0.4)
|
||||
if len(matches) > 0: bank_entry.party = matches[0]
|
||||
bank_entry.amount = -float(entry[statement_headers["Withdrawals"]]) if not entry[statement_headers["Deposits"]].strip() else float(entry[statement_headers["Deposits"]])
|
||||
self.map_unknown_transactions()
|
||||
self.map_transactions_on_journal_entry()
|
||||
|
||||
def map_transactions_on_journal_entry(self):
|
||||
for entry in self.new_transaction_items:
|
||||
vouchers = frappe.db.sql("""select name, posting_date from `tabJournal Entry`
|
||||
where posting_date='{0}' and total_credit={1} and cheque_no='{2}' and docstatus != 2
|
||||
""".format(entry.transaction_date, abs(entry.amount), frappe.safe_decode(entry.description)), as_dict=True)
|
||||
if (len(vouchers) == 1):
|
||||
entry.reference_name = vouchers[0].name
|
||||
|
||||
def populate_matching_invoices(self):
|
||||
self.payment_invoice_items = []
|
||||
self.map_unknown_transactions()
|
||||
added_invoices = []
|
||||
for entry in self.new_transaction_items:
|
||||
if (not entry.party or entry.party_type == "Account"): continue
|
||||
account = self.receivable_account if entry.party_type == "Customer" else self.payable_account
|
||||
invoices = get_outstanding_invoices(entry.party_type, entry.party, account)
|
||||
transaction_date = datetime.strptime(entry.transaction_date, "%Y-%m-%d").date()
|
||||
outstanding_invoices = [invoice for invoice in invoices if invoice.posting_date <= transaction_date]
|
||||
amount = abs(entry.amount)
|
||||
matching_invoices = [invoice for invoice in outstanding_invoices if invoice.outstanding_amount == amount]
|
||||
sorted(outstanding_invoices, key=lambda k: k['posting_date'])
|
||||
for e in (matching_invoices + outstanding_invoices):
|
||||
added = next((inv for inv in added_invoices if inv == e.get('voucher_no')), None)
|
||||
if (added is not None): continue
|
||||
ent = self.append('payment_invoice_items', {})
|
||||
ent.transaction_date = entry.transaction_date
|
||||
ent.payment_description = frappe.safe_decode(entry.description)
|
||||
ent.party_type = entry.party_type
|
||||
ent.party = entry.party
|
||||
ent.invoice = e.get('voucher_no')
|
||||
added_invoices += [ent.invoice]
|
||||
ent.invoice_type = "Sales Invoice" if entry.party_type == "Customer" else "Purchase Invoice"
|
||||
ent.invoice_date = e.get('posting_date')
|
||||
ent.outstanding_amount = e.get('outstanding_amount')
|
||||
ent.allocated_amount = min(float(e.get('outstanding_amount')), amount)
|
||||
amount -= float(e.get('outstanding_amount'))
|
||||
if (amount <= 5): break
|
||||
self.match_invoice_to_payment()
|
||||
self.populate_matching_vouchers()
|
||||
self.map_transactions_on_journal_entry()
|
||||
|
||||
def match_invoice_to_payment(self):
|
||||
added_payments = []
|
||||
for entry in self.new_transaction_items:
|
||||
if (not entry.party or entry.party_type == "Account"): continue
|
||||
entry.account = self.receivable_account if entry.party_type == "Customer" else self.payable_account
|
||||
amount = abs(entry.amount)
|
||||
payment, matching_invoices = None, []
|
||||
for inv_entry in self.payment_invoice_items:
|
||||
if (inv_entry.payment_description != frappe.safe_decode(entry.description) or inv_entry.transaction_date != entry.transaction_date): continue
|
||||
if (inv_entry.party != entry.party): continue
|
||||
matching_invoices += [inv_entry.invoice_type + "|" + inv_entry.invoice]
|
||||
payment = get_payments_matching_invoice(inv_entry.invoice, entry.amount, entry.transaction_date)
|
||||
doc = frappe.get_doc(inv_entry.invoice_type, inv_entry.invoice)
|
||||
inv_entry.invoice_date = doc.posting_date
|
||||
inv_entry.outstanding_amount = doc.outstanding_amount
|
||||
inv_entry.allocated_amount = min(float(doc.outstanding_amount), amount)
|
||||
amount -= inv_entry.allocated_amount
|
||||
if (amount < 0): break
|
||||
|
||||
amount = abs(entry.amount)
|
||||
if (payment is None):
|
||||
order_doctype = "Sales Order" if entry.party_type=="Customer" else "Purchase Order"
|
||||
from erpnext.controllers.accounts_controller import get_advance_payment_entries
|
||||
payment_entries = get_advance_payment_entries(entry.party_type, entry.party, entry.account, order_doctype, against_all_orders=True)
|
||||
payment_entries += self.get_matching_payments(entry.party, amount, entry.transaction_date)
|
||||
payment = next((payment for payment in payment_entries if payment.amount == amount and payment not in added_payments), None)
|
||||
if (payment is None):
|
||||
print("Failed to find payments for {0}:{1}".format(entry.party, amount))
|
||||
continue
|
||||
added_payments += [payment]
|
||||
entry.reference_type = payment.reference_type
|
||||
entry.reference_name = payment.reference_name
|
||||
entry.mode_of_payment = "Wire Transfer"
|
||||
entry.outstanding_amount = min(amount, 0)
|
||||
if (entry.payment_reference is None):
|
||||
entry.payment_reference = frappe.safe_decode(entry.description)
|
||||
entry.invoices = ",".join(matching_invoices)
|
||||
#print("Matching payment is {0}:{1}".format(entry.reference_type, entry.reference_name))
|
||||
|
||||
def get_matching_payments(self, party, amount, pay_date):
|
||||
query = """select 'Payment Entry' as reference_type, name as reference_name, paid_amount as amount
|
||||
from `tabPayment Entry` where party='{0}' and paid_amount={1} and posting_date='{2}' and docstatus != 2
|
||||
""".format(party, amount, pay_date)
|
||||
matching_payments = frappe.db.sql(query, as_dict=True)
|
||||
return matching_payments
|
||||
|
||||
def map_unknown_transactions(self):
|
||||
for entry in self.new_transaction_items:
|
||||
if (entry.party): continue
|
||||
inv_type = "Sales Invoice" if (entry.amount > 0) else "Purchase Invoice"
|
||||
party_type = "customer" if (entry.amount > 0) else "supplier"
|
||||
|
||||
query = """select posting_date, name, {0}, outstanding_amount
|
||||
from `tab{1}` where ROUND(outstanding_amount)={2} and posting_date < '{3}'
|
||||
""".format(party_type, inv_type, round(abs(entry.amount)), entry.transaction_date)
|
||||
invoices = frappe.db.sql(query, as_dict = True)
|
||||
if(len(invoices) > 0):
|
||||
entry.party = invoices[0].get(party_type)
|
||||
|
||||
def populate_matching_vouchers(self):
|
||||
for entry in self.new_transaction_items:
|
||||
if (not entry.party or entry.reference_name): continue
|
||||
print("Finding matching voucher for {0}".format(frappe.safe_decode(entry.description)))
|
||||
amount = abs(entry.amount)
|
||||
invoices = []
|
||||
vouchers = get_matching_journal_entries(self.from_date, self.to_date, entry.party, self.bank_account, amount)
|
||||
if len(vouchers) == 0: continue
|
||||
for voucher in vouchers:
|
||||
added = next((entry.invoice for entry in self.payment_invoice_items if entry.invoice == voucher.voucher_no), None)
|
||||
if (added):
|
||||
print("Found voucher {0}".format(added))
|
||||
continue
|
||||
print("Adding voucher {0} {1} {2}".format(voucher.voucher_no, voucher.posting_date, voucher.debit))
|
||||
ent = self.append('payment_invoice_items', {})
|
||||
ent.invoice_date = voucher.posting_date
|
||||
ent.invoice_type = "Journal Entry"
|
||||
ent.invoice = voucher.voucher_no
|
||||
ent.payment_description = frappe.safe_decode(entry.description)
|
||||
ent.allocated_amount = max(voucher.debit, voucher.credit)
|
||||
|
||||
invoices += [ent.invoice_type + "|" + ent.invoice]
|
||||
entry.reference_type = "Journal Entry"
|
||||
entry.mode_of_payment = "Wire Transfer"
|
||||
entry.reference_name = ent.invoice
|
||||
#entry.account = entry.party
|
||||
entry.invoices = ",".join(invoices)
|
||||
break
|
||||
|
||||
|
||||
def create_payment_entries(self):
|
||||
for payment_entry in self.new_transaction_items:
|
||||
if (not payment_entry.party): continue
|
||||
if (payment_entry.reference_name): continue
|
||||
print("Creating payment entry for {0}".format(frappe.safe_decode(payment_entry.description)))
|
||||
if (payment_entry.party_type == "Account"):
|
||||
payment = self.create_journal_entry(payment_entry)
|
||||
invoices = [payment.doctype + "|" + payment.name]
|
||||
payment_entry.invoices = ",".join(invoices)
|
||||
else:
|
||||
payment = self.create_payment_entry(payment_entry)
|
||||
invoices = [entry.reference_doctype + "|" + entry.reference_name for entry in payment.references if entry is not None]
|
||||
payment_entry.invoices = ",".join(invoices)
|
||||
payment_entry.mode_of_payment = payment.mode_of_payment
|
||||
payment_entry.account = self.receivable_account if payment_entry.party_type == "Customer" else self.payable_account
|
||||
payment_entry.reference_name = payment.name
|
||||
payment_entry.reference_type = payment.doctype
|
||||
frappe.msgprint(_("Successfully created payment entries"))
|
||||
|
||||
def create_payment_entry(self, pe):
|
||||
payment = frappe.new_doc("Payment Entry")
|
||||
payment.posting_date = pe.transaction_date
|
||||
payment.payment_type = "Receive" if pe.party_type == "Customer" else "Pay"
|
||||
payment.mode_of_payment = "Wire Transfer"
|
||||
payment.party_type = pe.party_type
|
||||
payment.party = pe.party
|
||||
payment.paid_to = self.bank_account if pe.party_type == "Customer" else self.payable_account
|
||||
payment.paid_from = self.receivable_account if pe.party_type == "Customer" else self.bank_account
|
||||
payment.paid_amount = payment.received_amount = abs(pe.amount)
|
||||
payment.reference_no = pe.description
|
||||
payment.reference_date = pe.transaction_date
|
||||
payment.save()
|
||||
for inv_entry in self.payment_invoice_items:
|
||||
if (pe.description != inv_entry.payment_description or pe.transaction_date != inv_entry.transaction_date): continue
|
||||
if (pe.party != inv_entry.party): continue
|
||||
reference = payment.append("references", {})
|
||||
reference.reference_doctype = inv_entry.invoice_type
|
||||
reference.reference_name = inv_entry.invoice
|
||||
reference.allocated_amount = inv_entry.allocated_amount
|
||||
print ("Adding invoice {0} {1}".format(reference.reference_name, reference.allocated_amount))
|
||||
payment.setup_party_account_field()
|
||||
payment.set_missing_values()
|
||||
#payment.set_exchange_rate()
|
||||
#payment.set_amounts()
|
||||
#print("Created payment entry {0}".format(payment.as_dict()))
|
||||
payment.save()
|
||||
return payment
|
||||
|
||||
def create_journal_entry(self, pe):
|
||||
je = frappe.new_doc("Journal Entry")
|
||||
je.is_opening = "No"
|
||||
je.voucher_type = "Bank Entry"
|
||||
je.cheque_no = pe.description
|
||||
je.cheque_date = pe.transaction_date
|
||||
je.remark = pe.description
|
||||
je.posting_date = pe.transaction_date
|
||||
if (pe.amount < 0):
|
||||
je.append("accounts", {"account": pe.party, "debit_in_account_currency": abs(pe.amount)})
|
||||
je.append("accounts", {"account": self.bank_account, "credit_in_account_currency": abs(pe.amount)})
|
||||
else:
|
||||
je.append("accounts", {"account": pe.party, "credit_in_account_currency": pe.amount})
|
||||
je.append("accounts", {"account": self.bank_account, "debit_in_account_currency": pe.amount})
|
||||
je.save()
|
||||
return je
|
||||
|
||||
def update_payment_entry(self, payment):
|
||||
lst = []
|
||||
invoices = payment.invoices.strip().split(',')
|
||||
if (len(invoices) == 0): return
|
||||
amount = float(abs(payment.amount))
|
||||
for invoice_entry in invoices:
|
||||
if (not invoice_entry.strip()): continue
|
||||
invs = invoice_entry.split('|')
|
||||
invoice_type, invoice = invs[0], invs[1]
|
||||
outstanding_amount = frappe.get_value(invoice_type, invoice, 'outstanding_amount')
|
||||
|
||||
lst.append(frappe._dict({
|
||||
'voucher_type': payment.reference_type,
|
||||
'voucher_no' : payment.reference_name,
|
||||
'against_voucher_type' : invoice_type,
|
||||
'against_voucher' : invoice,
|
||||
'account' : payment.account,
|
||||
'party_type': payment.party_type,
|
||||
'party': frappe.get_value("Payment Entry", payment.reference_name, "party"),
|
||||
'unadjusted_amount' : float(amount),
|
||||
'allocated_amount' : min(outstanding_amount, amount)
|
||||
}))
|
||||
amount -= outstanding_amount
|
||||
if lst:
|
||||
from erpnext.accounts.utils import reconcile_against_document
|
||||
try:
|
||||
reconcile_against_document(lst)
|
||||
except:
|
||||
frappe.throw(_("Exception occurred while reconciling {0}").format(payment.reference_name))
|
||||
|
||||
def submit_payment_entries(self):
|
||||
for payment in self.new_transaction_items:
|
||||
if payment.reference_name is None: continue
|
||||
doc = frappe.get_doc(payment.reference_type, payment.reference_name)
|
||||
if doc.docstatus == 1:
|
||||
if (payment.reference_type == "Journal Entry"): continue
|
||||
if doc.unallocated_amount == 0: continue
|
||||
print("Reconciling payment {0}".format(payment.reference_name))
|
||||
self.update_payment_entry(payment)
|
||||
else:
|
||||
print("Submitting payment {0}".format(payment.reference_name))
|
||||
if (payment.reference_type == "Payment Entry"):
|
||||
if (payment.payment_reference):
|
||||
doc.reference_no = payment.payment_reference
|
||||
doc.mode_of_payment = payment.mode_of_payment
|
||||
doc.save()
|
||||
doc.submit()
|
||||
self.move_reconciled_entries()
|
||||
self.populate_matching_invoices()
|
||||
|
||||
def move_reconciled_entries(self):
|
||||
idx = 0
|
||||
while idx < len(self.new_transaction_items):
|
||||
entry = self.new_transaction_items[idx]
|
||||
try:
|
||||
print("Checking transaction {0}: {2} in {1} entries".format(idx, len(self.new_transaction_items), frappe.safe_decode(entry.description)))
|
||||
except UnicodeEncodeError:
|
||||
pass
|
||||
idx += 1
|
||||
if entry.reference_name is None: continue
|
||||
doc = frappe.get_doc(entry.reference_type, entry.reference_name)
|
||||
if doc.docstatus == 1 and (entry.reference_type == "Journal Entry" or doc.unallocated_amount == 0):
|
||||
self.remove(entry)
|
||||
rc_entry = self.append('reconciled_transaction_items', {})
|
||||
dentry = entry.as_dict()
|
||||
dentry.pop('idx', None)
|
||||
rc_entry.update(dentry)
|
||||
idx -= 1
|
||||
|
||||
|
||||
def get_matching_journal_entries(from_date, to_date, account, against, amount):
|
||||
query = """select voucher_no, posting_date, account, against, debit_in_account_currency as debit, credit_in_account_currency as credit
|
||||
from `tabGL Entry`
|
||||
where posting_date between '{0}' and '{1}' and account = '{2}' and against = '{3}' and debit = '{4}'
|
||||
""".format(from_date, to_date, account, against, amount)
|
||||
jv_entries = frappe.db.sql(query, as_dict=True)
|
||||
#print("voucher query:{0}\n Returned {1} entries".format(query, len(jv_entries)))
|
||||
return jv_entries
|
||||
|
||||
def get_payments_matching_invoice(invoice, amount, pay_date):
|
||||
query = """select pe.name as reference_name, per.reference_doctype as reference_type, per.outstanding_amount, per.allocated_amount
|
||||
from `tabPayment Entry Reference` as per JOIN `tabPayment Entry` as pe on pe.name = per.parent
|
||||
where per.reference_name='{0}' and (posting_date='{1}' or reference_date='{1}') and pe.docstatus != 2
|
||||
""".format(invoice, pay_date)
|
||||
payments = frappe.db.sql(query, as_dict=True)
|
||||
if (len(payments) == 0): return
|
||||
payment = next((payment for payment in payments if payment.allocated_amount == amount), payments[0])
|
||||
#Hack: Update the reference type which is set to invoice type
|
||||
payment.reference_type = "Payment Entry"
|
||||
return payment
|
||||
|
||||
def is_headers_present(headers, row):
|
||||
for header in headers:
|
||||
if header not in row:
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_header_index(headers, row):
|
||||
header_index = {}
|
||||
for header in headers:
|
||||
if header in row:
|
||||
header_index[header] = row.index(header)
|
||||
return header_index
|
||||
|
||||
def get_transaction_info(headers, header_index, row):
|
||||
transaction = {}
|
||||
for header in headers:
|
||||
transaction[header] = row[header_index[header]]
|
||||
if (transaction[header] == None):
|
||||
transaction[header] = ""
|
||||
return transaction
|
||||
|
||||
def get_transaction_entries(file_url, headers):
|
||||
header_index = {}
|
||||
rows, transactions = [], []
|
||||
|
||||
if (file_url.lower().endswith("xlsx")):
|
||||
from frappe.utils.xlsxutils import read_xlsx_file_from_attached_file
|
||||
rows = read_xlsx_file_from_attached_file(file_url=file_url)
|
||||
elif (file_url.lower().endswith("csv")):
|
||||
from frappe.utils.csvutils import read_csv_content
|
||||
_file = frappe.get_doc("File", {"file_url": file_url})
|
||||
filepath = _file.get_full_path()
|
||||
with open(filepath,'rb') as csvfile:
|
||||
rows = read_csv_content(csvfile.read())
|
||||
elif (file_url.lower().endswith("xls")):
|
||||
filename = file_url.split("/")[-1]
|
||||
rows = get_rows_from_xls_file(filename)
|
||||
else:
|
||||
frappe.throw(_("Only .csv and .xlsx files are supported currently"))
|
||||
|
||||
stmt_headers = headers.values()
|
||||
for row in rows:
|
||||
if len(row) == 0 or row[0] == None or not row[0]: continue
|
||||
#print("Processing row {0}".format(row))
|
||||
if header_index:
|
||||
transaction = get_transaction_info(stmt_headers, header_index, row)
|
||||
transactions.append(transaction)
|
||||
elif is_headers_present(stmt_headers, row):
|
||||
header_index = get_header_index(stmt_headers, row)
|
||||
return transactions
|
||||
|
||||
def get_rows_from_xls_file(filename):
|
||||
_file = frappe.get_doc("File", {"file_name": filename})
|
||||
filepath = _file.get_full_path()
|
||||
import xlrd
|
||||
book = xlrd.open_workbook(filepath)
|
||||
sheets = book.sheets()
|
||||
rows = []
|
||||
for row in range(1, sheets[0].nrows):
|
||||
row_values = []
|
||||
for col in range(1, sheets[0].ncols):
|
||||
row_values.append(sheets[0].cell_value(row, col))
|
||||
rows.append(row_values)
|
||||
return rows
|
||||
@@ -1,23 +0,0 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Bank Statement Transaction Entry", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Bank Statement Transaction Entry
|
||||
() => frappe.tests.make('Bank Statement Transaction Entry', [
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, sathishpy@gmail.com and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
|
||||
class TestBankStatementTransactionEntry(unittest.TestCase):
|
||||
pass
|
||||
@@ -1,365 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2017-11-07 13:58:53.827058",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "transaction_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Transaction Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 4,
|
||||
"fieldname": "payment_description",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Payment Description",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "party_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Party Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Customer\nSupplier\nAccount",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "party",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Party",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "party_type",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_4",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"fieldname": "invoice_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Invoice Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "invoice_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Invoice Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Sales Invoice\nPurchase Invoice\nJournal Entry",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"fieldname": "invoice",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "invoice",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "invoice_type",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 1,
|
||||
"fieldname": "outstanding_amount",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Outstanding Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 1,
|
||||
"fieldname": "allocated_amount",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Allocated Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-09-14 19:03:30.949831",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Statement Transaction Invoice Item",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
}
|
||||
@@ -1,494 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2017-11-07 14:03:05.651413",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 1,
|
||||
"fieldname": "transaction_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Transaction Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 4,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Description",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 1,
|
||||
"fieldname": "amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 1,
|
||||
"fieldname": "party_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Party Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Customer\nSupplier\nAccount",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"fieldname": "party",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Party",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "party_type",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_6",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "reference_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reference Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Payment Entry\nJournal Entry",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "mode_of_payment",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Mode of Payment",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Mode of Payment",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "outstanding_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "outstanding_amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_10",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"fieldname": "reference_name",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reference Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "reference_type",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "payment_reference",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Payment Reference",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "invoices",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Invoices",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-11-15 19:18:52.876221",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Statement Transaction Payment Item",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2017, sathishpy@gmail.com and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Bank Statement Settings', {
|
||||
refresh: function(frm) {
|
||||
|
||||
}
|
||||
});
|
||||
@@ -1,266 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 1,
|
||||
"beta": 0,
|
||||
"creation": "2017-11-13 13:38:10.863592",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "bank_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Bank Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "'%d/%m/%Y'",
|
||||
"fieldname": "date_format",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Date Format",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "statement_header_mapping",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Statement Header Mapping",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "header_items",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Statement Headers",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Bank Statement Settings Item",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "transaction_data_mapping",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Transaction Data Mapping",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "mapped_items",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Mapped Items",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Bank Statement Transaction Settings Item",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-01-12 10:34:32.840487",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Statement Settings",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, sathishpy@gmail.com and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class BankStatementSettings(Document):
|
||||
def autoname(self):
|
||||
self.name = self.bank_account + "-Mappings"
|
||||
@@ -1,23 +0,0 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Bank Statement Settings", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Bank Statement Settings
|
||||
() => frappe.tests.make('Bank Statement Settings', [
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, sathishpy@gmail.com and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
|
||||
class TestBankStatementSettings(unittest.TestCase):
|
||||
pass
|
||||
@@ -1,166 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2017-11-13 13:42:00.335432",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Transaction",
|
||||
"fieldname": "mapping_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Mapping Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Transaction",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "bank_data",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Bank Data",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Account",
|
||||
"fieldname": "mapped_data_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Mapped Data Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account\nCustomer\nSupplier\nAccount",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "mapped_data",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Mapped Data",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "mapped_data_type",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-01-08 00:13:49.973501",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Statement Transaction Settings Item",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -1,32 +1,70 @@
|
||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Bank Transaction', {
|
||||
frappe.ui.form.on("Bank Transaction", {
|
||||
onload(frm) {
|
||||
frm.set_query('payment_document', 'payment_entries', function() {
|
||||
frm.set_query("payment_document", "payment_entries", function () {
|
||||
return {
|
||||
"filters": {
|
||||
"name": ["in", ["Payment Entry", "Journal Entry", "Sales Invoice", "Purchase Invoice", "Expense Claim"]]
|
||||
}
|
||||
filters: {
|
||||
name: [
|
||||
"in",
|
||||
[
|
||||
"Payment Entry",
|
||||
"Journal Entry",
|
||||
"Sales Invoice",
|
||||
"Purchase Invoice",
|
||||
"Expense Claim",
|
||||
],
|
||||
],
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
},
|
||||
bank_account: function (frm) {
|
||||
set_bank_statement_filter(frm);
|
||||
},
|
||||
|
||||
setup: function (frm) {
|
||||
frm.set_query("party_type", function () {
|
||||
return {
|
||||
filters: {
|
||||
name: ["in", Object.keys(frappe.boot.party_account_types)],
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
frappe.ui.form.on('Bank Transaction Payments', {
|
||||
payment_entries_remove: function(frm, cdt, cdn) {
|
||||
frappe.ui.form.on("Bank Transaction Payments", {
|
||||
payment_entries_remove: function (frm, cdt, cdn) {
|
||||
update_clearance_date(frm, cdt, cdn);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const update_clearance_date = (frm, cdt, cdn) => {
|
||||
if (frm.doc.docstatus === 1) {
|
||||
frappe.xcall('erpnext.accounts.doctype.bank_transaction.bank_transaction.unclear_reference_payment',
|
||||
{doctype: cdt, docname: cdn})
|
||||
.then(e => {
|
||||
frappe
|
||||
.xcall(
|
||||
"erpnext.accounts.doctype.bank_transaction.bank_transaction.unclear_reference_payment",
|
||||
{ doctype: cdt, docname: cdn }
|
||||
)
|
||||
.then((e) => {
|
||||
if (e == "success") {
|
||||
frappe.show_alert({message:__("Document {0} successfully uncleared", [e]), indicator:'green'});
|
||||
frappe.show_alert({
|
||||
message: __("Document {0} successfully uncleared", [e]),
|
||||
indicator: "green",
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
function set_bank_statement_filter(frm) {
|
||||
frm.set_query("bank_statement", function () {
|
||||
return {
|
||||
filters: {
|
||||
bank_account: frm.doc.bank_account,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,833 +1,245 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_events_in_timeline": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"actions": [],
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "naming_series:",
|
||||
"beta": 0,
|
||||
"creation": "2018-10-22 18:19:02.784533",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"naming_series",
|
||||
"date",
|
||||
"column_break_2",
|
||||
"status",
|
||||
"bank_account",
|
||||
"company",
|
||||
"section_break_4",
|
||||
"deposit",
|
||||
"withdrawal",
|
||||
"column_break_7",
|
||||
"currency",
|
||||
"section_break_10",
|
||||
"description",
|
||||
"section_break_14",
|
||||
"reference_number",
|
||||
"transaction_id",
|
||||
"payment_entries",
|
||||
"section_break_18",
|
||||
"allocated_amount",
|
||||
"amended_from",
|
||||
"column_break_17",
|
||||
"unallocated_amount",
|
||||
"party_section",
|
||||
"party_type",
|
||||
"party"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "ACC-BTN-.YYYY.-",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Series",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "ACC-BTN-.YYYY.-",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 1,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"set_only_once": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Date"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break_2",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Pending",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Status",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nPending\nSettled\nUnreconciled\nReconciled",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"options": "\nPending\nSettled\nUnreconciled\nReconciled"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "bank_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Bank Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Bank Account",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"options": "Bank Account"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "",
|
||||
"fetch_from": "bank_account.company",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Company",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "section_break_4",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "debit",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Debit",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "credit",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Credit",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break_7",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Currency",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"options": "Currency"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "section_break_10",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Description",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Description"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "section_break_14",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "reference_number",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reference Number",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Reference Number"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "transaction_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Transaction ID",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "payment_entries",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Payment Entries",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Bank Transaction Payments",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"options": "Bank Transaction Payments"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "section_break_18",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "allocated_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Allocated Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Allocated Amount"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Amended From",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Bank Transaction",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break_17",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "unallocated_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Unallocated Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Unallocated Amount"
|
||||
},
|
||||
{
|
||||
"fieldname": "party_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Payment From / To"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "party_type",
|
||||
"fieldtype": "Link",
|
||||
"label": "Party Type",
|
||||
"options": "DocType"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "party",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"label": "Party",
|
||||
"options": "party_type"
|
||||
},
|
||||
{
|
||||
"fieldname": "deposit",
|
||||
"oldfieldname": "debit",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Deposit"
|
||||
},
|
||||
{
|
||||
"fieldname": "withdrawal",
|
||||
"oldfieldname": "credit",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Withdrawal"
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 1,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2019-05-11 05:27:55.244721",
|
||||
"links": [],
|
||||
"modified": "2020-12-30 19:40:54.221070",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Transaction",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "date",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "bank_account",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
"track_changes": 1
|
||||
}
|
||||
@@ -11,7 +11,7 @@ from frappe import _
|
||||
|
||||
class BankTransaction(StatusUpdater):
|
||||
def after_insert(self):
|
||||
self.unallocated_amount = abs(flt(self.credit) - flt(self.debit))
|
||||
self.unallocated_amount = abs(flt(self.withdrawal) - flt(self.deposit))
|
||||
|
||||
def on_submit(self):
|
||||
self.clear_linked_payment_entries()
|
||||
@@ -30,13 +30,13 @@ class BankTransaction(StatusUpdater):
|
||||
|
||||
if allocated_amount:
|
||||
frappe.db.set_value(self.doctype, self.name, "allocated_amount", flt(allocated_amount))
|
||||
frappe.db.set_value(self.doctype, self.name, "unallocated_amount", abs(flt(self.credit) - flt(self.debit)) - flt(allocated_amount))
|
||||
frappe.db.set_value(self.doctype, self.name, "unallocated_amount", abs(flt(self.withdrawal) - flt(self.deposit)) - flt(allocated_amount))
|
||||
|
||||
else:
|
||||
frappe.db.set_value(self.doctype, self.name, "allocated_amount", 0)
|
||||
frappe.db.set_value(self.doctype, self.name, "unallocated_amount", abs(flt(self.credit) - flt(self.debit)))
|
||||
frappe.db.set_value(self.doctype, self.name, "unallocated_amount", abs(flt(self.withdrawal) - flt(self.deposit)))
|
||||
|
||||
amount = self.debit or self.credit
|
||||
amount = self.deposit or self.withdrawal
|
||||
if amount == self.allocated_amount:
|
||||
frappe.db.set_value(self.doctype, self.name, "status", "Reconciled")
|
||||
|
||||
@@ -44,18 +44,11 @@ class BankTransaction(StatusUpdater):
|
||||
|
||||
def clear_linked_payment_entries(self):
|
||||
for payment_entry in self.payment_entries:
|
||||
allocated_amount = get_total_allocated_amount(payment_entry)
|
||||
paid_amount = get_paid_amount(payment_entry, self.currency)
|
||||
if payment_entry.payment_document in ["Payment Entry", "Journal Entry", "Purchase Invoice", "Expense Claim"]:
|
||||
self.clear_simple_entry(payment_entry)
|
||||
|
||||
if paid_amount and allocated_amount:
|
||||
if flt(allocated_amount[0]["allocated_amount"]) > flt(paid_amount):
|
||||
frappe.throw(_("The total allocated amount ({0}) is greated than the paid amount ({1}).").format(flt(allocated_amount[0]["allocated_amount"]), flt(paid_amount)))
|
||||
else:
|
||||
if payment_entry.payment_document in ["Payment Entry", "Journal Entry", "Purchase Invoice", "Expense Claim"]:
|
||||
self.clear_simple_entry(payment_entry)
|
||||
|
||||
elif payment_entry.payment_document == "Sales Invoice":
|
||||
self.clear_sales_invoice(payment_entry)
|
||||
elif payment_entry.payment_document == "Sales Invoice":
|
||||
self.clear_sales_invoice(payment_entry)
|
||||
|
||||
def clear_simple_entry(self, payment_entry):
|
||||
frappe.db.set_value(payment_entry.payment_document, payment_entry.payment_entry, "clearance_date", self.date)
|
||||
@@ -112,3 +105,4 @@ def unclear_reference_payment(doctype, docname):
|
||||
frappe.db.set_value(doc.payment_document, doc.payment_entry, "clearance_date", None)
|
||||
|
||||
return doc.payment_entry
|
||||
|
||||
|
||||
@@ -5,10 +5,11 @@ from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
import json
|
||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
|
||||
from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
|
||||
from erpnext.accounts.page.bank_reconciliation.bank_reconciliation import reconcile, get_linked_payments
|
||||
from erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool import reconcile_vouchers, get_linked_payments
|
||||
from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profile
|
||||
|
||||
test_dependencies = ["Item", "Cost Center"]
|
||||
@@ -17,7 +18,7 @@ class TestBankTransaction(unittest.TestCase):
|
||||
def setUp(self):
|
||||
make_pos_profile()
|
||||
add_transactions()
|
||||
add_payments()
|
||||
add_vouchers()
|
||||
|
||||
def tearDown(self):
|
||||
for bt in frappe.get_all("Bank Transaction"):
|
||||
@@ -38,14 +39,18 @@ class TestBankTransaction(unittest.TestCase):
|
||||
# This test checks if ERPNext is able to provide a linked payment for a bank transaction based on the amount of the bank transaction.
|
||||
def test_linked_payments(self):
|
||||
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="Re 95282925234 FE/000002917 AT171513000281183046 Conrad Electronic"))
|
||||
linked_payments = get_linked_payments(bank_transaction.name)
|
||||
self.assertTrue(linked_payments[0].party == "Conrad Electronic")
|
||||
linked_payments = get_linked_payments(bank_transaction.name, ['payment_entry', 'exact_match'])
|
||||
self.assertTrue(linked_payments[0][6] == "Conrad Electronic")
|
||||
|
||||
# This test validates a simple reconciliation leading to the clearance of the bank transaction and the payment
|
||||
def test_reconcile(self):
|
||||
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="1512567 BG/000002918 OPSKATTUZWXXX AT776000000098709837 Herr G"))
|
||||
payment = frappe.get_doc("Payment Entry", dict(party="Mr G", paid_amount=1200))
|
||||
reconcile(bank_transaction.name, "Payment Entry", payment.name)
|
||||
vouchers = json.dumps([{
|
||||
"payment_doctype":"Payment Entry",
|
||||
"payment_name":payment.name,
|
||||
"amount":bank_transaction.unallocated_amount}])
|
||||
reconcile_vouchers(bank_transaction.name, vouchers)
|
||||
|
||||
unallocated_amount = frappe.db.get_value("Bank Transaction", bank_transaction.name, "unallocated_amount")
|
||||
self.assertTrue(unallocated_amount == 0)
|
||||
@@ -53,45 +58,40 @@ class TestBankTransaction(unittest.TestCase):
|
||||
clearance_date = frappe.db.get_value("Payment Entry", payment.name, "clearance_date")
|
||||
self.assertTrue(clearance_date is not None)
|
||||
|
||||
# Check if ERPNext can correctly fetch a linked payment based on the party
|
||||
def test_linked_payments_based_on_party(self):
|
||||
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="1512567 BG/000003025 OPSKATTUZWXXX AT776000000098709849 Herr G"))
|
||||
linked_payments = get_linked_payments(bank_transaction.name)
|
||||
self.assertTrue(len(linked_payments)==1)
|
||||
|
||||
# Check if ERPNext can correctly filter a linked payments based on the debit/credit amount
|
||||
def test_debit_credit_output(self):
|
||||
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="Auszahlung Karte MC/000002916 AUTOMAT 698769 K002 27.10. 14:07"))
|
||||
linked_payments = get_linked_payments(bank_transaction.name)
|
||||
self.assertTrue(linked_payments[0].payment_type == "Pay")
|
||||
linked_payments = get_linked_payments(bank_transaction.name, ['payment_entry', 'exact_match'])
|
||||
print(linked_payments)
|
||||
self.assertTrue(linked_payments[0][3])
|
||||
|
||||
# Check error if already reconciled
|
||||
def test_already_reconciled(self):
|
||||
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="1512567 BG/000002918 OPSKATTUZWXXX AT776000000098709837 Herr G"))
|
||||
payment = frappe.get_doc("Payment Entry", dict(party="Mr G", paid_amount=1200))
|
||||
reconcile(bank_transaction.name, "Payment Entry", payment.name)
|
||||
vouchers = json.dumps([{
|
||||
"payment_doctype":"Payment Entry",
|
||||
"payment_name":payment.name,
|
||||
"amount":bank_transaction.unallocated_amount}])
|
||||
reconcile_vouchers(bank_transaction.name, vouchers)
|
||||
|
||||
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="1512567 BG/000002918 OPSKATTUZWXXX AT776000000098709837 Herr G"))
|
||||
payment = frappe.get_doc("Payment Entry", dict(party="Mr G", paid_amount=1200))
|
||||
self.assertRaises(frappe.ValidationError, reconcile, bank_transaction=bank_transaction.name, payment_doctype="Payment Entry", payment_name=payment.name)
|
||||
|
||||
# Raise an error if creditor transaction vs creditor payment
|
||||
def test_invalid_creditor_reconcilation(self):
|
||||
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="I2015000011 VD/000002514 ATWWXXX AT4701345000003510057 Bio"))
|
||||
payment = frappe.get_doc("Payment Entry", dict(party="Conrad Electronic", paid_amount=690))
|
||||
self.assertRaises(frappe.ValidationError, reconcile, bank_transaction=bank_transaction.name, payment_doctype="Payment Entry", payment_name=payment.name)
|
||||
|
||||
# Raise an error if debitor transaction vs debitor payment
|
||||
def test_invalid_debitor_reconcilation(self):
|
||||
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="Auszahlung Karte MC/000002916 AUTOMAT 698769 K002 27.10. 14:07"))
|
||||
payment = frappe.get_doc("Payment Entry", dict(party="Fayva", paid_amount=109080))
|
||||
self.assertRaises(frappe.ValidationError, reconcile, bank_transaction=bank_transaction.name, payment_doctype="Payment Entry", payment_name=payment.name)
|
||||
vouchers = json.dumps([{
|
||||
"payment_doctype":"Payment Entry",
|
||||
"payment_name":payment.name,
|
||||
"amount":bank_transaction.unallocated_amount}])
|
||||
self.assertRaises(frappe.ValidationError, reconcile_vouchers, bank_transaction_name=bank_transaction.name, vouchers=vouchers)
|
||||
|
||||
# Raise an error if debitor transaction vs debitor payment
|
||||
def test_clear_sales_invoice(self):
|
||||
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="I2015000011 VD/000002514 ATWWXXX AT4701345000003510057 Bio"))
|
||||
payment = frappe.get_doc("Sales Invoice", dict(customer="Fayva", status=["=", "Paid"]))
|
||||
reconcile(bank_transaction.name, "Sales Invoice", payment.name)
|
||||
vouchers = json.dumps([{
|
||||
"payment_doctype":"Sales Invoice",
|
||||
"payment_name":payment.name,
|
||||
"amount":bank_transaction.unallocated_amount}])
|
||||
reconcile_vouchers(bank_transaction.name, vouchers=vouchers)
|
||||
|
||||
self.assertEqual(frappe.db.get_value("Bank Transaction", bank_transaction.name, "unallocated_amount"), 0)
|
||||
self.assertTrue(frappe.db.get_value("Sales Invoice Payment", dict(parent=payment.name), "clearance_date") is not None)
|
||||
@@ -126,7 +126,7 @@ def add_transactions():
|
||||
"doctype": "Bank Transaction",
|
||||
"description":"1512567 BG/000002918 OPSKATTUZWXXX AT776000000098709837 Herr G",
|
||||
"date": "2018-10-23",
|
||||
"debit": 1200,
|
||||
"deposit": 1200,
|
||||
"currency": "INR",
|
||||
"bank_account": "Checking Account - Citi Bank"
|
||||
}).insert()
|
||||
@@ -136,7 +136,7 @@ def add_transactions():
|
||||
"doctype": "Bank Transaction",
|
||||
"description":"1512567 BG/000003025 OPSKATTUZWXXX AT776000000098709849 Herr G",
|
||||
"date": "2018-10-23",
|
||||
"debit": 1700,
|
||||
"deposit": 1700,
|
||||
"currency": "INR",
|
||||
"bank_account": "Checking Account - Citi Bank"
|
||||
}).insert()
|
||||
@@ -146,7 +146,7 @@ def add_transactions():
|
||||
"doctype": "Bank Transaction",
|
||||
"description":"Re 95282925234 FE/000002917 AT171513000281183046 Conrad Electronic",
|
||||
"date": "2018-10-26",
|
||||
"debit": 690,
|
||||
"withdrawal": 690,
|
||||
"currency": "INR",
|
||||
"bank_account": "Checking Account - Citi Bank"
|
||||
}).insert()
|
||||
@@ -156,7 +156,7 @@ def add_transactions():
|
||||
"doctype": "Bank Transaction",
|
||||
"description":"Auszahlung Karte MC/000002916 AUTOMAT 698769 K002 27.10. 14:07",
|
||||
"date": "2018-10-27",
|
||||
"debit": 3900,
|
||||
"deposit": 3900,
|
||||
"currency": "INR",
|
||||
"bank_account": "Checking Account - Citi Bank"
|
||||
}).insert()
|
||||
@@ -166,7 +166,7 @@ def add_transactions():
|
||||
"doctype": "Bank Transaction",
|
||||
"description":"I2015000011 VD/000002514 ATWWXXX AT4701345000003510057 Bio",
|
||||
"date": "2018-10-27",
|
||||
"credit": 109080,
|
||||
"withdrawal": 109080,
|
||||
"currency": "INR",
|
||||
"bank_account": "Checking Account - Citi Bank"
|
||||
}).insert()
|
||||
@@ -174,7 +174,7 @@ def add_transactions():
|
||||
|
||||
frappe.flags.test_bank_transactions_created = True
|
||||
|
||||
def add_payments():
|
||||
def add_vouchers():
|
||||
if frappe.flags.test_payments_created:
|
||||
return
|
||||
|
||||
@@ -192,6 +192,7 @@ def add_payments():
|
||||
pass
|
||||
|
||||
pi = make_purchase_invoice(supplier="Conrad Electronic", qty=1, rate=690)
|
||||
|
||||
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
|
||||
pe.reference_no = "Conrad Oct 18"
|
||||
pe.reference_date = "2018-10-24"
|
||||
@@ -242,10 +243,15 @@ def add_payments():
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
|
||||
pi = make_purchase_invoice(supplier="Poore Simon's", qty=1, rate=3900)
|
||||
pi = make_purchase_invoice(supplier="Poore Simon's", qty=1, rate=3900, is_paid=1, do_not_save =1)
|
||||
pi.cash_bank_account = "_Test Bank - _TC"
|
||||
pi.insert()
|
||||
pi.submit()
|
||||
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
|
||||
pe.reference_no = "Poore Simon's Oct 18"
|
||||
pe.reference_date = "2018-10-28"
|
||||
pe.paid_amount = 690
|
||||
pe.received_amount = 690
|
||||
pe.insert()
|
||||
pe.submit()
|
||||
|
||||
@@ -295,4 +301,4 @@ def add_payments():
|
||||
si.save()
|
||||
si.submit()
|
||||
|
||||
frappe.flags.test_payments_created = True
|
||||
frappe.flags.test_payments_created = True
|
||||
|
||||
@@ -22,9 +22,10 @@ def validate_company(company):
|
||||
'allow_account_creation_against_child_company'])
|
||||
|
||||
if parent_company and (not allow_account_creation_against_child_company):
|
||||
frappe.throw(_("""{0} is a child company. Please import accounts against parent company
|
||||
or enable {1} in company master""").format(frappe.bold(company),
|
||||
frappe.bold('Allow Account Creation Against Child Company')), title='Wrong Company')
|
||||
msg = _("{} is a child company. ").format(frappe.bold(company))
|
||||
msg += _("Please import accounts against parent company or enable {} in company master.").format(
|
||||
frappe.bold('Allow Account Creation Against Child Company'))
|
||||
frappe.throw(msg, title=_('Wrong Company'))
|
||||
|
||||
if frappe.db.get_all('GL Entry', {"company": company}, "name", limit=1):
|
||||
return False
|
||||
@@ -74,7 +75,9 @@ def generate_data_from_csv(file_doc, as_dict=False):
|
||||
if as_dict:
|
||||
data.append({frappe.scrub(header): row[index] for index, header in enumerate(headers)})
|
||||
else:
|
||||
if not row[1]: row[1] = row[0]
|
||||
if not row[1]:
|
||||
row[1] = row[0]
|
||||
row[3] = row[2]
|
||||
data.append(row)
|
||||
|
||||
# convert csv data
|
||||
@@ -96,7 +99,9 @@ def generate_data_from_excel(file_doc, extension, as_dict=False):
|
||||
if as_dict:
|
||||
data.append({frappe.scrub(header): row[index] for index, header in enumerate(headers)})
|
||||
else:
|
||||
if not row[1]: row[1] = row[0]
|
||||
if not row[1]:
|
||||
row[1] = row[0]
|
||||
row[3] = row[2]
|
||||
data.append(row)
|
||||
|
||||
return data
|
||||
@@ -147,7 +152,13 @@ def build_forest(data):
|
||||
from frappe import _
|
||||
|
||||
for row in data:
|
||||
account_name, parent_account = row[0:2]
|
||||
account_name, parent_account, account_number, parent_account_number = row[0:4]
|
||||
if account_number:
|
||||
account_name = "{} - {}".format(account_number, account_name)
|
||||
if parent_account_number:
|
||||
parent_account_number = cstr(parent_account_number).strip()
|
||||
parent_account = "{} - {}".format(parent_account_number, parent_account)
|
||||
|
||||
if parent_account == account_name == child:
|
||||
return [parent_account]
|
||||
elif account_name == child:
|
||||
@@ -159,20 +170,23 @@ def build_forest(data):
|
||||
|
||||
charts_map, paths = {}, []
|
||||
|
||||
line_no = 3
|
||||
line_no = 2
|
||||
error_messages = []
|
||||
|
||||
for i in data:
|
||||
account_name, dummy, account_number, is_group, account_type, root_type = i
|
||||
account_name, parent_account, account_number, parent_account_number, is_group, account_type, root_type = i
|
||||
|
||||
if not account_name:
|
||||
error_messages.append("Row {0}: Please enter Account Name".format(line_no))
|
||||
|
||||
if account_number:
|
||||
account_number = cstr(account_number).strip()
|
||||
account_name = "{} - {}".format(account_number, account_name)
|
||||
|
||||
charts_map[account_name] = {}
|
||||
if cint(is_group) == 1: charts_map[account_name]["is_group"] = is_group
|
||||
if account_type: charts_map[account_name]["account_type"] = account_type
|
||||
if root_type: charts_map[account_name]["root_type"] = root_type
|
||||
if account_number: charts_map[account_name]["account_number"] = account_number
|
||||
path = return_parent(data, account_name)[::-1]
|
||||
paths.append(path) # List of path is created
|
||||
line_no += 1
|
||||
@@ -221,7 +235,7 @@ def download_template(file_type, template_type):
|
||||
|
||||
def get_template(template_type):
|
||||
|
||||
fields = ["Account Name", "Parent Account", "Account Number", "Is Group", "Account Type", "Root Type"]
|
||||
fields = ["Account Name", "Parent Account", "Account Number", "Parent Account Number", "Is Group", "Account Type", "Root Type"]
|
||||
writer = UnicodeWriter()
|
||||
writer.writerow(fields)
|
||||
|
||||
@@ -241,23 +255,23 @@ def get_template(template_type):
|
||||
|
||||
def get_sample_template(writer):
|
||||
template = [
|
||||
["Application Of Funds(Assets)", "", "", 1, "", "Asset"],
|
||||
["Sources Of Funds(Liabilities)", "", "", 1, "", "Liability"],
|
||||
["Equity", "", "", 1, "", "Equity"],
|
||||
["Expenses", "", "", 1, "", "Expense"],
|
||||
["Income", "", "", 1, "", "Income"],
|
||||
["Bank Accounts", "Application Of Funds(Assets)", "", 1, "Bank", "Asset"],
|
||||
["Cash In Hand", "Application Of Funds(Assets)", "", 1, "Cash", "Asset"],
|
||||
["Stock Assets", "Application Of Funds(Assets)", "", 1, "Stock", "Asset"],
|
||||
["Cost Of Goods Sold", "Expenses", "", 0, "Cost of Goods Sold", "Expense"],
|
||||
["Asset Depreciation", "Expenses", "", 0, "Depreciation", "Expense"],
|
||||
["Fixed Assets", "Application Of Funds(Assets)", "", 0, "Fixed Asset", "Asset"],
|
||||
["Accounts Payable", "Sources Of Funds(Liabilities)", "", 0, "Payable", "Liability"],
|
||||
["Accounts Receivable", "Application Of Funds(Assets)", "", 1, "Receivable", "Asset"],
|
||||
["Stock Expenses", "Expenses", "", 0, "Stock Adjustment", "Expense"],
|
||||
["Sample Bank", "Bank Accounts", "", 0, "Bank", "Asset"],
|
||||
["Cash", "Cash In Hand", "", 0, "Cash", "Asset"],
|
||||
["Stores", "Stock Assets", "", 0, "Stock", "Asset"],
|
||||
["Application Of Funds(Assets)", "", "", "", 1, "", "Asset"],
|
||||
["Sources Of Funds(Liabilities)", "", "", "", 1, "", "Liability"],
|
||||
["Equity", "", "", "", 1, "", "Equity"],
|
||||
["Expenses", "", "", "", 1, "", "Expense"],
|
||||
["Income", "", "", "", 1, "", "Income"],
|
||||
["Bank Accounts", "Application Of Funds(Assets)", "", "", 1, "Bank", "Asset"],
|
||||
["Cash In Hand", "Application Of Funds(Assets)", "", "", 1, "Cash", "Asset"],
|
||||
["Stock Assets", "Application Of Funds(Assets)", "", "", 1, "Stock", "Asset"],
|
||||
["Cost Of Goods Sold", "Expenses", "", "", 0, "Cost of Goods Sold", "Expense"],
|
||||
["Asset Depreciation", "Expenses", "", "", 0, "Depreciation", "Expense"],
|
||||
["Fixed Assets", "Application Of Funds(Assets)", "", "", 0, "Fixed Asset", "Asset"],
|
||||
["Accounts Payable", "Sources Of Funds(Liabilities)", "", "", 0, "Payable", "Liability"],
|
||||
["Accounts Receivable", "Application Of Funds(Assets)", "", "", 1, "Receivable", "Asset"],
|
||||
["Stock Expenses", "Expenses", "", "", 0, "Stock Adjustment", "Expense"],
|
||||
["Sample Bank", "Bank Accounts", "", "", 0, "Bank", "Asset"],
|
||||
["Cash", "Cash In Hand", "", "", 0, "Cash", "Asset"],
|
||||
["Stores", "Stock Assets", "", "", 0, "Stock", "Asset"],
|
||||
]
|
||||
|
||||
for row in template:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:title",
|
||||
"creation": "2018-11-22 22:45:00.370913",
|
||||
"doctype": "DocType",
|
||||
"document_type": "Setup",
|
||||
@@ -20,8 +20,7 @@
|
||||
"in_list_view": 1,
|
||||
"label": "Title",
|
||||
"no_copy": 1,
|
||||
"reqd": 1,
|
||||
"unique": 1
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "taxes",
|
||||
@@ -33,12 +32,14 @@
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Company",
|
||||
"options": "Company",
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"modified": "2020-09-18 17:26:09.703215",
|
||||
"links": [],
|
||||
"modified": "2021-03-08 19:50:21.416513",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Item Tax Template",
|
||||
@@ -81,5 +82,6 @@
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "title",
|
||||
"track_changes": 1
|
||||
}
|
||||
@@ -11,6 +11,11 @@ class ItemTaxTemplate(Document):
|
||||
def validate(self):
|
||||
self.validate_tax_accounts()
|
||||
|
||||
def autoname(self):
|
||||
if self.company and self.title:
|
||||
abbr = frappe.get_cached_value('Company', self.company, 'abbr')
|
||||
self.name = '{0} - {1}'.format(self.title, abbr)
|
||||
|
||||
def validate_tax_accounts(self):
|
||||
"""Check whether Tax Rate is not entered twice for same Tax Type"""
|
||||
check_list = []
|
||||
|
||||
@@ -102,7 +102,7 @@ class JournalEntry(AccountsController):
|
||||
if account_currency == previous_account_currency:
|
||||
if self.total_credit != doc.total_debit or self.total_debit != doc.total_credit:
|
||||
frappe.throw(_("Total Credit/ Debit Amount should be same as linked Journal Entry"))
|
||||
|
||||
|
||||
def validate_stock_accounts(self):
|
||||
stock_accounts = get_stock_accounts(self.company, self.doctype, self.name)
|
||||
for account in stock_accounts:
|
||||
@@ -229,11 +229,11 @@ class JournalEntry(AccountsController):
|
||||
if d.reference_type=="Journal Entry":
|
||||
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 accounts can be linked against another debit entry")
|
||||
.format(d.account))
|
||||
frappe.throw(_("Row #{0}: For {1}, you can select reference document only if account gets credited")
|
||||
.format(d.idx, d.account))
|
||||
elif account_root_type == "Liability" and flt(d.credit) > 0:
|
||||
frappe.throw(_("For {0}, only debit accounts can be linked against another credit entry")
|
||||
.format(d.account))
|
||||
frappe.throw(_("Row #{0}: For {1}, you can select reference document only if account gets debited")
|
||||
.format(d.idx, d.account))
|
||||
|
||||
if d.reference_name == self.name:
|
||||
frappe.throw(_("You can not enter current voucher in 'Against Journal Entry' column"))
|
||||
@@ -1077,4 +1077,4 @@ def make_reverse_journal_entry(source_name, target_doc=None):
|
||||
},
|
||||
}, target_doc)
|
||||
|
||||
return doclist
|
||||
return doclist
|
||||
|
||||
@@ -12,7 +12,7 @@ class ModeofPayment(Document):
|
||||
self.validate_accounts()
|
||||
self.validate_repeating_companies()
|
||||
self.validate_pos_mode_of_payment()
|
||||
|
||||
|
||||
def validate_repeating_companies(self):
|
||||
"""Error when Same Company is entered multiple times in accounts"""
|
||||
accounts_list = []
|
||||
@@ -31,10 +31,10 @@ class ModeofPayment(Document):
|
||||
|
||||
def validate_pos_mode_of_payment(self):
|
||||
if not self.enabled:
|
||||
pos_profiles = frappe.db.sql("""SELECT sip.parent FROM `tabSales Invoice Payment` sip
|
||||
pos_profiles = frappe.db.sql("""SELECT sip.parent FROM `tabSales Invoice Payment` sip
|
||||
WHERE sip.parenttype = 'POS Profile' and sip.mode_of_payment = %s""", (self.name))
|
||||
pos_profiles = list(map(lambda x: x[0], pos_profiles))
|
||||
|
||||
|
||||
if pos_profiles:
|
||||
message = "POS Profile " + frappe.bold(", ".join(pos_profiles)) + " contains \
|
||||
Mode of Payment " + frappe.bold(str(self.name)) + ". Please remove them to disable this mode."
|
||||
|
||||
@@ -121,7 +121,8 @@ frappe.ui.form.on('Opening Invoice Creation Tool', {
|
||||
frappe.render_template('opening_invoice_creation_tool_dashboard', {
|
||||
data: opening_invoices_summary,
|
||||
max_count: max_count
|
||||
})
|
||||
}),
|
||||
__("Opening Invoices Summary")
|
||||
);
|
||||
|
||||
section.on('click', '.invoice-link', function() {
|
||||
|
||||
@@ -64,11 +64,11 @@ class OpeningInvoiceCreationTool(Document):
|
||||
prepare_invoice_summary(doctype, invoices)
|
||||
|
||||
return invoices_summary, max_count
|
||||
|
||||
|
||||
def validate_company(self):
|
||||
if not self.company:
|
||||
frappe.throw(_("Please select the Company"))
|
||||
|
||||
|
||||
def set_missing_values(self, row):
|
||||
row.qty = row.qty or 1.0
|
||||
row.temporary_opening_account = row.temporary_opening_account or get_temporary_opening_account(self.company)
|
||||
@@ -198,6 +198,7 @@ def start_import(invoices):
|
||||
try:
|
||||
publish(idx, len(invoices), d.doctype)
|
||||
doc = frappe.get_doc(d)
|
||||
doc.flags.ignore_mandatory = True
|
||||
doc.insert()
|
||||
doc.submit()
|
||||
frappe.db.commit()
|
||||
@@ -210,7 +211,7 @@ def start_import(invoices):
|
||||
frappe.db.commit()
|
||||
if errors:
|
||||
frappe.msgprint(_("You had {} errors while creating opening invoices. Check {} for more details")
|
||||
.format(errors, "<a href='#List/Error Log' class='variant-click'>Error Log</a>"), indicator="red", title=_("Error Occured"))
|
||||
.format(errors, "<a href='/app/List/Error Log' class='variant-click'>Error Log</a>"), indicator="red", title=_("Error Occured"))
|
||||
return names
|
||||
|
||||
def publish(index, total, doctype):
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
<h5 style="margin-top: 0px;">{{ __("Opening Invoices Summary") }}</h5>
|
||||
{% $.each(data, (company, summary) => { %}
|
||||
<h6 style="margin: 15px 0px -10px 0px;"><a class="company-link"> {{ company }}</a></h6>
|
||||
|
||||
|
||||
@@ -92,14 +92,16 @@ frappe.ui.form.on('Payment Entry', {
|
||||
});
|
||||
|
||||
frm.set_query("reference_doctype", "references", function() {
|
||||
if (frm.doc.party_type=="Customer") {
|
||||
if (frm.doc.party_type == "Customer") {
|
||||
var doctypes = ["Sales Order", "Sales Invoice", "Journal Entry", "Dunning"];
|
||||
} else if (frm.doc.party_type=="Supplier") {
|
||||
} else if (frm.doc.party_type == "Supplier") {
|
||||
var doctypes = ["Purchase Order", "Purchase Invoice", "Journal Entry"];
|
||||
} else if (frm.doc.party_type=="Employee") {
|
||||
} else if (frm.doc.party_type == "Employee") {
|
||||
var doctypes = ["Expense Claim", "Journal Entry"];
|
||||
} else if (frm.doc.party_type=="Student") {
|
||||
} else if (frm.doc.party_type == "Student") {
|
||||
var doctypes = ["Fees"];
|
||||
} else if (frm.doc.party_type == "Donor") {
|
||||
var doctypes = ["Donation"];
|
||||
} else {
|
||||
var doctypes = ["Journal Entry"];
|
||||
}
|
||||
@@ -128,7 +130,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
const child = locals[cdt][cdn];
|
||||
const filters = {"docstatus": 1, "company": doc.company};
|
||||
const party_type_doctypes = ['Sales Invoice', 'Sales Order', 'Purchase Invoice',
|
||||
'Purchase Order', 'Expense Claim', 'Fees', 'Dunning'];
|
||||
'Purchase Order', 'Expense Claim', 'Fees', 'Dunning', 'Donation'];
|
||||
|
||||
if (in_list(party_type_doctypes, child.reference_doctype)) {
|
||||
filters[doc.party_type.toLowerCase()] = doc.party;
|
||||
@@ -281,7 +283,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
let party_types = Object.keys(frappe.boot.party_account_types);
|
||||
if(frm.doc.party_type && !party_types.includes(frm.doc.party_type)){
|
||||
frm.set_value("party_type", "");
|
||||
frappe.throw(__("Party can only be one of "+ party_types.join(", ")));
|
||||
frappe.throw(__("Party can only be one of {0}", [party_types.join(", ")]));
|
||||
}
|
||||
|
||||
frm.set_query("party", function() {
|
||||
@@ -603,12 +605,22 @@ frappe.ui.form.on('Payment Entry', {
|
||||
{fieldtype:"Column Break"},
|
||||
{fieldtype:"Float", label: __("Less Than Amount"), fieldname:"outstanding_amt_less_than"},
|
||||
{fieldtype:"Section Break"},
|
||||
{fieldtype:"Link", label:__("Cost Center"), fieldname:"cost_center", options:"Cost Center",
|
||||
"get_query": function() {
|
||||
return {
|
||||
"filters": {"company": frm.doc.company}
|
||||
}
|
||||
}
|
||||
},
|
||||
{fieldtype:"Column Break"},
|
||||
{fieldtype:"Section Break"},
|
||||
{fieldtype:"Check", label: __("Allocate Payment Amount"), fieldname:"allocate_payment_amount", default:1},
|
||||
];
|
||||
|
||||
frappe.prompt(fields, function(filters){
|
||||
frappe.flags.allocate_payment_amount = true;
|
||||
frm.events.validate_filters_data(frm, filters);
|
||||
frm.doc.cost_center = filters.cost_center;
|
||||
frm.events.get_outstanding_documents(frm, filters);
|
||||
}, __("Filters"), __("Get Outstanding Documents"));
|
||||
},
|
||||
@@ -625,13 +637,13 @@ frappe.ui.form.on('Payment Entry', {
|
||||
let to_field = fields[key][1];
|
||||
|
||||
if (filters[from_field] && !filters[to_field]) {
|
||||
frappe.throw(__("Error: {0} is mandatory field",
|
||||
[to_field.replace(/_/g, " ")]
|
||||
));
|
||||
frappe.throw(
|
||||
__("Error: {0} is mandatory field", [to_field.replace(/_/g, " ")])
|
||||
);
|
||||
} else if (filters[from_field] && filters[from_field] > filters[to_field]) {
|
||||
frappe.throw(__("{0}: {1} must be less than {2}",
|
||||
[key, from_field.replace(/_/g, " "), to_field.replace(/_/g, " ")]
|
||||
));
|
||||
frappe.throw(
|
||||
__("{0}: {1} must be less than {2}", [key, from_field.replace(/_/g, " "), to_field.replace(/_/g, " ")])
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -680,6 +692,8 @@ frappe.ui.form.on('Payment Entry', {
|
||||
c.total_amount = d.invoice_amount;
|
||||
c.outstanding_amount = d.outstanding_amount;
|
||||
c.bill_no = d.bill_no;
|
||||
c.payment_term = d.payment_term;
|
||||
c.allocated_amount = d.allocated_amount;
|
||||
|
||||
if(!in_list(["Sales Order", "Purchase Order", "Expense Claim", "Fees"], d.voucher_type)) {
|
||||
if(flt(d.outstanding_amount) > 0)
|
||||
@@ -705,7 +719,8 @@ frappe.ui.form.on('Payment Entry', {
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee") ||
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Student")
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Student") ||
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Donor")
|
||||
) {
|
||||
if(total_positive_outstanding > total_negative_outstanding)
|
||||
if (!frm.doc.paid_amount)
|
||||
@@ -748,7 +763,8 @@ frappe.ui.form.on('Payment Entry', {
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee") ||
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Student")
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Student") ||
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Donor")
|
||||
) {
|
||||
if(total_positive_outstanding_including_order > paid_amount) {
|
||||
var remaining_outstanding = total_positive_outstanding_including_order - paid_amount;
|
||||
@@ -760,12 +776,15 @@ frappe.ui.form.on('Payment Entry', {
|
||||
} else if (in_list(["Customer", "Supplier"], frm.doc.party_type)) {
|
||||
if(paid_amount > total_negative_outstanding) {
|
||||
if(total_negative_outstanding == 0) {
|
||||
frappe.msgprint(__("Cannot {0} {1} {2} without any negative outstanding invoice",
|
||||
[frm.doc.payment_type,
|
||||
(frm.doc.party_type=="Customer" ? "to" : "from"), frm.doc.party_type]));
|
||||
frappe.msgprint(
|
||||
__("Cannot {0} {1} {2} without any negative outstanding invoice", [frm.doc.payment_type,
|
||||
(frm.doc.party_type=="Customer" ? "to" : "from"), frm.doc.party_type])
|
||||
);
|
||||
return false
|
||||
} else {
|
||||
frappe.msgprint(__("Paid Amount cannot be greater than total negative outstanding amount {0}", [total_negative_outstanding]));
|
||||
frappe.msgprint(
|
||||
__("Paid Amount cannot be greater than total negative outstanding amount {0}", [total_negative_outstanding])
|
||||
);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
@@ -777,10 +796,13 @@ frappe.ui.form.on('Payment Entry', {
|
||||
}
|
||||
|
||||
$.each(frm.doc.references || [], function(i, row) {
|
||||
row.allocated_amount = 0 //If allocate payment amount checkbox is unchecked, set zero to allocate amount
|
||||
if(frappe.flags.allocate_payment_amount != 0){
|
||||
if(row.outstanding_amount > 0 && allocated_positive_outstanding > 0) {
|
||||
if(row.outstanding_amount >= allocated_positive_outstanding) {
|
||||
if (frappe.flags.allocate_payment_amount == 0) {
|
||||
//If allocate payment amount checkbox is unchecked, set zero to allocate amount
|
||||
row.allocated_amount = 0;
|
||||
|
||||
} else if (frappe.flags.allocate_payment_amount != 0 && !row.allocated_amount) {
|
||||
if (row.outstanding_amount > 0 && allocated_positive_outstanding > 0) {
|
||||
if (row.outstanding_amount >= allocated_positive_outstanding) {
|
||||
row.allocated_amount = allocated_positive_outstanding;
|
||||
} else {
|
||||
row.allocated_amount = row.outstanding_amount;
|
||||
@@ -788,9 +810,11 @@ frappe.ui.form.on('Payment Entry', {
|
||||
|
||||
allocated_positive_outstanding -= flt(row.allocated_amount);
|
||||
} else if (row.outstanding_amount < 0 && allocated_negative_outstanding) {
|
||||
if(Math.abs(row.outstanding_amount) >= allocated_negative_outstanding)
|
||||
if (Math.abs(row.outstanding_amount) >= allocated_negative_outstanding) {
|
||||
row.allocated_amount = -1*allocated_negative_outstanding;
|
||||
else row.allocated_amount = row.outstanding_amount;
|
||||
} else {
|
||||
row.allocated_amount = row.outstanding_amount;
|
||||
};
|
||||
|
||||
allocated_negative_outstanding -= Math.abs(flt(row.allocated_amount));
|
||||
}
|
||||
@@ -905,6 +929,12 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frappe.msgprint(__("Row #{0}: Reference Document Type must be one of Expense Claim or Journal Entry", [row.idx]));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (frm.doc.party_type == "Donor" && row.reference_doctype != "Donation") {
|
||||
frappe.model.set_value(row.doctype, row.name, "reference_doctype", null);
|
||||
frappe.msgprint(__("Row #{0}: Reference Document Type must be Donation", [row.idx]));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (row) {
|
||||
@@ -1056,11 +1086,6 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frm.set_value("paid_from_account_balance", r.message.paid_from_account_balance);
|
||||
frm.set_value("paid_to_account_balance", r.message.paid_to_account_balance);
|
||||
frm.set_value("party_balance", r.message.party_balance);
|
||||
},
|
||||
() => {
|
||||
if(frm.doc.payment_type != "Internal") {
|
||||
frm.clear_table("references");
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
|
||||
@@ -536,7 +536,8 @@
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Title",
|
||||
"print_hide": 1
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "party",
|
||||
@@ -588,7 +589,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-10-30 13:56:20.007336",
|
||||
"modified": "2021-03-08 13:05:16.958866",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Entry",
|
||||
@@ -632,4 +633,4 @@
|
||||
"sort_order": "DESC",
|
||||
"title_field": "title",
|
||||
"track_changes": 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ class PaymentEntry(AccountsController):
|
||||
self.update_outstanding_amounts()
|
||||
self.update_advance_paid()
|
||||
self.update_expense_claim()
|
||||
self.update_donation()
|
||||
self.update_payment_schedule()
|
||||
self.set_status()
|
||||
|
||||
@@ -82,6 +83,7 @@ class PaymentEntry(AccountsController):
|
||||
self.update_outstanding_amounts()
|
||||
self.update_advance_paid()
|
||||
self.update_expense_claim()
|
||||
self.update_donation(cancel=1)
|
||||
self.delink_advance_entry_references()
|
||||
self.update_payment_schedule(cancel=1)
|
||||
self.set_payment_req_status()
|
||||
@@ -242,9 +244,11 @@ class PaymentEntry(AccountsController):
|
||||
elif self.party_type == "Supplier":
|
||||
valid_reference_doctypes = ("Purchase Order", "Purchase Invoice", "Journal Entry")
|
||||
elif self.party_type == "Employee":
|
||||
valid_reference_doctypes = ("Expense Claim", "Journal Entry", "Employee Advance")
|
||||
valid_reference_doctypes = ("Expense Claim", "Journal Entry", "Employee Advance", "Gratuity")
|
||||
elif self.party_type == "Shareholder":
|
||||
valid_reference_doctypes = ("Journal Entry")
|
||||
elif self.party_type == "Donor":
|
||||
valid_reference_doctypes = ("Donation")
|
||||
|
||||
for d in self.get("references"):
|
||||
if not d.allocated_amount:
|
||||
@@ -329,33 +333,50 @@ class PaymentEntry(AccountsController):
|
||||
invoice_payment_amount_map = {}
|
||||
invoice_paid_amount_map = {}
|
||||
|
||||
for reference in self.get('references'):
|
||||
if reference.payment_term and reference.reference_name:
|
||||
key = (reference.payment_term, reference.reference_name)
|
||||
for ref in self.get('references'):
|
||||
if ref.payment_term and ref.reference_name:
|
||||
key = (ref.payment_term, ref.reference_name)
|
||||
invoice_payment_amount_map.setdefault(key, 0.0)
|
||||
invoice_payment_amount_map[key] += reference.allocated_amount
|
||||
invoice_payment_amount_map[key] += ref.allocated_amount
|
||||
|
||||
if not invoice_paid_amount_map.get(key):
|
||||
payment_schedule = frappe.get_all('Payment Schedule', filters={'parent': reference.reference_name},
|
||||
fields=['paid_amount', 'payment_amount', 'payment_term'])
|
||||
payment_schedule = frappe.get_all(
|
||||
'Payment Schedule',
|
||||
filters={'parent': ref.reference_name},
|
||||
fields=['paid_amount', 'payment_amount', 'payment_term', 'discount', 'outstanding']
|
||||
)
|
||||
for term in payment_schedule:
|
||||
invoice_key = (term.payment_term, reference.reference_name)
|
||||
invoice_key = (term.payment_term, ref.reference_name)
|
||||
invoice_paid_amount_map.setdefault(invoice_key, {})
|
||||
invoice_paid_amount_map[invoice_key]['outstanding'] = term.payment_amount - term.paid_amount
|
||||
invoice_paid_amount_map[invoice_key]['outstanding'] = term.outstanding
|
||||
invoice_paid_amount_map[invoice_key]['discounted_amt'] = ref.total_amount * (term.discount / 100)
|
||||
|
||||
for key, allocated_amount in iteritems(invoice_payment_amount_map):
|
||||
outstanding = flt(invoice_paid_amount_map.get(key, {}).get('outstanding'))
|
||||
discounted_amt = flt(invoice_paid_amount_map.get(key, {}).get('discounted_amt'))
|
||||
|
||||
for key, amount in iteritems(invoice_payment_amount_map):
|
||||
if cancel:
|
||||
frappe.db.sql(""" UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` - %s
|
||||
WHERE parent = %s and payment_term = %s""", (amount, key[1], key[0]))
|
||||
frappe.db.sql("""
|
||||
UPDATE `tabPayment Schedule`
|
||||
SET
|
||||
paid_amount = `paid_amount` - %s,
|
||||
discounted_amount = `discounted_amount` - %s,
|
||||
outstanding = `outstanding` + %s
|
||||
WHERE parent = %s and payment_term = %s""",
|
||||
(allocated_amount - discounted_amt, discounted_amt, allocated_amount, key[1], key[0]))
|
||||
else:
|
||||
outstanding = flt(invoice_paid_amount_map.get(key, {}).get('outstanding'))
|
||||
|
||||
if amount > outstanding:
|
||||
if allocated_amount > outstanding:
|
||||
frappe.throw(_('Cannot allocate more than {0} against payment term {1}').format(outstanding, key[0]))
|
||||
|
||||
if amount and outstanding:
|
||||
frappe.db.sql(""" UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` + %s
|
||||
WHERE parent = %s and payment_term = %s""", (amount, key[1], key[0]))
|
||||
if allocated_amount and outstanding:
|
||||
frappe.db.sql("""
|
||||
UPDATE `tabPayment Schedule`
|
||||
SET
|
||||
paid_amount = `paid_amount` + %s,
|
||||
discounted_amount = `discounted_amount` + %s,
|
||||
outstanding = `outstanding` - %s
|
||||
WHERE parent = %s and payment_term = %s""",
|
||||
(allocated_amount - discounted_amt, discounted_amt, allocated_amount, key[1], key[0]))
|
||||
|
||||
def set_status(self):
|
||||
if self.docstatus == 2:
|
||||
@@ -455,6 +476,10 @@ class PaymentEntry(AccountsController):
|
||||
.format(total_negative_outstanding), InvalidPaymentEntry)
|
||||
|
||||
def set_title(self):
|
||||
if frappe.flags.in_import and self.title:
|
||||
# do not set title dynamically if title exists during data import.
|
||||
return
|
||||
|
||||
if self.payment_type in ("Receive", "Pay"):
|
||||
self.title = self.party
|
||||
else:
|
||||
@@ -604,7 +629,7 @@ class PaymentEntry(AccountsController):
|
||||
if self.payment_type in ("Receive", "Pay") and self.party:
|
||||
for d in self.get("references"):
|
||||
if d.allocated_amount \
|
||||
and d.reference_doctype in ("Sales Order", "Purchase Order", "Employee Advance"):
|
||||
and d.reference_doctype in ("Sales Order", "Purchase Order", "Employee Advance", "Gratuity"):
|
||||
frappe.get_doc(d.reference_doctype, d.reference_name).set_total_advance_paid()
|
||||
|
||||
def update_expense_claim(self):
|
||||
@@ -614,6 +639,13 @@ class PaymentEntry(AccountsController):
|
||||
doc = frappe.get_doc("Expense Claim", d.reference_name)
|
||||
update_reimbursed_amount(doc, self.name)
|
||||
|
||||
def update_donation(self, cancel=0):
|
||||
if self.payment_type == "Receive" and self.party_type == "Donor" and self.party:
|
||||
for d in self.get("references"):
|
||||
if d.reference_doctype=="Donation" and d.reference_name:
|
||||
is_paid = 0 if cancel else 1
|
||||
frappe.db.set_value("Donation", d.reference_name, "paid", is_paid)
|
||||
|
||||
def on_recurring(self, reference_doc, auto_repeat_doc):
|
||||
self.reference_no = reference_doc.name
|
||||
self.reference_date = nowdate()
|
||||
@@ -693,6 +725,8 @@ def get_outstanding_reference_documents(args):
|
||||
outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"),
|
||||
args.get("party_account"), filters=args, condition=condition)
|
||||
|
||||
outstanding_invoices = split_invoices_based_on_payment_terms(outstanding_invoices)
|
||||
|
||||
for d in outstanding_invoices:
|
||||
d["exchange_rate"] = 1
|
||||
if party_account_currency != company_currency:
|
||||
@@ -720,6 +754,46 @@ def get_outstanding_reference_documents(args):
|
||||
return data
|
||||
|
||||
|
||||
def split_invoices_based_on_payment_terms(outstanding_invoices):
|
||||
invoice_ref_based_on_payment_terms = {}
|
||||
for idx, d in enumerate(outstanding_invoices):
|
||||
if d.voucher_type in ['Sales Invoice', 'Purchase Invoice']:
|
||||
payment_term_template = frappe.db.get_value(d.voucher_type, d.voucher_no, 'payment_terms_template')
|
||||
if payment_term_template:
|
||||
allocate_payment_based_on_payment_terms = frappe.db.get_value(
|
||||
'Payment Terms Template', payment_term_template, 'allocate_payment_based_on_payment_terms')
|
||||
if allocate_payment_based_on_payment_terms:
|
||||
payment_schedule = frappe.get_all('Payment Schedule', filters={'parent': d.voucher_no}, fields=["*"])
|
||||
|
||||
for payment_term in payment_schedule:
|
||||
if payment_term.outstanding > 0.1:
|
||||
invoice_ref_based_on_payment_terms.setdefault(idx, [])
|
||||
invoice_ref_based_on_payment_terms[idx].append(frappe._dict({
|
||||
'due_date': d.due_date,
|
||||
'currency': d.currency,
|
||||
'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.outstanding_amount),
|
||||
'payment_amount': payment_term.payment_amount,
|
||||
'payment_term': payment_term.payment_term,
|
||||
'allocated_amount': payment_term.outstanding
|
||||
}))
|
||||
|
||||
if invoice_ref_based_on_payment_terms:
|
||||
for idx, ref in invoice_ref_based_on_payment_terms.items():
|
||||
voucher_no = outstanding_invoices[idx]['voucher_no']
|
||||
voucher_type = outstanding_invoices[idx]['voucher_type']
|
||||
|
||||
frappe.msgprint(_("Spliting {} {} into {} rows as per payment terms").format(
|
||||
voucher_type, voucher_no, len(ref)), alert=True)
|
||||
|
||||
outstanding_invoices.pop(idx - 1)
|
||||
outstanding_invoices += invoice_ref_based_on_payment_terms[idx]
|
||||
|
||||
return outstanding_invoices
|
||||
|
||||
def get_orders_to_be_billed(posting_date, party_type, party,
|
||||
company, party_account_currency, company_currency, cost_center=None, filters=None):
|
||||
if party_type == "Customer":
|
||||
@@ -913,6 +987,9 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
||||
total_amount = ref_doc.get("grand_total")
|
||||
exchange_rate = 1
|
||||
outstanding_amount = ref_doc.get("outstanding_amount")
|
||||
elif reference_doctype == "Donation":
|
||||
total_amount = ref_doc.get("amount")
|
||||
exchange_rate = 1
|
||||
elif reference_doctype == "Dunning":
|
||||
total_amount = ref_doc.get("dunning_amount")
|
||||
exchange_rate = 1
|
||||
@@ -932,6 +1009,8 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
||||
exchange_rate = ref_doc.get("exchange_rate")
|
||||
if party_account_currency != ref_doc.currency:
|
||||
total_amount = flt(total_amount) * flt(exchange_rate)
|
||||
elif ref_doc.doctype == "Gratuity":
|
||||
total_amount = ref_doc.amount
|
||||
if not total_amount:
|
||||
if party_account_currency == company_currency:
|
||||
total_amount = ref_doc.base_grand_total
|
||||
@@ -955,6 +1034,8 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
||||
outstanding_amount = flt(outstanding_amount) * flt(exchange_rate)
|
||||
if party_account_currency == company_currency:
|
||||
exchange_rate = 1
|
||||
elif reference_doctype == "Gratuity":
|
||||
outstanding_amount = ref_doc.amount - flt(ref_doc.paid_amount)
|
||||
else:
|
||||
outstanding_amount = flt(total_amount) - flt(ref_doc.advance_paid)
|
||||
else:
|
||||
@@ -996,7 +1077,7 @@ def get_amounts_based_on_ref_doc(reference_doctype, ref_doc, party_account_curre
|
||||
total_amount = flt(ref_doc.total_sanctioned_amount) + flt(ref_doc.total_taxes_and_charges)
|
||||
elif ref_doc.doctype == "Employee Advance":
|
||||
total_amount, exchange_rate = get_total_amount_exchange_rate_for_employee_advance(party_account_currency, ref_doc)
|
||||
|
||||
|
||||
if not total_amount:
|
||||
total_amount, exchange_rate = get_total_amount_exchange_rate_base_on_currency(
|
||||
party_account_currency, company_currency, ref_doc)
|
||||
@@ -1069,6 +1150,8 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
||||
paid_amount, received_amount = set_paid_amount_and_received_amount(
|
||||
dt, party_account_currency, bank, outstanding_amount, payment_type, bank_amount, doc)
|
||||
|
||||
paid_amount, received_amount, discount_amount = apply_early_payment_discount(paid_amount, received_amount, doc)
|
||||
|
||||
pe = frappe.new_doc("Payment Entry")
|
||||
pe.payment_type = payment_type
|
||||
pe.company = doc.company
|
||||
@@ -1138,11 +1221,20 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
||||
|
||||
pe.setup_party_account_field()
|
||||
pe.set_missing_values()
|
||||
|
||||
if party_account and bank:
|
||||
if dt == "Employee Advance":
|
||||
reference_doc = doc
|
||||
pe.set_exchange_rate(ref_doc=reference_doc)
|
||||
pe.set_amounts()
|
||||
if discount_amount:
|
||||
pe.set_gain_or_loss(account_details={
|
||||
'account': frappe.get_cached_value('Company', pe.company, "default_discount_account"),
|
||||
'cost_center': pe.cost_center or frappe.get_cached_value('Company', pe.company, "cost_center"),
|
||||
'amount': discount_amount * (-1 if payment_type == "Pay" else 1)
|
||||
})
|
||||
pe.set_difference_amount()
|
||||
|
||||
return pe
|
||||
|
||||
def get_bank_cash_account(doc, bank_account):
|
||||
@@ -1160,10 +1252,12 @@ def set_party_type(dt):
|
||||
party_type = "Customer"
|
||||
elif dt in ("Purchase Invoice", "Purchase Order"):
|
||||
party_type = "Supplier"
|
||||
elif dt in ("Expense Claim", "Employee Advance"):
|
||||
elif dt in ("Expense Claim", "Employee Advance", "Gratuity"):
|
||||
party_type = "Employee"
|
||||
elif dt in ("Fees"):
|
||||
elif dt == "Fees":
|
||||
party_type = "Student"
|
||||
elif dt == "Donation":
|
||||
party_type = "Donor"
|
||||
return party_type
|
||||
|
||||
def set_party_account(dt, dn, doc, party_type):
|
||||
@@ -1177,6 +1271,8 @@ def set_party_account(dt, dn, doc, party_type):
|
||||
party_account = doc.advance_account
|
||||
elif dt == "Expense Claim":
|
||||
party_account = doc.payable_account
|
||||
elif dt == "Gratuity":
|
||||
party_account = doc.payable_account
|
||||
else:
|
||||
party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company)
|
||||
return party_account
|
||||
@@ -1189,7 +1285,7 @@ def set_party_account_currency(dt, party_account, doc):
|
||||
return party_account_currency
|
||||
|
||||
def set_payment_type(dt, doc):
|
||||
if (dt == "Sales Order" or (dt in ("Sales Invoice", "Fees", "Dunning") and doc.outstanding_amount > 0)) \
|
||||
if (dt in ("Sales Order", "Donation") or (dt in ("Sales Invoice", "Fees", "Dunning") and doc.outstanding_amount > 0)) \
|
||||
or (dt=="Purchase Invoice" and doc.outstanding_amount < 0):
|
||||
payment_type = "Receive"
|
||||
else:
|
||||
@@ -1222,6 +1318,12 @@ def set_grand_total_and_outstanding_amount(party_amount, dt, party_account_curre
|
||||
elif dt == "Dunning":
|
||||
grand_total = doc.grand_total
|
||||
outstanding_amount = doc.grand_total
|
||||
elif dt == "Donation":
|
||||
grand_total = doc.amount
|
||||
outstanding_amount = doc.amount
|
||||
elif dt == "Gratuity":
|
||||
grand_total = doc.amount
|
||||
outstanding_amount = flt(doc.amount) - flt(doc.paid_amount)
|
||||
else:
|
||||
if party_account_currency == doc.company_currency:
|
||||
grand_total = flt(doc.get("base_rounded_total") or doc.base_grand_total)
|
||||
@@ -1253,6 +1355,33 @@ def set_paid_amount_and_received_amount(dt, party_account_currency, bank, outsta
|
||||
paid_amount = received_amount * doc.get('exchange_rate', 1)
|
||||
return paid_amount, received_amount
|
||||
|
||||
def apply_early_payment_discount(paid_amount, received_amount, doc):
|
||||
total_discount = 0
|
||||
if doc.doctype in ['Sales Invoice', 'Purchase Invoice'] and doc.payment_schedule:
|
||||
for term in doc.payment_schedule:
|
||||
if not term.discounted_amount and term.discount and getdate(nowdate()) <= term.discount_date:
|
||||
if term.discount_type == 'Percentage':
|
||||
discount_amount = flt(doc.get('grand_total')) * (term.discount / 100)
|
||||
else:
|
||||
discount_amount = term.discount
|
||||
|
||||
discount_amount_in_foreign_currency = discount_amount * doc.get('conversion_rate', 1)
|
||||
|
||||
if doc.doctype == 'Sales Invoice':
|
||||
paid_amount -= discount_amount
|
||||
received_amount -= discount_amount_in_foreign_currency
|
||||
else:
|
||||
received_amount -= discount_amount
|
||||
paid_amount -= discount_amount_in_foreign_currency
|
||||
|
||||
total_discount += discount_amount
|
||||
|
||||
if total_discount:
|
||||
money = frappe.utils.fmt_money(total_discount, currency=doc.get('currency'))
|
||||
frappe.msgprint(_("Discount of {} applied as per Payment Term").format(money), alert=1)
|
||||
|
||||
return paid_amount, received_amount, total_discount
|
||||
|
||||
def get_reference_as_per_payment_terms(payment_schedule, dt, dn, doc, grand_total, outstanding_amount):
|
||||
references = []
|
||||
for payment_term in payment_schedule:
|
||||
@@ -1326,4 +1455,4 @@ def make_payment_order(source_name, target_doc=None):
|
||||
|
||||
}, target_doc, set_missing_values)
|
||||
|
||||
return doclist
|
||||
return doclist
|
||||
|
||||
@@ -193,6 +193,34 @@ class TestPaymentEntry(unittest.TestCase):
|
||||
self.assertEqual(si.payment_schedule[0].paid_amount, 200.0)
|
||||
self.assertEqual(si.payment_schedule[1].paid_amount, 36.0)
|
||||
|
||||
def test_payment_entry_against_payment_terms_with_discount(self):
|
||||
si = create_sales_invoice(do_not_save=1, qty=1, rate=200)
|
||||
create_payment_terms_template_with_discount()
|
||||
si.payment_terms_template = 'Test Discount Template'
|
||||
|
||||
frappe.db.set_value('Company', si.company, 'default_discount_account', 'Write Off - _TC')
|
||||
|
||||
si.append('taxes', {
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": "_Test Account Service Tax - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Service Tax",
|
||||
"rate": 18
|
||||
})
|
||||
si.save()
|
||||
|
||||
si.submit()
|
||||
|
||||
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC")
|
||||
pe.submit()
|
||||
si.load_from_db()
|
||||
|
||||
self.assertEqual(pe.references[0].payment_term, '30 Credit Days with 10% Discount')
|
||||
self.assertEqual(si.payment_schedule[0].payment_amount, 236.0)
|
||||
self.assertEqual(si.payment_schedule[0].paid_amount, 212.40)
|
||||
self.assertEqual(si.payment_schedule[0].outstanding, 0)
|
||||
self.assertEqual(si.payment_schedule[0].discounted_amount, 23.6)
|
||||
|
||||
|
||||
def test_payment_against_purchase_invoice_to_check_status(self):
|
||||
pi = make_purchase_invoice(supplier="_Test Supplier USD", debit_to="_Test Payable USD - _TC",
|
||||
@@ -591,6 +619,26 @@ def create_payment_terms_template():
|
||||
}]
|
||||
}).insert()
|
||||
|
||||
def create_payment_terms_template_with_discount():
|
||||
|
||||
create_payment_term('30 Credit Days with 10% Discount')
|
||||
|
||||
if not frappe.db.exists('Payment Terms Template', 'Test Discount Template'):
|
||||
payment_term_template = frappe.get_doc({
|
||||
'doctype': 'Payment Terms Template',
|
||||
'template_name': 'Test Discount Template',
|
||||
'allocate_payment_based_on_payment_terms': 1,
|
||||
'terms': [{
|
||||
'doctype': 'Payment Terms Template Detail',
|
||||
'payment_term': '30 Credit Days with 10% Discount',
|
||||
'invoice_portion': 100,
|
||||
'credit_days_based_on': 'Day(s) after invoice date',
|
||||
'credit_days': 2,
|
||||
'discount': 10,
|
||||
'discount_validity_based_on': 'Day(s) after invoice date',
|
||||
'discount_validity': 1
|
||||
}]
|
||||
}).insert()
|
||||
|
||||
def create_payment_term(name):
|
||||
if not frappe.db.exists('Payment Term', name):
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
"fieldname": "total_amount",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Total Amount",
|
||||
"label": "Grand Total",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
@@ -92,9 +92,10 @@
|
||||
"options": "Payment Term"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-03-13 12:07:19.362539",
|
||||
"modified": "2021-02-10 11:25:47.144392",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Entry Reference",
|
||||
|
||||
@@ -88,19 +88,19 @@ class PaymentReconciliation(Document):
|
||||
voucher_type = ('Sales Invoice'
|
||||
if self.party_type == 'Customer' else "Purchase Invoice")
|
||||
|
||||
return frappe.db.sql(""" SELECT `tab{doc}`.name as reference_name, %(voucher_type)s as reference_type,
|
||||
(sum(`tabGL Entry`.{dr_or_cr}) - sum(`tabGL Entry`.{reconciled_dr_or_cr})) as amount,
|
||||
return frappe.db.sql(""" SELECT doc.name as reference_name, %(voucher_type)s as reference_type,
|
||||
(sum(gl.{dr_or_cr}) - sum(gl.{reconciled_dr_or_cr})) as amount,
|
||||
account_currency as currency
|
||||
FROM `tab{doc}`, `tabGL Entry`
|
||||
FROM `tab{doc}` doc, `tabGL Entry` gl
|
||||
WHERE
|
||||
(`tab{doc}`.name = `tabGL Entry`.against_voucher or `tab{doc}`.name = `tabGL Entry`.voucher_no)
|
||||
and `tab{doc}`.{party_type_field} = %(party)s
|
||||
and `tab{doc}`.is_return = 1 and `tab{doc}`.return_against IS NULL
|
||||
and `tabGL Entry`.against_voucher_type = %(voucher_type)s
|
||||
and `tab{doc}`.docstatus = 1 and `tabGL Entry`.party = %(party)s
|
||||
and `tabGL Entry`.party_type = %(party_type)s and `tabGL Entry`.account = %(account)s
|
||||
and `tabGL Entry`.is_cancelled = 0
|
||||
GROUP BY `tab{doc}`.name
|
||||
(doc.name = gl.against_voucher or doc.name = gl.voucher_no)
|
||||
and doc.{party_type_field} = %(party)s
|
||||
and doc.is_return = 1 and ifnull(doc.return_against, "") = ""
|
||||
and gl.against_voucher_type = %(voucher_type)s
|
||||
and doc.docstatus = 1 and gl.party = %(party)s
|
||||
and gl.party_type = %(party_type)s and gl.account = %(account)s
|
||||
and gl.is_cancelled = 0
|
||||
GROUP BY doc.name
|
||||
Having
|
||||
amount > 0
|
||||
""".format(
|
||||
@@ -113,7 +113,7 @@ class PaymentReconciliation(Document):
|
||||
'party_type': self.party_type,
|
||||
'voucher_type': voucher_type,
|
||||
'account': self.receivable_payable_account
|
||||
}, as_dict=1)
|
||||
}, as_dict=1, debug=1)
|
||||
|
||||
def add_payment_entries(self, entries):
|
||||
self.set('payments', [])
|
||||
|
||||
@@ -2,7 +2,7 @@ frappe.listview_settings['Payment Request'] = {
|
||||
add_fields: ["status"],
|
||||
get_indicator: function(doc) {
|
||||
if(doc.status == "Draft") {
|
||||
return [__("Draft"), "darkgrey", "status,=,Draft"];
|
||||
return [__("Draft"), "gray", "status,=,Draft"];
|
||||
}
|
||||
if(doc.status == "Requested") {
|
||||
return [__("Requested"), "green", "status,=,Requested"];
|
||||
@@ -19,5 +19,5 @@ frappe.listview_settings['Payment Request'] = {
|
||||
else if(doc.status == "Cancelled") {
|
||||
return [__("Cancelled"), "red", "status,=,Cancelled"];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,23 @@
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"payment_term",
|
||||
"section_break_15",
|
||||
"description",
|
||||
"section_break_4",
|
||||
"due_date",
|
||||
"invoice_portion",
|
||||
"payment_amount",
|
||||
"mode_of_payment",
|
||||
"column_break_5",
|
||||
"invoice_portion",
|
||||
"section_break_6",
|
||||
"discount_type",
|
||||
"discount_date",
|
||||
"column_break_9",
|
||||
"discount",
|
||||
"section_break_9",
|
||||
"payment_amount",
|
||||
"discounted_amount",
|
||||
"column_break_3",
|
||||
"outstanding",
|
||||
"paid_amount"
|
||||
],
|
||||
"fields": [
|
||||
@@ -25,6 +37,7 @@
|
||||
},
|
||||
{
|
||||
"columns": 2,
|
||||
"fetch_from": "payment_term.description",
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"in_list_view": 1,
|
||||
@@ -62,14 +75,82 @@
|
||||
"options": "Mode of Payment"
|
||||
},
|
||||
{
|
||||
"depends_on": "paid_amount",
|
||||
"fieldname": "paid_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Paid Amount"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "discounted_amount",
|
||||
"fieldname": "discounted_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Discounted Amount",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "payment_amount",
|
||||
"fieldname": "outstanding",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Outstanding",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_5",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"depends_on": "discount",
|
||||
"fieldname": "discount_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Discount Date",
|
||||
"mandatory_depends_on": "discount"
|
||||
},
|
||||
{
|
||||
"default": "Percentage",
|
||||
"fetch_from": "payment_term.discount_type",
|
||||
"fieldname": "discount_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Discount Type",
|
||||
"options": "Percentage\nAmount"
|
||||
},
|
||||
{
|
||||
"fetch_from": "payment_term.discount",
|
||||
"fieldname": "discount",
|
||||
"fieldtype": "Float",
|
||||
"label": "Discount"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_9",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "section_break_15",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Description"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_6",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_9",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_4",
|
||||
"fieldtype": "Section Break"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-03-13 17:58:24.729526",
|
||||
"modified": "2021-02-15 21:03:12.540546",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Schedule",
|
||||
|
||||
@@ -1,2 +1,22 @@
|
||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
frappe.ui.form.on('Payment Term', {
|
||||
onload(frm) {
|
||||
frm.trigger('set_dynamic_description');
|
||||
},
|
||||
discount(frm) {
|
||||
frm.trigger('set_dynamic_description');
|
||||
},
|
||||
discount_type(frm) {
|
||||
frm.trigger('set_dynamic_description');
|
||||
},
|
||||
set_dynamic_description(frm) {
|
||||
if (frm.doc.discount) {
|
||||
let description = __("{0}% of total invoice value will be given as discount.", [frm.doc.discount]);
|
||||
if (frm.doc.discount_type == 'Amount') {
|
||||
description = __("{0} will be given as discount.", [fmt_money(frm.doc.discount)]);
|
||||
}
|
||||
frm.set_df_property("discount", "description", description);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1,386 +1,166 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:payment_term_name",
|
||||
"beta": 0,
|
||||
"creation": "2017-08-10 15:24:54.876365",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"actions": [],
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:payment_term_name",
|
||||
"creation": "2017-08-10 15:24:54.876365",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"payment_term_name",
|
||||
"invoice_portion",
|
||||
"mode_of_payment",
|
||||
"column_break_3",
|
||||
"due_date_based_on",
|
||||
"credit_days",
|
||||
"credit_months",
|
||||
"section_break_8",
|
||||
"discount_type",
|
||||
"discount",
|
||||
"column_break_11",
|
||||
"discount_validity_based_on",
|
||||
"discount_validity",
|
||||
"section_break_6",
|
||||
"description"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 1,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "payment_term_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Payment Term Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"bold": 1,
|
||||
"fieldname": "payment_term_name",
|
||||
"fieldtype": "Data",
|
||||
"label": "Payment Term Name",
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"description": "Provide the invoice portion in percent",
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 1,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "invoice_portion",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Invoice Portion",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"bold": 1,
|
||||
"fieldname": "invoice_portion",
|
||||
"fieldtype": "Float",
|
||||
"label": "Invoice Portion (%)"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "mode_of_payment",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Mode of Payment",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Mode of Payment",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "mode_of_payment",
|
||||
"fieldtype": "Link",
|
||||
"label": "Mode of Payment",
|
||||
"options": "Mode of Payment"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 1,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "due_date_based_on",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Due Date Based On",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Day(s) after invoice date\nDay(s) after the end of the invoice month\nMonth(s) after the end of the invoice month",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"bold": 1,
|
||||
"fieldname": "due_date_based_on",
|
||||
"fieldtype": "Select",
|
||||
"label": "Due Date Based On",
|
||||
"options": "Day(s) after invoice date\nDay(s) after the end of the invoice month\nMonth(s) after the end of the invoice month"
|
||||
},
|
||||
{
|
||||
"description": "Give number of days according to prior selection",
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 1,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:in_list(['Day(s) after invoice date', 'Day(s) after the end of the invoice month'], doc.due_date_based_on)",
|
||||
"fieldname": "credit_days",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Credit Days",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"bold": 1,
|
||||
"depends_on": "eval:in_list(['Day(s) after invoice date', 'Day(s) after the end of the invoice month'], doc.due_date_based_on)",
|
||||
"fieldname": "credit_days",
|
||||
"fieldtype": "Int",
|
||||
"label": "Credit Days"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.due_date_based_on=='Month(s) after the end of the invoice month'",
|
||||
"fieldname": "credit_months",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Credit Months",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"depends_on": "eval:doc.due_date_based_on=='Month(s) after the end of the invoice month'",
|
||||
"fieldname": "credit_months",
|
||||
"fieldtype": "Int",
|
||||
"label": "Credit Months"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_6",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "section_break_6",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 1,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Description",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"bold": 1,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Description"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_8",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Discount Settings"
|
||||
},
|
||||
{
|
||||
"default": "Percentage",
|
||||
"fieldname": "discount_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Discount Type",
|
||||
"options": "Percentage\nAmount"
|
||||
},
|
||||
{
|
||||
"fieldname": "discount",
|
||||
"fieldtype": "Float",
|
||||
"label": "Discount"
|
||||
},
|
||||
{
|
||||
"default": "Day(s) after invoice date",
|
||||
"depends_on": "discount",
|
||||
"fieldname": "discount_validity_based_on",
|
||||
"fieldtype": "Select",
|
||||
"label": "Discount Validity Based On",
|
||||
"options": "Day(s) after invoice date\nDay(s) after the end of the invoice month\nMonth(s) after the end of the invoice month"
|
||||
},
|
||||
{
|
||||
"depends_on": "discount",
|
||||
"fieldname": "discount_validity",
|
||||
"fieldtype": "Int",
|
||||
"label": "Discount Validity",
|
||||
"mandatory_depends_on": "discount"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_11",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2020-10-14 10:47:32.830478",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Term",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
],
|
||||
"links": [],
|
||||
"modified": "2021-02-15 20:30:56.256403",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Term",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
@@ -3,11 +3,6 @@
|
||||
|
||||
frappe.ui.form.on('Payment Terms Template', {
|
||||
setup: function(frm) {
|
||||
frm.add_fetch("payment_term", "description", "description");
|
||||
frm.add_fetch("payment_term", "invoice_portion", "invoice_portion");
|
||||
frm.add_fetch("payment_term", "due_date_based_on", "due_date_based_on");
|
||||
frm.add_fetch("payment_term", "credit_days", "credit_days");
|
||||
frm.add_fetch("payment_term", "credit_months", "credit_months");
|
||||
frm.add_fetch("payment_term", "mode_of_payment", "mode_of_payment");
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
@@ -13,7 +13,6 @@ from frappe import _
|
||||
class PaymentTermsTemplate(Document):
|
||||
def validate(self):
|
||||
self.validate_invoice_portion()
|
||||
self.validate_credit_days()
|
||||
self.check_duplicate_terms()
|
||||
|
||||
def validate_invoice_portion(self):
|
||||
@@ -24,11 +23,6 @@ class PaymentTermsTemplate(Document):
|
||||
if flt(total_portion, 2) != 100.00:
|
||||
frappe.msgprint(_('Combined invoice portion must equal 100%'), raise_exception=1, indicator='red')
|
||||
|
||||
def validate_credit_days(self):
|
||||
for term in self.terms:
|
||||
if cint(term.credit_days) < 0:
|
||||
frappe.msgprint(_('Credit Days cannot be a negative number'), raise_exception=1, indicator='red')
|
||||
|
||||
def check_duplicate_terms(self):
|
||||
terms = []
|
||||
for term in self.terms:
|
||||
|
||||
@@ -1,278 +1,164 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "",
|
||||
"beta": 0,
|
||||
"creation": "2017-08-10 15:34:09.409562",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"actions": [],
|
||||
"creation": "2017-08-10 15:34:09.409562",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"payment_term",
|
||||
"section_break_13",
|
||||
"description",
|
||||
"section_break_4",
|
||||
"invoice_portion",
|
||||
"mode_of_payment",
|
||||
"column_break_3",
|
||||
"due_date_based_on",
|
||||
"credit_days",
|
||||
"credit_months",
|
||||
"section_break_8",
|
||||
"discount_type",
|
||||
"discount",
|
||||
"column_break_11",
|
||||
"discount_validity_based_on",
|
||||
"discount_validity"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"fieldname": "payment_term",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Payment Term",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Payment Term",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"columns": 2,
|
||||
"fieldname": "payment_term",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Payment Term",
|
||||
"options": "Payment Term"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Description",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"columns": 2,
|
||||
"fetch_from": "payment_term.description",
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"in_list_view": 1,
|
||||
"label": "Description"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"default": "0",
|
||||
"fieldname": "invoice_portion",
|
||||
"fieldtype": "Percent",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Invoice Portion",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"columns": 2,
|
||||
"fetch_from": "payment_term.invoice_portion",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "invoice_portion",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Invoice Portion (%)",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"fieldname": "due_date_based_on",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Due Date Based On",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Day(s) after invoice date\nDay(s) after the end of the invoice month\nMonth(s) after the end of the invoice month",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"columns": 2,
|
||||
"fetch_from": "payment_term.due_date_based_on",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "due_date_based_on",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Due Date Based On",
|
||||
"options": "Day(s) after invoice date\nDay(s) after the end of the invoice month\nMonth(s) after the end of the invoice month",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"default": "0",
|
||||
"depends_on": "eval:in_list(['Day(s) after invoice date', 'Day(s) after the end of the invoice month'], doc.due_date_based_on)",
|
||||
"fieldname": "credit_days",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Credit Days",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"columns": 2,
|
||||
"default": "0",
|
||||
"depends_on": "eval:in_list(['Day(s) after invoice date', 'Day(s) after the end of the invoice month'], doc.due_date_based_on)",
|
||||
"fetch_from": "payment_term.credit_days",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "credit_days",
|
||||
"fieldtype": "Int",
|
||||
"in_list_view": 1,
|
||||
"label": "Credit Days",
|
||||
"non_negative": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"depends_on": "eval:doc.due_date_based_on=='Month(s) after the end of the invoice month'",
|
||||
"fieldname": "credit_months",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Credit Months",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"default": "0",
|
||||
"depends_on": "eval:doc.due_date_based_on=='Month(s) after the end of the invoice month'",
|
||||
"fetch_from": "payment_term.credit_months",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "credit_months",
|
||||
"fieldtype": "Int",
|
||||
"label": "Credit Months",
|
||||
"non_negative": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "mode_of_payment",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Mode of Payment",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Mode of Payment",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fetch_from": "payment_term.mode_of_payment",
|
||||
"fieldname": "mode_of_payment",
|
||||
"fieldtype": "Link",
|
||||
"label": "Mode of Payment",
|
||||
"options": "Mode of Payment"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_8",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Discount Settings"
|
||||
},
|
||||
{
|
||||
"default": "Percentage",
|
||||
"fetch_from": "payment_term.discount_type",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "discount_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Discount Type",
|
||||
"options": "Percentage\nAmount"
|
||||
},
|
||||
{
|
||||
"fetch_from": "payment_term.discount",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "discount",
|
||||
"fieldtype": "Float",
|
||||
"label": "Discount"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_11",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"default": "Day(s) after invoice date",
|
||||
"depends_on": "discount",
|
||||
"fetch_from": "payment_term.discount_validity_based_on",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "discount_validity_based_on",
|
||||
"fieldtype": "Select",
|
||||
"label": "Discount Validity Based On",
|
||||
"options": "Day(s) after invoice date\nDay(s) after the end of the invoice month\nMonth(s) after the end of the invoice month"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "section_break_13",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Description"
|
||||
},
|
||||
{
|
||||
"depends_on": "discount",
|
||||
"fetch_from": "payment_term.discount_validity",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "discount_validity",
|
||||
"fieldtype": "Int",
|
||||
"label": "Discount Validity",
|
||||
"mandatory_depends_on": "discount"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_4",
|
||||
"fieldtype": "Section Break"
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-08-21 16:15:55.143025",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Terms Template Detail",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-02-24 11:56:12.410807",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Terms Template Detail",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"period_details_section",
|
||||
"period_start_date",
|
||||
"period_end_date",
|
||||
"column_break_3",
|
||||
@@ -65,7 +66,8 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_5",
|
||||
"fieldtype": "Section Break"
|
||||
"fieldtype": "Section Break",
|
||||
"label": "User Details"
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
@@ -121,7 +123,7 @@
|
||||
"collapsible_depends_on": "eval:doc.docstatus==0",
|
||||
"fieldname": "section_break_13",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Details"
|
||||
"label": "Totals"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
@@ -196,6 +198,11 @@
|
||||
"options": "Draft\nSubmitted\nQueued\nCancelled",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "period_details_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Period Details"
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
@@ -205,7 +212,7 @@
|
||||
"link_fieldname": "pos_closing_entry"
|
||||
}
|
||||
],
|
||||
"modified": "2021-01-12 12:21:05.388650",
|
||||
"modified": "2021-02-01 13:47:20.722104",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Closing Entry",
|
||||
|
||||
@@ -20,11 +20,16 @@ class POSClosingEntry(StatusUpdater):
|
||||
self.validate_pos_invoices()
|
||||
|
||||
def validate_pos_closing(self):
|
||||
user = frappe.get_all("POS Closing Entry",
|
||||
filters = { "user": self.user, "docstatus": 1, "pos_profile": self.pos_profile },
|
||||
or_filters = {
|
||||
"period_start_date": ("between", [self.period_start_date, self.period_end_date]),
|
||||
"period_end_date": ("between", [self.period_start_date, self.period_end_date])
|
||||
user = frappe.db.sql("""
|
||||
SELECT name FROM `tabPOS Closing Entry`
|
||||
WHERE
|
||||
user = %(user)s AND docstatus = 1 AND pos_profile = %(profile)s AND
|
||||
(period_start_date between %(start)s and %(end)s OR period_end_date between %(start)s and %(end)s)
|
||||
""", {
|
||||
'user': self.user,
|
||||
'profile': self.pos_profile,
|
||||
'start': self.period_start_date,
|
||||
'end': self.period_end_date
|
||||
})
|
||||
|
||||
if user:
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
"customer",
|
||||
"customer_name",
|
||||
"tax_id",
|
||||
"is_pos",
|
||||
"pos_profile",
|
||||
"offline_pos_name",
|
||||
"is_return",
|
||||
"consolidated_invoice",
|
||||
"is_pos",
|
||||
"is_return",
|
||||
"update_billed_amount_in_sales_order",
|
||||
"column_break1",
|
||||
"company",
|
||||
"posting_date",
|
||||
@@ -25,10 +25,7 @@
|
||||
"set_posting_time",
|
||||
"due_date",
|
||||
"amended_from",
|
||||
"returns",
|
||||
"return_against",
|
||||
"column_break_21",
|
||||
"update_billed_amount_in_sales_order",
|
||||
"accounting_dimensions_section",
|
||||
"project",
|
||||
"dimension_col_break",
|
||||
@@ -183,8 +180,7 @@
|
||||
"column_break_140",
|
||||
"auto_repeat",
|
||||
"update_auto_repeat_reference",
|
||||
"against_income_account",
|
||||
"pos_total_qty"
|
||||
"against_income_account"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -265,14 +261,6 @@
|
||||
"options": "POS Profile",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "offline_pos_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Offline POS Name",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"default": "0",
|
||||
@@ -348,26 +336,16 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "return_against",
|
||||
"fieldname": "returns",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Returns"
|
||||
},
|
||||
{
|
||||
"depends_on": "return_against",
|
||||
"fieldname": "return_against",
|
||||
"fieldtype": "Link",
|
||||
"label": "Return Against POS Invoice",
|
||||
"label": "Return Against",
|
||||
"no_copy": 1,
|
||||
"options": "POS Invoice",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_21",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "eval: doc.is_return && doc.return_against",
|
||||
@@ -587,19 +565,21 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "sec_warehouse",
|
||||
"fieldtype": "Section Break"
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Warehouse"
|
||||
},
|
||||
{
|
||||
"depends_on": "update_stock",
|
||||
"fieldname": "set_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Set Source Warehouse",
|
||||
"label": "Source Warehouse",
|
||||
"options": "Warehouse",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "items_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Items",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "fa fa-shopping-cart"
|
||||
},
|
||||
@@ -1501,7 +1481,7 @@
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "sales_team",
|
||||
"fieldtype": "Table",
|
||||
"label": "Sales Team1",
|
||||
"label": "Sales Team",
|
||||
"oldfieldname": "sales_team",
|
||||
"oldfieldtype": "Table",
|
||||
"options": "Sales Team",
|
||||
@@ -1560,15 +1540,6 @@
|
||||
"print_hide": 1,
|
||||
"report_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pos_total_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 1,
|
||||
"label": "Total Qty",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "consolidated_invoice",
|
||||
@@ -1581,7 +1552,7 @@
|
||||
"icon": "fa fa-file-text",
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-10-30 13:56:51.056083",
|
||||
"modified": "2021-02-01 15:03:33.800707",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Invoice",
|
||||
@@ -1626,7 +1597,6 @@
|
||||
"role": "All"
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"search_fields": "posting_date, due_date, customer, base_grand_total, outstanding_amount",
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_field": "modified",
|
||||
|
||||
@@ -57,7 +57,7 @@ class POSInvoice(SalesInvoice):
|
||||
self.apply_loyalty_points()
|
||||
self.check_phone_payments()
|
||||
self.set_status(update=True)
|
||||
|
||||
|
||||
def before_cancel(self):
|
||||
if self.consolidated_invoice and frappe.db.get_value('Sales Invoice', self.consolidated_invoice, 'docstatus') == 1:
|
||||
pos_closing_entry = frappe.get_all(
|
||||
@@ -178,10 +178,18 @@ class POSInvoice(SalesInvoice):
|
||||
if d.get("serial_no"):
|
||||
serial_nos = get_serial_nos(d.serial_no)
|
||||
for sr in serial_nos:
|
||||
serial_no_exists = frappe.db.exists("POS Invoice Item", {
|
||||
"parent": self.return_against,
|
||||
"serial_no": ["like", d.get("serial_no")]
|
||||
})
|
||||
serial_no_exists = frappe.db.sql("""
|
||||
SELECT name
|
||||
FROM `tabPOS Invoice Item`
|
||||
WHERE
|
||||
parent = %s
|
||||
and (serial_no = %s
|
||||
or serial_no like %s
|
||||
or serial_no like %s
|
||||
or serial_no like %s
|
||||
)
|
||||
""", (self.return_against, sr, sr+'\n%', '%\n'+sr, '%\n'+sr+'\n%'))
|
||||
|
||||
if not serial_no_exists:
|
||||
bold_return_against = frappe.bold(self.return_against)
|
||||
bold_serial_no = frappe.bold(sr)
|
||||
@@ -189,7 +197,7 @@ class POSInvoice(SalesInvoice):
|
||||
_("Row #{}: Serial No {} cannot be returned since it was not transacted in original invoice {}")
|
||||
.format(d.idx, bold_serial_no, bold_return_against)
|
||||
)
|
||||
|
||||
|
||||
def validate_non_stock_items(self):
|
||||
for d in self.get("items"):
|
||||
is_stock_item = frappe.get_cached_value("Item", d.get("item_code"), "is_stock_item")
|
||||
@@ -291,7 +299,7 @@ class POSInvoice(SalesInvoice):
|
||||
|
||||
if not self.get('payments') and not for_validate:
|
||||
update_multi_mode_option(self, profile)
|
||||
|
||||
|
||||
if self.is_return and not for_validate:
|
||||
add_return_modes(self, profile)
|
||||
|
||||
@@ -324,8 +332,6 @@ class POSInvoice(SalesInvoice):
|
||||
|
||||
if selling_price_list:
|
||||
self.set('selling_price_list', selling_price_list)
|
||||
if customer_currency != profile.get('currency'):
|
||||
self.set('currency', customer_currency)
|
||||
|
||||
# set pos values in items
|
||||
for item in self.get("items"):
|
||||
@@ -393,7 +399,7 @@ class POSInvoice(SalesInvoice):
|
||||
pay_req.request_phone_payment()
|
||||
|
||||
return pay_req
|
||||
|
||||
|
||||
def get_new_payment_request(self, mop):
|
||||
payment_gateway_account = frappe.db.get_value("Payment Gateway Account", {
|
||||
"payment_account": mop.account,
|
||||
@@ -428,21 +434,6 @@ class POSInvoice(SalesInvoice):
|
||||
if pr:
|
||||
return frappe.get_doc('Payment Request', pr[0][0])
|
||||
|
||||
def add_return_modes(doc, pos_profile):
|
||||
def append_payment(payment_mode):
|
||||
payment = doc.append('payments', {})
|
||||
payment.default = payment_mode.default
|
||||
payment.mode_of_payment = payment_mode.parent
|
||||
payment.account = payment_mode.default_account
|
||||
payment.type = payment_mode.type
|
||||
|
||||
for pos_payment_method in pos_profile.get('payments'):
|
||||
pos_payment_method = pos_payment_method.as_dict()
|
||||
mode_of_payment = pos_payment_method.mode_of_payment
|
||||
if pos_payment_method.allow_in_returns and not [d for d in doc.get('payments') if d.mode_of_payment == mode_of_payment]:
|
||||
payment_mode = get_mode_of_payment_info(mode_of_payment, doc.company)
|
||||
append_payment(payment_mode[0])
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_stock_availability(item_code, warehouse):
|
||||
latest_sle = frappe.db.sql("""select qty_after_transaction
|
||||
|
||||
@@ -99,10 +99,10 @@ class TestPOSInvoice(unittest.TestCase):
|
||||
item_row = inv.get("items")[0]
|
||||
|
||||
add_items = [
|
||||
(54, '_Test Account Excise Duty @ 12'),
|
||||
(288, '_Test Account Excise Duty @ 15'),
|
||||
(144, '_Test Account Excise Duty @ 20'),
|
||||
(430, '_Test Item Tax Template 1')
|
||||
(54, '_Test Account Excise Duty @ 12 - _TC'),
|
||||
(288, '_Test Account Excise Duty @ 15 - _TC'),
|
||||
(144, '_Test Account Excise Duty @ 20 - _TC'),
|
||||
(430, '_Test Item Tax Template 1 - _TC')
|
||||
]
|
||||
for qty, item_tax_template in add_items:
|
||||
item_row_copy = copy.deepcopy(item_row)
|
||||
@@ -198,6 +198,65 @@ class TestPOSInvoice(unittest.TestCase):
|
||||
self.assertEqual(pos_return.get('payments')[0].amount, -500)
|
||||
self.assertEqual(pos_return.get('payments')[1].amount, -500)
|
||||
|
||||
def test_pos_return_for_serialized_item(self):
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item
|
||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||
|
||||
se = make_serialized_item(company='_Test Company',
|
||||
target_warehouse="Stores - _TC", cost_center='Main - _TC', expense_account='Cost of Goods Sold - _TC')
|
||||
|
||||
serial_nos = get_serial_nos(se.get("items")[0].serial_no)
|
||||
|
||||
pos = create_pos_invoice(company='_Test Company', debit_to='Debtors - _TC',
|
||||
account_for_change_amount='Cash - _TC', warehouse='Stores - _TC', income_account='Sales - _TC',
|
||||
expense_account='Cost of Goods Sold - _TC', cost_center='Main - _TC',
|
||||
item=se.get("items")[0].item_code, rate=1000, do_not_save=1)
|
||||
|
||||
pos.get("items")[0].serial_no = serial_nos[0]
|
||||
pos.append("payments", {'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 1000, 'default': 1})
|
||||
|
||||
pos.insert()
|
||||
pos.submit()
|
||||
|
||||
pos_return = make_sales_return(pos.name)
|
||||
|
||||
pos_return.insert()
|
||||
pos_return.submit()
|
||||
self.assertEqual(pos_return.get('items')[0].serial_no, serial_nos[0])
|
||||
|
||||
def test_partial_pos_returns(self):
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item
|
||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||
|
||||
se = make_serialized_item(company='_Test Company',
|
||||
target_warehouse="Stores - _TC", cost_center='Main - _TC', expense_account='Cost of Goods Sold - _TC')
|
||||
|
||||
serial_nos = get_serial_nos(se.get("items")[0].serial_no)
|
||||
|
||||
pos = create_pos_invoice(company='_Test Company', debit_to='Debtors - _TC',
|
||||
account_for_change_amount='Cash - _TC', warehouse='Stores - _TC', income_account='Sales - _TC',
|
||||
expense_account='Cost of Goods Sold - _TC', cost_center='Main - _TC',
|
||||
item=se.get("items")[0].item_code, qty=2, rate=1000, do_not_save=1)
|
||||
|
||||
pos.get("items")[0].serial_no = serial_nos[0] + "\n" + serial_nos[1]
|
||||
pos.append("payments", {'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 1000, 'default': 1})
|
||||
|
||||
pos.insert()
|
||||
pos.submit()
|
||||
|
||||
pos_return1 = make_sales_return(pos.name)
|
||||
|
||||
# partial return 1
|
||||
pos_return1.get('items')[0].qty = -1
|
||||
pos_return1.get('items')[0].serial_no = serial_nos[0]
|
||||
pos_return1.insert()
|
||||
pos_return1.submit()
|
||||
|
||||
# partial return 2
|
||||
pos_return2 = make_sales_return(pos.name)
|
||||
self.assertEqual(pos_return2.get('items')[0].qty, -1)
|
||||
self.assertEqual(pos_return2.get('items')[0].serial_no, serial_nos[1])
|
||||
|
||||
def test_pos_change_amount(self):
|
||||
pos = create_pos_invoice(company= "_Test Company", debit_to="Debtors - _TC",
|
||||
income_account = "Sales - _TC", expense_account = "Cost of Goods Sold - _TC", rate=105,
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
"edit_references",
|
||||
"sales_order",
|
||||
"so_detail",
|
||||
"pos_invoice_item",
|
||||
"column_break_74",
|
||||
"delivery_note",
|
||||
"dn_detail",
|
||||
@@ -790,11 +791,20 @@
|
||||
"fieldtype": "Link",
|
||||
"label": "Project",
|
||||
"options": "Project"
|
||||
},
|
||||
{
|
||||
"fieldname": "pos_invoice_item",
|
||||
"fieldtype": "Data",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "POS Invoice Item",
|
||||
"no_copy": 1,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-07-22 13:40:34.418346",
|
||||
"modified": "2021-01-04 17:34:49.924531",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Invoice Item",
|
||||
|
||||
@@ -29,7 +29,7 @@ class POSInvoiceMergeLog(Document):
|
||||
for d in self.pos_invoices:
|
||||
status, docstatus, is_return, return_against = frappe.db.get_value(
|
||||
'POS Invoice', d.pos_invoice, ['status', 'docstatus', 'is_return', 'return_against'])
|
||||
|
||||
|
||||
bold_pos_invoice = frappe.bold(d.pos_invoice)
|
||||
bold_status = frappe.bold(status)
|
||||
if docstatus != 1:
|
||||
@@ -58,7 +58,7 @@ class POSInvoiceMergeLog(Document):
|
||||
sales_invoice, credit_note = "", ""
|
||||
if sales:
|
||||
sales_invoice = self.process_merging_into_sales_invoice(sales)
|
||||
|
||||
|
||||
if returns:
|
||||
credit_note = self.process_merging_into_credit_note(returns)
|
||||
|
||||
@@ -74,7 +74,7 @@ class POSInvoiceMergeLog(Document):
|
||||
|
||||
def process_merging_into_sales_invoice(self, data):
|
||||
sales_invoice = self.get_new_sales_invoice()
|
||||
|
||||
|
||||
sales_invoice = self.merge_pos_invoice_into(sales_invoice, data)
|
||||
|
||||
sales_invoice.is_consolidated = 1
|
||||
@@ -98,19 +98,19 @@ class POSInvoiceMergeLog(Document):
|
||||
self.consolidated_credit_note = credit_note.name
|
||||
|
||||
return credit_note.name
|
||||
|
||||
|
||||
def merge_pos_invoice_into(self, invoice, data):
|
||||
items, payments, taxes = [], [], []
|
||||
loyalty_amount_sum, loyalty_points_sum = 0, 0
|
||||
for doc in data:
|
||||
map_doc(doc, invoice, table_map={ "doctype": invoice.doctype })
|
||||
|
||||
|
||||
if doc.redeem_loyalty_points:
|
||||
invoice.loyalty_redemption_account = doc.loyalty_redemption_account
|
||||
invoice.loyalty_redemption_cost_center = doc.loyalty_redemption_cost_center
|
||||
loyalty_points_sum += doc.loyalty_points
|
||||
loyalty_amount_sum += doc.loyalty_amount
|
||||
|
||||
|
||||
for item in doc.get('items'):
|
||||
found = False
|
||||
for i in items:
|
||||
@@ -118,12 +118,13 @@ class POSInvoiceMergeLog(Document):
|
||||
i.uom == item.uom and i.net_rate == item.net_rate):
|
||||
found = True
|
||||
i.qty = i.qty + item.qty
|
||||
|
||||
if not found:
|
||||
item.rate = item.net_rate
|
||||
item.price_list_rate = 0
|
||||
si_item = map_child_doc(item, invoice, {"doctype": "Sales Invoice Item"})
|
||||
items.append(si_item)
|
||||
|
||||
|
||||
for tax in doc.get('taxes'):
|
||||
found = False
|
||||
for t in taxes:
|
||||
@@ -162,7 +163,7 @@ class POSInvoiceMergeLog(Document):
|
||||
invoice.ignore_pricing_rule = 1
|
||||
|
||||
return invoice
|
||||
|
||||
|
||||
def get_new_sales_invoice(self):
|
||||
sales_invoice = frappe.new_doc('Sales Invoice')
|
||||
sales_invoice.customer = self.customer
|
||||
@@ -194,7 +195,7 @@ def get_all_unconsolidated_invoices():
|
||||
}
|
||||
pos_invoices = frappe.db.get_all('POS Invoice', filters=filters,
|
||||
fields=["name as pos_invoice", 'posting_date', 'grand_total', 'customer'])
|
||||
|
||||
|
||||
return pos_invoices
|
||||
|
||||
def get_invoice_customer_map(pos_invoices):
|
||||
@@ -204,7 +205,7 @@ def get_invoice_customer_map(pos_invoices):
|
||||
customer = invoice.get('customer')
|
||||
pos_invoice_customer_map.setdefault(customer, [])
|
||||
pos_invoice_customer_map[customer].append(invoice)
|
||||
|
||||
|
||||
return pos_invoice_customer_map
|
||||
|
||||
def consolidate_pos_invoices(pos_invoices=[], closing_entry={}):
|
||||
@@ -212,8 +213,8 @@ def consolidate_pos_invoices(pos_invoices=[], closing_entry={}):
|
||||
invoice_by_customer = get_invoice_customer_map(invoices)
|
||||
|
||||
if len(invoices) >= 5 and closing_entry:
|
||||
enqueue_job(create_merge_logs, invoice_by_customer, closing_entry)
|
||||
closing_entry.set_status(update=True, status='Queued')
|
||||
enqueue_job(create_merge_logs, invoice_by_customer, closing_entry)
|
||||
else:
|
||||
create_merge_logs(invoice_by_customer, closing_entry)
|
||||
|
||||
@@ -225,8 +226,8 @@ def unconsolidate_pos_invoices(closing_entry):
|
||||
)
|
||||
|
||||
if len(merge_logs) >= 5:
|
||||
enqueue_job(cancel_merge_logs, merge_logs, closing_entry)
|
||||
closing_entry.set_status(update=True, status='Queued')
|
||||
enqueue_job(cancel_merge_logs, merge_logs, closing_entry)
|
||||
else:
|
||||
cancel_merge_logs(merge_logs, closing_entry)
|
||||
|
||||
|
||||
@@ -20,15 +20,16 @@ class POSOpeningEntry(StatusUpdater):
|
||||
|
||||
if not cint(frappe.db.get_value("User", self.user, "enabled")):
|
||||
frappe.throw(_("User {} is disabled. Please select valid user/cashier").format(self.user))
|
||||
|
||||
|
||||
def validate_payment_method_account(self):
|
||||
invalid_modes = []
|
||||
for d in self.balance_details:
|
||||
account = frappe.db.get_value("Mode of Payment Account",
|
||||
{"parent": d.mode_of_payment, "company": self.company}, "default_account")
|
||||
if not account:
|
||||
invalid_modes.append(get_link_to_form("Mode of Payment", d.mode_of_payment))
|
||||
|
||||
if d.mode_of_payment:
|
||||
account = frappe.db.get_value("Mode of Payment Account",
|
||||
{"parent": d.mode_of_payment, "company": self.company}, "default_account")
|
||||
if not account:
|
||||
invalid_modes.append(get_link_to_form("Mode of Payment", d.mode_of_payment))
|
||||
|
||||
if invalid_modes:
|
||||
if invalid_modes == 1:
|
||||
msg = _("Please set default Cash or Bank account in Mode of Payment {}")
|
||||
|
||||
@@ -6,11 +6,10 @@
|
||||
"doctype": "DocType",
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"disabled",
|
||||
"section_break_2",
|
||||
"customer",
|
||||
"company",
|
||||
"customer",
|
||||
"country",
|
||||
"disabled",
|
||||
"column_break_9",
|
||||
"warehouse",
|
||||
"campaign",
|
||||
@@ -61,10 +60,6 @@
|
||||
"fieldtype": "Check",
|
||||
"label": "Disabled"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_2",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "customer",
|
||||
"fieldtype": "Link",
|
||||
@@ -348,9 +343,9 @@
|
||||
"label": "Allow User to Edit Discount"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "section_break_23",
|
||||
"fieldtype": "Section Break"
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Filters"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_25",
|
||||
@@ -360,8 +355,29 @@
|
||||
"icon": "icon-cog",
|
||||
"idx": 1,
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2021-01-06 14:42:41.713864",
|
||||
"links": [
|
||||
{
|
||||
"group": "Invoices",
|
||||
"link_doctype": "Sales Invoice",
|
||||
"link_fieldname": "pos_profile"
|
||||
},
|
||||
{
|
||||
"group": "Invoices",
|
||||
"link_doctype": "POS Invoice",
|
||||
"link_fieldname": "pos_profile"
|
||||
},
|
||||
{
|
||||
"group": "Opening & Closing",
|
||||
"link_doctype": "POS Opening Entry",
|
||||
"link_fieldname": "pos_profile"
|
||||
},
|
||||
{
|
||||
"group": "Opening & Closing",
|
||||
"link_doctype": "POS Closing Entry",
|
||||
"link_fieldname": "pos_profile"
|
||||
}
|
||||
],
|
||||
"modified": "2021-02-01 13:52:51.081311",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Profile",
|
||||
|
||||
@@ -62,14 +62,15 @@ class POSProfile(Document):
|
||||
|
||||
if len(default_mode) > 1:
|
||||
frappe.throw(_("You can only select one mode of payment as default"))
|
||||
|
||||
|
||||
invalid_modes = []
|
||||
for d in self.payments:
|
||||
account = frappe.db.get_value(
|
||||
"Mode of Payment Account",
|
||||
"Mode of Payment Account",
|
||||
{"parent": d.mode_of_payment, "company": self.company},
|
||||
"default_account"
|
||||
)
|
||||
|
||||
if not account:
|
||||
invalid_modes.append(get_link_to_form("Mode of Payment", d.mode_of_payment))
|
||||
|
||||
|
||||
@@ -92,11 +92,21 @@ def make_pos_profile(**args):
|
||||
"write_off_cost_center": args.write_off_cost_center or "_Test Write Off Cost Center - _TC"
|
||||
})
|
||||
|
||||
payments = [{
|
||||
mode_of_payment = frappe.get_doc("Mode of Payment", "Cash")
|
||||
company = args.company or "_Test Company"
|
||||
default_account = args.income_account or "Sales - _TC"
|
||||
|
||||
if not frappe.db.get_value("Mode of Payment Account", {"company": company, "parent": "Cash"}):
|
||||
mode_of_payment.append("accounts", {
|
||||
"company": company,
|
||||
"default_account": default_account
|
||||
})
|
||||
mode_of_payment.save()
|
||||
|
||||
pos_profile.append("payments", {
|
||||
'mode_of_payment': 'Cash',
|
||||
'default': 1
|
||||
}]
|
||||
pos_profile.set("payments", payments)
|
||||
})
|
||||
|
||||
if not frappe.db.exists("POS Profile", args.name or "_Test POS Profile"):
|
||||
pos_profile.insert()
|
||||
|
||||
@@ -44,6 +44,14 @@
|
||||
"column_break_21",
|
||||
"min_amt",
|
||||
"max_amt",
|
||||
"product_discount_scheme_section",
|
||||
"same_item",
|
||||
"free_item",
|
||||
"free_qty",
|
||||
"free_item_rate",
|
||||
"column_break_42",
|
||||
"free_item_uom",
|
||||
"is_recursive",
|
||||
"section_break_23",
|
||||
"valid_from",
|
||||
"valid_upto",
|
||||
@@ -62,13 +70,6 @@
|
||||
"discount_amount",
|
||||
"discount_percentage",
|
||||
"for_price_list",
|
||||
"product_discount_scheme_section",
|
||||
"same_item",
|
||||
"free_item",
|
||||
"free_qty",
|
||||
"column_break_51",
|
||||
"free_item_uom",
|
||||
"free_item_rate",
|
||||
"section_break_13",
|
||||
"threshold_percentage",
|
||||
"priority",
|
||||
@@ -357,7 +358,6 @@
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.selling == 1",
|
||||
"fieldname": "margin",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Margin"
|
||||
@@ -459,10 +459,6 @@
|
||||
"fieldtype": "Float",
|
||||
"label": "Qty"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_51",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "free_item_uom",
|
||||
"fieldtype": "Link",
|
||||
@@ -553,19 +549,33 @@
|
||||
"fieldname": "promotional_scheme",
|
||||
"fieldtype": "Link",
|
||||
"label": "Promotional Scheme",
|
||||
"options": "Promotional Scheme"
|
||||
"no_copy": 1,
|
||||
"options": "Promotional Scheme",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"description": "Simple Python Expression, Example: territory != 'All Territories'",
|
||||
"fieldname": "condition",
|
||||
"fieldtype": "Code",
|
||||
"label": "Condition"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_42",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Discounts to be applied in sequential ranges like buy 1 get 1, buy 2 get 2, buy 3 get 3 and so on",
|
||||
"fieldname": "is_recursive",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Recursive"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-gift",
|
||||
"idx": 1,
|
||||
"links": [],
|
||||
"modified": "2020-12-04 00:36:24.698219",
|
||||
"modified": "2021-03-06 22:01:24.840422",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Pricing Rule",
|
||||
|
||||
@@ -136,7 +136,7 @@ class PricingRule(Document):
|
||||
for d in self.items:
|
||||
max_discount = frappe.get_cached_value("Item", d.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))
|
||||
throw(_("Max discount allowed for item: {0} is {1}%").format(d.item_code, max_discount))
|
||||
|
||||
def validate_price_list_with_currency(self):
|
||||
if self.currency and self.for_price_list:
|
||||
@@ -237,6 +237,7 @@ def get_pricing_rule_for_item(args, price_list_rate=0, doc=None, for_validate=Fa
|
||||
"doctype": args.doctype,
|
||||
"has_margin": False,
|
||||
"name": args.name,
|
||||
"free_item_data": [],
|
||||
"parent": args.parent,
|
||||
"parenttype": args.parenttype,
|
||||
"child_docname": args.get('child_docname')
|
||||
|
||||
@@ -328,6 +328,21 @@ class TestPricingRule(unittest.TestCase):
|
||||
self.assertEquals(item.discount_amount, 110)
|
||||
self.assertEquals(item.rate, 990)
|
||||
|
||||
def test_pricing_rule_with_margin_and_discount_amount(self):
|
||||
frappe.delete_doc_if_exists('Pricing Rule', '_Test Pricing Rule')
|
||||
make_pricing_rule(selling=1, margin_type="Percentage", margin_rate_or_amount=10,
|
||||
rate_or_discount="Discount Amount", discount_amount=110)
|
||||
si = create_sales_invoice(do_not_save=True)
|
||||
si.items[0].price_list_rate = 1000
|
||||
si.payment_schedule = []
|
||||
si.insert(ignore_permissions=True)
|
||||
|
||||
item = si.items[0]
|
||||
self.assertEquals(item.margin_rate_or_amount, 10)
|
||||
self.assertEquals(item.rate_with_margin, 1100)
|
||||
self.assertEquals(item.discount_amount, 110)
|
||||
self.assertEquals(item.rate, 990)
|
||||
|
||||
def test_pricing_rule_for_product_discount_on_same_item(self):
|
||||
frappe.delete_doc_if_exists('Pricing Rule', '_Test Pricing Rule')
|
||||
test_record = {
|
||||
@@ -560,6 +575,7 @@ def make_pricing_rule(**args):
|
||||
"margin_rate_or_amount": args.margin_rate_or_amount or 0.0,
|
||||
"condition": args.condition or '',
|
||||
"priority": 1,
|
||||
"discount_amount": args.discount_amount or 0.0,
|
||||
"apply_multiple_pricing_rules": args.apply_multiple_pricing_rules or 0
|
||||
})
|
||||
|
||||
|
||||
@@ -367,7 +367,7 @@ def get_qty_and_rate_for_mixed_conditions(doc, pr_doc, args):
|
||||
|
||||
if items and doc.get("items"):
|
||||
for row in doc.get('items'):
|
||||
if row.get(apply_on) not in items: continue
|
||||
if (row.get(apply_on) or args.get(apply_on)) not in items: continue
|
||||
|
||||
if pr_doc.mixed_conditions:
|
||||
amt = args.get('qty') * args.get("price_list_rate")
|
||||
@@ -479,7 +479,7 @@ def apply_pricing_rule_on_transaction(doc):
|
||||
|
||||
doc.calculate_taxes_and_totals()
|
||||
elif d.price_or_product_discount == 'Product':
|
||||
item_details = frappe._dict({'parenttype': doc.doctype})
|
||||
item_details = frappe._dict({'parenttype': doc.doctype, 'free_item_data': []})
|
||||
get_product_discount_rule(d, item_details, doc=doc)
|
||||
apply_pricing_rule_for_free_items(doc, item_details.free_item_data)
|
||||
doc.set_missing_values()
|
||||
@@ -508,9 +508,16 @@ def get_product_discount_rule(pricing_rule, item_details, args=None, doc=None):
|
||||
frappe.throw(_("Free item not set in the pricing rule {0}")
|
||||
.format(get_link_to_form("Pricing Rule", pricing_rule.name)))
|
||||
|
||||
item_details.free_item_data = {
|
||||
qty = pricing_rule.free_qty or 1
|
||||
if pricing_rule.is_recursive:
|
||||
transaction_qty = args.get('qty') if args else doc.total_qty
|
||||
if transaction_qty:
|
||||
qty = flt(transaction_qty) * qty
|
||||
|
||||
free_item_data_args = {
|
||||
'item_code': free_item,
|
||||
'qty': pricing_rule.free_qty or 1,
|
||||
'qty': qty,
|
||||
'pricing_rules': pricing_rule.name,
|
||||
'rate': pricing_rule.free_item_rate or 0,
|
||||
'price_list_rate': pricing_rule.free_item_rate or 0,
|
||||
'is_free_item': 1
|
||||
@@ -519,24 +526,26 @@ def get_product_discount_rule(pricing_rule, item_details, args=None, doc=None):
|
||||
item_data = frappe.get_cached_value('Item', free_item, ['item_name',
|
||||
'description', 'stock_uom'], as_dict=1)
|
||||
|
||||
item_details.free_item_data.update(item_data)
|
||||
item_details.free_item_data['uom'] = pricing_rule.free_item_uom or item_data.stock_uom
|
||||
item_details.free_item_data['conversion_factor'] = get_conversion_factor(free_item,
|
||||
item_details.free_item_data['uom']).get("conversion_factor", 1)
|
||||
free_item_data_args.update(item_data)
|
||||
free_item_data_args['uom'] = pricing_rule.free_item_uom or item_data.stock_uom
|
||||
free_item_data_args['conversion_factor'] = get_conversion_factor(free_item,
|
||||
free_item_data_args['uom']).get("conversion_factor", 1)
|
||||
|
||||
if item_details.get("parenttype") == 'Purchase Order':
|
||||
item_details.free_item_data['schedule_date'] = doc.schedule_date if doc else today()
|
||||
free_item_data_args['schedule_date'] = doc.schedule_date if doc else today()
|
||||
|
||||
if item_details.get("parenttype") == 'Sales Order':
|
||||
item_details.free_item_data['delivery_date'] = doc.delivery_date if doc else today()
|
||||
free_item_data_args['delivery_date'] = doc.delivery_date if doc else today()
|
||||
|
||||
item_details.free_item_data.append(free_item_data_args)
|
||||
|
||||
def apply_pricing_rule_for_free_items(doc, pricing_rule_args, set_missing_values=False):
|
||||
if pricing_rule_args.get('item_code'):
|
||||
items = [d.item_code for d in doc.items
|
||||
if d.item_code == (pricing_rule_args.get("item_code")) and d.is_free_item]
|
||||
if pricing_rule_args:
|
||||
items = tuple([(d.item_code, d.pricing_rules) for d in doc.items if d.is_free_item])
|
||||
|
||||
if not items:
|
||||
doc.append('items', pricing_rule_args)
|
||||
for args in pricing_rule_args:
|
||||
if not items or (args.get('item_code'), args.get('pricing_rules')) not in items:
|
||||
doc.append('items', args)
|
||||
|
||||
def get_pricing_rule_items(pr_doc):
|
||||
apply_on_data = []
|
||||
|
||||
@@ -12,16 +12,16 @@ from frappe.model.document import Document
|
||||
pricing_rule_fields = ['apply_on', 'mixed_conditions', 'is_cumulative', 'other_item_code', 'other_item_group'
|
||||
'apply_rule_on_other', 'other_brand', 'selling', 'buying', 'applicable_for', 'valid_from',
|
||||
'valid_upto', 'customer', 'customer_group', 'territory', 'sales_partner', 'campaign', 'supplier',
|
||||
'supplier_group', 'company', 'currency']
|
||||
'supplier_group', 'company', 'currency', 'apply_multiple_pricing_rules']
|
||||
|
||||
other_fields = ['min_qty', 'max_qty', 'min_amt',
|
||||
'max_amt', 'priority','warehouse', 'threshold_percentage', 'rule_description']
|
||||
|
||||
price_discount_fields = ['rate_or_discount', 'apply_discount_on', 'apply_discount_on_rate',
|
||||
'rate', 'discount_amount', 'discount_percentage', 'validate_applied_rule']
|
||||
'rate', 'discount_amount', 'discount_percentage', 'validate_applied_rule', 'apply_multiple_pricing_rules']
|
||||
|
||||
product_discount_fields = ['free_item', 'free_qty', 'free_item_uom',
|
||||
'free_item_rate', 'same_item']
|
||||
'free_item_rate', 'same_item', 'is_recursive', 'apply_multiple_pricing_rules']
|
||||
|
||||
class PromotionalScheme(Document):
|
||||
def validate(self):
|
||||
|
||||
@@ -1,792 +1,181 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_events_in_timeline": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"actions": [],
|
||||
"creation": "2019-03-24 14:48:59.649168",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"disable",
|
||||
"apply_multiple_pricing_rules",
|
||||
"column_break_2",
|
||||
"rule_description",
|
||||
"section_break_2",
|
||||
"min_qty",
|
||||
"max_qty",
|
||||
"column_break_3",
|
||||
"min_amount",
|
||||
"max_amount",
|
||||
"section_break_6",
|
||||
"rate_or_discount",
|
||||
"column_break_10",
|
||||
"rate",
|
||||
"discount_amount",
|
||||
"discount_percentage",
|
||||
"section_break_11",
|
||||
"warehouse",
|
||||
"threshold_percentage",
|
||||
"validate_applied_rule",
|
||||
"column_break_14",
|
||||
"priority",
|
||||
"apply_discount_on_rate"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"fieldname": "disable",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Disable",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Disable"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_2",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "rule_description",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Rule Description",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_2",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 1,
|
||||
"default": "0",
|
||||
"fieldname": "min_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Min Qty",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Min Qty"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 1,
|
||||
"default": "0",
|
||||
"fieldname": "max_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Max Qty",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Max Qty"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"fieldname": "min_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Min Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Min Amount"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"depends_on": "",
|
||||
"fieldname": "max_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Max Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Max Amount"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "section_break_6",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Discount Percentage",
|
||||
"depends_on": "",
|
||||
"fieldname": "rate_or_discount",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Discount Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nRate\nDiscount Percentage\nDiscount Amount",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"options": "\nRate\nDiscount Percentage\nDiscount Amount"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "column_break_10",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"depends_on": "eval:doc.rate_or_discount==\"Rate\"",
|
||||
"fieldname": "rate",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Rate",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Rate"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.rate_or_discount==\"Discount Amount\"",
|
||||
"fieldname": "discount_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Discount Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Discount Amount"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.rate_or_discount==\"Discount Percentage\"",
|
||||
"fieldname": "discount_percentage",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Discount Percentage",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Discount Percentage"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_11",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "warehouse",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Warehouse",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"options": "Warehouse"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "threshold_percentage",
|
||||
"fieldtype": "Percent",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Threshold for Suggestion",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Threshold for Suggestion"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "1",
|
||||
"fieldname": "validate_applied_rule",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Validate Applied Rule",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Validate Applied Rule"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_14",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "priority",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Priority",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"depends_on": "priority",
|
||||
"fieldname": "apply_multiple_pricing_rules",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Apply Multiple Pricing Rules",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Apply Multiple Pricing Rules"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"depends_on": "eval:in_list(['Discount Percentage', 'Discount Amount'], doc.rate_or_discount) && doc.apply_multiple_pricing_rules",
|
||||
"fieldname": "apply_discount_on_rate",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Apply Discount on Rate",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Apply Discount on Rate"
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2019-03-24 14:48:59.649168",
|
||||
"links": [],
|
||||
"modified": "2021-03-07 11:56:23.424137",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Promotional Scheme Price Discount",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2019-03-24 14:48:59.649168",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"disable",
|
||||
"apply_multiple_pricing_rules",
|
||||
"column_break_2",
|
||||
"rule_description",
|
||||
"section_break_1",
|
||||
@@ -25,7 +27,7 @@
|
||||
"threshold_percentage",
|
||||
"column_break_15",
|
||||
"priority",
|
||||
"apply_multiple_pricing_rules"
|
||||
"is_recursive"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -152,10 +154,19 @@
|
||||
"fieldname": "apply_multiple_pricing_rules",
|
||||
"fieldtype": "Check",
|
||||
"label": "Apply Multiple Pricing Rules"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Discounts to be applied in sequential ranges like buy 1 get 1, buy 2 get 2, buy 3 get 3 and so on",
|
||||
"fieldname": "is_recursive",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Recursive"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"modified": "2019-07-21 00:00:56.674284",
|
||||
"links": [],
|
||||
"modified": "2021-03-06 21:58:18.162346",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Promotional Scheme Product Discount",
|
||||
|
||||
@@ -524,7 +524,7 @@ frappe.ui.form.on("Purchase Invoice", {
|
||||
},
|
||||
|
||||
onload: function(frm) {
|
||||
if(frm.doc.__onload) {
|
||||
if(frm.doc.__onload && frm.is_new()) {
|
||||
if(frm.doc.supplier) {
|
||||
frm.doc.apply_tds = frm.doc.__onload.supplier_tds ? 1 : 0;
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
"rejected_warehouse",
|
||||
"col_break_warehouse",
|
||||
"set_from_warehouse",
|
||||
"supplier_warehouse",
|
||||
"is_subcontracted",
|
||||
"items_section",
|
||||
"update_stock",
|
||||
@@ -1350,7 +1351,7 @@
|
||||
"options": "Company"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.update_stock && (doc.is_subcontracted==\"Yes\" || doc.is_internal_supplier)",
|
||||
"depends_on": "eval:doc.update_stock && doc.is_internal_supplier",
|
||||
"description": "Sets 'From Warehouse' in each row of the items table.",
|
||||
"fieldname": "set_from_warehouse",
|
||||
"fieldtype": "Link",
|
||||
@@ -1360,13 +1361,24 @@
|
||||
"print_hide": 1,
|
||||
"print_width": "50px",
|
||||
"width": "50px"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.update_stock && doc.is_subcontracted==\"Yes\"",
|
||||
"fieldname": "supplier_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Supplier Warehouse",
|
||||
"no_copy": 1,
|
||||
"options": "Warehouse",
|
||||
"print_hide": 1,
|
||||
"print_width": "50px",
|
||||
"width": "50px"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-file-text",
|
||||
"idx": 204,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-12-26 20:49:03.305063",
|
||||
"modified": "2021-03-09 21:15:30.422084",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice",
|
||||
|
||||
@@ -968,7 +968,7 @@ class PurchaseInvoice(BuyingController):
|
||||
# base_rounding_adjustment may become zero due to small precision
|
||||
# eg: rounding_adjustment = 0.01 and exchange rate = 0.05 and precision of base_rounding_adjustment is 2
|
||||
# then base_rounding_adjustment becomes zero and error is thrown in GL Entry
|
||||
if self.rounding_adjustment and self.base_rounding_adjustment:
|
||||
if not self.is_internal_transfer() and self.rounding_adjustment and self.base_rounding_adjustment:
|
||||
round_off_account, round_off_cost_center = \
|
||||
get_round_off_account_and_cost_center(self.company)
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ frappe.listview_settings['Purchase Invoice'] = {
|
||||
return [__("Unpaid"), "orange", "outstanding_amount,>,0|due_date,>=,Today"];
|
||||
}
|
||||
} else if (cint(doc.is_return)) {
|
||||
return [__("Return"), "darkgrey", "is_return,=,Yes"];
|
||||
return [__("Return"), "gray", "is_return,=,Yes"];
|
||||
} else if (doc.company == doc.represents_company && doc.is_internal_supplier) {
|
||||
return [__("Internal Transfer"), "darkgrey", "outstanding_amount,=,0"];
|
||||
} else if (flt(doc.outstanding_amount)==0 && doc.docstatus==1) {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"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_template": "_Test Account Excise Duty @ 10",
|
||||
"item_tax_template": "_Test Account Excise Duty @ 10 - _TC",
|
||||
"parentfield": "items",
|
||||
"qty": 10,
|
||||
"rate": 50,
|
||||
@@ -43,7 +43,7 @@
|
||||
}
|
||||
],
|
||||
"grand_total": 0,
|
||||
"naming_series": "_T-BILL",
|
||||
"naming_series": "T-PINV-",
|
||||
"taxes": [
|
||||
{
|
||||
"account_head": "_Test Account Shipping Charges - _TC",
|
||||
@@ -167,7 +167,7 @@
|
||||
}
|
||||
],
|
||||
"grand_total": 0,
|
||||
"naming_series": "_T-Purchase Invoice-",
|
||||
"naming_series": "T-PINV-",
|
||||
"taxes": [
|
||||
{
|
||||
"account_head": "_Test Account Shipping Charges - _TC",
|
||||
|
||||
@@ -28,10 +28,16 @@
|
||||
"stock_qty",
|
||||
"sec_break1",
|
||||
"price_list_rate",
|
||||
"discount_percentage",
|
||||
"discount_amount",
|
||||
"col_break3",
|
||||
"base_price_list_rate",
|
||||
"section_break_26",
|
||||
"margin_type",
|
||||
"margin_rate_or_amount",
|
||||
"rate_with_margin",
|
||||
"column_break_30",
|
||||
"discount_percentage",
|
||||
"discount_amount",
|
||||
"base_rate_with_margin",
|
||||
"sec_break2",
|
||||
"rate",
|
||||
"amount",
|
||||
@@ -789,6 +795,7 @@
|
||||
"fieldname": "stock_uom_rate",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Rate of Stock UOM",
|
||||
"no_copy": 1,
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
@@ -799,12 +806,54 @@
|
||||
"no_copy": 1,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "section_break_26",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Discount and Margin"
|
||||
},
|
||||
{
|
||||
"depends_on": "price_list_rate",
|
||||
"fieldname": "margin_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Margin Type",
|
||||
"options": "\nPercentage\nAmount",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.margin_type && doc.price_list_rate",
|
||||
"fieldname": "margin_rate_or_amount",
|
||||
"fieldtype": "Float",
|
||||
"label": "Margin Rate or Amount",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.margin_type && doc.price_list_rate && doc.margin_rate_or_amount",
|
||||
"fieldname": "rate_with_margin",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Rate With Margin",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_30",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.margin_type && doc.price_list_rate && doc.margin_rate_or_amount",
|
||||
"fieldname": "base_rate_with_margin",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Rate With Margin (Company Currency)",
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-01-30 21:43:21.488258",
|
||||
"modified": "2021-02-23 00:59:52.614805",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice Item",
|
||||
|
||||
@@ -6,8 +6,5 @@ import frappe
|
||||
|
||||
from frappe.model.document import Document
|
||||
|
||||
from erpnext.controllers.print_settings import print_settings_for_item_table
|
||||
|
||||
class PurchaseInvoiceItem(Document):
|
||||
def __setup__(self):
|
||||
print_settings_for_item_table(self)
|
||||
pass
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
var globalOnload = frappe.listview_settings['Sales Invoice'].onload;
|
||||
frappe.listview_settings['Sales Invoice'].onload = function (doclist) {
|
||||
frappe.listview_settings['Sales Invoice'].onload = function (list_view) {
|
||||
|
||||
// Provision in case onload event is added to sales_invoice.js in future
|
||||
if (globalOnload) {
|
||||
globalOnload(doclist);
|
||||
globalOnload(list_view);
|
||||
}
|
||||
|
||||
const action = () => {
|
||||
const selected_docs = doclist.get_checked_items();
|
||||
const docnames = doclist.get_checked_items(true);
|
||||
const selected_docs = list_view.get_checked_items();
|
||||
const docnames = list_view.get_checked_items(true);
|
||||
|
||||
for (let doc of selected_docs) {
|
||||
if (doc.docstatus !== 1) {
|
||||
@@ -19,7 +19,7 @@ frappe.listview_settings['Sales Invoice'].onload = function (doclist) {
|
||||
frappe.call({
|
||||
method: 'erpnext.regional.india.utils.generate_ewb_json',
|
||||
args: {
|
||||
'dt': doclist.doctype,
|
||||
'dt': list_view.doctype,
|
||||
'dn': docnames
|
||||
},
|
||||
callback: function(r) {
|
||||
@@ -35,5 +35,140 @@ frappe.listview_settings['Sales Invoice'].onload = function (doclist) {
|
||||
});
|
||||
};
|
||||
|
||||
doclist.page.add_actions_menu_item(__('Generate E-Way Bill JSON'), action, false);
|
||||
list_view.page.add_actions_menu_item(__('Generate E-Way Bill JSON'), action, false);
|
||||
|
||||
const generate_irns = () => {
|
||||
const docnames = list_view.get_checked_items(true);
|
||||
if (docnames && docnames.length) {
|
||||
frappe.call({
|
||||
method: 'erpnext.regional.india.e_invoice.utils.generate_einvoices',
|
||||
args: { docnames },
|
||||
freeze: true,
|
||||
freeze_message: __('Generating E-Invoices...')
|
||||
});
|
||||
} else {
|
||||
frappe.msgprint({
|
||||
message: __('Please select at least one sales invoice to generate IRN'),
|
||||
title: __('No Invoice Selected'),
|
||||
indicator: 'red'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const cancel_irns = () => {
|
||||
const docnames = list_view.get_checked_items(true);
|
||||
|
||||
const fields = [
|
||||
{
|
||||
"label": "Reason",
|
||||
"fieldname": "reason",
|
||||
"fieldtype": "Select",
|
||||
"reqd": 1,
|
||||
"default": "1-Duplicate",
|
||||
"options": ["1-Duplicate", "2-Data Entry Error", "3-Order Cancelled", "4-Other"]
|
||||
},
|
||||
{
|
||||
"label": "Remark",
|
||||
"fieldname": "remark",
|
||||
"fieldtype": "Data",
|
||||
"reqd": 1
|
||||
}
|
||||
];
|
||||
|
||||
const d = new frappe.ui.Dialog({
|
||||
title: __("Cancel IRN"),
|
||||
fields: fields,
|
||||
primary_action: function() {
|
||||
const data = d.get_values();
|
||||
frappe.call({
|
||||
method: 'erpnext.regional.india.e_invoice.utils.cancel_irns',
|
||||
args: {
|
||||
doctype: list_view.doctype,
|
||||
docnames,
|
||||
reason: data.reason.split('-')[0],
|
||||
remark: data.remark
|
||||
},
|
||||
freeze: true,
|
||||
freeze_message: __('Cancelling E-Invoices...'),
|
||||
});
|
||||
d.hide();
|
||||
},
|
||||
primary_action_label: __('Submit')
|
||||
});
|
||||
d.show();
|
||||
};
|
||||
|
||||
let einvoicing_enabled = false;
|
||||
frappe.db.get_single_value("E Invoice Settings", "enable").then(enabled => {
|
||||
einvoicing_enabled = enabled;
|
||||
});
|
||||
|
||||
list_view.$result.on("change", "input[type=checkbox]", () => {
|
||||
if (einvoicing_enabled) {
|
||||
const docnames = list_view.get_checked_items(true);
|
||||
// show/hide e-invoicing actions when no sales invoices are checked
|
||||
if (docnames && docnames.length) {
|
||||
// prevent adding actions twice if e-invoicing action group already exists
|
||||
if (list_view.page.get_inner_group_button(__('E-Invoicing')).length == 0) {
|
||||
list_view.page.add_inner_button(__('Generate IRNs'), generate_irns, __('E-Invoicing'));
|
||||
list_view.page.add_inner_button(__('Cancel IRNs'), cancel_irns, __('E-Invoicing'));
|
||||
}
|
||||
} else {
|
||||
list_view.page.remove_inner_button(__('Generate IRNs'), __('E-Invoicing'));
|
||||
list_view.page.remove_inner_button(__('Cancel IRNs'), __('E-Invoicing'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frappe.realtime.on("bulk_einvoice_generation_complete", (data) => {
|
||||
const { failures, user, invoices } = data;
|
||||
|
||||
if (invoices.length != failures.length) {
|
||||
frappe.msgprint({
|
||||
message: __('{0} e-invoices generated successfully', [invoices.length]),
|
||||
title: __('Bulk E-Invoice Generation Complete'),
|
||||
indicator: 'orange'
|
||||
});
|
||||
}
|
||||
|
||||
if (failures && failures.length && user == frappe.session.user) {
|
||||
let message = `
|
||||
Failed to generate IRNs for following ${failures.length} sales invoices:
|
||||
<ul style="padding-left: 20px; padding-top: 5px;">
|
||||
${failures.map(d => `<li>${d.docname}</li>`).join('')}
|
||||
</ul>
|
||||
`;
|
||||
frappe.msgprint({
|
||||
message: message,
|
||||
title: __('Bulk E-Invoice Generation Complete'),
|
||||
indicator: 'orange'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
frappe.realtime.on("bulk_einvoice_cancellation_complete", (data) => {
|
||||
const { failures, user, invoices } = data;
|
||||
|
||||
if (invoices.length != failures.length) {
|
||||
frappe.msgprint({
|
||||
message: __('{0} e-invoices cancelled successfully', [invoices.length]),
|
||||
title: __('Bulk E-Invoice Cancellation Complete'),
|
||||
indicator: 'orange'
|
||||
});
|
||||
}
|
||||
|
||||
if (failures && failures.length && user == frappe.session.user) {
|
||||
let message = `
|
||||
Failed to cancel IRNs for following ${failures.length} sales invoices:
|
||||
<ul style="padding-left: 20px; padding-top: 5px;">
|
||||
${failures.map(d => `<li>${d.docname}</li>`).join('')}
|
||||
</ul>
|
||||
`;
|
||||
frappe.msgprint({
|
||||
message: message,
|
||||
title: __('Bulk E-Invoice Cancellation Complete'),
|
||||
indicator: 'orange'
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -669,12 +669,12 @@ frappe.ui.form.on('Sales Invoice', {
|
||||
};
|
||||
},
|
||||
// When multiple companies are set up. in case company name is changed set default company address
|
||||
company:function(frm){
|
||||
if (frm.doc.company)
|
||||
{
|
||||
company: function(frm){
|
||||
if (frm.doc.company) {
|
||||
frappe.call({
|
||||
method:"erpnext.setup.doctype.company.company.get_default_company_address",
|
||||
args:{name:frm.doc.company, existing_address: frm.doc.company_address},
|
||||
method: "erpnext.setup.doctype.company.company.get_default_company_address",
|
||||
args: {name:frm.doc.company, existing_address: frm.doc.company_address || ""},
|
||||
debounce: 2000,
|
||||
callback: function(r){
|
||||
if (r.message){
|
||||
frm.set_value("company_address",r.message)
|
||||
@@ -695,6 +695,7 @@ frappe.ui.form.on('Sales Invoice', {
|
||||
refresh_field(['timesheets'])
|
||||
}
|
||||
})
|
||||
frm.refresh();
|
||||
},
|
||||
|
||||
onload: function(frm) {
|
||||
@@ -810,6 +811,65 @@ frappe.ui.form.on('Sales Invoice', {
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
if (frm.doc.project) {
|
||||
frm.add_custom_button(__('Fetch Timesheet'), function() {
|
||||
let d = new frappe.ui.Dialog({
|
||||
title: __('Fetch Timesheet'),
|
||||
fields: [
|
||||
{
|
||||
"label" : "From",
|
||||
"fieldname": "from_time",
|
||||
"fieldtype": "Date",
|
||||
"reqd": 1,
|
||||
},
|
||||
{
|
||||
fieldtype: 'Column Break',
|
||||
fieldname: 'col_break_1',
|
||||
},
|
||||
{
|
||||
"label" : "To",
|
||||
"fieldname": "to_time",
|
||||
"fieldtype": "Date",
|
||||
"reqd": 1,
|
||||
}
|
||||
],
|
||||
primary_action: function() {
|
||||
let data = d.get_values();
|
||||
frappe.call({
|
||||
method: "erpnext.projects.doctype.timesheet.timesheet.get_projectwise_timesheet_data",
|
||||
args: {
|
||||
from_time: data.from_time,
|
||||
to_time: data.to_time,
|
||||
project: frm.doc.project
|
||||
},
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
if(r.message.length > 0) {
|
||||
frm.clear_table('timesheets')
|
||||
r.message.forEach((d) => {
|
||||
frm.add_child('timesheets',{
|
||||
'time_sheet': d.parent,
|
||||
'billing_hours': d.billing_hours,
|
||||
'billing_amount': d.billing_amt,
|
||||
'timesheet_detail': d.name
|
||||
});
|
||||
});
|
||||
frm.refresh_field('timesheets')
|
||||
}
|
||||
else {
|
||||
frappe.msgprint(__('No Timesheet Found.'))
|
||||
}
|
||||
d.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
primary_action_label: __('Get Timesheets')
|
||||
});
|
||||
d.show();
|
||||
})
|
||||
}
|
||||
|
||||
if (frappe.boot.active_domains.includes("Healthcare")) {
|
||||
frm.set_df_property("patient", "hidden", 0);
|
||||
frm.set_df_property("patient_name", "hidden", 0);
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
"customer",
|
||||
"customer_name",
|
||||
"tax_id",
|
||||
"pos_profile",
|
||||
"is_pos",
|
||||
"is_consolidated",
|
||||
"pos_profile",
|
||||
"offline_pos_name",
|
||||
"is_return",
|
||||
"update_billed_amount_in_sales_order",
|
||||
"column_break1",
|
||||
"company",
|
||||
"company_tax_id",
|
||||
@@ -24,11 +24,8 @@
|
||||
"posting_time",
|
||||
"set_posting_time",
|
||||
"due_date",
|
||||
"amended_from",
|
||||
"returns",
|
||||
"return_against",
|
||||
"column_break_21",
|
||||
"update_billed_amount_in_sales_order",
|
||||
"amended_from",
|
||||
"accounting_dimensions_section",
|
||||
"project",
|
||||
"dimension_col_break",
|
||||
@@ -188,8 +185,7 @@
|
||||
"column_break_140",
|
||||
"auto_repeat",
|
||||
"update_auto_repeat_reference",
|
||||
"against_income_account",
|
||||
"pos_total_qty"
|
||||
"against_income_account"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -296,16 +292,6 @@
|
||||
"options": "POS Profile",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "offline_pos_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"label": "Offline POS Name",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "is_return",
|
||||
@@ -404,33 +390,19 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "return_against",
|
||||
"fieldname": "returns",
|
||||
"fieldtype": "Section Break",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"label": "Returns"
|
||||
},
|
||||
{
|
||||
"depends_on": "return_against",
|
||||
"fieldname": "return_against",
|
||||
"fieldtype": "Link",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"label": "Return Against Sales Invoice",
|
||||
"label": "Return Against",
|
||||
"no_copy": 1,
|
||||
"options": "Sales Invoice",
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_21",
|
||||
"fieldtype": "Column Break",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "eval: doc.is_return && doc.return_against",
|
||||
@@ -678,7 +650,8 @@
|
||||
"fieldname": "sec_warehouse",
|
||||
"fieldtype": "Section Break",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1
|
||||
"hide_seconds": 1,
|
||||
"label": "Warehouse"
|
||||
},
|
||||
{
|
||||
"depends_on": "update_stock",
|
||||
@@ -686,7 +659,7 @@
|
||||
"fieldtype": "Link",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"label": "Set Source Warehouse",
|
||||
"label": "Source Warehouse",
|
||||
"options": "Warehouse",
|
||||
"print_hide": 1
|
||||
},
|
||||
@@ -695,6 +668,7 @@
|
||||
"fieldtype": "Section Break",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"label": "Items",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "fa fa-shopping-cart"
|
||||
},
|
||||
@@ -1904,17 +1878,6 @@
|
||||
"print_hide": 1,
|
||||
"report_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pos_total_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 1,
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"label": "Total Qty",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "accounting_dimensions_section",
|
||||
@@ -1989,13 +1952,12 @@
|
||||
"is_submittable": 1,
|
||||
"links": [
|
||||
{
|
||||
"custom": 1,
|
||||
"group": "Reference",
|
||||
"link_doctype": "POS Invoice",
|
||||
"link_fieldname": "consolidated_invoice"
|
||||
}
|
||||
],
|
||||
"modified": "2021-01-12 12:16:15.192520",
|
||||
"modified": "2021-03-31 15:42:26.261540",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice",
|
||||
|
||||
@@ -21,8 +21,10 @@ from erpnext.accounts.general_ledger import get_round_off_account_and_cost_cente
|
||||
from erpnext.accounts.doctype.loyalty_program.loyalty_program import \
|
||||
get_loyalty_program_details_with_points, get_loyalty_details, validate_loyalty_points
|
||||
from erpnext.accounts.deferred_revenue import validate_service_stop_date
|
||||
from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import get_party_tax_withholding_details
|
||||
from frappe.model.utils import get_fetch_values
|
||||
from frappe.contacts.doctype.address.address import get_address_display
|
||||
from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import get_party_tax_withholding_details
|
||||
|
||||
from erpnext.healthcare.utils import manage_invoice_submit_cancel
|
||||
|
||||
@@ -55,7 +57,7 @@ class SalesInvoice(SellingController):
|
||||
"""Set indicator for portal"""
|
||||
if self.outstanding_amount < 0:
|
||||
self.indicator_title = _("Credit Note Issued")
|
||||
self.indicator_color = "darkgrey"
|
||||
self.indicator_color = "gray"
|
||||
elif self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()):
|
||||
self.indicator_color = "orange"
|
||||
self.indicator_title = _("Unpaid")
|
||||
@@ -64,7 +66,7 @@ class SalesInvoice(SellingController):
|
||||
self.indicator_title = _("Overdue")
|
||||
elif cint(self.is_return) == 1:
|
||||
self.indicator_title = _("Return")
|
||||
self.indicator_color = "darkgrey"
|
||||
self.indicator_color = "gray"
|
||||
else:
|
||||
self.indicator_color = "green"
|
||||
self.indicator_title = _("Paid")
|
||||
@@ -75,6 +77,8 @@ class SalesInvoice(SellingController):
|
||||
|
||||
if not self.is_pos:
|
||||
self.so_dn_required()
|
||||
|
||||
self.set_tax_withholding()
|
||||
|
||||
self.validate_proj_cust()
|
||||
self.validate_pos_return()
|
||||
@@ -153,6 +157,32 @@ class SalesInvoice(SellingController):
|
||||
if cost_center_company != self.company:
|
||||
frappe.throw(_("Row #{0}: Cost Center {1} does not belong to company {2}").format(frappe.bold(item.idx), frappe.bold(item.cost_center), frappe.bold(self.company)))
|
||||
|
||||
def set_tax_withholding(self):
|
||||
tax_withholding_details = get_party_tax_withholding_details(self)
|
||||
|
||||
if not tax_withholding_details:
|
||||
return
|
||||
|
||||
accounts = []
|
||||
tax_withholding_account = tax_withholding_details.get("account_head")
|
||||
|
||||
for d in self.taxes:
|
||||
if d.account_head == tax_withholding_account:
|
||||
d.update(tax_withholding_details)
|
||||
accounts.append(d.account_head)
|
||||
|
||||
if not accounts or tax_withholding_account not in accounts:
|
||||
self.append("taxes", tax_withholding_details)
|
||||
|
||||
to_remove = [d for d in self.taxes
|
||||
if not d.tax_amount and d.charge_type == "Actual" and d.account_head == tax_withholding_account]
|
||||
|
||||
for d in to_remove:
|
||||
self.remove(d)
|
||||
|
||||
# calculate totals again after applying TDS
|
||||
self.calculate_taxes_and_totals()
|
||||
|
||||
def before_save(self):
|
||||
set_account_for_mode_of_payment(self)
|
||||
|
||||
@@ -1033,7 +1063,8 @@ class SalesInvoice(SellingController):
|
||||
)
|
||||
|
||||
def make_gle_for_rounding_adjustment(self, gl_entries):
|
||||
if flt(self.rounding_adjustment, self.precision("rounding_adjustment")) and self.base_rounding_adjustment:
|
||||
if flt(self.rounding_adjustment, self.precision("rounding_adjustment")) and self.base_rounding_adjustment \
|
||||
and not self.is_internal_transfer():
|
||||
round_off_account, round_off_cost_center = \
|
||||
get_round_off_account_and_cost_center(self.company)
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ frappe.listview_settings['Sales Invoice'] = {
|
||||
"Draft": "grey",
|
||||
"Unpaid": "orange",
|
||||
"Paid": "green",
|
||||
"Return": "darkgrey",
|
||||
"Credit Note Issued": "darkgrey",
|
||||
"Return": "gray",
|
||||
"Credit Note Issued": "gray",
|
||||
"Unpaid and Discounted": "orange",
|
||||
"Overdue and Discounted": "red",
|
||||
"Overdue": "red",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user