Compare commits
1099 Commits
v14.65.1
...
pe_referen
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3117cca0c | ||
|
|
7cbb6c4de9 | ||
|
|
b602a0dcb0 | ||
|
|
26adbc6282 | ||
|
|
861aa9e08a | ||
|
|
c1a82dc9e5 | ||
|
|
b1242bc56c | ||
|
|
af1f98e188 | ||
|
|
e5566b31d5 | ||
|
|
a6794c3606 | ||
|
|
19db7e2989 | ||
|
|
d23b5d8f2f | ||
|
|
01b84a9751 | ||
|
|
3aa6f97420 | ||
|
|
63393fa503 | ||
|
|
921f8edde8 | ||
|
|
5853b80d25 | ||
|
|
8301d3b13f | ||
|
|
a26a29f33b | ||
|
|
a074ffa880 | ||
|
|
e526a0e282 | ||
|
|
a2abc879c9 | ||
|
|
d0478ec3b8 | ||
|
|
713330cbf6 | ||
|
|
7bd0e977bf | ||
|
|
3814db02eb | ||
|
|
ef9d126254 | ||
|
|
31db0e7c79 | ||
|
|
2c4eb371a6 | ||
|
|
eb66b749b2 | ||
|
|
083a954b5d | ||
|
|
66dbf94151 | ||
|
|
295ce0e8e9 | ||
|
|
2cce6f2a34 | ||
|
|
b3ae6cc4b9 | ||
|
|
2058fac177 | ||
|
|
5949a7ecff | ||
|
|
3ce8386ca3 | ||
|
|
2106de0fa5 | ||
|
|
9ddd838f2d | ||
|
|
8d36328544 | ||
|
|
4856e750f9 | ||
|
|
03f7bfbbde | ||
|
|
826f45ad60 | ||
|
|
9b8d6fe411 | ||
|
|
5b1743330d | ||
|
|
2886d8ab5a | ||
|
|
5b1798363c | ||
|
|
d892e27289 | ||
|
|
93f29d8f08 | ||
|
|
9a8f3f4280 | ||
|
|
827ad01d4f | ||
|
|
ba38001116 | ||
|
|
25522444b8 | ||
|
|
0e8edd1ee9 | ||
|
|
bfb81ef56f | ||
|
|
64e5a79a91 | ||
|
|
c5edbe2e2f | ||
|
|
12637cda84 | ||
|
|
43d08b4c74 | ||
|
|
ca0485a503 | ||
|
|
4bd9289d7d | ||
|
|
2e2590b224 | ||
|
|
3eb1ed19a1 | ||
|
|
bfd7a97ea9 | ||
|
|
ce7720b14c | ||
|
|
6dd84cb977 | ||
|
|
a7b7d0d99d | ||
|
|
8253f4379f | ||
|
|
56b96f0a9c | ||
|
|
bdb15c3331 | ||
|
|
8287fb5104 | ||
|
|
8112493c3c | ||
|
|
a222b0a6ae | ||
|
|
06e094b5fc | ||
|
|
b606a9684b | ||
|
|
b2105a8be7 | ||
|
|
6a47fb6c9e | ||
|
|
4750bfaeab | ||
|
|
a9cf9e5a88 | ||
|
|
ec95a9b760 | ||
|
|
7a887cf8ba | ||
|
|
8948e42a6d | ||
|
|
4e10352b48 | ||
|
|
eeec008547 | ||
|
|
6868b4d7c3 | ||
|
|
eeda264eb6 | ||
|
|
fa15221455 | ||
|
|
ba77da0874 | ||
|
|
6ebe8ad60d | ||
|
|
b8b9d1b0a8 | ||
|
|
e02f35c8ff | ||
|
|
9fd70a6827 | ||
|
|
f6126069ee | ||
|
|
63b9795d41 | ||
|
|
4f2ece34df | ||
|
|
dedd722aef | ||
|
|
397a0e2a3a | ||
|
|
0919976414 | ||
|
|
ef7fd670fc | ||
|
|
481149814e | ||
|
|
2e4f3e9317 | ||
|
|
87b39f045c | ||
|
|
8cb7112e72 | ||
|
|
10a2121361 | ||
|
|
905a50cbb2 | ||
|
|
0f87d329d6 | ||
|
|
2c18a95115 | ||
|
|
c6984cd1c4 | ||
|
|
cc63415887 | ||
|
|
fe87c27acd | ||
|
|
722e29df5c | ||
|
|
7fd2639e68 | ||
|
|
4e7613d4ce | ||
|
|
df0fee2312 | ||
|
|
b0c8643517 | ||
|
|
541eb7e43b | ||
|
|
87d37e90a2 | ||
|
|
104fdcb9f9 | ||
|
|
80813c66e3 | ||
|
|
93f6ea1e55 | ||
|
|
4ad0e2ed7e | ||
|
|
95a620a30d | ||
|
|
0e726609f1 | ||
|
|
3724f2287c | ||
|
|
dc8d635120 | ||
|
|
88a0aa4077 | ||
|
|
b482e3876d | ||
|
|
60740baf3b | ||
|
|
7a7b8c2284 | ||
|
|
5e4a287624 | ||
|
|
a378619c9a | ||
|
|
0e3438db10 | ||
|
|
f448a077b8 | ||
|
|
bbfa644475 | ||
|
|
be19e4f621 | ||
|
|
a3c81da890 | ||
|
|
68424887e4 | ||
|
|
06c9c679e6 | ||
|
|
34e775136d | ||
|
|
eb74362263 | ||
|
|
0fffe61e3c | ||
|
|
0fdde2e5c0 | ||
|
|
46e8cdf31a | ||
|
|
31f463dd83 | ||
|
|
454b598718 | ||
|
|
e96be712b8 | ||
|
|
541cf153f7 | ||
|
|
bf76b85dfd | ||
|
|
cd88a53533 | ||
|
|
1b9e83251f | ||
|
|
81c856ccb8 | ||
|
|
1100816d7a | ||
|
|
5d9960ae5b | ||
|
|
80e45828ae | ||
|
|
7cc99ab63b | ||
|
|
b9d0b4e2d3 | ||
|
|
022d8d5d79 | ||
|
|
e25d0ead1a | ||
|
|
c2b3c3a29d | ||
|
|
15e74c5d7b | ||
|
|
64802d1220 | ||
|
|
89631fa744 | ||
|
|
26dcde2931 | ||
|
|
f96c66bbc0 | ||
|
|
dd2493a541 | ||
|
|
5caaccc94b | ||
|
|
68b04e2577 | ||
|
|
491857b3c8 | ||
|
|
df096688f7 | ||
|
|
8b394afaa9 | ||
|
|
985ce0dc42 | ||
|
|
602a13b0ac | ||
|
|
62c0210463 | ||
|
|
29132609ff | ||
|
|
12d7b7e9c2 | ||
|
|
cbfd8da848 | ||
|
|
d1f85dd9fc | ||
|
|
a5966b6f84 | ||
|
|
ffd287d5a6 | ||
|
|
77105306f2 | ||
|
|
029f22c549 | ||
|
|
ce83f02f24 | ||
|
|
d2563ee973 | ||
|
|
1a1bfc8db9 | ||
|
|
48413b0778 | ||
|
|
66ac65482d | ||
|
|
8ae58ed427 | ||
|
|
fdfe5cbf93 | ||
|
|
678a4c33da | ||
|
|
0b5584a54a | ||
|
|
546c809cbe | ||
|
|
cbe8fa7fd2 | ||
|
|
29a8d9a9b4 | ||
|
|
2dfe849c7d | ||
|
|
be15419bd5 | ||
|
|
61f05132db | ||
|
|
fd3c7903ba | ||
|
|
da4c20f7be | ||
|
|
40f90d3e95 | ||
|
|
1349d24514 | ||
|
|
2f4940cc26 | ||
|
|
34e4903ed7 | ||
|
|
f71f27462d | ||
|
|
e13b9e839d | ||
|
|
7f6e447d45 | ||
|
|
5efbc2cbf8 | ||
|
|
218da1217a | ||
|
|
538da9a58e | ||
|
|
b5e5d3b3af | ||
|
|
b03b568e6c | ||
|
|
1bd886387b | ||
|
|
5083c22490 | ||
|
|
c460141f0d | ||
|
|
31afae3e75 | ||
|
|
ffa30127e7 | ||
|
|
7bd06e6fbc | ||
|
|
9154d08b89 | ||
|
|
3a523b56bf | ||
|
|
aae2408f70 | ||
|
|
aac1f4923b | ||
|
|
e81bec5fc9 | ||
|
|
399ee80d80 | ||
|
|
7dd7617ec7 | ||
|
|
8a73e963ce | ||
|
|
e5dfd53e6f | ||
|
|
ba6189d054 | ||
|
|
343b414b40 | ||
|
|
89aabdaaaa | ||
|
|
d86afddb60 | ||
|
|
71412f6877 | ||
|
|
0486078ba9 | ||
|
|
b89b07d0ff | ||
|
|
33b61aef5a | ||
|
|
3a35651441 | ||
|
|
c013db6ea1 | ||
|
|
b3bc1c66a3 | ||
|
|
0a69523940 | ||
|
|
6f2989c7f2 | ||
|
|
369db4eacc | ||
|
|
01f56c621c | ||
|
|
3706a9b4dc | ||
|
|
35088bb4c4 | ||
|
|
a0d9e1bd57 | ||
|
|
91fad1935e | ||
|
|
9f5d613c78 | ||
|
|
a1a992b0dd | ||
|
|
cee069d426 | ||
|
|
8c13f70fc5 | ||
|
|
01cc58db83 | ||
|
|
105c272816 | ||
|
|
ab1722d78e | ||
|
|
490b0e3cdf | ||
|
|
a191ce6200 | ||
|
|
7ba8350089 | ||
|
|
22598a09de | ||
|
|
b06345af46 | ||
|
|
a2260a3dc2 | ||
|
|
6b93b3f12a | ||
|
|
4b9921782b | ||
|
|
7df2921d38 | ||
|
|
42a59d5c17 | ||
|
|
4e9a63423f | ||
|
|
d03979eef9 | ||
|
|
2c8b0b17a7 | ||
|
|
e4d16c31da | ||
|
|
8ae9c1d192 | ||
|
|
902e1ab74b | ||
|
|
f4920d6475 | ||
|
|
9d5c8d9d6b | ||
|
|
06a42caa5b | ||
|
|
e559fea8ff | ||
|
|
8f65677cb4 | ||
|
|
362ec7b673 | ||
|
|
51521fc19f | ||
|
|
e9306f3c75 | ||
|
|
e7fa2e08ad | ||
|
|
9730cd0aec | ||
|
|
c16553626f | ||
|
|
1283c5b7a5 | ||
|
|
a007f1da9d | ||
|
|
499dfee2d4 | ||
|
|
7e1742956c | ||
|
|
57038c3969 | ||
|
|
fb7ee301b5 | ||
|
|
ff51f3b95e | ||
|
|
5f1b226362 | ||
|
|
077f3c515f | ||
|
|
7278387879 | ||
|
|
438f2ac1a8 | ||
|
|
030ef6da25 | ||
|
|
4082149f0e | ||
|
|
c8619284bc | ||
|
|
47248251e2 | ||
|
|
a863f59cf0 | ||
|
|
84ab100d86 | ||
|
|
55d6773be6 | ||
|
|
7b5cf6978e | ||
|
|
0448c0fa36 | ||
|
|
b5d64bc7c5 | ||
|
|
2b65b22aa2 | ||
|
|
1d52084b05 | ||
|
|
5e8a22be24 | ||
|
|
1f13bc906b | ||
|
|
637c08d189 | ||
|
|
404662e794 | ||
|
|
d6ab2b3b87 | ||
|
|
734db5b722 | ||
|
|
bf4b012cec | ||
|
|
f8d2e276a5 | ||
|
|
e29f756146 | ||
|
|
5fe55176ec | ||
|
|
30daeb90a8 | ||
|
|
eb4820b68b | ||
|
|
8355c1092c | ||
|
|
5e7a69e649 | ||
|
|
4efc947f14 | ||
|
|
8859e6f1bb | ||
|
|
4d8da4420e | ||
|
|
70c9b8dc50 | ||
|
|
c447dfaa9c | ||
|
|
9209ec59c2 | ||
|
|
d2b6490bca | ||
|
|
8d30ebb12b | ||
|
|
0394080898 | ||
|
|
75983ce809 | ||
|
|
e820629f83 | ||
|
|
cc8d540943 | ||
|
|
90fbab4b1e | ||
|
|
5665d1afa0 | ||
|
|
be0f6b3e6e | ||
|
|
0966867c08 | ||
|
|
4ff06a9d79 | ||
|
|
b5221a5c74 | ||
|
|
324bfa9fde | ||
|
|
760c26e9c0 | ||
|
|
761e9df1bf | ||
|
|
611d827e0b | ||
|
|
54072ec9cd | ||
|
|
4a4abf9b64 | ||
|
|
3ca9d53d1b | ||
|
|
f4779df9b3 | ||
|
|
428971f127 | ||
|
|
181df2fe63 | ||
|
|
1328a45f2a | ||
|
|
cbf82872fb | ||
|
|
159b511d16 | ||
|
|
441f082fcb | ||
|
|
f6a61b999f | ||
|
|
ad0dd693ac | ||
|
|
153675e52a | ||
|
|
e2ad785422 | ||
|
|
0caa35a251 | ||
|
|
e5b19e3f70 | ||
|
|
010bd9c558 | ||
|
|
27df455b98 | ||
|
|
7a5a500d29 | ||
|
|
b0fc568c80 | ||
|
|
12456f9850 | ||
|
|
f5478c871c | ||
|
|
8581b7820d | ||
|
|
c95f05a3dc | ||
|
|
cd5836243d | ||
|
|
c3dc1c272b | ||
|
|
25a2c8ab82 | ||
|
|
721ac6b847 | ||
|
|
1a0a8ac7e2 | ||
|
|
81d791eea0 | ||
|
|
e1f9ba78e5 | ||
|
|
ea387937d0 | ||
|
|
2ca0cf6fc4 | ||
|
|
be4593c1d9 | ||
|
|
aa6e8c9ec0 | ||
|
|
4aff2a32ad | ||
|
|
579afed460 | ||
|
|
a6a280669c | ||
|
|
3f2728e3f7 | ||
|
|
e0a705afe7 | ||
|
|
62ae329be3 | ||
|
|
31f95da947 | ||
|
|
a4f7079270 | ||
|
|
5b74161195 | ||
|
|
f7c9258770 | ||
|
|
8ea6983734 | ||
|
|
ddd1b4be3f | ||
|
|
05d2c7f9ae | ||
|
|
1d83fb20d6 | ||
|
|
9c57f3d339 | ||
|
|
6b0178e9fb | ||
|
|
790b371e47 | ||
|
|
cc6dfd91cf | ||
|
|
672fbd3849 | ||
|
|
935f31eff9 | ||
|
|
65e855bfff | ||
|
|
9fb3fb4c83 | ||
|
|
4487065b67 | ||
|
|
1033d34964 | ||
|
|
5b150abdcb | ||
|
|
b98d25dafb | ||
|
|
06e8e28531 | ||
|
|
92f37ca111 | ||
|
|
3a420ec808 | ||
|
|
45ededbed5 | ||
|
|
f322c608cf | ||
|
|
a612a666f3 | ||
|
|
4e26d42d17 | ||
|
|
54c2ffc36b | ||
|
|
16a8bcc77d | ||
|
|
15ebf4a0cf | ||
|
|
cca36cab70 | ||
|
|
49343e9f68 | ||
|
|
b6ade62211 | ||
|
|
323e45374f | ||
|
|
aee4fe9f7b | ||
|
|
50652be6e3 | ||
|
|
92f2d9f99f | ||
|
|
25eac80ae6 | ||
|
|
9ac1c4bc4f | ||
|
|
c3275c3f3c | ||
|
|
d9eda45b0b | ||
|
|
b9d497c61c | ||
|
|
fed39a53cb | ||
|
|
4765f937ea | ||
|
|
aadb6b1772 | ||
|
|
fb41bdd700 | ||
|
|
c71f805667 | ||
|
|
db0f2c0b10 | ||
|
|
09fa2298ba | ||
|
|
e8c0157017 | ||
|
|
a04c44fe34 | ||
|
|
334b158f0b | ||
|
|
16959c0a8c | ||
|
|
591291caee | ||
|
|
de20dfe459 | ||
|
|
8f0e63cd27 | ||
|
|
a5a73ba857 | ||
|
|
e7caa48e2f | ||
|
|
6063c4e3c0 | ||
|
|
4cd65027c4 | ||
|
|
f9f78c1086 | ||
|
|
4c7fa9482d | ||
|
|
9c529c61bb | ||
|
|
b7b53b5857 | ||
|
|
2012bdf4bd | ||
|
|
48ed6381b3 | ||
|
|
083a78135c | ||
|
|
c1e608d9ef | ||
|
|
71a0ae2e59 | ||
|
|
a671652ab2 | ||
|
|
a963618b08 | ||
|
|
397e3b1ade | ||
|
|
a18a715bb4 | ||
|
|
49ee873655 | ||
|
|
183662c0e2 | ||
|
|
5f84993bae | ||
|
|
46d148defd | ||
|
|
267e7c3a90 | ||
|
|
1a980123a2 | ||
|
|
ed98015a56 | ||
|
|
1105e52031 | ||
|
|
48808aeb8a | ||
|
|
e59b147a62 | ||
|
|
77d509eb9a | ||
|
|
ef0cb17faf | ||
|
|
26c00f8dd3 | ||
|
|
40bd121593 | ||
|
|
cde785f1bb | ||
|
|
feaa2dbba8 | ||
|
|
eedf7e44a2 | ||
|
|
51d8e9dc5e | ||
|
|
2a50a0ce69 | ||
|
|
11207c4e56 | ||
|
|
b88e850d55 | ||
|
|
adeb1f92c8 | ||
|
|
9cfe527492 | ||
|
|
1ca472cc8a | ||
|
|
b4d008b743 | ||
|
|
ae54610b2a | ||
|
|
873502c95d | ||
|
|
796f2d3c09 | ||
|
|
c52b41d311 | ||
|
|
4ad3002861 | ||
|
|
6e55b419a6 | ||
|
|
8f60f0a0cf | ||
|
|
4d5ef721f7 | ||
|
|
ad278b2007 | ||
|
|
de4c0528f9 | ||
|
|
23f0bb45b0 | ||
|
|
430492152f | ||
|
|
4a35a224e2 | ||
|
|
21d09c5bf2 | ||
|
|
8b2165e0d1 | ||
|
|
d100e68fd0 | ||
|
|
f844097f8e | ||
|
|
96b4211ea1 | ||
|
|
8f42e7f703 | ||
|
|
f08c42e920 | ||
|
|
ae8a63827d | ||
|
|
7184330acd | ||
|
|
43b80683eb | ||
|
|
42e4c37f15 | ||
|
|
32117c030a | ||
|
|
9df9915600 | ||
|
|
faadf78332 | ||
|
|
aab325eca5 | ||
|
|
9b50221bf0 | ||
|
|
2665d7d293 | ||
|
|
98b695984b | ||
|
|
8b16ba7f3a | ||
|
|
d794b834fd | ||
|
|
e626107d3d | ||
|
|
582e1bf10c | ||
|
|
ced8d2a537 | ||
|
|
cda0baa7fe | ||
|
|
0f358e3ca1 | ||
|
|
2481574a28 | ||
|
|
6381e75fa5 | ||
|
|
484b115b09 | ||
|
|
309fc6db43 | ||
|
|
dc3fe85921 | ||
|
|
30da6ab2c1 | ||
|
|
682fb171cb | ||
|
|
177c9c93e8 | ||
|
|
40b3d8ec1b | ||
|
|
fc795275f2 | ||
|
|
5f3796f6ea | ||
|
|
3c1bd90d0d | ||
|
|
9127b96033 | ||
|
|
50e9698932 | ||
|
|
fd49503ba2 | ||
|
|
2d0217abd5 | ||
|
|
f561d8f689 | ||
|
|
56a4a77398 | ||
|
|
edc93ab6aa | ||
|
|
e543dca6a0 | ||
|
|
d6c28aa64d | ||
|
|
bb7897caab | ||
|
|
610d18cc25 | ||
|
|
7dfd741ced | ||
|
|
e583d17062 | ||
|
|
692462d7c8 | ||
|
|
43c2bd1351 | ||
|
|
ab137472b0 | ||
|
|
eb819368aa | ||
|
|
9aa5e20ef7 | ||
|
|
98bf8e1304 | ||
|
|
3266e54e33 | ||
|
|
683a47f7a1 | ||
|
|
65992304bc | ||
|
|
49601558c6 | ||
|
|
1c05c004cd | ||
|
|
c8d2181498 | ||
|
|
59edf64951 | ||
|
|
0af385d73f | ||
|
|
d2755c0106 | ||
|
|
43037d893d | ||
|
|
3426d91140 | ||
|
|
ef60c533a0 | ||
|
|
7da32c7db3 | ||
|
|
6ce3ce758c | ||
|
|
16aef53470 | ||
|
|
a161048a9d | ||
|
|
38b34f2a45 | ||
|
|
df2a0e265b | ||
|
|
dc20b21fb5 | ||
|
|
b31c3bd35d | ||
|
|
633c2a289e | ||
|
|
e71c417f7e | ||
|
|
5389a35798 | ||
|
|
aaf3c2b329 | ||
|
|
35f836c4b7 | ||
|
|
3d9263bf86 | ||
|
|
2172c5034a | ||
|
|
10a25603ac | ||
|
|
7546562139 | ||
|
|
f6613e1e4c | ||
|
|
9e2bd10d03 | ||
|
|
dddbc130db | ||
|
|
4b908ebcd6 | ||
|
|
b99b2b75ca | ||
|
|
6a2edab6eb | ||
|
|
ba754825b9 | ||
|
|
e4d7d8c42d | ||
|
|
2d30b36cca | ||
|
|
65194efa97 | ||
|
|
143f905838 | ||
|
|
a14c5dbcc4 | ||
|
|
be1ebd348b | ||
|
|
537d953f4c | ||
|
|
0f033bf8f6 | ||
|
|
d806e32030 | ||
|
|
4b828dd276 | ||
|
|
60befcd8a8 | ||
|
|
4992e4a2b8 | ||
|
|
fcc1272d42 | ||
|
|
2657ece2cd | ||
|
|
ce20b05ed0 | ||
|
|
e78a706994 | ||
|
|
ce5a792e34 | ||
|
|
73a9791401 | ||
|
|
d59ed24e6c | ||
|
|
a14b9c7bac | ||
|
|
a5b3f8cae9 | ||
|
|
17201facf1 | ||
|
|
781d160c68 | ||
|
|
abf5b6be3e | ||
|
|
f0f2413932 | ||
|
|
8103856a41 | ||
|
|
7c759b193c | ||
|
|
d7c3b7633a | ||
|
|
8376fbc982 | ||
|
|
d3c073dc25 | ||
|
|
c18f13a45b | ||
|
|
07c4a74838 | ||
|
|
8d1db0ea3d | ||
|
|
0e4017cbe5 | ||
|
|
0235901614 | ||
|
|
fbdd1f39e7 | ||
|
|
777ed10e21 | ||
|
|
aaabba9b1e | ||
|
|
39707757a6 | ||
|
|
74505a116f | ||
|
|
518ab93e03 | ||
|
|
da43a5e371 | ||
|
|
c35adcf5a1 | ||
|
|
7d84cca431 | ||
|
|
e758a753f8 | ||
|
|
ccf2952b76 | ||
|
|
e295d0c091 | ||
|
|
ba02209f1d | ||
|
|
1c5ae80029 | ||
|
|
8c23b19da1 | ||
|
|
0b1727cf79 | ||
|
|
69efd2ee24 | ||
|
|
91055151ce | ||
|
|
73e5a7d671 | ||
|
|
601880f1ce | ||
|
|
28772bc9a4 | ||
|
|
04f9e7fa73 | ||
|
|
47bd4be71b | ||
|
|
1c560a967c | ||
|
|
62c5b28690 | ||
|
|
c9275f156e | ||
|
|
e71b25107d | ||
|
|
793295cfe9 | ||
|
|
128c4bb7cb | ||
|
|
f95ed7dca2 | ||
|
|
1f4e4db50d | ||
|
|
c7d808a560 | ||
|
|
ca2958a999 | ||
|
|
dc8d49260c | ||
|
|
eedaf9cd26 | ||
|
|
fa2290657a | ||
|
|
cceb29c005 | ||
|
|
a79d074436 | ||
|
|
429303bbb7 | ||
|
|
fe891aa488 | ||
|
|
9245d3b5cd | ||
|
|
bf7a51791a | ||
|
|
6d0842465b | ||
|
|
679b5ed551 | ||
|
|
b1edd911f9 | ||
|
|
774097bd10 | ||
|
|
2ddee50f27 | ||
|
|
3466461eb3 | ||
|
|
76c6ccab5d | ||
|
|
eadcd8e614 | ||
|
|
28952eda87 | ||
|
|
990514ae6d | ||
|
|
f1169fb213 | ||
|
|
f04ae7a112 | ||
|
|
ffef659782 | ||
|
|
10b7592d14 | ||
|
|
3656f7d06f | ||
|
|
469a97ddd2 | ||
|
|
0b3b4c99e6 | ||
|
|
b734f9d237 | ||
|
|
fd889fd29a | ||
|
|
b3c4305fa2 | ||
|
|
369a343fb2 | ||
|
|
bff3cd9068 | ||
|
|
08443c6421 | ||
|
|
84ab5d45fd | ||
|
|
d4242de699 | ||
|
|
f4bf9c672f | ||
|
|
9743add40e | ||
|
|
a145d1065a | ||
|
|
ac7409bbf3 | ||
|
|
0618f606b2 | ||
|
|
a8dd3c3a7c | ||
|
|
1725672168 | ||
|
|
f9f68005a5 | ||
|
|
e63e017d20 | ||
|
|
80080a3d7b | ||
|
|
be623ce8e8 | ||
|
|
0439e41a44 | ||
|
|
dde8b2afff | ||
|
|
f42a8e4e03 | ||
|
|
c1e3498a2a | ||
|
|
d5359bbdc2 | ||
|
|
0c869251ce | ||
|
|
d850b0adb1 | ||
|
|
e392ea1104 | ||
|
|
dbe4fdc73d | ||
|
|
4c8617e1bb | ||
|
|
82a2f31ada | ||
|
|
cf72931816 | ||
|
|
c6a7de0e54 | ||
|
|
14e2d31619 | ||
|
|
f95de1fd4d | ||
|
|
cbfe28286a | ||
|
|
6145013f30 | ||
|
|
e39e088f18 | ||
|
|
1f6205e1ea | ||
|
|
376febb9d1 | ||
|
|
c760ca2323 | ||
|
|
05392e0918 | ||
|
|
c917d716f7 | ||
|
|
a4a86ee23f | ||
|
|
9049db41ae | ||
|
|
21095502b9 | ||
|
|
ce80b9fa0e | ||
|
|
6e47fd54a0 | ||
|
|
106ee1bf4d | ||
|
|
6a67cc96d0 | ||
|
|
499ce5139c | ||
|
|
728ef46048 | ||
|
|
e683cccf35 | ||
|
|
e312d17eae | ||
|
|
f41d1500b0 | ||
|
|
a80e8726e7 | ||
|
|
afb323b01c | ||
|
|
2647018870 | ||
|
|
9a1fa53791 | ||
|
|
d84fd6c925 | ||
|
|
9b38a372fb | ||
|
|
389fa180c8 | ||
|
|
539f8550c7 | ||
|
|
8b21d27f04 | ||
|
|
6919f389aa | ||
|
|
b33fb26b84 | ||
|
|
b93331e844 | ||
|
|
22299d2382 | ||
|
|
bb59346651 | ||
|
|
bc3ab45af2 | ||
|
|
1c1f991d2f | ||
|
|
2c9d9577e3 | ||
|
|
c4919cf5ec | ||
|
|
4efb8b142c | ||
|
|
729193aca8 | ||
|
|
8417b9b99c | ||
|
|
d7e699ea1a | ||
|
|
caf23e6b8e | ||
|
|
07f87b9147 | ||
|
|
86c9ce9c20 | ||
|
|
5aff9e999e | ||
|
|
1c0f1a2831 | ||
|
|
56f9c1b6f7 | ||
|
|
122d5f2729 | ||
|
|
d3a6881737 | ||
|
|
2235f31ffe | ||
|
|
0048f58500 | ||
|
|
92e03e2c22 | ||
|
|
6e65f01ede | ||
|
|
19e64eb247 | ||
|
|
70f6484d9d | ||
|
|
000c538d65 | ||
|
|
390ce5719d | ||
|
|
8fd7c04920 | ||
|
|
4f2486a67a | ||
|
|
d4b01f6ffd | ||
|
|
ecb5fff2ec | ||
|
|
ef7d7e7d71 | ||
|
|
2186a89781 | ||
|
|
dad40b8d51 | ||
|
|
3dc754cac2 | ||
|
|
f0a78aa559 | ||
|
|
3d356763d0 | ||
|
|
49538e81de | ||
|
|
1f4932966a | ||
|
|
9aa1f84d45 | ||
|
|
94199b7867 | ||
|
|
aa49ec815a | ||
|
|
9decebe6e1 | ||
|
|
377576f131 | ||
|
|
a4db9abcb4 | ||
|
|
3a9c08e7c9 | ||
|
|
083309c056 | ||
|
|
efc9553561 | ||
|
|
fac82cf69b | ||
|
|
785eaf8e8f | ||
|
|
b944849bd4 | ||
|
|
b747d9d05e | ||
|
|
b90875575c | ||
|
|
110840aa98 | ||
|
|
77fdc37cb7 | ||
|
|
3b5284ec2b | ||
|
|
2f97370b8e | ||
|
|
3c01bf3a12 | ||
|
|
32e75ff808 | ||
|
|
613c8158a8 | ||
|
|
93e134aab0 | ||
|
|
43ebfa7982 | ||
|
|
8c5b420aea | ||
|
|
bd6af7c613 | ||
|
|
5bd5dd7262 | ||
|
|
f5bd3fa952 | ||
|
|
5be7d42dfd | ||
|
|
f4b64686ae | ||
|
|
36d0906ea2 | ||
|
|
487d825ede | ||
|
|
f0ae77b23b | ||
|
|
0a6462e627 | ||
|
|
be0d9d8c13 | ||
|
|
b8cf3b4c77 | ||
|
|
38d00f407e | ||
|
|
e4ef6c9645 | ||
|
|
0286f2da78 | ||
|
|
a1fcabee0e | ||
|
|
9c96cd6090 | ||
|
|
43a3400221 | ||
|
|
5a8b28c194 | ||
|
|
11ac20e5ee | ||
|
|
786891c600 | ||
|
|
0d732609f0 | ||
|
|
c5c6a69269 | ||
|
|
73f6c5fe35 | ||
|
|
5fa3450a9c | ||
|
|
ff5cad1cd6 | ||
|
|
29db084dc3 | ||
|
|
af21a11e1e | ||
|
|
cb763938dc | ||
|
|
c0da948a4e | ||
|
|
3457105504 | ||
|
|
a5b5885933 | ||
|
|
cbf973d90f | ||
|
|
97977cdb4b | ||
|
|
87160c8d2f | ||
|
|
f2209045f8 | ||
|
|
b6184ce471 | ||
|
|
444fda5d82 | ||
|
|
b6d87ae25b | ||
|
|
bf1fa014f4 | ||
|
|
7b878ea3d8 | ||
|
|
3fb1595a4e | ||
|
|
246c1a9380 | ||
|
|
8043f4fc10 | ||
|
|
e24a4b18c4 | ||
|
|
58d430fe3e | ||
|
|
dc985e0e83 | ||
|
|
f2b7c9ee66 | ||
|
|
fffc245922 | ||
|
|
f8bee0e75f | ||
|
|
eb01f9729d | ||
|
|
51c37aeee3 | ||
|
|
e00ece7a78 | ||
|
|
62163ab3d3 | ||
|
|
2ecd2a3c44 | ||
|
|
4f1cc41b86 | ||
|
|
d4071575a4 | ||
|
|
2336bcfe20 | ||
|
|
b3b1df7184 | ||
|
|
d3cd3bc5ef | ||
|
|
e1a98c1ff7 | ||
|
|
a8fd92ddc1 | ||
|
|
8f787c08a2 | ||
|
|
7a968a5f0d | ||
|
|
56192daabf | ||
|
|
ce0676ac70 | ||
|
|
e2b4ae13fa | ||
|
|
a30f38481d | ||
|
|
12d99b3292 | ||
|
|
6b94b5334c | ||
|
|
ada1ab3509 | ||
|
|
a86023eb09 | ||
|
|
5245928648 | ||
|
|
0aeb7c6484 | ||
|
|
4adc372f9a | ||
|
|
4576c1ebc3 | ||
|
|
e4a1cf0cd2 | ||
|
|
5558191a2a | ||
|
|
d4c4dddfc3 | ||
|
|
70313df531 | ||
|
|
723fa9eebc | ||
|
|
1dce3c98d8 | ||
|
|
fefe95052d | ||
|
|
2e314a20f1 | ||
|
|
9a3dcb9ad1 | ||
|
|
30909a9b79 | ||
|
|
0f655e4430 | ||
|
|
659d007bf0 | ||
|
|
b49caf170c | ||
|
|
33d0e09497 | ||
|
|
6da45144d0 | ||
|
|
a03b4ce213 | ||
|
|
9d453c91f1 | ||
|
|
61110dbfe4 | ||
|
|
3585daab95 | ||
|
|
aea7188304 | ||
|
|
ccb2889cac | ||
|
|
72d5366e96 | ||
|
|
448c5ff3dc | ||
|
|
7dc8ab4069 | ||
|
|
f1c4aea7b5 | ||
|
|
6bfd193b0d | ||
|
|
741b5b4978 | ||
|
|
f19049e643 | ||
|
|
01c2e4d2cf | ||
|
|
ef7def8f1d | ||
|
|
5b02adbd33 | ||
|
|
9d1be48bd2 | ||
|
|
aab2c9c682 | ||
|
|
b4a102d119 | ||
|
|
a6fbb80b94 | ||
|
|
008542b715 | ||
|
|
8efd305afd | ||
|
|
506b289b2a | ||
|
|
2f00413864 | ||
|
|
c6380a25d6 | ||
|
|
5ab5811770 | ||
|
|
75fcab04b1 | ||
|
|
4b13452022 | ||
|
|
2a100abef1 | ||
|
|
3abd00f3bb | ||
|
|
fb54277484 | ||
|
|
74c2458bdb | ||
|
|
a349b58306 | ||
|
|
4a7add2169 | ||
|
|
987ac513c8 | ||
|
|
57257a1795 | ||
|
|
3c055f94e1 | ||
|
|
118b0c0f86 | ||
|
|
10d94ed539 | ||
|
|
86395c6adb | ||
|
|
acb88e5c57 | ||
|
|
78d1b83d11 | ||
|
|
1a61d4e8a8 | ||
|
|
ad8d0efa29 | ||
|
|
237299948a | ||
|
|
0efc6a9abe | ||
|
|
92b0f9cd7e | ||
|
|
875ff15109 | ||
|
|
58e553151e | ||
|
|
7919513c8a | ||
|
|
e424ad5ff2 | ||
|
|
64f8010a25 | ||
|
|
1c385541fa | ||
|
|
08f2e4edc3 | ||
|
|
6e8395cccd | ||
|
|
68907ca783 | ||
|
|
75396c02d2 | ||
|
|
069cb10d6f | ||
|
|
2e9f531e2c | ||
|
|
2085626390 | ||
|
|
b05fdb28ff | ||
|
|
30039e8e62 | ||
|
|
4a38ce659d | ||
|
|
8f51ccd002 | ||
|
|
a76d3827ec | ||
|
|
eefc9b7172 | ||
|
|
ffa3071d36 | ||
|
|
9e0e308a44 | ||
|
|
73f4d5931d | ||
|
|
2d41704424 | ||
|
|
25072e5d32 | ||
|
|
d522f13d55 | ||
|
|
3a6b095ed4 | ||
|
|
5782c4469a | ||
|
|
6881b68ed7 | ||
|
|
9dbaaa33f5 | ||
|
|
69ffef8c0e | ||
|
|
61c143cb82 | ||
|
|
318da16b99 | ||
|
|
af5cbc881f | ||
|
|
7da39c3ff3 | ||
|
|
ac57101833 | ||
|
|
87ca23736d | ||
|
|
6cd7ef9cc3 | ||
|
|
c42fef541a | ||
|
|
5ac27100a5 | ||
|
|
bd4b4ddd8b | ||
|
|
d19b664ba9 | ||
|
|
ac66538651 | ||
|
|
9d02fbadb4 | ||
|
|
902797d0f0 | ||
|
|
6aa8fd0f7b | ||
|
|
8566832dd5 | ||
|
|
9e43c9cff3 | ||
|
|
b27f3ab327 | ||
|
|
dae112eed2 | ||
|
|
9ab10def49 | ||
|
|
c1f6dd46d1 | ||
|
|
5fd468d9ec | ||
|
|
e9b0c7177f | ||
|
|
915102a400 | ||
|
|
5187a9a5ad | ||
|
|
9b626d06fc | ||
|
|
1af22e5312 | ||
|
|
77906ea4ab | ||
|
|
40bf1a50fd | ||
|
|
91d6454f87 | ||
|
|
e5b04d54ff | ||
|
|
ee889afd4c | ||
|
|
299da5d596 | ||
|
|
1f6f2747d4 | ||
|
|
264f98af14 | ||
|
|
122f1c0ced | ||
|
|
f9a7b31b5b | ||
|
|
36f5883dda | ||
|
|
0e26df331c | ||
|
|
b4a2eb2e65 | ||
|
|
fdd167cac1 | ||
|
|
fe73d55f70 | ||
|
|
277ef04b60 | ||
|
|
a956e20f29 | ||
|
|
9fd0c25c9f | ||
|
|
1cb7ae16ab | ||
|
|
2effbb55ae | ||
|
|
bf5c43322a | ||
|
|
e888639c7e | ||
|
|
8cb7567fd3 | ||
|
|
42de9ca49e | ||
|
|
ae3dce0cbd | ||
|
|
f4673941e0 | ||
|
|
3b15966cc9 | ||
|
|
520306dc87 | ||
|
|
588ca68171 | ||
|
|
3b51874da5 | ||
|
|
f92f3e0208 | ||
|
|
f8c11847bb | ||
|
|
1d28ea5458 | ||
|
|
dd719099bc | ||
|
|
c247cf728c | ||
|
|
addd7347d8 | ||
|
|
756fe4b375 | ||
|
|
aafb735283 | ||
|
|
256b4245d5 | ||
|
|
2fc6833684 | ||
|
|
7e88eb549f | ||
|
|
ea82fe5bc2 | ||
|
|
eabd3135f0 | ||
|
|
d7ed4093d8 | ||
|
|
72a7ed5b58 | ||
|
|
86bdddd1b8 | ||
|
|
1a6508972e | ||
|
|
8704ca783d | ||
|
|
d38778e400 | ||
|
|
f1a612245c | ||
|
|
967dd398e7 | ||
|
|
2d04e71412 | ||
|
|
396667b702 | ||
|
|
ea84c157e0 | ||
|
|
0b39a0123e | ||
|
|
dd08045f28 | ||
|
|
795c94384a | ||
|
|
313625c349 | ||
|
|
538cd6fdcf | ||
|
|
5fd0770372 | ||
|
|
3b4c0a3fc0 | ||
|
|
3ef551872a | ||
|
|
27891ecb77 | ||
|
|
0047e18a9b | ||
|
|
e5e88bb9f1 | ||
|
|
4ff1cba522 | ||
|
|
79ac50d0f7 | ||
|
|
72869ed197 | ||
|
|
5018472840 | ||
|
|
33762dbbac | ||
|
|
eb25eddc22 | ||
|
|
909945c0ac | ||
|
|
bb40e38451 | ||
|
|
7ecd67605f | ||
|
|
08d7c48dc7 | ||
|
|
32b30bc5de | ||
|
|
a2252c9236 | ||
|
|
e93a1cc02e | ||
|
|
6b510546ae | ||
|
|
ddd24ea8c8 | ||
|
|
534d7ce64b | ||
|
|
5c4cc5ae5b | ||
|
|
9ef8d5c5c3 | ||
|
|
b85dbdc3c1 | ||
|
|
e5a68b2dcb | ||
|
|
d05082987f | ||
|
|
a3625b3817 | ||
|
|
03002f7431 | ||
|
|
80f508c4b1 | ||
|
|
a272d73dd9 | ||
|
|
452584c4bd | ||
|
|
c95b986414 | ||
|
|
af0a353b79 | ||
|
|
ef312b8fc4 | ||
|
|
5f1562c5b2 | ||
|
|
91762097a5 | ||
|
|
17b9bfd249 | ||
|
|
ea88451875 | ||
|
|
9c580dde39 | ||
|
|
9baa222976 | ||
|
|
0ef9c03f05 |
@@ -9,13 +9,6 @@ trim_trailing_whitespace = true
|
|||||||
charset = utf-8
|
charset = utf-8
|
||||||
|
|
||||||
# python, js indentation settings
|
# python, js indentation settings
|
||||||
[{*.py,*.js,*.vue,*.css,*.scss,*.html}]
|
[{*.py,*.js}]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
max_line_length = 110
|
|
||||||
|
|
||||||
# JSON files - mostly doctype schema files
|
|
||||||
[{*.json}]
|
|
||||||
insert_final_newline = false
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
|
|||||||
@@ -156,7 +156,6 @@
|
|||||||
"onScan": true,
|
"onScan": true,
|
||||||
"html2canvas": true,
|
"html2canvas": true,
|
||||||
"extend_cscript": true,
|
"extend_cscript": true,
|
||||||
"localforage": true,
|
"localforage": true
|
||||||
"Plaid": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
3
.github/helper/.flake8_strict
vendored
3
.github/helper/.flake8_strict
vendored
@@ -66,8 +66,7 @@ ignore =
|
|||||||
F841,
|
F841,
|
||||||
E713,
|
E713,
|
||||||
E712,
|
E712,
|
||||||
B023,
|
B023
|
||||||
B028
|
|
||||||
|
|
||||||
|
|
||||||
max-line-length = 200
|
max-line-length = 200
|
||||||
|
|||||||
77
.github/helper/documentation.py
vendored
77
.github/helper/documentation.py
vendored
@@ -3,71 +3,52 @@ import requests
|
|||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
|
||||||
WEBSITE_REPOS = [
|
docs_repos = [
|
||||||
|
"frappe_docs",
|
||||||
|
"erpnext_documentation",
|
||||||
"erpnext_com",
|
"erpnext_com",
|
||||||
"frappe_io",
|
"frappe_io",
|
||||||
]
|
]
|
||||||
|
|
||||||
DOCUMENTATION_DOMAINS = [
|
|
||||||
"docs.erpnext.com",
|
|
||||||
"frappeframework.com",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
def uri_validator(x):
|
||||||
|
result = urlparse(x)
|
||||||
|
return all([result.scheme, result.netloc, result.path])
|
||||||
|
|
||||||
def is_valid_url(url: str) -> bool:
|
def docs_link_exists(body):
|
||||||
parts = urlparse(url)
|
for line in body.splitlines():
|
||||||
return all((parts.scheme, parts.netloc, parts.path))
|
for word in line.split():
|
||||||
|
if word.startswith('http') and uri_validator(word):
|
||||||
|
|
||||||
def is_documentation_link(word: str) -> bool:
|
|
||||||
if not word.startswith("http") or not is_valid_url(word):
|
|
||||||
return False
|
|
||||||
|
|
||||||
parsed_url = urlparse(word)
|
parsed_url = urlparse(word)
|
||||||
if parsed_url.netloc in DOCUMENTATION_DOMAINS:
|
|
||||||
return True
|
|
||||||
|
|
||||||
if parsed_url.netloc == "github.com":
|
if parsed_url.netloc == "github.com":
|
||||||
parts = parsed_url.path.split("/")
|
parts = parsed_url.path.split('/')
|
||||||
if len(parts) == 5 and parts[1] == "frappe" and parts[2] in WEBSITE_REPOS:
|
if len(parts) == 5 and parts[1] == "frappe" and parts[2] in docs_repos:
|
||||||
|
return True
|
||||||
|
elif parsed_url.netloc == "docs.erpnext.com":
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
pr = sys.argv[1]
|
||||||
|
response = requests.get("https://api.github.com/repos/frappe/erpnext/pulls/{}".format(pr))
|
||||||
|
|
||||||
def contains_documentation_link(body: str) -> bool:
|
if response.ok:
|
||||||
return any(
|
|
||||||
is_documentation_link(word)
|
|
||||||
for line in body.splitlines()
|
|
||||||
for word in line.split()
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def check_pull_request(number: str) -> "tuple[int, str]":
|
|
||||||
response = requests.get(f"https://api.github.com/repos/frappe/erpnext/pulls/{number}")
|
|
||||||
if not response.ok:
|
|
||||||
return 1, "Pull Request Not Found! ⚠️"
|
|
||||||
|
|
||||||
payload = response.json()
|
payload = response.json()
|
||||||
title = (payload.get("title") or "").lower().strip()
|
title = (payload.get("title") or "").lower().strip()
|
||||||
head_sha = (payload.get("head") or {}).get("sha")
|
head_sha = (payload.get("head") or {}).get("sha")
|
||||||
body = (payload.get("body") or "").lower()
|
body = (payload.get("body") or "").lower()
|
||||||
|
|
||||||
if (
|
if (title.startswith("feat")
|
||||||
not title.startswith("feat")
|
and head_sha
|
||||||
or not head_sha
|
and "no-docs" not in body
|
||||||
or "no-docs" in body
|
and "backport" not in body
|
||||||
or "backport" in body
|
|
||||||
):
|
):
|
||||||
return 0, "Skipping documentation checks... 🏃"
|
if docs_link_exists(body):
|
||||||
|
print("Documentation Link Found. You're Awesome! 🎉")
|
||||||
|
|
||||||
if contains_documentation_link(body):
|
else:
|
||||||
return 0, "Documentation Link Found. You're Awesome! 🎉"
|
print("Documentation Link Not Found! ⚠️")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
return 1, "Documentation Link Not Found! ⚠️"
|
else:
|
||||||
|
print("Skipping documentation checks... 🏃")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
exit_code, message = check_pull_request(sys.argv[1])
|
|
||||||
print(message)
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|||||||
18
.github/helper/install.sh
vendored
18
.github/helper/install.sh
vendored
@@ -8,9 +8,8 @@ sudo apt update && sudo apt install redis-server libcups2-dev
|
|||||||
|
|
||||||
pip install frappe-bench
|
pip install frappe-bench
|
||||||
|
|
||||||
githubbranch=${GITHUB_BASE_REF:-${GITHUB_REF##*/}}
|
|
||||||
frappeuser=${FRAPPE_USER:-"frappe"}
|
frappeuser=${FRAPPE_USER:-"frappe"}
|
||||||
frappebranch=${FRAPPE_BRANCH:-$githubbranch}
|
frappebranch=${FRAPPE_BRANCH:-${GITHUB_BASE_REF:-${GITHUB_REF##*/}}}
|
||||||
|
|
||||||
git clone "https://github.com/${frappeuser}/frappe" --branch "${frappebranch}" --depth 1
|
git clone "https://github.com/${frappeuser}/frappe" --branch "${frappebranch}" --depth 1
|
||||||
bench init --skip-assets --frappe-path ~/frappe --python "$(which python)" frappe-bench
|
bench init --skip-assets --frappe-path ~/frappe --python "$(which python)" frappe-bench
|
||||||
@@ -25,15 +24,14 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
if [ "$DB" == "mariadb" ];then
|
if [ "$DB" == "mariadb" ];then
|
||||||
mysql --host 127.0.0.1 --port 3306 -u root -e "SET GLOBAL character_set_server = 'utf8mb4'"
|
mysql --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL character_set_server = 'utf8mb4'"
|
||||||
mysql --host 127.0.0.1 --port 3306 -u root -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'"
|
mysql --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'"
|
||||||
|
|
||||||
mysql --host 127.0.0.1 --port 3306 -u root -e "CREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe'"
|
mysql --host 127.0.0.1 --port 3306 -u root -proot -e "CREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe'"
|
||||||
mysql --host 127.0.0.1 --port 3306 -u root -e "CREATE DATABASE test_frappe"
|
mysql --host 127.0.0.1 --port 3306 -u root -proot -e "CREATE DATABASE test_frappe"
|
||||||
mysql --host 127.0.0.1 --port 3306 -u root -e "GRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'localhost'"
|
mysql --host 127.0.0.1 --port 3306 -u root -proot -e "GRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'localhost'"
|
||||||
|
|
||||||
mysql --host 127.0.0.1 --port 3306 -u root -e "UPDATE mysql.user SET Password=PASSWORD('travis') WHERE User='root'"
|
mysql --host 127.0.0.1 --port 3306 -u root -proot -e "FLUSH PRIVILEGES"
|
||||||
mysql --host 127.0.0.1 --port 3306 -u root -e "FLUSH PRIVILEGES"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$DB" == "postgres" ];then
|
if [ "$DB" == "postgres" ];then
|
||||||
@@ -57,7 +55,7 @@ sed -i 's/schedule:/# schedule:/g' Procfile
|
|||||||
sed -i 's/socketio:/# socketio:/g' Procfile
|
sed -i 's/socketio:/# socketio:/g' Procfile
|
||||||
sed -i 's/redis_socketio:/# redis_socketio:/g' Procfile
|
sed -i 's/redis_socketio:/# redis_socketio:/g' Procfile
|
||||||
|
|
||||||
bench get-app payments --branch ${githubbranch%"-hotfix"}
|
bench get-app payments
|
||||||
bench get-app erpnext "${GITHUB_WORKSPACE}"
|
bench get-app erpnext "${GITHUB_WORKSPACE}"
|
||||||
|
|
||||||
if [ "$TYPE" == "server" ]; then bench setup requirements --dev; fi
|
if [ "$TYPE" == "server" ]; then bench setup requirements --dev; fi
|
||||||
|
|||||||
4
.github/helper/site_config_mariadb.json
vendored
4
.github/helper/site_config_mariadb.json
vendored
@@ -9,8 +9,8 @@
|
|||||||
"mail_password": "test",
|
"mail_password": "test",
|
||||||
"admin_password": "admin",
|
"admin_password": "admin",
|
||||||
"root_login": "root",
|
"root_login": "root",
|
||||||
"root_password": "travis",
|
"root_password": "root",
|
||||||
"host_name": "http://test_site:8000",
|
"host_name": "http://test_site:8000",
|
||||||
"install_apps": ["payments", "erpnext"],
|
"install_apps": ["erpnext"],
|
||||||
"throttle_user_limit": 100
|
"throttle_user_limit": 100
|
||||||
}
|
}
|
||||||
|
|||||||
2
.github/stale.yml
vendored
2
.github/stale.yml
vendored
@@ -13,7 +13,7 @@ exemptProjects: true
|
|||||||
exemptMilestones: true
|
exemptMilestones: true
|
||||||
|
|
||||||
pulls:
|
pulls:
|
||||||
daysUntilStale: 14
|
daysUntilStale: 15
|
||||||
daysUntilClose: 3
|
daysUntilClose: 3
|
||||||
exemptLabels:
|
exemptLabels:
|
||||||
- hotfix
|
- hotfix
|
||||||
|
|||||||
32
.github/workflows/initiate_release.yml
vendored
Normal file
32
.github/workflows/initiate_release.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# This workflow is agnostic to branches. Only maintain on develop branch.
|
||||||
|
# To add/remove versions just modify the matrix.
|
||||||
|
|
||||||
|
name: Create weekly release pull requests
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
# 9:30 UTC => 3 PM IST Tuesday
|
||||||
|
- cron: "30 9 * * 2"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
name: Release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
version: ["13", "14"]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: octokit/request-action@v2.x
|
||||||
|
with:
|
||||||
|
route: POST /repos/{owner}/{repo}/pulls
|
||||||
|
owner: frappe
|
||||||
|
repo: erpnext
|
||||||
|
title: |-
|
||||||
|
"chore: release v${{ matrix.version }}"
|
||||||
|
body: "Automated weekly release."
|
||||||
|
base: version-${{ matrix.version }}
|
||||||
|
head: version-${{ matrix.version }}-hotfix
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||||
17
.github/workflows/patch.yml
vendored
17
.github/workflows/patch.yml
vendored
@@ -11,7 +11,7 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: patch-develop-${{ github.event.number }}
|
group: patch-develop-${{ github.event_name }}-${{ github.event.number || github.event_name == 'workflow_dispatch' && github.run_id || '' }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -25,7 +25,7 @@ jobs:
|
|||||||
mysql:
|
mysql:
|
||||||
image: mariadb:10.3
|
image: mariadb:10.3
|
||||||
env:
|
env:
|
||||||
MYSQL_ALLOW_EMPTY_PASSWORD: YES
|
MARIADB_ROOT_PASSWORD: 'root'
|
||||||
ports:
|
ports:
|
||||||
- 3306:3306
|
- 3306:3306
|
||||||
options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
|
options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
|
||||||
@@ -43,11 +43,9 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: "actions/setup-python@v4"
|
uses: "gabrielfalcao/pyenv-action@v9"
|
||||||
with:
|
with:
|
||||||
python-version: |
|
versions: 3.10:latest, 3.7:latest
|
||||||
3.7
|
|
||||||
3.10
|
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v2
|
uses: actions/setup-node@v2
|
||||||
@@ -94,6 +92,7 @@ jobs:
|
|||||||
- name: Install
|
- name: Install
|
||||||
run: |
|
run: |
|
||||||
pip install frappe-bench
|
pip install frappe-bench
|
||||||
|
pyenv global $(pyenv versions | grep '3.10')
|
||||||
bash ${GITHUB_WORKSPACE}/.github/helper/install.sh
|
bash ${GITHUB_WORKSPACE}/.github/helper/install.sh
|
||||||
env:
|
env:
|
||||||
DB: mariadb
|
DB: mariadb
|
||||||
@@ -108,6 +107,7 @@ jobs:
|
|||||||
git -C "apps/frappe" remote set-url upstream https://github.com/frappe/frappe.git
|
git -C "apps/frappe" remote set-url upstream https://github.com/frappe/frappe.git
|
||||||
git -C "apps/erpnext" remote set-url upstream https://github.com/frappe/erpnext.git
|
git -C "apps/erpnext" remote set-url upstream https://github.com/frappe/erpnext.git
|
||||||
|
|
||||||
|
pyenv global $(pyenv versions | grep '3.7')
|
||||||
for version in $(seq 12 13)
|
for version in $(seq 12 13)
|
||||||
do
|
do
|
||||||
echo "Updating to v$version"
|
echo "Updating to v$version"
|
||||||
@@ -120,7 +120,7 @@ jobs:
|
|||||||
git -C "apps/erpnext" checkout -q -f $branch_name
|
git -C "apps/erpnext" checkout -q -f $branch_name
|
||||||
|
|
||||||
rm -rf ~/frappe-bench/env
|
rm -rf ~/frappe-bench/env
|
||||||
bench setup env --python python3.7
|
bench setup env
|
||||||
bench pip install -e ./apps/payments
|
bench pip install -e ./apps/payments
|
||||||
bench pip install -e ./apps/erpnext
|
bench pip install -e ./apps/erpnext
|
||||||
|
|
||||||
@@ -132,8 +132,9 @@ jobs:
|
|||||||
git -C "apps/frappe" checkout -q -f "${GITHUB_BASE_REF:-${GITHUB_REF##*/}}"
|
git -C "apps/frappe" checkout -q -f "${GITHUB_BASE_REF:-${GITHUB_REF##*/}}"
|
||||||
git -C "apps/erpnext" checkout -q -f "$GITHUB_SHA"
|
git -C "apps/erpnext" checkout -q -f "$GITHUB_SHA"
|
||||||
|
|
||||||
|
pyenv global $(pyenv versions | grep '3.10')
|
||||||
rm -rf ~/frappe-bench/env
|
rm -rf ~/frappe-bench/env
|
||||||
bench -v setup env --python python3.10
|
bench -v setup env
|
||||||
bench pip install -e ./apps/payments
|
bench pip install -e ./apps/payments
|
||||||
bench pip install -e ./apps/erpnext
|
bench pip install -e ./apps/erpnext
|
||||||
|
|
||||||
|
|||||||
8
.github/workflows/release.yml
vendored
8
.github/workflows/release.yml
vendored
@@ -2,7 +2,7 @@ name: Generate Semantic Release
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- version-14
|
- version-13
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
name: Release
|
name: Release
|
||||||
@@ -13,12 +13,10 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
- name: Setup Node.js v14
|
||||||
- name: Setup Node.js
|
|
||||||
uses: actions/setup-node@v2
|
uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 14
|
||||||
|
|
||||||
- name: Setup dependencies
|
- name: Setup dependencies
|
||||||
run: |
|
run: |
|
||||||
npm install @semantic-release/git @semantic-release/exec --no-save
|
npm install @semantic-release/git @semantic-release/exec --no-save
|
||||||
|
|||||||
38
.github/workflows/release_notes.yml
vendored
38
.github/workflows/release_notes.yml
vendored
@@ -1,38 +0,0 @@
|
|||||||
# This action:
|
|
||||||
#
|
|
||||||
# 1. Generates release notes using github API.
|
|
||||||
# 2. Strips unnecessary info like chore/style etc from notes.
|
|
||||||
# 3. Updates release info.
|
|
||||||
|
|
||||||
# This action needs to be maintained on all branches that do releases.
|
|
||||||
|
|
||||||
name: 'Release Notes'
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
tag_name:
|
|
||||||
description: 'Tag of release like v13.0.0'
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
release:
|
|
||||||
types: [released]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
regen-notes:
|
|
||||||
name: 'Regenerate release notes'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Update notes
|
|
||||||
run: |
|
|
||||||
NEW_NOTES=$(gh api --method POST -H "Accept: application/vnd.github+json" /repos/frappe/erpnext/releases/generate-notes -f tag_name=$RELEASE_TAG | jq -r '.body' | sed -E '/^\* (chore|ci|test|docs|style)/d' )
|
|
||||||
RELEASE_ID=$(gh api -H "Accept: application/vnd.github+json" /repos/frappe/erpnext/releases/tags/$RELEASE_TAG | jq -r '.id')
|
|
||||||
gh api --method PATCH -H "Accept: application/vnd.github+json" /repos/frappe/erpnext/releases/$RELEASE_ID -f body="$NEW_NOTES"
|
|
||||||
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
|
||||||
RELEASE_TAG: ${{ github.event.inputs.tag_name || github.event.release.tag_name }}
|
|
||||||
2
.github/workflows/semantic-commits.yml
vendored
2
.github/workflows/semantic-commits.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 14
|
||||||
check-latest: true
|
check-latest: true
|
||||||
|
|
||||||
- name: Check commit titles
|
- name: Check commit titles
|
||||||
|
|||||||
37
.github/workflows/server-tests-mariadb.yml
vendored
37
.github/workflows/server-tests-mariadb.yml
vendored
@@ -27,7 +27,7 @@ on:
|
|||||||
type: string
|
type: string
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: server-mariadb-develop-${{ github.event.number }}
|
group: server-mariadb-develop-${{ github.event_name }}-${{ github.event.number || github.event_name == 'workflow_dispatch' && github.run_id || '' }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -39,15 +39,15 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
container: [1, 2, 3]
|
container: [1, 2, 3, 4]
|
||||||
|
|
||||||
name: Python Unit Tests
|
name: Python Unit Tests
|
||||||
|
|
||||||
services:
|
services:
|
||||||
mysql:
|
mysql:
|
||||||
image: mariadb:10.3
|
image: mariadb:10.6
|
||||||
env:
|
env:
|
||||||
MYSQL_ALLOW_EMPTY_PASSWORD: YES
|
MARIADB_ROOT_PASSWORD: 'root'
|
||||||
ports:
|
ports:
|
||||||
- 3306:3306
|
- 3306:3306
|
||||||
options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
|
options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
|
||||||
@@ -59,7 +59,7 @@ jobs:
|
|||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v2
|
uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: '3.10'
|
python-version: '3.11'
|
||||||
|
|
||||||
- name: Check for valid Python & Merge Conflicts
|
- name: Check for valid Python & Merge Conflicts
|
||||||
run: |
|
run: |
|
||||||
@@ -120,7 +120,32 @@ jobs:
|
|||||||
FRAPPE_BRANCH: ${{ github.event.inputs.branch }}
|
FRAPPE_BRANCH: ${{ github.event.inputs.branch }}
|
||||||
|
|
||||||
- name: Run Tests
|
- name: Run Tests
|
||||||
run: 'cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --app erpnext --total-builds 3 --build-number ${{ matrix.container }}'
|
run: 'cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --app erpnext --with-coverage --total-builds 4 --build-number ${{ matrix.container }}'
|
||||||
env:
|
env:
|
||||||
TYPE: server
|
TYPE: server
|
||||||
CI_BUILD_ID: ${{ github.run_id }}
|
CI_BUILD_ID: ${{ github.run_id }}
|
||||||
|
ORCHESTRATOR_URL: http://test-orchestrator.frappe.io
|
||||||
|
|
||||||
|
- name: Upload coverage data
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: coverage-${{ matrix.container }}
|
||||||
|
path: /home/runner/frappe-bench/sites/coverage.xml
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
name: Coverage Wrap Up
|
||||||
|
needs: test
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Clone
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Download artifacts
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
|
||||||
|
- name: Upload coverage data
|
||||||
|
uses: codecov/codecov-action@v2
|
||||||
|
with:
|
||||||
|
name: MariaDB
|
||||||
|
fail_ci_if_error: true
|
||||||
|
verbose: true
|
||||||
|
|||||||
2
.github/workflows/server-tests-postgres.yml
vendored
2
.github/workflows/server-tests-postgres.yml
vendored
@@ -9,7 +9,7 @@ on:
|
|||||||
types: [opened, labelled, synchronize, reopened]
|
types: [opened, labelled, synchronize, reopened]
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: server-postgres-develop-${{ github.event.number }}
|
group: server-postgres-develop-${{ github.event_name }}-${{ github.event.number || github.event_name == 'workflow_dispatch' && github.run_id || '' }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ pull_request_rules:
|
|||||||
- author!=nabinhait
|
- author!=nabinhait
|
||||||
- author!=ankush
|
- author!=ankush
|
||||||
- author!=deepeshgarg007
|
- author!=deepeshgarg007
|
||||||
|
- author!=frappe-pr-bot
|
||||||
- author!=mergify[bot]
|
- author!=mergify[bot]
|
||||||
|
|
||||||
- or:
|
- or:
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ fail_fast: false
|
|||||||
|
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.3.0
|
rev: v4.0.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
files: "erpnext.*"
|
files: "erpnext.*"
|
||||||
@@ -15,55 +15,6 @@ repos:
|
|||||||
args: ['--branch', 'develop']
|
args: ['--branch', 'develop']
|
||||||
- id: check-merge-conflict
|
- id: check-merge-conflict
|
||||||
- id: check-ast
|
- id: check-ast
|
||||||
- id: check-json
|
|
||||||
- id: check-toml
|
|
||||||
- id: check-yaml
|
|
||||||
- id: debug-statements
|
|
||||||
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
|
||||||
rev: v2.7.1
|
|
||||||
hooks:
|
|
||||||
- id: prettier
|
|
||||||
types_or: [javascript, vue, scss]
|
|
||||||
# Ignore any files that might contain jinja / bundles
|
|
||||||
exclude: |
|
|
||||||
(?x)^(
|
|
||||||
erpnext/public/dist/.*|
|
|
||||||
cypress/.*|
|
|
||||||
.*node_modules.*|
|
|
||||||
.*boilerplate.*|
|
|
||||||
erpnext/public/js/controllers/.*|
|
|
||||||
erpnext/templates/pages/order.js|
|
|
||||||
erpnext/templates/includes/.*|
|
|
||||||
.*/supplier_quotation.js|
|
|
||||||
.*/sales_taxes_and_charges_template.js|
|
|
||||||
.*/purchase_taxes_and_charges_template.js|
|
|
||||||
.*/subcontracting_order.js|
|
|
||||||
.*/landed_cost_voucher.js|
|
|
||||||
.*/payment_entry.js|
|
|
||||||
.*/loan_interest_accrual.js|
|
|
||||||
.*/loan_disbursement.js|
|
|
||||||
.*/loan_application.js|
|
|
||||||
.*/italy.js|
|
|
||||||
.*/sales_invoice.js|
|
|
||||||
.*/subcontracting_receipt.js|
|
|
||||||
.*/request_for_quotation.js|
|
|
||||||
.*/pos_profile.js|
|
|
||||||
.*/opportunity.js|
|
|
||||||
.*/quotation.js|
|
|
||||||
.*/sales_common.js|
|
|
||||||
.*/sales_order.js|
|
|
||||||
.*/pos_invoice.js|
|
|
||||||
.*/purchase_invoice.js|
|
|
||||||
.*/loan_repayment.js|
|
|
||||||
.*/material_request.js|
|
|
||||||
.*/purchase_receipt.js|
|
|
||||||
.*/delivery_note.js|
|
|
||||||
.*/loan.js|
|
|
||||||
.*/stock_entry.js|
|
|
||||||
.*/purchase_order.js|
|
|
||||||
.*/loan_write_off.js
|
|
||||||
)$
|
|
||||||
|
|
||||||
- repo: https://github.com/PyCQA/flake8
|
- repo: https://github.com/PyCQA/flake8
|
||||||
rev: 5.0.4
|
rev: 5.0.4
|
||||||
@@ -81,8 +32,8 @@ repos:
|
|||||||
- id: black
|
- id: black
|
||||||
additional_dependencies: ['click==8.0.4']
|
additional_dependencies: ['click==8.0.4']
|
||||||
|
|
||||||
- repo: https://github.com/PyCQA/isort
|
- repo: https://github.com/timothycrosley/isort
|
||||||
rev: 5.12.0
|
rev: 5.9.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: isort
|
||||||
exclude: ".*setup.py$"
|
exclude: ".*setup.py$"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"branches": ["version-14"],
|
"branches": ["version-13"],
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"@semantic-release/commit-analyzer", {
|
"@semantic-release/commit-analyzer", {
|
||||||
"preset": "angular",
|
"preset": "angular",
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
"@semantic-release/release-notes-generator",
|
"@semantic-release/release-notes-generator",
|
||||||
[
|
[
|
||||||
"@semantic-release/exec", {
|
"@semantic-release/exec", {
|
||||||
"prepareCmd": 'sed -ir -E "s/\"[0-9]+\.[0-9]+\.[0-9]+\"/\"${nextRelease.version}\"/" erpnext/__init__.py'
|
"prepareCmd": 'sed -ir "s/[0-9]*\.[0-9]*\.[0-9]*/${nextRelease.version}/" erpnext/__init__.py'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
|||||||
25
CODEOWNERS
25
CODEOWNERS
@@ -3,23 +3,26 @@
|
|||||||
# These owners will be the default owners for everything in
|
# These owners will be the default owners for everything in
|
||||||
# the repo. Unless a later match takes precedence,
|
# the repo. Unless a later match takes precedence,
|
||||||
|
|
||||||
erpnext/accounts/ @deepeshgarg007 @ruthra-kumar
|
erpnext/accounts/ @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
||||||
erpnext/assets/ @anandbaburajan @deepeshgarg007
|
erpnext/assets/ @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
||||||
erpnext/loan_management/ @deepeshgarg007
|
erpnext/loan_management/ @nextchamp-saqib @deepeshgarg007
|
||||||
erpnext/regional @deepeshgarg007 @ruthra-kumar
|
erpnext/regional @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
||||||
erpnext/selling @deepeshgarg007 @ruthra-kumar
|
erpnext/selling @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
||||||
erpnext/support/ @deepeshgarg007
|
erpnext/support/ @nextchamp-saqib @deepeshgarg007
|
||||||
pos*
|
pos* @nextchamp-saqib
|
||||||
|
|
||||||
erpnext/buying/ @rohitwaghchaure @s-aga-r
|
erpnext/buying/ @rohitwaghchaure @s-aga-r
|
||||||
erpnext/maintenance/ @rohitwaghchaure @s-aga-r
|
erpnext/maintenance/ @rohitwaghchaure @s-aga-r
|
||||||
erpnext/manufacturing/ @rohitwaghchaure @s-aga-r
|
erpnext/manufacturing/ @rohitwaghchaure @s-aga-r
|
||||||
erpnext/quality_management/ @rohitwaghchaure @s-aga-r
|
erpnext/quality_management/ @rohitwaghchaure @s-aga-r
|
||||||
erpnext/stock/ @rohitwaghchaure @s-aga-r
|
erpnext/stock/ @rohitwaghchaure @s-aga-r
|
||||||
erpnext/subcontracting @rohitwaghchaure @s-aga-r
|
|
||||||
|
|
||||||
erpnext/controllers/ @deepeshgarg007 @rohitwaghchaure
|
erpnext/crm/ @NagariaHussain
|
||||||
erpnext/patches/ @deepeshgarg007
|
erpnext/education/ @rutwikhdev
|
||||||
|
erpnext/projects/ @ruchamahabal
|
||||||
|
|
||||||
.github/ @deepeshgarg007
|
erpnext/controllers/ @deepeshgarg007 @nextchamp-saqib @rohitwaghchaure
|
||||||
|
erpnext/patches/ @deepeshgarg007 @nextchamp-saqib
|
||||||
|
|
||||||
|
.github/ @ankush
|
||||||
pyproject.toml @ankush
|
pyproject.toml @ankush
|
||||||
|
|||||||
@@ -1,13 +1,25 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
parserPreset: "conventional-changelog-conventionalcommits",
|
parserPreset: 'conventional-changelog-conventionalcommits',
|
||||||
rules: {
|
rules: {
|
||||||
"subject-empty": [2, "never"],
|
'subject-empty': [2, 'never'],
|
||||||
"type-case": [2, "always", "lower-case"],
|
'type-case': [2, 'always', 'lower-case'],
|
||||||
"type-empty": [2, "never"],
|
'type-empty': [2, 'never'],
|
||||||
"type-enum": [
|
'type-enum': [
|
||||||
2,
|
2,
|
||||||
"always",
|
'always',
|
||||||
["build", "chore", "ci", "docs", "feat", "fix", "perf", "refactor", "revert", "style", "test"],
|
[
|
||||||
|
'build',
|
||||||
|
'chore',
|
||||||
|
'ci',
|
||||||
|
'docs',
|
||||||
|
'feat',
|
||||||
|
'fix',
|
||||||
|
'perf',
|
||||||
|
'refactor',
|
||||||
|
'revert',
|
||||||
|
'style',
|
||||||
|
'test',
|
||||||
|
],
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import functools
|
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
|
||||||
__version__ = "14.65.1"
|
__version__ = "14.0.0-dev"
|
||||||
|
|
||||||
|
|
||||||
def get_default_company(user=None):
|
def get_default_company(user=None):
|
||||||
@@ -13,7 +12,7 @@ def get_default_company(user=None):
|
|||||||
if not user:
|
if not user:
|
||||||
user = frappe.session.user
|
user = frappe.session.user
|
||||||
|
|
||||||
companies = get_user_default_as_list("company", user)
|
companies = get_user_default_as_list(user, "company")
|
||||||
if companies:
|
if companies:
|
||||||
default_company = companies[0]
|
default_company = companies[0]
|
||||||
else:
|
else:
|
||||||
@@ -121,14 +120,12 @@ def get_region(company=None):
|
|||||||
|
|
||||||
You can also set global company flag in `frappe.flags.company`
|
You can also set global company flag in `frappe.flags.company`
|
||||||
"""
|
"""
|
||||||
|
if company or frappe.flags.company:
|
||||||
if not company:
|
return frappe.get_cached_value("Company", company or frappe.flags.company, "country")
|
||||||
company = frappe.local.flags.company
|
elif frappe.flags.country:
|
||||||
|
return frappe.flags.country
|
||||||
if company:
|
else:
|
||||||
return frappe.get_cached_value("Company", company, "country")
|
return frappe.get_system_settings("country")
|
||||||
|
|
||||||
return frappe.flags.country or frappe.get_system_settings("country")
|
|
||||||
|
|
||||||
|
|
||||||
def allow_regional(fn):
|
def allow_regional(fn):
|
||||||
@@ -139,7 +136,6 @@ def allow_regional(fn):
|
|||||||
def myfunction():
|
def myfunction():
|
||||||
pass"""
|
pass"""
|
||||||
|
|
||||||
@functools.wraps(fn)
|
|
||||||
def caller(*args, **kwargs):
|
def caller(*args, **kwargs):
|
||||||
overrides = frappe.get_hooks("regional_overrides", {}).get(get_region())
|
overrides = frappe.get_hooks("regional_overrides", {}).get(get_region())
|
||||||
function_path = f"{inspect.getmodule(fn).__name__}.{fn.__name__}"
|
function_path = f"{inspect.getmodule(fn).__name__}.{fn.__name__}"
|
||||||
|
|||||||
@@ -4,19 +4,18 @@
|
|||||||
"creation": "2020-07-17 11:25:34.593061",
|
"creation": "2020-07-17 11:25:34.593061",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Dashboard Chart",
|
"doctype": "Dashboard Chart",
|
||||||
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"from_fiscal_year\":\"erpnext.utils.get_fiscal_year()\",\"to_fiscal_year\":\"erpnext.utils.get_fiscal_year()\"}",
|
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"from_fiscal_year\":\"frappe.sys_defaults.fiscal_year\",\"to_fiscal_year\":\"frappe.sys_defaults.fiscal_year\"}",
|
||||||
"filters_json": "{\"period\":\"Monthly\",\"budget_against\":\"Cost Center\",\"show_cumulative\":0}",
|
"filters_json": "{\"period\":\"Monthly\",\"budget_against\":\"Cost Center\",\"show_cumulative\":0}",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_public": 1,
|
"is_public": 1,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"modified": "2023-07-19 13:13:13.307073",
|
"modified": "2020-07-22 12:24:49.144210",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Budget Variance",
|
"name": "Budget Variance",
|
||||||
"number_of_groups": 0,
|
"number_of_groups": 0,
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"report_name": "Budget Variance Report",
|
"report_name": "Budget Variance Report",
|
||||||
"roles": [],
|
|
||||||
"timeseries": 0,
|
"timeseries": 0,
|
||||||
"type": "Bar",
|
"type": "Bar",
|
||||||
"use_report_chart": 1,
|
"use_report_chart": 1,
|
||||||
|
|||||||
@@ -4,19 +4,18 @@
|
|||||||
"creation": "2020-07-17 11:25:34.448572",
|
"creation": "2020-07-17 11:25:34.448572",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Dashboard Chart",
|
"doctype": "Dashboard Chart",
|
||||||
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"from_fiscal_year\":\"erpnext.utils.get_fiscal_year()\",\"to_fiscal_year\":\"erpnext.utils.get_fiscal_year()\"}",
|
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"from_fiscal_year\":\"frappe.sys_defaults.fiscal_year\",\"to_fiscal_year\":\"frappe.sys_defaults.fiscal_year\"}",
|
||||||
"filters_json": "{\"filter_based_on\":\"Fiscal Year\",\"period_start_date\":\"2020-04-01\",\"period_end_date\":\"2021-03-31\",\"periodicity\":\"Yearly\",\"include_default_book_entries\":1}",
|
"filters_json": "{\"filter_based_on\":\"Fiscal Year\",\"period_start_date\":\"2020-04-01\",\"period_end_date\":\"2021-03-31\",\"periodicity\":\"Yearly\",\"include_default_book_entries\":1}",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_public": 1,
|
"is_public": 1,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"modified": "2023-07-19 13:08:56.470390",
|
"modified": "2020-07-22 12:33:48.888943",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Profit and Loss",
|
"name": "Profit and Loss",
|
||||||
"number_of_groups": 0,
|
"number_of_groups": 0,
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"report_name": "Profit and Loss Statement",
|
"report_name": "Profit and Loss Statement",
|
||||||
"roles": [],
|
|
||||||
"timeseries": 0,
|
"timeseries": 0,
|
||||||
"type": "Bar",
|
"type": "Bar",
|
||||||
"use_report_chart": 1,
|
"use_report_chart": 1,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
frappe.provide("frappe.dashboards.chart_sources");
|
frappe.provide('frappe.dashboards.chart_sources');
|
||||||
|
|
||||||
frappe.dashboards.chart_sources["Account Balance Timeline"] = {
|
frappe.dashboards.chart_sources["Account Balance Timeline"] = {
|
||||||
method: "erpnext.accounts.dashboard_chart_source.account_balance_timeline.account_balance_timeline.get",
|
method: "erpnext.accounts.dashboard_chart_source.account_balance_timeline.account_balance_timeline.get",
|
||||||
@@ -9,14 +9,14 @@ frappe.dashboards.chart_sources["Account Balance Timeline"] = {
|
|||||||
fieldtype: "Link",
|
fieldtype: "Link",
|
||||||
options: "Company",
|
options: "Company",
|
||||||
default: frappe.defaults.get_user_default("Company"),
|
default: frappe.defaults.get_user_default("Company"),
|
||||||
reqd: 1,
|
reqd: 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: "account",
|
fieldname: "account",
|
||||||
label: __("Account"),
|
label: __("Account"),
|
||||||
fieldtype: "Link",
|
fieldtype: "Link",
|
||||||
options: "Account",
|
options: "Account",
|
||||||
reqd: 1,
|
reqd: 1
|
||||||
},
|
},
|
||||||
],
|
]
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ def get(
|
|||||||
|
|
||||||
def build_result(account, dates, gl_entries):
|
def build_result(account, dates, gl_entries):
|
||||||
result = [[getdate(date), 0.0] for date in dates]
|
result = [[getdate(date), 0.0] for date in dates]
|
||||||
root_type = frappe.db.get_value("Account", account, "root_type")
|
root_type = frappe.get_cached_value("Account", account, "root_type")
|
||||||
|
|
||||||
# start with the first date
|
# start with the first date
|
||||||
date_index = 0
|
date_index = 0
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ def convert_deferred_revenue_to_income(
|
|||||||
send_mail(deferred_process)
|
send_mail(deferred_process)
|
||||||
|
|
||||||
|
|
||||||
def get_booking_dates(doc, item, posting_date=None, prev_posting_date=None):
|
def get_booking_dates(doc, item, posting_date=None):
|
||||||
if not posting_date:
|
if not posting_date:
|
||||||
posting_date = add_days(today(), -1)
|
posting_date = add_days(today(), -1)
|
||||||
|
|
||||||
@@ -146,7 +146,6 @@ def get_booking_dates(doc, item, posting_date=None, prev_posting_date=None):
|
|||||||
"deferred_revenue_account" if doc.doctype == "Sales Invoice" else "deferred_expense_account"
|
"deferred_revenue_account" if doc.doctype == "Sales Invoice" else "deferred_expense_account"
|
||||||
)
|
)
|
||||||
|
|
||||||
if not prev_posting_date:
|
|
||||||
prev_gl_entry = frappe.db.sql(
|
prev_gl_entry = frappe.db.sql(
|
||||||
"""
|
"""
|
||||||
select name, posting_date from `tabGL Entry` where company=%s and account=%s and
|
select name, posting_date from `tabGL Entry` where company=%s and account=%s and
|
||||||
@@ -180,8 +179,6 @@ def get_booking_dates(doc, item, posting_date=None, prev_posting_date=None):
|
|||||||
else:
|
else:
|
||||||
start_date = item.service_start_date
|
start_date = item.service_start_date
|
||||||
|
|
||||||
else:
|
|
||||||
start_date = getdate(add_days(prev_posting_date, 1))
|
|
||||||
end_date = get_last_day(start_date)
|
end_date = get_last_day(start_date)
|
||||||
if end_date >= item.service_end_date:
|
if end_date >= item.service_end_date:
|
||||||
end_date = item.service_end_date
|
end_date = item.service_end_date
|
||||||
@@ -341,18 +338,12 @@ def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
|
|||||||
"enable_deferred_revenue" if doc.doctype == "Sales Invoice" else "enable_deferred_expense"
|
"enable_deferred_revenue" if doc.doctype == "Sales Invoice" else "enable_deferred_expense"
|
||||||
)
|
)
|
||||||
|
|
||||||
accounts_frozen_upto = frappe.db.get_single_value("Accounts Settings", "acc_frozen_upto")
|
accounts_frozen_upto = frappe.get_cached_value("Accounts Settings", "None", "acc_frozen_upto")
|
||||||
|
|
||||||
def _book_deferred_revenue_or_expense(
|
def _book_deferred_revenue_or_expense(
|
||||||
item,
|
item, via_journal_entry, submit_journal_entry, book_deferred_entries_based_on
|
||||||
via_journal_entry,
|
|
||||||
submit_journal_entry,
|
|
||||||
book_deferred_entries_based_on,
|
|
||||||
prev_posting_date=None,
|
|
||||||
):
|
):
|
||||||
start_date, end_date, last_gl_entry = get_booking_dates(
|
start_date, end_date, last_gl_entry = get_booking_dates(doc, item, posting_date=posting_date)
|
||||||
doc, item, posting_date=posting_date, prev_posting_date=prev_posting_date
|
|
||||||
)
|
|
||||||
if not (start_date and end_date):
|
if not (start_date and end_date):
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -386,12 +377,9 @@ def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
|
|||||||
if not amount:
|
if not amount:
|
||||||
return
|
return
|
||||||
|
|
||||||
gl_posting_date = end_date
|
|
||||||
prev_posting_date = None
|
|
||||||
# check if books nor frozen till endate:
|
# check if books nor frozen till endate:
|
||||||
if accounts_frozen_upto and getdate(end_date) <= getdate(accounts_frozen_upto):
|
if accounts_frozen_upto and (end_date) <= getdate(accounts_frozen_upto):
|
||||||
gl_posting_date = get_last_day(add_days(accounts_frozen_upto, 1))
|
end_date = get_last_day(add_days(accounts_frozen_upto, 1))
|
||||||
prev_posting_date = end_date
|
|
||||||
|
|
||||||
if via_journal_entry:
|
if via_journal_entry:
|
||||||
book_revenue_via_journal_entry(
|
book_revenue_via_journal_entry(
|
||||||
@@ -400,7 +388,7 @@ def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
|
|||||||
debit_account,
|
debit_account,
|
||||||
amount,
|
amount,
|
||||||
base_amount,
|
base_amount,
|
||||||
gl_posting_date,
|
end_date,
|
||||||
project,
|
project,
|
||||||
account_currency,
|
account_currency,
|
||||||
item.cost_center,
|
item.cost_center,
|
||||||
@@ -416,7 +404,7 @@ def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
|
|||||||
against,
|
against,
|
||||||
amount,
|
amount,
|
||||||
base_amount,
|
base_amount,
|
||||||
gl_posting_date,
|
end_date,
|
||||||
project,
|
project,
|
||||||
account_currency,
|
account_currency,
|
||||||
item.cost_center,
|
item.cost_center,
|
||||||
@@ -430,11 +418,7 @@ def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
|
|||||||
|
|
||||||
if getdate(end_date) < getdate(posting_date) and not last_gl_entry:
|
if getdate(end_date) < getdate(posting_date) and not last_gl_entry:
|
||||||
_book_deferred_revenue_or_expense(
|
_book_deferred_revenue_or_expense(
|
||||||
item,
|
item, via_journal_entry, submit_journal_entry, book_deferred_entries_based_on
|
||||||
via_journal_entry,
|
|
||||||
submit_journal_entry,
|
|
||||||
book_deferred_entries_based_on,
|
|
||||||
prev_posting_date,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
via_journal_entry = cint(
|
via_journal_entry = cint(
|
||||||
|
|||||||
@@ -1,32 +1,33 @@
|
|||||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
// License: GNU General Public License v3. See license.txt
|
// License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Account", {
|
frappe.ui.form.on('Account', {
|
||||||
setup: function (frm) {
|
setup: function(frm) {
|
||||||
frm.add_fetch("parent_account", "report_type", "report_type");
|
frm.add_fetch('parent_account', 'report_type', 'report_type');
|
||||||
frm.add_fetch("parent_account", "root_type", "root_type");
|
frm.add_fetch('parent_account', 'root_type', 'root_type');
|
||||||
},
|
},
|
||||||
onload: function (frm) {
|
onload: function(frm) {
|
||||||
frm.set_query("parent_account", function (doc) {
|
frm.set_query('parent_account', function(doc) {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
is_group: 1,
|
"is_group": 1,
|
||||||
company: doc.company,
|
"company": doc.company
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
refresh: function (frm) {
|
refresh: function(frm) {
|
||||||
frm.toggle_display("account_name", frm.is_new());
|
frm.toggle_display('account_name', frm.is_new());
|
||||||
|
|
||||||
// hide fields if group
|
// hide fields if group
|
||||||
frm.toggle_display(["account_type", "tax_rate"], cint(frm.doc.is_group) == 0);
|
frm.toggle_display(['account_type', 'tax_rate'], cint(frm.doc.is_group) == 0);
|
||||||
|
|
||||||
// disable fields
|
// disable fields
|
||||||
frm.toggle_enable(["is_group", "company"], false);
|
frm.toggle_enable(['is_group', 'company'], false);
|
||||||
|
|
||||||
if (cint(frm.doc.is_group) == 0) {
|
if (cint(frm.doc.is_group) == 0) {
|
||||||
frm.toggle_display("freeze_account", frm.doc.__onload && frm.doc.__onload.can_freeze_account);
|
frm.toggle_display('freeze_account', frm.doc.__onload
|
||||||
|
&& frm.doc.__onload.can_freeze_account);
|
||||||
}
|
}
|
||||||
|
|
||||||
// read-only for root accounts
|
// read-only for root accounts
|
||||||
@@ -37,147 +38,125 @@ frappe.ui.form.on("Account", {
|
|||||||
} else {
|
} else {
|
||||||
// credit days and type if customer or supplier
|
// credit days and type if customer or supplier
|
||||||
frm.set_intro(null);
|
frm.set_intro(null);
|
||||||
frm.trigger("account_type");
|
frm.trigger('account_type');
|
||||||
// show / hide convert buttons
|
// show / hide convert buttons
|
||||||
frm.trigger("add_toolbar_buttons");
|
frm.trigger('add_toolbar_buttons');
|
||||||
}
|
}
|
||||||
if (frm.has_perm("write")) {
|
if (frm.has_perm('write')) {
|
||||||
frm.add_custom_button(
|
frm.add_custom_button(__('Merge Account'), function () {
|
||||||
__("Merge Account"),
|
|
||||||
function () {
|
|
||||||
frm.trigger("merge_account");
|
frm.trigger("merge_account");
|
||||||
},
|
}, __('Actions'));
|
||||||
__("Actions")
|
frm.add_custom_button(__('Update Account Name / Number'), function () {
|
||||||
);
|
|
||||||
frm.add_custom_button(
|
|
||||||
__("Update Account Name / Number"),
|
|
||||||
function () {
|
|
||||||
frm.trigger("update_account_number");
|
frm.trigger("update_account_number");
|
||||||
},
|
}, __('Actions'));
|
||||||
__("Actions")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
account_type: function (frm) {
|
account_type: function (frm) {
|
||||||
if (frm.doc.is_group == 0) {
|
if (frm.doc.is_group == 0) {
|
||||||
frm.toggle_display(["tax_rate"], frm.doc.account_type == "Tax");
|
frm.toggle_display(['tax_rate'], frm.doc.account_type == 'Tax');
|
||||||
frm.toggle_display("warehouse", frm.doc.account_type == "Stock");
|
frm.toggle_display('warehouse', frm.doc.account_type == 'Stock');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
add_toolbar_buttons: function (frm) {
|
add_toolbar_buttons: function(frm) {
|
||||||
frm.add_custom_button(
|
frm.add_custom_button(__('Chart of Accounts'), () => {
|
||||||
__("Chart of Accounts"),
|
|
||||||
() => {
|
|
||||||
frappe.set_route("Tree", "Account");
|
frappe.set_route("Tree", "Account");
|
||||||
},
|
}, __('View'));
|
||||||
__("View")
|
|
||||||
);
|
|
||||||
|
|
||||||
if (frm.doc.is_group == 1) {
|
if (frm.doc.is_group == 1) {
|
||||||
frm.add_custom_button(
|
frm.add_custom_button(__('Convert to Non-Group'), function () {
|
||||||
__("Convert to Non-Group"),
|
|
||||||
function () {
|
|
||||||
return frappe.call({
|
return frappe.call({
|
||||||
doc: frm.doc,
|
doc: frm.doc,
|
||||||
method: "convert_group_to_ledger",
|
method: 'convert_group_to_ledger',
|
||||||
callback: function () {
|
callback: function() {
|
||||||
frm.refresh();
|
frm.refresh();
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
},
|
}, __('Actions'));
|
||||||
__("Actions")
|
|
||||||
);
|
} else if (cint(frm.doc.is_group) == 0
|
||||||
} else if (cint(frm.doc.is_group) == 0 && frappe.boot.user.can_read.indexOf("GL Entry") !== -1) {
|
&& frappe.boot.user.can_read.indexOf("GL Entry") !== -1) {
|
||||||
frm.add_custom_button(
|
frm.add_custom_button(__('General Ledger'), function () {
|
||||||
__("General Ledger"),
|
|
||||||
function () {
|
|
||||||
frappe.route_options = {
|
frappe.route_options = {
|
||||||
account: frm.doc.name,
|
"account": frm.doc.name,
|
||||||
from_date: frappe.sys_defaults.year_start_date,
|
"from_date": frappe.sys_defaults.year_start_date,
|
||||||
to_date: frappe.sys_defaults.year_end_date,
|
"to_date": frappe.sys_defaults.year_end_date,
|
||||||
company: frm.doc.company,
|
"company": frm.doc.company
|
||||||
};
|
};
|
||||||
frappe.set_route("query-report", "General Ledger");
|
frappe.set_route("query-report", "General Ledger");
|
||||||
},
|
}, __('View'));
|
||||||
__("View")
|
|
||||||
);
|
|
||||||
|
|
||||||
frm.add_custom_button(
|
frm.add_custom_button(__('Convert to Group'), function () {
|
||||||
__("Convert to Group"),
|
|
||||||
function () {
|
|
||||||
return frappe.call({
|
return frappe.call({
|
||||||
doc: frm.doc,
|
doc: frm.doc,
|
||||||
method: "convert_ledger_to_group",
|
method: 'convert_ledger_to_group',
|
||||||
callback: function () {
|
callback: function() {
|
||||||
frm.refresh();
|
frm.refresh();
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
},
|
}, __('Actions'));
|
||||||
__("Actions")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
merge_account: function (frm) {
|
merge_account: function(frm) {
|
||||||
var d = new frappe.ui.Dialog({
|
var d = new frappe.ui.Dialog({
|
||||||
title: __("Merge with Existing Account"),
|
title: __('Merge with Existing Account'),
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
label: "Name",
|
"label" : "Name",
|
||||||
fieldname: "name",
|
"fieldname": "name",
|
||||||
fieldtype: "Data",
|
"fieldtype": "Data",
|
||||||
reqd: 1,
|
"reqd": 1,
|
||||||
default: frm.doc.name,
|
"default": frm.doc.name
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
primary_action: function () {
|
primary_action: function() {
|
||||||
var data = d.get_values();
|
var data = d.get_values();
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.accounts.doctype.account.account.merge_account",
|
method: "erpnext.accounts.doctype.account.account.merge_account",
|
||||||
args: {
|
args: {
|
||||||
old: frm.doc.name,
|
old: frm.doc.name,
|
||||||
new: data.name,
|
new: data.name,
|
||||||
|
is_group: frm.doc.is_group,
|
||||||
|
root_type: frm.doc.root_type,
|
||||||
|
company: frm.doc.company
|
||||||
},
|
},
|
||||||
callback: function (r) {
|
callback: function(r) {
|
||||||
if (!r.exc) {
|
if(!r.exc) {
|
||||||
if (r.message) {
|
if(r.message) {
|
||||||
frappe.set_route("Form", "Account", r.message);
|
frappe.set_route("Form", "Account", r.message);
|
||||||
}
|
}
|
||||||
d.hide();
|
d.hide();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
primary_action_label: __("Merge"),
|
primary_action_label: __('Merge')
|
||||||
});
|
});
|
||||||
d.show();
|
d.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
update_account_number: function (frm) {
|
update_account_number: function(frm) {
|
||||||
var d = new frappe.ui.Dialog({
|
var d = new frappe.ui.Dialog({
|
||||||
title: __("Update Account Number / Name"),
|
title: __('Update Account Number / Name'),
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
label: "Account Name",
|
"label": "Account Name",
|
||||||
fieldname: "account_name",
|
"fieldname": "account_name",
|
||||||
fieldtype: "Data",
|
"fieldtype": "Data",
|
||||||
reqd: 1,
|
"reqd": 1,
|
||||||
default: frm.doc.account_name,
|
"default": frm.doc.account_name
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Account Number",
|
"label": "Account Number",
|
||||||
fieldname: "account_number",
|
"fieldname": "account_number",
|
||||||
fieldtype: "Data",
|
"fieldtype": "Data",
|
||||||
default: frm.doc.account_number,
|
"default": frm.doc.account_number
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
primary_action: function () {
|
primary_action: function() {
|
||||||
var data = d.get_values();
|
var data = d.get_values();
|
||||||
if (
|
if(data.account_number === frm.doc.account_number && data.account_name === frm.doc.account_name) {
|
||||||
data.account_number === frm.doc.account_number &&
|
|
||||||
data.account_name === frm.doc.account_name
|
|
||||||
) {
|
|
||||||
d.hide();
|
d.hide();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -187,11 +166,11 @@ frappe.ui.form.on("Account", {
|
|||||||
args: {
|
args: {
|
||||||
account_number: data.account_number,
|
account_number: data.account_number,
|
||||||
account_name: data.account_name,
|
account_name: data.account_name,
|
||||||
name: frm.doc.name,
|
name: frm.doc.name
|
||||||
},
|
},
|
||||||
callback: function (r) {
|
callback: function(r) {
|
||||||
if (!r.exc) {
|
if(!r.exc) {
|
||||||
if (r.message) {
|
if(r.message) {
|
||||||
frappe.set_route("Form", "Account", r.message);
|
frappe.set_route("Form", "Account", r.message);
|
||||||
} else {
|
} else {
|
||||||
frm.set_value("account_number", data.account_number);
|
frm.set_value("account_number", data.account_number);
|
||||||
@@ -199,11 +178,11 @@ frappe.ui.form.on("Account", {
|
|||||||
}
|
}
|
||||||
d.hide();
|
d.hide();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
primary_action_label: __("Update"),
|
primary_action_label: __('Update')
|
||||||
});
|
});
|
||||||
d.show();
|
d.show();
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
"root_type",
|
"root_type",
|
||||||
"report_type",
|
"report_type",
|
||||||
"account_currency",
|
"account_currency",
|
||||||
|
"inter_company_account",
|
||||||
"column_break1",
|
"column_break1",
|
||||||
"parent_account",
|
"parent_account",
|
||||||
"account_type",
|
"account_type",
|
||||||
@@ -33,11 +34,15 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "properties",
|
"fieldname": "properties",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"oldfieldtype": "Section Break"
|
"oldfieldtype": "Section Break",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break0",
|
"fieldname": "column_break0",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1,
|
||||||
"width": "50%"
|
"width": "50%"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -48,7 +53,9 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldname": "account_name",
|
"oldfieldname": "account_name",
|
||||||
"oldfieldtype": "Data",
|
"oldfieldtype": "Data",
|
||||||
"reqd": 1
|
"reqd": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "account_number",
|
"fieldname": "account_number",
|
||||||
@@ -56,13 +63,17 @@
|
|||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Account Number",
|
"label": "Account Number",
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "is_group",
|
"fieldname": "is_group",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Is Group"
|
"label": "Is Group",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "company",
|
"fieldname": "company",
|
||||||
@@ -74,7 +85,9 @@
|
|||||||
"options": "Company",
|
"options": "Company",
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
"remember_last_selected_value": 1,
|
"remember_last_selected_value": 1,
|
||||||
"reqd": 1
|
"reqd": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "root_type",
|
"fieldname": "root_type",
|
||||||
@@ -82,7 +95,9 @@
|
|||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Root Type",
|
"label": "Root Type",
|
||||||
"options": "\nAsset\nLiability\nIncome\nExpense\nEquity",
|
"options": "\nAsset\nLiability\nIncome\nExpense\nEquity",
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "report_type",
|
"fieldname": "report_type",
|
||||||
@@ -90,18 +105,32 @@
|
|||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Report Type",
|
"label": "Report Type",
|
||||||
"options": "\nBalance Sheet\nProfit and Loss",
|
"options": "\nBalance Sheet\nProfit and Loss",
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.is_group==0",
|
"depends_on": "eval:doc.is_group==0",
|
||||||
"fieldname": "account_currency",
|
"fieldname": "account_currency",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Currency",
|
"label": "Currency",
|
||||||
"options": "Currency"
|
"options": "Currency",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "inter_company_account",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Inter Company Account",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break1",
|
"fieldname": "column_break1",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1,
|
||||||
"width": "50%"
|
"width": "50%"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -113,7 +142,9 @@
|
|||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"options": "Account",
|
"options": "Account",
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 1
|
"search_index": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Setting Account Type helps in selecting this Account in transactions.",
|
"description": "Setting Account Type helps in selecting this Account in transactions.",
|
||||||
@@ -123,7 +154,9 @@
|
|||||||
"label": "Account Type",
|
"label": "Account Type",
|
||||||
"oldfieldname": "account_type",
|
"oldfieldname": "account_type",
|
||||||
"oldfieldtype": "Select",
|
"oldfieldtype": "Select",
|
||||||
"options": "\nAccumulated Depreciation\nAsset Received But Not Billed\nBank\nCash\nChargeable\nCapital Work in Progress\nCost of Goods Sold\nDepreciation\nEquity\nExpense Account\nExpenses Included In Asset Valuation\nExpenses Included In Valuation\nFixed Asset\nIncome Account\nPayable\nReceivable\nRound Off\nStock\nStock Adjustment\nStock Received But Not Billed\nService Received But Not Billed\nTax\nTemporary"
|
"options": "\nAccumulated Depreciation\nAsset Received But Not Billed\nBank\nCash\nChargeable\nCapital Work in Progress\nCost of Goods Sold\nDepreciation\nEquity\nExpense Account\nExpenses Included In Asset Valuation\nExpenses Included In Valuation\nFixed Asset\nIncome Account\nPayable\nReceivable\nRound Off\nStock\nStock Adjustment\nStock Received But Not Billed\nService Received But Not Billed\nTax\nTemporary",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Rate at which this tax is applied",
|
"description": "Rate at which this tax is applied",
|
||||||
@@ -131,7 +164,9 @@
|
|||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"label": "Rate",
|
"label": "Rate",
|
||||||
"oldfieldname": "tax_rate",
|
"oldfieldname": "tax_rate",
|
||||||
"oldfieldtype": "Currency"
|
"oldfieldtype": "Currency",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "If the account is frozen, entries are allowed to restricted users.",
|
"description": "If the account is frozen, entries are allowed to restricted users.",
|
||||||
@@ -140,13 +175,17 @@
|
|||||||
"label": "Frozen",
|
"label": "Frozen",
|
||||||
"oldfieldname": "freeze_account",
|
"oldfieldname": "freeze_account",
|
||||||
"oldfieldtype": "Select",
|
"oldfieldtype": "Select",
|
||||||
"options": "No\nYes"
|
"options": "No\nYes",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "balance_must_be",
|
"fieldname": "balance_must_be",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Balance must be",
|
"label": "Balance must be",
|
||||||
"options": "\nDebit\nCredit"
|
"options": "\nDebit\nCredit",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "lft",
|
"fieldname": "lft",
|
||||||
@@ -155,7 +194,9 @@
|
|||||||
"label": "Lft",
|
"label": "Lft",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
"search_index": 1
|
"search_index": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "rgt",
|
"fieldname": "rgt",
|
||||||
@@ -164,7 +205,9 @@
|
|||||||
"label": "Rgt",
|
"label": "Rgt",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
"search_index": 1
|
"search_index": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "old_parent",
|
"fieldname": "old_parent",
|
||||||
@@ -172,27 +215,33 @@
|
|||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Old Parent",
|
"label": "Old Parent",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"depends_on": "eval:(doc.report_type == 'Profit and Loss' && !doc.is_group)",
|
"depends_on": "eval:(doc.report_type == 'Profit and Loss' && !doc.is_group)",
|
||||||
"fieldname": "include_in_gross",
|
"fieldname": "include_in_gross",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Include in gross"
|
"label": "Include in gross",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "disabled",
|
"fieldname": "disabled",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Disable"
|
"label": "Disable",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-money",
|
"icon": "fa fa-money",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"is_tree": 1,
|
"is_tree": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-04-11 16:08:46.983677",
|
"modified": "2020-06-11 15:15:54.338622",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Account",
|
"name": "Account",
|
||||||
@@ -252,6 +301,5 @@
|
|||||||
"show_name_in_global_search": 1,
|
"show_name_in_global_search": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "ASC",
|
"sort_order": "ASC",
|
||||||
"states": [],
|
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
@@ -18,10 +18,6 @@ class BalanceMismatchError(frappe.ValidationError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InvalidAccountMergeError(frappe.ValidationError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Account(NestedSet):
|
class Account(NestedSet):
|
||||||
nsm_parent_field = "parent_account"
|
nsm_parent_field = "parent_account"
|
||||||
|
|
||||||
@@ -58,12 +54,11 @@ class Account(NestedSet):
|
|||||||
self.validate_balance_must_be_debit_or_credit()
|
self.validate_balance_must_be_debit_or_credit()
|
||||||
self.validate_account_currency()
|
self.validate_account_currency()
|
||||||
self.validate_root_company_and_sync_account_to_children()
|
self.validate_root_company_and_sync_account_to_children()
|
||||||
self.validate_receivable_payable_account_type()
|
|
||||||
|
|
||||||
def validate_parent(self):
|
def validate_parent(self):
|
||||||
"""Fetch Parent Details and validate parent account"""
|
"""Fetch Parent Details and validate parent account"""
|
||||||
if self.parent_account:
|
if self.parent_account:
|
||||||
par = frappe.db.get_value(
|
par = frappe.get_cached_value(
|
||||||
"Account", self.parent_account, ["name", "is_group", "company"], as_dict=1
|
"Account", self.parent_account, ["name", "is_group", "company"], as_dict=1
|
||||||
)
|
)
|
||||||
if not par:
|
if not par:
|
||||||
@@ -87,7 +82,7 @@ class Account(NestedSet):
|
|||||||
|
|
||||||
def set_root_and_report_type(self):
|
def set_root_and_report_type(self):
|
||||||
if self.parent_account:
|
if self.parent_account:
|
||||||
par = frappe.db.get_value(
|
par = frappe.get_cached_value(
|
||||||
"Account", self.parent_account, ["report_type", "root_type"], as_dict=1
|
"Account", self.parent_account, ["report_type", "root_type"], as_dict=1
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -97,7 +92,7 @@ class Account(NestedSet):
|
|||||||
self.root_type = par.root_type
|
self.root_type = par.root_type
|
||||||
|
|
||||||
if self.is_group:
|
if self.is_group:
|
||||||
db_value = frappe.db.get_value("Account", self.name, ["report_type", "root_type"], as_dict=1)
|
db_value = self.get_doc_before_save()
|
||||||
if db_value:
|
if db_value:
|
||||||
if self.report_type != db_value.report_type:
|
if self.report_type != db_value.report_type:
|
||||||
frappe.db.sql(
|
frappe.db.sql(
|
||||||
@@ -115,32 +110,14 @@ class Account(NestedSet):
|
|||||||
"Balance Sheet" if self.root_type in ("Asset", "Liability", "Equity") else "Profit and Loss"
|
"Balance Sheet" if self.root_type in ("Asset", "Liability", "Equity") else "Profit and Loss"
|
||||||
)
|
)
|
||||||
|
|
||||||
def validate_receivable_payable_account_type(self):
|
|
||||||
doc_before_save = self.get_doc_before_save()
|
|
||||||
receivable_payable_types = ["Receivable", "Payable"]
|
|
||||||
if (
|
|
||||||
doc_before_save
|
|
||||||
and doc_before_save.account_type in receivable_payable_types
|
|
||||||
and doc_before_save.account_type != self.account_type
|
|
||||||
):
|
|
||||||
# check for ledger entries
|
|
||||||
if frappe.db.get_all("GL Entry", filters={"account": self.name, "is_cancelled": 0}, limit=1):
|
|
||||||
msg = _(
|
|
||||||
"There are ledger entries against this account. Changing {0} to non-{1} in live system will cause incorrect output in 'Accounts {2}' report"
|
|
||||||
).format(
|
|
||||||
frappe.bold("Account Type"), doc_before_save.account_type, doc_before_save.account_type
|
|
||||||
)
|
|
||||||
frappe.msgprint(msg)
|
|
||||||
self.add_comment("Comment", msg)
|
|
||||||
|
|
||||||
def validate_root_details(self):
|
def validate_root_details(self):
|
||||||
# does not exists parent
|
doc_before_save = self.get_doc_before_save()
|
||||||
if frappe.db.exists("Account", self.name):
|
|
||||||
if not frappe.db.get_value("Account", self.name, "parent_account"):
|
if doc_before_save and not doc_before_save.parent_account:
|
||||||
throw(_("Root cannot be edited."), RootNotEditable)
|
throw(_("Root cannot be edited."), RootNotEditable)
|
||||||
|
|
||||||
if not self.parent_account and not self.is_group:
|
if not self.parent_account and not self.is_group:
|
||||||
frappe.throw(_("The root account {0} must be a group").format(frappe.bold(self.name)))
|
throw(_("The root account {0} must be a group").format(frappe.bold(self.name)))
|
||||||
|
|
||||||
def validate_root_company_and_sync_account_to_children(self):
|
def validate_root_company_and_sync_account_to_children(self):
|
||||||
# ignore validation while creating new compnay or while syncing to child companies
|
# ignore validation while creating new compnay or while syncing to child companies
|
||||||
@@ -150,7 +127,9 @@ class Account(NestedSet):
|
|||||||
return
|
return
|
||||||
ancestors = get_root_company(self.company)
|
ancestors = get_root_company(self.company)
|
||||||
if ancestors:
|
if ancestors:
|
||||||
if frappe.get_value("Company", self.company, "allow_account_creation_against_child_company"):
|
if frappe.get_cached_value(
|
||||||
|
"Company", self.company, "allow_account_creation_against_child_company"
|
||||||
|
):
|
||||||
return
|
return
|
||||||
if not frappe.db.get_value(
|
if not frappe.db.get_value(
|
||||||
"Account", {"account_name": self.account_name, "company": ancestors[0]}, "name"
|
"Account", {"account_name": self.account_name, "company": ancestors[0]}, "name"
|
||||||
@@ -161,7 +140,7 @@ class Account(NestedSet):
|
|||||||
if not descendants:
|
if not descendants:
|
||||||
return
|
return
|
||||||
parent_acc_name_map = {}
|
parent_acc_name_map = {}
|
||||||
parent_acc_name, parent_acc_number = frappe.db.get_value(
|
parent_acc_name, parent_acc_number = frappe.get_cached_value(
|
||||||
"Account", self.parent_account, ["account_name", "account_number"]
|
"Account", self.parent_account, ["account_name", "account_number"]
|
||||||
)
|
)
|
||||||
filters = {
|
filters = {
|
||||||
@@ -182,11 +161,10 @@ class Account(NestedSet):
|
|||||||
self.create_account_for_child_company(parent_acc_name_map, descendants, parent_acc_name)
|
self.create_account_for_child_company(parent_acc_name_map, descendants, parent_acc_name)
|
||||||
|
|
||||||
def validate_group_or_ledger(self):
|
def validate_group_or_ledger(self):
|
||||||
if self.get("__islocal"):
|
doc_before_save = self.get_doc_before_save()
|
||||||
|
if not doc_before_save or cint(doc_before_save.is_group) == cint(self.is_group):
|
||||||
return
|
return
|
||||||
|
|
||||||
existing_is_group = frappe.db.get_value("Account", self.name, "is_group")
|
|
||||||
if cint(self.is_group) != cint(existing_is_group):
|
|
||||||
if self.check_gle_exists():
|
if self.check_gle_exists():
|
||||||
throw(_("Account with existing transaction cannot be converted to ledger"))
|
throw(_("Account with existing transaction cannot be converted to ledger"))
|
||||||
elif self.is_group:
|
elif self.is_group:
|
||||||
@@ -196,10 +174,12 @@ class Account(NestedSet):
|
|||||||
throw(_("Account with child nodes cannot be set as ledger"))
|
throw(_("Account with child nodes cannot be set as ledger"))
|
||||||
|
|
||||||
def validate_frozen_accounts_modifier(self):
|
def validate_frozen_accounts_modifier(self):
|
||||||
old_value = frappe.db.get_value("Account", self.name, "freeze_account")
|
doc_before_save = self.get_doc_before_save()
|
||||||
if old_value and old_value != self.freeze_account:
|
if not doc_before_save or doc_before_save.freeze_account == self.freeze_account:
|
||||||
frozen_accounts_modifier = frappe.db.get_value(
|
return
|
||||||
"Accounts Settings", None, "frozen_accounts_modifier"
|
|
||||||
|
frozen_accounts_modifier = frappe.get_cached_value(
|
||||||
|
"Accounts Settings", "Accounts Settings", "frozen_accounts_modifier"
|
||||||
)
|
)
|
||||||
if not frozen_accounts_modifier or frozen_accounts_modifier not in frappe.get_roles():
|
if not frozen_accounts_modifier or frozen_accounts_modifier not in frappe.get_roles():
|
||||||
throw(_("You are not authorized to set Frozen value"))
|
throw(_("You are not authorized to set Frozen value"))
|
||||||
@@ -224,11 +204,8 @@ class Account(NestedSet):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def validate_account_currency(self):
|
def validate_account_currency(self):
|
||||||
self.currency_explicitly_specified = True
|
|
||||||
|
|
||||||
if not self.account_currency:
|
if not self.account_currency:
|
||||||
self.account_currency = frappe.get_cached_value("Company", self.company, "default_currency")
|
self.account_currency = frappe.get_cached_value("Company", self.company, "default_currency")
|
||||||
self.currency_explicitly_specified = False
|
|
||||||
|
|
||||||
gl_currency = frappe.db.get_value("GL Entry", {"account": self.name}, "account_currency")
|
gl_currency = frappe.db.get_value("GL Entry", {"account": self.name}, "account_currency")
|
||||||
|
|
||||||
@@ -249,9 +226,9 @@ class Account(NestedSet):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# validate if parent of child company account to be added is a group
|
# validate if parent of child company account to be added is a group
|
||||||
if frappe.db.get_value("Account", self.parent_account, "is_group") and not frappe.db.get_value(
|
if frappe.get_cached_value(
|
||||||
"Account", parent_acc_name_map[company], "is_group"
|
"Account", self.parent_account, "is_group"
|
||||||
):
|
) and not frappe.get_cached_value("Account", parent_acc_name_map[company], "is_group"):
|
||||||
msg = _(
|
msg = _(
|
||||||
"While creating account for Child Company {0}, parent account {1} found as a ledger account."
|
"While creating account for Child Company {0}, parent account {1} found as a ledger account."
|
||||||
).format(company_bold, parent_acc_name_bold)
|
).format(company_bold, parent_acc_name_bold)
|
||||||
@@ -274,10 +251,8 @@ class Account(NestedSet):
|
|||||||
{
|
{
|
||||||
"company": company,
|
"company": company,
|
||||||
# parent account's currency should be passed down to child account's curreny
|
# parent account's currency should be passed down to child account's curreny
|
||||||
# if currency explicitly specified by user, child will inherit. else, default currency will be used.
|
# if it is None, it picks it up from default company currency, which might be unintended
|
||||||
"account_currency": self.account_currency
|
"account_currency": erpnext.get_company_currency(company),
|
||||||
if self.currency_explicitly_specified
|
|
||||||
else erpnext.get_company_currency(company),
|
|
||||||
"parent_account": parent_acc_name_map[company],
|
"parent_account": parent_acc_name_map[company],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -405,29 +380,21 @@ def validate_account_number(name, account_number, company):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def update_account_number(name, account_name, account_number=None, from_descendant=False):
|
def update_account_number(name, account_name, account_number=None, from_descendant=False):
|
||||||
account = frappe.db.get_value("Account", name, "company", as_dict=True)
|
account = frappe.get_cached_doc("Account", name)
|
||||||
if not account:
|
if not account:
|
||||||
return
|
return
|
||||||
|
|
||||||
old_acc_name, old_acc_number = frappe.db.get_value(
|
old_acc_name, old_acc_number = account.account_name, account.account_number
|
||||||
"Account", name, ["account_name", "account_number"]
|
|
||||||
)
|
|
||||||
|
|
||||||
# check if account exists in parent company
|
# check if account exists in parent company
|
||||||
ancestors = get_ancestors_of("Company", account.company)
|
ancestors = get_ancestors_of("Company", account.company)
|
||||||
allow_independent_account_creation = frappe.get_value(
|
allow_independent_account_creation = frappe.get_cached_value(
|
||||||
"Company", account.company, "allow_account_creation_against_child_company"
|
"Company", account.company, "allow_account_creation_against_child_company"
|
||||||
)
|
)
|
||||||
|
|
||||||
if ancestors and not allow_independent_account_creation:
|
if ancestors and not allow_independent_account_creation:
|
||||||
for ancestor in ancestors:
|
for ancestor in ancestors:
|
||||||
old_name = frappe.db.get_value(
|
if frappe.db.get_value("Account", {"account_name": old_acc_name, "company": ancestor}, "name"):
|
||||||
"Account",
|
|
||||||
{"account_number": old_acc_number, "account_name": old_acc_name, "company": ancestor},
|
|
||||||
"name",
|
|
||||||
)
|
|
||||||
|
|
||||||
if old_name:
|
|
||||||
# same account in parent company exists
|
# same account in parent company exists
|
||||||
allow_child_account_creation = _("Allow Account Creation Against Child Company")
|
allow_child_account_creation = _("Allow Account Creation Against Child Company")
|
||||||
|
|
||||||
@@ -467,34 +434,25 @@ def update_account_number(name, account_name, account_number=None, from_descenda
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def merge_account(old, new):
|
def merge_account(old, new, is_group, root_type, company):
|
||||||
# Validate properties before merging
|
# Validate properties before merging
|
||||||
new_account = frappe.get_cached_doc("Account", new)
|
new_account = frappe.get_cached_doc("Account", new)
|
||||||
old_account = frappe.get_cached_doc("Account", old)
|
|
||||||
|
|
||||||
if not new_account:
|
if not new_account:
|
||||||
throw(_("Account {0} does not exist").format(new))
|
throw(_("Account {0} does not exist").format(new))
|
||||||
|
|
||||||
if (
|
if (new_account.is_group, new_account.root_type, new_account.company) != (
|
||||||
cint(new_account.is_group),
|
cint(is_group),
|
||||||
new_account.root_type,
|
root_type,
|
||||||
new_account.company,
|
company,
|
||||||
cstr(new_account.account_currency),
|
|
||||||
) != (
|
|
||||||
cint(old_account.is_group),
|
|
||||||
old_account.root_type,
|
|
||||||
old_account.company,
|
|
||||||
cstr(old_account.account_currency),
|
|
||||||
):
|
):
|
||||||
throw(
|
throw(
|
||||||
msg=_(
|
_(
|
||||||
"""Merging is only possible if following properties are same in both records. Is Group, Root Type, Company and Account Currency"""
|
"""Merging is only possible if following properties are same in both records. Is Group, Root Type, Company"""
|
||||||
),
|
)
|
||||||
title=("Invalid Accounts"),
|
|
||||||
exc=InvalidAccountMergeError,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if old_account.is_group and new_account.parent_account == old:
|
if is_group and new_account.parent_account == old:
|
||||||
new_account.db_set("parent_account", frappe.get_cached_value("Account", old, "parent_account"))
|
new_account.db_set("parent_account", frappe.get_cached_value("Account", old, "parent_account"))
|
||||||
|
|
||||||
frappe.rename_doc("Account", old, new, merge=1, force=1)
|
frappe.rename_doc("Account", old, new, merge=1, force=1)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
frappe.provide("frappe.treeview_settings");
|
frappe.provide("frappe.treeview_settings")
|
||||||
|
|
||||||
frappe.treeview_settings["Account"] = {
|
frappe.treeview_settings["Account"] = {
|
||||||
breadcrumb: "Accounts",
|
breadcrumb: "Accounts",
|
||||||
@@ -7,12 +7,12 @@ frappe.treeview_settings["Account"] = {
|
|||||||
filters: [
|
filters: [
|
||||||
{
|
{
|
||||||
fieldname: "company",
|
fieldname: "company",
|
||||||
fieldtype: "Select",
|
fieldtype:"Select",
|
||||||
options: erpnext.utils.get_tree_options("company"),
|
options: erpnext.utils.get_tree_options("company"),
|
||||||
label: __("Company"),
|
label: __("Company"),
|
||||||
default: erpnext.utils.get_tree_default("company"),
|
default: erpnext.utils.get_tree_default("company"),
|
||||||
on_change: function () {
|
on_change: function() {
|
||||||
var me = frappe.treeview_settings["Account"].treeview;
|
var me = frappe.treeview_settings['Account'].treeview;
|
||||||
var company = me.page.fields_dict.company.get_value();
|
var company = me.page.fields_dict.company.get_value();
|
||||||
if (!company) {
|
if (!company) {
|
||||||
frappe.throw(__("Please set a Company"));
|
frappe.throw(__("Please set a Company"));
|
||||||
@@ -22,36 +22,30 @@ frappe.treeview_settings["Account"] = {
|
|||||||
args: {
|
args: {
|
||||||
company: company,
|
company: company,
|
||||||
},
|
},
|
||||||
callback: function (r) {
|
callback: function(r) {
|
||||||
if (r.message) {
|
if(r.message) {
|
||||||
let root_company = r.message.length ? r.message[0] : "";
|
let root_company = r.message.length ? r.message[0] : "";
|
||||||
me.page.fields_dict.root_company.set_value(root_company);
|
me.page.fields_dict.root_company.set_value(root_company);
|
||||||
|
|
||||||
frappe.db.get_value(
|
frappe.db.get_value("Company", {"name": company}, "allow_account_creation_against_child_company", (r) => {
|
||||||
"Company",
|
frappe.flags.ignore_root_company_validation = r.allow_account_creation_against_child_company;
|
||||||
{ name: company },
|
|
||||||
"allow_account_creation_against_child_company",
|
|
||||||
(r) => {
|
|
||||||
frappe.flags.ignore_root_company_validation =
|
|
||||||
r.allow_account_creation_against_child_company;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: "root_company",
|
fieldname: "root_company",
|
||||||
fieldtype: "Data",
|
fieldtype:"Data",
|
||||||
label: __("Root Company"),
|
label: __("Root Company"),
|
||||||
hidden: true,
|
hidden: true,
|
||||||
disable_onchange: true,
|
disable_onchange: true
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
root_label: "Accounts",
|
root_label: "Accounts",
|
||||||
get_tree_nodes: "erpnext.accounts.utils.get_children",
|
get_tree_nodes: 'erpnext.accounts.utils.get_children',
|
||||||
on_get_node: function (nodes, deep = false) {
|
on_get_node: function(nodes, deep=false) {
|
||||||
if (frappe.boot.user.can_read.indexOf("GL Entry") == -1) return;
|
if (frappe.boot.user.can_read.indexOf("GL Entry") == -1) return;
|
||||||
|
|
||||||
let accounts = [];
|
let accounts = [];
|
||||||
@@ -62,232 +56,147 @@ frappe.treeview_settings["Account"] = {
|
|||||||
accounts = nodes;
|
accounts = nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
frappe.db.get_single_value("Accounts Settings", "show_balance_in_coa").then((value) => {
|
|
||||||
if (value) {
|
|
||||||
const get_balances = frappe.call({
|
const get_balances = frappe.call({
|
||||||
method: "erpnext.accounts.utils.get_account_balances",
|
method: 'erpnext.accounts.utils.get_account_balances',
|
||||||
args: {
|
args: {
|
||||||
accounts: accounts,
|
accounts: accounts,
|
||||||
company: cur_tree.args.company,
|
company: cur_tree.args.company
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
get_balances.then((r) => {
|
get_balances.then(r => {
|
||||||
if (!r.message || r.message.length == 0) return;
|
if (!r.message || r.message.length == 0) return;
|
||||||
|
|
||||||
for (let account of r.message) {
|
for (let account of r.message) {
|
||||||
|
|
||||||
const node = cur_tree.nodes && cur_tree.nodes[account.value];
|
const node = cur_tree.nodes && cur_tree.nodes[account.value];
|
||||||
if (!node || node.is_root) continue;
|
if (!node || node.is_root) continue;
|
||||||
|
|
||||||
// show Dr if positive since balance is calculated as debit - credit else show Cr
|
// show Dr if positive since balance is calculated as debit - credit else show Cr
|
||||||
const balance = account.balance_in_account_currency || account.balance;
|
const balance = account.balance_in_account_currency || account.balance;
|
||||||
const dr_or_cr = balance > 0 ? "Dr" : "Cr";
|
const dr_or_cr = balance > 0 ? "Dr": "Cr";
|
||||||
const format = (value, currency) => format_currency(Math.abs(value), currency);
|
const format = (value, currency) => format_currency(Math.abs(value), currency);
|
||||||
|
|
||||||
if (account.balance !== undefined) {
|
if (account.balance!==undefined) {
|
||||||
node.parent && node.parent.find(".balance-area").remove();
|
node.parent && node.parent.find('.balance-area').remove();
|
||||||
$(
|
$('<span class="balance-area pull-right">'
|
||||||
'<span class="balance-area pull-right">' +
|
+ (account.balance_in_account_currency ?
|
||||||
(account.balance_in_account_currency
|
(format(account.balance_in_account_currency, account.account_currency) + " / ") : "")
|
||||||
? format(
|
+ format(account.balance, account.company_currency)
|
||||||
account.balance_in_account_currency,
|
+ " " + dr_or_cr
|
||||||
account.account_currency
|
+ '</span>').insertBefore(node.$ul);
|
||||||
) + " / "
|
|
||||||
: "") +
|
|
||||||
format(account.balance, account.company_currency) +
|
|
||||||
" " +
|
|
||||||
dr_or_cr +
|
|
||||||
"</span>"
|
|
||||||
).insertBefore(node.$ul);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
add_tree_node: "erpnext.accounts.utils.add_ac",
|
add_tree_node: 'erpnext.accounts.utils.add_ac',
|
||||||
menu_items: [
|
menu_items:[
|
||||||
{
|
{
|
||||||
label: __("New Company"),
|
label: __('New Company'),
|
||||||
action: function () {
|
action: function() { frappe.new_doc("Company", true) },
|
||||||
frappe.new_doc("Company", true);
|
condition: 'frappe.boot.user.can_create.indexOf("Company") !== -1'
|
||||||
},
|
}
|
||||||
condition: 'frappe.boot.user.can_create.indexOf("Company") !== -1',
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{fieldtype:'Data', fieldname:'account_name', label:__('New Account Name'), reqd:true,
|
||||||
fieldtype: "Data",
|
description: __("Name of new Account. Note: Please don't create accounts for Customers and Suppliers")},
|
||||||
fieldname: "account_name",
|
{fieldtype:'Data', fieldname:'account_number', label:__('Account Number'),
|
||||||
label: __("New Account Name"),
|
description: __("Number of new Account, it will be included in the account name as a prefix")},
|
||||||
reqd: true,
|
{fieldtype:'Check', fieldname:'is_group', label:__('Is Group'),
|
||||||
description: __(
|
description: __('Further accounts can be made under Groups, but entries can be made against non-Groups')},
|
||||||
"Name of new Account. Note: Please don't create accounts for Customers and Suppliers"
|
{fieldtype:'Select', fieldname:'root_type', label:__('Root Type'),
|
||||||
),
|
options: ['Asset', 'Liability', 'Equity', 'Income', 'Expense'].join('\n'),
|
||||||
},
|
depends_on: 'eval:doc.is_group && !doc.parent_account'},
|
||||||
{
|
{fieldtype:'Select', fieldname:'account_type', label:__('Account Type'),
|
||||||
fieldtype: "Data",
|
options: frappe.get_meta("Account").fields.filter(d => d.fieldname=='account_type')[0].options,
|
||||||
fieldname: "account_number",
|
description: __("Optional. This setting will be used to filter in various transactions.")
|
||||||
label: __("Account Number"),
|
|
||||||
description: __("Number of new Account, it will be included in the account name as a prefix"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldtype: "Check",
|
|
||||||
fieldname: "is_group",
|
|
||||||
label: __("Is Group"),
|
|
||||||
description: __(
|
|
||||||
"Further accounts can be made under Groups, but entries can be made against non-Groups"
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldtype: "Select",
|
|
||||||
fieldname: "root_type",
|
|
||||||
label: __("Root Type"),
|
|
||||||
options: ["Asset", "Liability", "Equity", "Income", "Expense"].join("\n"),
|
|
||||||
depends_on: "eval:doc.is_group && !doc.parent_account",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldtype: "Select",
|
|
||||||
fieldname: "account_type",
|
|
||||||
label: __("Account Type"),
|
|
||||||
options: frappe.get_meta("Account").fields.filter((d) => d.fieldname == "account_type")[0]
|
|
||||||
.options,
|
|
||||||
description: __("Optional. This setting will be used to filter in various transactions."),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldtype: "Float",
|
|
||||||
fieldname: "tax_rate",
|
|
||||||
label: __("Tax Rate"),
|
|
||||||
depends_on: 'eval:doc.is_group==0&&doc.account_type=="Tax"',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldtype: "Link",
|
|
||||||
fieldname: "account_currency",
|
|
||||||
label: __("Currency"),
|
|
||||||
options: "Currency",
|
|
||||||
description: __("Optional. Sets company's default currency, if not specified."),
|
|
||||||
},
|
},
|
||||||
|
{fieldtype:'Float', fieldname:'tax_rate', label:__('Tax Rate'),
|
||||||
|
depends_on: 'eval:doc.is_group==0&&doc.account_type=="Tax"'},
|
||||||
|
{fieldtype:'Link', fieldname:'account_currency', label:__('Currency'), options:"Currency",
|
||||||
|
description: __("Optional. Sets company's default currency, if not specified.")}
|
||||||
],
|
],
|
||||||
ignore_fields: ["parent_account"],
|
ignore_fields:["parent_account"],
|
||||||
onload: function (treeview) {
|
onload: function(treeview) {
|
||||||
frappe.treeview_settings["Account"].treeview = {};
|
frappe.treeview_settings['Account'].treeview = {};
|
||||||
$.extend(frappe.treeview_settings["Account"].treeview, treeview);
|
$.extend(frappe.treeview_settings['Account'].treeview, treeview);
|
||||||
function get_company() {
|
function get_company() {
|
||||||
return treeview.page.fields_dict.company.get_value();
|
return treeview.page.fields_dict.company.get_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
// tools
|
// tools
|
||||||
treeview.page.add_inner_button(
|
treeview.page.add_inner_button(__("Chart of Cost Centers"), function() {
|
||||||
__("Chart of Cost Centers"),
|
frappe.set_route('Tree', 'Cost Center', {company: get_company()});
|
||||||
function () {
|
}, __('View'));
|
||||||
frappe.set_route("Tree", "Cost Center", { company: get_company() });
|
|
||||||
},
|
|
||||||
__("View")
|
|
||||||
);
|
|
||||||
|
|
||||||
treeview.page.add_inner_button(
|
treeview.page.add_inner_button(__("Opening Invoice Creation Tool"), function() {
|
||||||
__("Opening Invoice Creation Tool"),
|
frappe.set_route('Form', 'Opening Invoice Creation Tool', {company: get_company()});
|
||||||
function () {
|
}, __('View'));
|
||||||
frappe.set_route("Form", "Opening Invoice Creation Tool", { company: get_company() });
|
|
||||||
},
|
|
||||||
__("View")
|
|
||||||
);
|
|
||||||
|
|
||||||
treeview.page.add_inner_button(
|
treeview.page.add_inner_button(__("Period Closing Voucher"), function() {
|
||||||
__("Period Closing Voucher"),
|
frappe.set_route('List', 'Period Closing Voucher', {company: get_company()});
|
||||||
function () {
|
}, __('View'));
|
||||||
frappe.set_route("List", "Period Closing Voucher", { company: get_company() });
|
|
||||||
},
|
|
||||||
__("View")
|
|
||||||
);
|
|
||||||
|
|
||||||
treeview.page.add_inner_button(
|
|
||||||
__("Journal Entry"),
|
treeview.page.add_inner_button(__("Journal Entry"), function() {
|
||||||
function () {
|
frappe.new_doc('Journal Entry', {company: get_company()});
|
||||||
frappe.new_doc("Journal Entry", { company: get_company() });
|
}, __('Create'));
|
||||||
},
|
treeview.page.add_inner_button(__("Company"), function() {
|
||||||
__("Create")
|
frappe.new_doc('Company');
|
||||||
);
|
}, __('Create'));
|
||||||
treeview.page.add_inner_button(
|
|
||||||
__("Company"),
|
|
||||||
function () {
|
|
||||||
frappe.new_doc("Company");
|
|
||||||
},
|
|
||||||
__("Create")
|
|
||||||
);
|
|
||||||
|
|
||||||
// financial statements
|
// financial statements
|
||||||
for (let report of [
|
for (let report of ['Trial Balance', 'General Ledger', 'Balance Sheet',
|
||||||
"Trial Balance",
|
'Profit and Loss Statement', 'Cash Flow Statement', 'Accounts Payable', 'Accounts Receivable']) {
|
||||||
"General Ledger",
|
treeview.page.add_inner_button(__(report), function() {
|
||||||
"Balance Sheet",
|
frappe.set_route('query-report', report, {company: get_company()});
|
||||||
"Profit and Loss Statement",
|
}, __('Financial Statements'));
|
||||||
"Cash Flow Statement",
|
|
||||||
"Accounts Payable",
|
|
||||||
"Accounts Receivable",
|
|
||||||
]) {
|
|
||||||
treeview.page.add_inner_button(
|
|
||||||
__(report),
|
|
||||||
function () {
|
|
||||||
frappe.set_route("query-report", report, { company: get_company() });
|
|
||||||
},
|
|
||||||
__("Financial Statements")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
post_render: function (treeview) {
|
post_render: function(treeview) {
|
||||||
frappe.treeview_settings["Account"].treeview["tree"] = treeview.tree;
|
frappe.treeview_settings['Account'].treeview["tree"] = treeview.tree;
|
||||||
treeview.page.set_primary_action(
|
treeview.page.set_primary_action(__("New"), function() {
|
||||||
__("New"),
|
|
||||||
function () {
|
|
||||||
let root_company = treeview.page.fields_dict.root_company.get_value();
|
let root_company = treeview.page.fields_dict.root_company.get_value();
|
||||||
|
|
||||||
if (root_company) {
|
if(root_company) {
|
||||||
frappe.throw(__("Please add the account to root level Company - {0}"), [root_company]);
|
frappe.throw(__("Please add the account to root level Company - {0}"), [root_company]);
|
||||||
} else {
|
} else {
|
||||||
treeview.new_node();
|
treeview.new_node();
|
||||||
}
|
}
|
||||||
},
|
}, "add");
|
||||||
"add"
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
toolbar: [
|
toolbar: [
|
||||||
{
|
{
|
||||||
label: __("Add Child"),
|
label:__("Add Child"),
|
||||||
condition: function (node) {
|
condition: function(node) {
|
||||||
return (
|
return frappe.boot.user.can_create.indexOf("Account") !== -1
|
||||||
frappe.boot.user.can_create.indexOf("Account") !== -1 &&
|
&& (!frappe.treeview_settings['Account'].treeview.page.fields_dict.root_company.get_value()
|
||||||
(!frappe.treeview_settings[
|
|| frappe.flags.ignore_root_company_validation)
|
||||||
"Account"
|
&& node.expandable && !node.hide_add;
|
||||||
].treeview.page.fields_dict.root_company.get_value() ||
|
|
||||||
frappe.flags.ignore_root_company_validation) &&
|
|
||||||
node.expandable &&
|
|
||||||
!node.hide_add
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
click: function () {
|
click: function() {
|
||||||
var me = frappe.views.trees["Account"];
|
var me = frappe.views.trees['Account'];
|
||||||
me.new_node();
|
me.new_node();
|
||||||
},
|
},
|
||||||
btnClass: "hidden-xs",
|
btnClass: "hidden-xs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
condition: function (node) {
|
condition: function(node) {
|
||||||
return !node.root && frappe.boot.user.can_read.indexOf("GL Entry") !== -1;
|
return !node.root && frappe.boot.user.can_read.indexOf("GL Entry") !== -1
|
||||||
},
|
},
|
||||||
label: __("View Ledger"),
|
label: __("View Ledger"),
|
||||||
click: function (node, btn) {
|
click: function(node, btn) {
|
||||||
frappe.route_options = {
|
frappe.route_options = {
|
||||||
account: node.label,
|
"account": node.label,
|
||||||
from_date: frappe.sys_defaults.year_start_date,
|
"from_date": frappe.sys_defaults.year_start_date,
|
||||||
to_date: frappe.sys_defaults.year_end_date,
|
"to_date": frappe.sys_defaults.year_end_date,
|
||||||
company:
|
"company": frappe.treeview_settings['Account'].treeview.page.fields_dict.company.get_value()
|
||||||
frappe.treeview_settings["Account"].treeview.page.fields_dict.company.get_value(),
|
|
||||||
};
|
};
|
||||||
frappe.set_route("query-report", "General Ledger");
|
frappe.set_route("query-report", "General Ledger");
|
||||||
},
|
},
|
||||||
btnClass: "hidden-xs",
|
btnClass: "hidden-xs"
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
extend_toolbar: true,
|
extend_toolbar: true
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ def create_charts(
|
|||||||
"root_type",
|
"root_type",
|
||||||
"is_group",
|
"is_group",
|
||||||
"tax_rate",
|
"tax_rate",
|
||||||
"account_currency",
|
|
||||||
]:
|
]:
|
||||||
|
|
||||||
account_number = cstr(child.get("account_number")).strip()
|
account_number = cstr(child.get("account_number")).strip()
|
||||||
@@ -54,7 +53,7 @@ def create_charts(
|
|||||||
"account_number": account_number,
|
"account_number": account_number,
|
||||||
"account_type": child.get("account_type"),
|
"account_type": child.get("account_type"),
|
||||||
"account_currency": child.get("account_currency")
|
"account_currency": child.get("account_currency")
|
||||||
or frappe.db.get_value("Company", company, "default_currency"),
|
or frappe.get_cached_value("Company", company, "default_currency"),
|
||||||
"tax_rate": child.get("tax_rate"),
|
"tax_rate": child.get("tax_rate"),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -96,17 +95,7 @@ def identify_is_group(child):
|
|||||||
is_group = child.get("is_group")
|
is_group = child.get("is_group")
|
||||||
elif len(
|
elif len(
|
||||||
set(child.keys())
|
set(child.keys())
|
||||||
- set(
|
- set(["account_name", "account_type", "root_type", "is_group", "tax_rate", "account_number"])
|
||||||
[
|
|
||||||
"account_name",
|
|
||||||
"account_type",
|
|
||||||
"root_type",
|
|
||||||
"is_group",
|
|
||||||
"tax_rate",
|
|
||||||
"account_number",
|
|
||||||
"account_currency",
|
|
||||||
]
|
|
||||||
)
|
|
||||||
):
|
):
|
||||||
is_group = 1
|
is_group = 1
|
||||||
else:
|
else:
|
||||||
@@ -159,7 +148,7 @@ def get_charts_for_country(country, with_standard=False):
|
|||||||
) or frappe.local.flags.allow_unverified_charts:
|
) or frappe.local.flags.allow_unverified_charts:
|
||||||
charts.append(content["name"])
|
charts.append(content["name"])
|
||||||
|
|
||||||
country_code = frappe.db.get_value("Country", country, "code")
|
country_code = frappe.get_cached_value("Country", country, "code")
|
||||||
if country_code:
|
if country_code:
|
||||||
folders = ("verified",)
|
folders = ("verified",)
|
||||||
if frappe.local.flags.allow_unverified_charts:
|
if frappe.local.flags.allow_unverified_charts:
|
||||||
@@ -196,7 +185,6 @@ def get_account_tree_from_existing_company(existing_company):
|
|||||||
"root_type",
|
"root_type",
|
||||||
"tax_rate",
|
"tax_rate",
|
||||||
"account_number",
|
"account_number",
|
||||||
"account_currency",
|
|
||||||
],
|
],
|
||||||
order_by="lft, rgt",
|
order_by="lft, rgt",
|
||||||
)
|
)
|
||||||
@@ -279,7 +267,6 @@ def build_tree_from_json(chart_template, chart_data=None, from_coa_importer=Fals
|
|||||||
"root_type",
|
"root_type",
|
||||||
"is_group",
|
"is_group",
|
||||||
"tax_rate",
|
"tax_rate",
|
||||||
"account_currency",
|
|
||||||
]:
|
]:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|||||||
@@ -2,397 +2,438 @@
|
|||||||
"country_code": "at",
|
"country_code": "at",
|
||||||
"name": "Austria - Chart of Accounts",
|
"name": "Austria - Chart of Accounts",
|
||||||
"tree": {
|
"tree": {
|
||||||
"Summe Abschreibungen und Aufwendungen": {
|
"Klasse 0 Aktiva: Anlageverm\u00f6gen": {
|
||||||
"7010 bis 7080 Abschreibungen auf das Anlageverm\u00f6gen (ausgenommen Finanzanlagen)": {},
|
"0100 Konzessionen ": {"account_type": "Fixed Asset"},
|
||||||
"7100 bis 7190 Sonstige Steuern": {
|
"0110 Patentrechte und Lizenzen ": {"account_type": "Fixed Asset"},
|
||||||
"account_type": "Tax"
|
"0120 Datenverarbeitungsprogramme ": {"account_type": "Fixed Asset"},
|
||||||
|
"0130 Marken, Warenzeichen und Musterschutzrechte, sonstige Urheberrechte ": {"account_type": "Fixed Asset"},
|
||||||
|
"0140 Pacht- und Mietrechte ": {"account_type": "Fixed Asset"},
|
||||||
|
"0150 Bezugs- und ähnliche Rechte ": {"account_type": "Fixed Asset"},
|
||||||
|
"0160 Geschäfts-/Firmenwert ": {"account_type": "Fixed Asset"},
|
||||||
|
"0170 Umgründungsmehrwert ": {"account_type": "Fixed Asset"},
|
||||||
|
"0180 Geleistete Anzahlungen auf immaterielle Vermögensgegenstände": {"account_type": "Fixed Asset"},
|
||||||
|
"0190 Kumulierte Abschreibungen zu immateriellen Vermögensgegenständen ": {"account_type": "Fixed Asset"},
|
||||||
|
"0200 Unbebaute Grundstücke, soweit nicht landwirtschaftlich genutzt ": {"account_type": "Fixed Asset"},
|
||||||
|
"0210 Bebaute Grundstücke (Grundwert) ": {"account_type": "Fixed Asset"},
|
||||||
|
"0220 Landwirtschaftlich genutzte Grundstücke ": {"account_type": "Fixed Asset"},
|
||||||
|
"0230 Grundstücksgleiche Rechte ": {"account_type": "Fixed Asset"},
|
||||||
|
"0300 Betriebs- und Geschäftsgebäude auf eigenem Grund ": {"account_type": "Fixed Asset"},
|
||||||
|
"0310 Wohn- und Sozialgebäude auf eigenem Grund ": {"account_type": "Fixed Asset"},
|
||||||
|
"0320 Betriebs- und Geschäftsgebäude auf fremdem Grund ": {"account_type": "Fixed Asset"},
|
||||||
|
"0330 Wohn- und Sozialgebäude auf fremdem Grund ": {"account_type": "Fixed Asset"},
|
||||||
|
"0340 Grundstückseinrichtungen auf eigenem Grund ": {"account_type": "Fixed Asset"},
|
||||||
|
"0350 Grundstückseinrichtungen auf fremdem Grund ": {"account_type": "Fixed Asset"},
|
||||||
|
"0360 Bauliche Investitionen in fremden (gepachteten) Betriebs- und Geschäftsgebäuden": {"account_type": "Fixed Asset"},
|
||||||
|
"0370 Bauliche Investitionen in fremden (gepachteten) Wohn- und Sozialgebäuden": {"account_type": "Fixed Asset"},
|
||||||
|
"0390 Kumulierte Abschreibungen zu Grundstücken ": {"account_type": "Fixed Asset"},
|
||||||
|
"0400 Maschinen und Geräte ": {"account_type": "Fixed Asset"},
|
||||||
|
"0500 Maschinenwerkzeuge ": {"account_type": "Fixed Asset"},
|
||||||
|
"0510 Allgemeine Werkzeuge und Handwerkzeuge ": {"account_type": "Fixed Asset"},
|
||||||
|
"0520 Prototypen, Formen, Modelle ": {"account_type": "Fixed Asset"},
|
||||||
|
"0530 Andere Erzeugungshilfsmittel (auch Softwarewerkzeuge)": {"account_type": "Fixed Asset"},
|
||||||
|
"0540 Hebezeuge und Montageanlagen ": {"account_type": "Fixed Asset"},
|
||||||
|
"0550 Geringwertige Vermögensgegenstände, soweit im Erzeugungsprozess ": {"account_type": "Fixed Asset"},
|
||||||
|
"0560 Festwerte technische Anlagen und Maschinen ": {"account_type": "Fixed Asset"},
|
||||||
|
"0590 Kumulierte Abschreibungen zu technischen Anlagen und Maschinen ": {"account_type": "Fixed Asset"},
|
||||||
|
"0600 Betriebs- und Geschäftsausstattung, soweit nicht gesondert angeführt ": {"account_type": "Fixed Asset"},
|
||||||
|
"0610 Andere Anlagen, soweit nicht gesondert angeführt ": {"account_type": "Fixed Asset"},
|
||||||
|
"0620 Büromaschinen, EDV-Anlagen ": {"account_type": "Fixed Asset"},
|
||||||
|
"0630 PKW und Kombis ": {"account_type": "Fixed Asset"},
|
||||||
|
"0640 LKW ": {"account_type": "Fixed Asset"},
|
||||||
|
"0650 Andere Beförderungsmittel ": {"account_type": "Fixed Asset"},
|
||||||
|
"0660 Gebinde ": {"account_type": "Fixed Asset"},
|
||||||
|
"0670 Geringwertige Vermögensgegenstände, soweit nicht im Erzeugungssprozess verwendet": {"account_type": "Fixed Asset"},
|
||||||
|
"0680 Festwerte außer technische Anlagen und Maschinen ": {"account_type": "Fixed Asset"},
|
||||||
|
"0690 Kumulierte Abschreibungen zu anderen Anlagen, Betriebs- und Geschäftsausstattung": {"account_type": "Fixed Asset"},
|
||||||
|
"0700 Geleistete Anzahlungen auf Sachanlagen ": {"account_type": "Fixed Asset"},
|
||||||
|
"0710 Anlagen in Bau ": {"account_type": "Fixed Asset"},
|
||||||
|
"0790 Kumulierte Abschreibungen zu geleisteten Anzahlungen auf Sachanlagen ": {"account_type": "Fixed Asset"},
|
||||||
|
"0800 Anteile an verbundenen Unternehmen ": {"account_type": "Fixed Asset"},
|
||||||
|
"0810 Beteiligungen an Gemeinschaftsunternehmen ": {"account_type": "Fixed Asset"},
|
||||||
|
"0820 Beteiligungen an angeschlossenen (assoziierten) Unternehmen ": {"account_type": "Fixed Asset"},
|
||||||
|
"0830 Eigene Anteile, Anteile an herrschenden oder mit Mehrheit beteiligten ": {"account_type": "Fixed Asset"},
|
||||||
|
"0840 Sonstige Beteiligungen ": {"account_type": "Fixed Asset"},
|
||||||
|
"0850 Ausleihungen an verbundene Unternehmen ": {"account_type": "Fixed Asset"},
|
||||||
|
"0860 Ausleihungen an Unternehmen mit Beteiligungsverhältnis": {"account_type": "Fixed Asset"},
|
||||||
|
"0870 Ausleihungen an Gesellschafter ": {"account_type": "Fixed Asset"},
|
||||||
|
"0880 Sonstige Ausleihungen ": {"account_type": "Fixed Asset"},
|
||||||
|
"0890 Anteile an Kapitalgesellschaften ohne Beteiligungscharakter ": {"account_type": "Fixed Asset"},
|
||||||
|
"0900 Anteile an Personengesellschaften ohne Beteiligungscharakter ": {"account_type": "Fixed Asset"},
|
||||||
|
"0910 Genossenschaftsanteile ohne Beteiligungscharakter ": {"account_type": "Fixed Asset"},
|
||||||
|
"0920 Anteile an Investmentfonds ": {"account_type": "Fixed Asset"},
|
||||||
|
"0930 Festverzinsliche Wertpapiere des Anlagevermögens ": {"account_type": "Fixed Asset"},
|
||||||
|
"0980 Geleistete Anzahlungen auf Finanzanlagen ": {"account_type": "Fixed Asset"},
|
||||||
|
"0990 Kumulierte Abschreibungen zu Finanzanlagen ": {"account_type": "Fixed Asset"},
|
||||||
|
"root_type": "Asset"
|
||||||
},
|
},
|
||||||
"7200 bis 7290 Instandhaltung u. Reinigung durh Dritte, Entsorgung, Beleuchtung": {},
|
"Klasse 1 Aktiva: Vorr\u00e4te": {
|
||||||
"7300 bis 7310 Transporte durch Dritte": {},
|
"1000 Bezugsverrechnung": {"account_type": "Stock"},
|
||||||
"7320 bis 7330 Kfz - Aufwand": {},
|
"1100 Rohstoffe": {"account_type": "Stock"},
|
||||||
"7340 bis 7350 Reise- und Fahraufwand": {},
|
"1200 Bezogene Teile": {"account_type": "Stock"},
|
||||||
"7360 bis 7370 Tag- und N\u00e4chtigungsgelder": {},
|
"1300 Hilfsstoffe": {"account_type": "Stock"},
|
||||||
"7380 bis 7390 Nachrichtenaufwand": {},
|
"1350 Betriebsstoffe": {"account_type": "Stock"},
|
||||||
"7400 bis 7430 Miet- und Pachtaufwand": {},
|
"1360 Vorrat Energietraeger": {"account_type": "Stock"},
|
||||||
"7440 bis 7470 Leasingaufwand": {},
|
"1400 Unfertige Erzeugnisse": {"account_type": "Stock"},
|
||||||
"7480 bis 7490 Lizenzaufwand": {},
|
"1500 Fertige Erzeugnisse": {"account_type": "Stock"},
|
||||||
"7500 bis 7530 Aufwand f\u00fcr beigestelltes Personal": {},
|
"1600 Handelswarenvorrat": {"account_type": "Stock Received But Not Billed"},
|
||||||
"7540 bis 7570 Provisionen an Dritte": {},
|
"1700 Noch nicht abrechenbare Leistungen": {"account_type": "Stock"},
|
||||||
"7580 bis 7590 Aufsichtsratsverg\u00fctungen": {},
|
"1900 Wertberichtigungen": {"account_type": "Stock"},
|
||||||
"7610 bis 7620 Druckerzeugnisse und Vervielf\u00e4ltigungen": {},
|
"1800 Geleistete Anzahlungen": {"account_type": "Stock"},
|
||||||
"7650 bis 7680 Werbung und Repr\u00e4sentationen": {},
|
"1900 Wertberichtigungen": {"account_type": "Stock"},
|
||||||
"7700 bis 7740 Versicherungen": {},
|
"root_type": "Asset"
|
||||||
"7750 bis 7760 Beratungs- und Pr\u00fcfungsaufwand": {},
|
|
||||||
"7800 bis 7810 Schadensf\u00e4lle": {},
|
|
||||||
"7840 bis 7880 Verschiedene betriebliche Aufwendungen": {},
|
|
||||||
"7910 bis 7950 Aufwandsstellenrechung der Hersteller": {},
|
|
||||||
"Abschreibungen auf aktivierte Aufwendungen f\u00fcr das Ingangs. u. Erweitern des Betriebes": {},
|
|
||||||
"Abschreibungen vom Umlaufverm\u00f6gen, soweit diese die im Unternehmen \u00fcblichen Abschreibungen \u00fcbersteigen": {},
|
|
||||||
"Aufwandsstellenrechnung": {},
|
|
||||||
"Aus- und Fortbildung": {},
|
|
||||||
"Buchwert abgegangener Anlagen, ausgenommen Finanzanlagen": {},
|
|
||||||
"B\u00fcromaterial und Drucksorten": {},
|
|
||||||
"Fachliteratur und Zeitungen ": {},
|
|
||||||
"Herstellungskosten der zur Erzielung der Umsatzerl\u00f6se erbrachten Leistungen": {},
|
|
||||||
"Mitgliedsbeitr\u00e4ge": {},
|
|
||||||
"Skontoertr\u00e4ge auf sonstige betriebliche Aufwendungen": {},
|
|
||||||
"Sonstige betrieblichen Aufwendungen": {},
|
|
||||||
"Spenden und Trinkgelder": {},
|
|
||||||
"Spesen des Geldverkehrs": {},
|
|
||||||
"Verluste aus dem Abgang vom Anlageverm\u00f6gen, ausgenommen Finanzanlagen": {},
|
|
||||||
"Vertriebskosten": {},
|
|
||||||
"Verwaltungskosten": {},
|
|
||||||
"root_type": "Expense"
|
|
||||||
},
|
},
|
||||||
"Summe Betriebliche Ertr\u00e4ge": {
|
"Klasse 3 Passiva: Verbindlichkeiten": {
|
||||||
"4400 bis 4490 Erl\u00f6sschm\u00e4lerungen": {},
|
"3000 Allgemeine Verbindlichkeiten (Schuld)": {"account_type": "Payable"},
|
||||||
"4500 bis 4570 Ver\u00e4nderungen des Bestandes an fertigen und unfertigen Erzeugn. sowie an noch nicht abrechenbaren Leistungen": {},
|
"3010 R\u00fcckstellungen f\u00fcr Pensionen": {"account_type": "Payable"},
|
||||||
"4580 bis 4590 andere aktivierte Eigenleistungen": {},
|
"3020 Steuerr\u00fcckstellungen": {"account_type": "Tax"},
|
||||||
"4600 bis 4620 Erl\u00f6se aus dem Abgang vom Anlageverm\u00f6gen, ausgen. Finanzanlagen": {},
|
"3041 Sonstige R\u00fcckstellungen": {"account_type": "Payable"},
|
||||||
"4630 bis 4650 Ertr\u00e4ge aus dem Abgang vom Anlageverm\u00f6gen, ausgen. Finanzanlagen": {},
|
"3110 Verbindlichkeiten gegen\u00fcber Bank": {"account_type": "Payable"},
|
||||||
"4660 bis 4670 Ertr\u00e4ge aus der Zuschreibung zum Anlageverm\u00f6gen, ausgen. Finanzanlagen": {},
|
"3150 Verbindlichkeiten Darlehen": {"account_type": "Payable"},
|
||||||
"4700 bis 4790 Ertr\u00e4ge aus der Aufl\u00f6sung von R\u00fcckstellungen": {},
|
"3185 Verbindlichkeiten Kreditkarte": {"account_type": "Payable"},
|
||||||
"4800 bis 4990 \u00dcbrige betriebliche Ertr\u00e4ge": {},
|
"3380 Verbindlichkeiten aus der Annahme gezogener Wechsel u. d. Ausstellungen eigener Wechsel": {
|
||||||
"Erl\u00f6se 0 % Ausfuhrlieferungen/Drittl\u00e4nder": {},
|
|
||||||
"Erl\u00f6se 10 %": {},
|
|
||||||
"Erl\u00f6se 20 %": {},
|
|
||||||
"Erl\u00f6se aus im Inland stpfl. EG Lieferungen 10 % USt": {},
|
|
||||||
"Erl\u00f6se aus im Inland stpfl. EG Lieferungen 20 % USt": {},
|
|
||||||
"Erl\u00f6se i.g. Lieferungen (stfr)": {},
|
|
||||||
"root_type": "Income"
|
|
||||||
},
|
|
||||||
"Summe Eigenkapital R\u00fccklagen Abschlusskonten": {
|
|
||||||
"9000 bis 9180 Gezeichnetes bzw. gewidmetes Kapital": {
|
|
||||||
"account_type": "Equity"
|
|
||||||
},
|
|
||||||
"9200 bis 9290 Kapitalr\u00fccklagen": {
|
|
||||||
"account_type": "Equity"
|
|
||||||
},
|
|
||||||
"9300 bis 9380 Gewinnr\u00fccklagen": {
|
|
||||||
"account_type": "Equity"
|
|
||||||
},
|
|
||||||
"9400 bis 9590 Bewertungsreserven uns sonst. unversteuerte R\u00fccklagen": {
|
|
||||||
"account_type": "Equity"
|
|
||||||
},
|
|
||||||
"9600 bis 9690 Privat und Verrechnungskonten bei Einzelunternehmen und Personengesellschaften": {},
|
|
||||||
"9700 bis 9790 Einlagen stiller Gesellschafter ": {},
|
|
||||||
"9900 bis 9999 Evidenzkonten": {},
|
|
||||||
"Bilanzgewinn (-verlust )": {
|
|
||||||
"account_type": "Equity"
|
|
||||||
},
|
|
||||||
"Er\u00f6ffnungsbilanz": {},
|
|
||||||
"Gewinn- und Verlustrechnung": {},
|
|
||||||
"Schlussbilanz": {},
|
|
||||||
"nicht eingeforderte ausstehende Einlagen": {
|
|
||||||
"account_type": "Equity"
|
|
||||||
},
|
|
||||||
"root_type": "Equity"
|
|
||||||
},
|
|
||||||
"Summe Finanzertr\u00e4ge und Aufwendungen": {
|
|
||||||
"8000 bis 8040 Ertr\u00e4ge aus Beteiligungen": {},
|
|
||||||
"8050 bis 8090 Ertr\u00e4ge aus anderen Wertpapieren und Ausleihungen des Finanzanlageverm\u00f6gens": {},
|
|
||||||
"8100 bis 8130 Sonstige Zinsen und \u00e4hnliche Ertr\u00e4ge": {},
|
|
||||||
"8220 bis 8250 Aufwendungen aus Beteiligungen": {},
|
|
||||||
"8260 bis 8270 Aufwendungen aus sonst. Fiananzanlagen und aus Wertpapieren des Umlaufverm\u00f6gens": {},
|
|
||||||
"8280 bis 8340 Zinsen und \u00e4hnliche Aufwendungem": {},
|
|
||||||
"8400 bis 8440 Au\u00dferordentliche Ertr\u00e4ge": {},
|
|
||||||
"8450 bis 8490 Au\u00dferordentliche Aufwendungen": {},
|
|
||||||
"8500 bis 8590 Steuern vom Einkommen und vom Ertrag": {
|
|
||||||
"account_type": "Tax"
|
|
||||||
},
|
|
||||||
"8600 bis 8690 Aufl\u00f6sung unversteuerten R\u00fccklagen": {},
|
|
||||||
"8700 bis 8740 Aufl\u00f6sung von Kapitalr\u00fccklagen": {},
|
|
||||||
"8750 bis 8790 Aufl\u00f6sung von Gewinnr\u00fccklagen": {},
|
|
||||||
"8800 bis 8890 Zuweisung von unversteuerten R\u00fccklagen": {},
|
|
||||||
"Buchwert abgegangener Beteiligungen": {},
|
|
||||||
"Buchwert abgegangener Wertpapiere des Umlaufverm\u00f6gens": {},
|
|
||||||
"Buchwert abgegangener sonstiger Finanzanlagen": {},
|
|
||||||
"Erl\u00f6se aus dem Abgang von Beteiligungen": {},
|
|
||||||
"Erl\u00f6se aus dem Abgang von Wertpapieren des Umlaufverm\u00f6gens": {},
|
|
||||||
"Erl\u00f6se aus dem Abgang von sonstigen Finanzanlagen": {},
|
|
||||||
"Ertr\u00e4ge aus dem Abgang von und der Zuschreibung zu Finanzanlagen": {},
|
|
||||||
"Ertr\u00e4ge aus dem Abgang von und der Zuschreibung zu Wertpapieren des Umlaufverm\u00f6gens": {},
|
|
||||||
"Gewinabfuhr bzw. Verlust\u00fcberrechnung aus Ergebnisabf\u00fchrungsvertr\u00e4gen": {},
|
|
||||||
"nicht ausgenutzte Lieferantenskonti": {},
|
|
||||||
"root_type": "Income"
|
|
||||||
},
|
|
||||||
"Summe Fremdkapital": {
|
|
||||||
"3020 bis 3030 Steuerr\u00fcckstellungen": {},
|
|
||||||
"3040 bis 3090 Sonstige R\u00fcckstellungen": {},
|
|
||||||
"3110 bis 3170 Verbindlichkeiten gegen\u00fcber Kredidinstituten": {},
|
|
||||||
"3180 bis 3190 Verbindlichkeiten gegen\u00fcber Finanzinstituten": {},
|
|
||||||
"3380 bis 3390 Verbindlichkeiten aus der Annahme gezogener Wechsel u. d. Ausstellungen eigener Wechsel": {
|
|
||||||
"account_type": "Payable"
|
"account_type": "Payable"
|
||||||
},
|
},
|
||||||
"3400 bis 3470 Verbindlichkeiten gegen\u00fc. verb. Untern., Verbindl. gegen\u00fc. Untern., mit denen eine Beteiligungsverh\u00e4lnis besteht": {},
|
"3400 Verbindlichkeiten gegen\u00fc. verb. Untern., Verbindl. gegen\u00fc. Untern., mit denen eine Beteiligungsverh\u00e4lnis besteht": {},
|
||||||
"3600 bis 3690 Verbindlichkeiten im Rahmen der sozialen Sicherheit": {},
|
"3460 Verbindlichkeiten gegenueber Gesellschaftern": {"account_type": "Payable"},
|
||||||
"3700 bis 3890 \u00dcbrige sonstige Verbindlichkeiten": {},
|
"3470 Einlagen stiller Gesellschafter": {"account_type": "Payable"},
|
||||||
"3900 bis 3990 Passive Rechnungsabgrenzungsposten": {},
|
"3585 Verbindlichkeiten Lohnsteuer": {"account_type": "Tax"},
|
||||||
"Anleihen (einschlie\u00dflich konvertibler)": {},
|
"3590 Verbindlichkeiten Kommunalabgaben": {"account_type": "Tax"},
|
||||||
"Erhaltene Anzahlungenauf Bestellungen": {},
|
"3595 Verbindlichkeiten Dienstgeberbeitrag": {"account_type": "Tax"},
|
||||||
"R\u00fcckstellungen f\u00fcr Abfertigung": {},
|
"3600 Verbindlichkeiten Sozialversicherung": {"account_type": "Payable"},
|
||||||
"R\u00fcckstellungen f\u00fcr Pensionen": {},
|
"3640 Verbindlichkeiten Loehne und Gehaelter": {"account_type": "Payable"},
|
||||||
"USt. \u00a719 /art (reverse charge)": {
|
"3700 Sonstige Verbindlichkeiten": {"account_type": "Payable"},
|
||||||
|
"3900 Passive Rechnungsabgrenzungsposten": {"account_type": "Payable"},
|
||||||
|
"3100 Anleihen (einschlie\u00dflich konvertibler)": {"account_type": "Payable"},
|
||||||
|
"3200 Erhaltene Anzahlungen auf Bestellungen": {"account_type": "Payable"},
|
||||||
|
"3040 R\u00fcckstellungen f\u00fcr Abfertigung": {"account_type": "Payable"},
|
||||||
|
|
||||||
|
"3530 USt. \u00a719 (reverse charge)": {
|
||||||
"account_type": "Tax"
|
"account_type": "Tax"
|
||||||
},
|
},
|
||||||
"Umsatzsteuer": {},
|
"3500 Verbindlichkeiten aus Umsatzsteuer": {"account_type": "Tax"},
|
||||||
"Umsatzsteuer Zahllast": {
|
"3580 Umsatzsteuer Zahllast": {
|
||||||
"account_type": "Tax"
|
"account_type": "Tax"
|
||||||
},
|
},
|
||||||
"Umsatzsteuer aus i.g. Erwerb 10%": {
|
"3510 Umsatzsteuer Inland 20%": {
|
||||||
"account_type": "Tax"
|
"account_type": "Tax"
|
||||||
},
|
},
|
||||||
"Umsatzsteuer aus i.g. Erwerb 20%": {
|
"3515 Umsatzsteuer Inland 10%": {
|
||||||
"account_type": "Tax"
|
"account_type": "Tax"
|
||||||
},
|
},
|
||||||
"Umsatzsteuer aus i.g. Lieferungen 10%": {
|
"3520 Umsatzsteuer aus i.g. Erwerb 20%": {
|
||||||
"account_type": "Tax"
|
"account_type": "Tax"
|
||||||
},
|
},
|
||||||
"Umsatzsteuer aus i.g. Lieferungen 20%": {
|
"3525 Umsatzsteuer aus i.g. Erwerb 10%": {
|
||||||
"account_type": "Tax"
|
"account_type": "Tax"
|
||||||
},
|
},
|
||||||
"Umsatzsteuer-Evidenzkonto f\u00fcr erhaltene Anzahlungen auf Bestellungen": {},
|
"3560 Umsatzsteuer-Evidenzkonto f\u00fcr erhaltene Anzahlungen auf Bestellungen": {},
|
||||||
"Verbindlichkeiten aus Lieferungen u. Leistungen EU": {
|
"3360 Verbindlichkeiten aus Lieferungen u. Leistungen EU": {
|
||||||
"account_type": "Payable"
|
"account_type": "Payable"
|
||||||
},
|
},
|
||||||
"Verbindlichkeiten aus Lieferungen u. Leistungen Inland": {
|
"3000 Verbindlichkeiten aus Lieferungen u. Leistungen Inland": {
|
||||||
"account_type": "Payable"
|
"account_type": "Payable"
|
||||||
},
|
},
|
||||||
"Verbindlichkeiten aus Lieferungen u. Leistungen sonst. Ausland": {
|
"3370 Verbindlichkeiten aus Lieferungen u. Leistungen sonst. Ausland": {
|
||||||
"account_type": "Payable"
|
"account_type": "Payable"
|
||||||
},
|
},
|
||||||
"Verbindlichkeiten gegen\u00fcber Gesellschaften": {},
|
"3400 Verbindlichkeiten gegen\u00fcber verbundenen Unternehmen": {},
|
||||||
"Verrechnung Finanzamt": {
|
"3570 Verrechnung Finanzamt": {
|
||||||
"account_type": "Tax"
|
"account_type": "Tax"
|
||||||
},
|
},
|
||||||
"root_type": "Liability"
|
"root_type": "Liability"
|
||||||
},
|
},
|
||||||
"Summe Kontoklasse 0 Anlageverm\u00f6gen": {
|
"Klasse 2 Aktiva: Umlaufverm\u00f6gen, Rechnungsabgrenzungen": {
|
||||||
"44 bis 49 Sonstige Maschinen und maschinelle Anlagen": {},
|
"2030 Forderungen aus Lieferungen und Leistungen Inland (0% USt, umsatzsteuerfrei)": {
|
||||||
"920 bis 930 Festverzinsliche Wertpapiere des Anlageverm\u00f6gens": {},
|
"account_type": "Receivable"
|
||||||
"940 bis 970 Sonstige Finanzanlagen, Wertrechte": {},
|
},
|
||||||
"Allgemeine Werkzeuge und Handwerkzeuge": {},
|
"2010 Forderungen aus Lieferungen und Leistungen Inland (10% USt, umsatzsteuerfrei)": {
|
||||||
"Andere Bef\u00f6rderungsmittel": {},
|
"account_type": "Receivable"
|
||||||
"Andere Betriebs- und Gesch\u00e4ftsausstattung": {},
|
},
|
||||||
"Andere Erzeugungshilfsmittel": {},
|
"2000 Forderungen aus Lieferungen und Leistungen Inland (20% USt, umsatzsteuerfrei)": {
|
||||||
"Anlagen im Bau": {},
|
"account_type": "Receivable"
|
||||||
"Anteile an Investmentfonds": {},
|
},
|
||||||
"Anteile an Kapitalgesellschaften ohne Beteiligungscharakter": {},
|
"2040 Forderungen aus Lieferungen und Leistungen Inland (sonstiger USt-Satz)": {
|
||||||
"Anteile an Personengesellschaften ohne Beteiligungscharakter": {},
|
"account_type": "Receivable"
|
||||||
"Anteile an verbundenen Unternehmen": {},
|
},
|
||||||
"Antriebsmaschinen": {},
|
"2100 Forderungen aus Lieferungen und Leistungen EU": {
|
||||||
"Aufwendungen f\u00fcs das Ingangssetzen u. Erweitern eines Betriebes": {},
|
"account_type": "Receivable"
|
||||||
"Ausleihungen an verbundene Unternehmen": {},
|
},
|
||||||
"Ausleihungen an verbundene Unternehmen, mit denen ein Beteiligungsverh\u00e4lnis besteht": {},
|
"2150 Forderungen aus Lieferungen und Leistungen Ausland (Nicht-EU)": {
|
||||||
"Bauliche Investitionen in fremden (gepachteten) Betriebs- und Gesch\u00e4ftsgeb\u00e4uden": {},
|
"account_type": "Receivable"
|
||||||
"Bauliche Investitionen in fremden (gepachteten) Wohn- und Sozialgeb\u00e4uden": {},
|
},
|
||||||
"Bebaute Grundst\u00fccke (Grundwert)": {},
|
"2200 Forderungen gegen\u00fcber verbundenen Unternehmen": {
|
||||||
"Beheizungs- und Beleuchtungsanlagen": {},
|
"account_type": "Receivable"
|
||||||
"Beteiligungen an Gemeinschaftunternehmen": {},
|
},
|
||||||
"Beteiligungen an angeschlossenen (assoziierten) Unternehmen": {},
|
"2250 Forderungen gegen\u00fcber Unternehmen, mit denen ein Beteiligungsverh\u00e4ltnis besteht": {
|
||||||
"Betriebs- und Gesch\u00e4ftsgeb\u00e4ude auf eigenem Grund": {},
|
"account_type": "Receivable"
|
||||||
"Betriebs- und Gesch\u00e4ftsgeb\u00e4ude auf fremdem Grund": {},
|
},
|
||||||
"B\u00fcromaschinen, EDV - Anlagen": {},
|
"2300 Sonstige Forderungen und Verm\u00f6gensgegenst\u00e4nde": {
|
||||||
"Datenverarbeitungsprogramme": {},
|
"account_type": "Receivable"
|
||||||
"Energieversorgungsanlagen": {},
|
},
|
||||||
"Fertigungsmaschinen": {},
|
"2630 Sonstige Wertpapiere": {
|
||||||
"Gebinde": {},
|
"account_type": "Stock"
|
||||||
"Geleistete Anzahlungen": {},
|
},
|
||||||
"Genossenschaften ohne Beteiligungscharakter": {},
|
"2750 Kassenbest\u00e4nde in Fremdw\u00e4hrung": {
|
||||||
"Geringwertige Verm\u00f6gensgegenst\u00e4nde, soweit im Erzeugerprozess verwendet": {},
|
"account_type": "Cash"
|
||||||
"Geringwertige Verm\u00f6gensgegenst\u00e4nde, soweit nicht im Erzeugungsprozess verwendet": {},
|
},
|
||||||
"Gesch\u00e4fts(Firmen)wert": {},
|
"2900 Aktive Rechnungsabrenzungsposten": {
|
||||||
"Grundst\u00fcckseinrichtunten auf eigenem Grund": {},
|
"account_type": "Receivable"
|
||||||
"Grundst\u00fcckseinrichtunten auf fremdem Grund": {},
|
},
|
||||||
"Grundst\u00fccksgleiche Rechte": {},
|
"2600 Anteile an verbundenen Unternehmen": {
|
||||||
"Hebezeuge und Montageanlagen": {},
|
"account_type": "Equity"
|
||||||
"Konzessionen": {},
|
},
|
||||||
"Kumulierte Abschreibungen": {},
|
"2680 Besitzwechsel ohne Forderungen": {
|
||||||
"LKW": {},
|
"account_type": "Receivable"
|
||||||
"Marken, Warenzeichen und Musterschutzrechte": {},
|
},
|
||||||
"Maschinenwerkzeuge": {},
|
"2950 Aktiviertes Disagio": {
|
||||||
"Nachrichten- und Kontrollanlagen": {},
|
"account_type": "Receivable"
|
||||||
"PKW": {},
|
},
|
||||||
"Pacht- und Mietrechte": {},
|
"2610 Eigene Anteile und Wertpapiere an mit Mehrheit beteiligten Unternehmen": {
|
||||||
"Patentrechte und Lizenzen": {},
|
"account_type": "Receivable"
|
||||||
"Sonstige Ausleihungen": {},
|
},
|
||||||
"Sonstige Beteiligungen": {},
|
"2570 Einfuhrumsatzsteuer (bezahlt)": {"account_type": "Tax"},
|
||||||
"Transportanlagen": {},
|
|
||||||
"Unbebaute Grundst\u00fccke": {},
|
"2460 Eingeforderte aber noch nicht eingezahlte Einlagen": {
|
||||||
"Vorrichtungen, Formen und Modelle": {},
|
"account_type": "Receivable"
|
||||||
"Wohn- und Sozialgeb\u00e4ude auf eigenem Grund": {},
|
},
|
||||||
"Wohn- und Sozialgeb\u00e4ude auf fremdem Grund": {},
|
"2180 Einzelwertberichtigungen zu Forderungen aus Lief. und Leist. Ausland": {
|
||||||
|
"account_type": "Receivable"
|
||||||
|
},
|
||||||
|
"2130 Einzelwertberichtigungen zu Forderungen aus Lief. und Leist. EU": {
|
||||||
|
"account_type": "Receivable"
|
||||||
|
},
|
||||||
|
"2080 Einzelwertberichtigungen zu Forderungen aus Lief. und Leist. Inland ": {
|
||||||
|
"account_type": "Receivable"
|
||||||
|
},
|
||||||
|
"2270 Einzelwertberichtigungen zu Forderungen gegen\u00fcber Unternehmen mit denen ein Beteiligungsverh\u00e4ltnis besteht": {
|
||||||
|
"account_type": "Receivable"
|
||||||
|
},
|
||||||
|
"2230 Einzelwertberichtigungen zu Forderungen gegen\u00fcber verbundenen Unternehmen": {
|
||||||
|
"account_type": "Receivable"
|
||||||
|
},
|
||||||
|
"2470 Einzelwertberichtigungen zu sonstigen Forderungen und Verm\u00f6gensgegenst\u00e4nden": {
|
||||||
|
"account_type": "Receivable"
|
||||||
|
},
|
||||||
|
"2700 Kassenbestand": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"2190 Pauschalwertberichtigungen zu Forderungen aus Lief. und Leist. sonstiges Ausland": {
|
||||||
|
"account_type": "Receivable"
|
||||||
|
},
|
||||||
|
"2130 Pauschalwertberichtigungen zu Forderungen aus Lief. und Leist. EU": {
|
||||||
|
"account_type": "Receivable"
|
||||||
|
},
|
||||||
|
"2100 Pauschalwertberichtigungen zu Forderungen aus Lief. und Leist. Inland ": {
|
||||||
|
"account_type": "Receivable"
|
||||||
|
},
|
||||||
|
"2280 Pauschalwertberichtigungen zu Forderungen gegen\u00fcber Unternehmen mit denen ein Beteiligungsverh\u00e4ltnis besteht": {
|
||||||
|
"account_type": "Receivable"
|
||||||
|
},
|
||||||
|
"2240 Pauschalwertberichtigungen zu Forderungen gegen\u00fcber verbundenen Unternehmen": {
|
||||||
|
"account_type": "Receivable"
|
||||||
|
},
|
||||||
|
"2480 Pauschalwertberichtigungen zu sonstigen Forderungen und Verm\u00f6gensgegenst\u00e4nden": {
|
||||||
|
"account_type": "Receivable"
|
||||||
|
},
|
||||||
|
"2740 Postwertzeichen": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"2780 Schecks in Euro": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"2800 Guthaben bei Bank": {
|
||||||
|
"account_type": "Bank"
|
||||||
|
},
|
||||||
|
"2801 Guthaben bei Bank - Sparkonto": {
|
||||||
|
"account_type": "Bank"
|
||||||
|
},
|
||||||
|
"2810 Guthaben bei Paypal": {
|
||||||
|
"account_type": "Bank"
|
||||||
|
},
|
||||||
|
"2930 Mietvorauszahlungen": {
|
||||||
|
"account_type": "Receivable"
|
||||||
|
},
|
||||||
|
"2980 Abgrenzung latenter Steuern": {
|
||||||
|
"account_type": "Receivable"
|
||||||
|
},
|
||||||
|
"2500 Vorsteuer": {
|
||||||
|
"account_type": "Receivable"
|
||||||
|
},
|
||||||
|
"2510 Vorsteuer Inland 10%": {
|
||||||
|
"account_type": "Tax"
|
||||||
|
},
|
||||||
|
"2895 Schwebende Geldbewegugen": {
|
||||||
|
"account_type": "Bank"
|
||||||
|
},
|
||||||
|
"2513 Vorsteuer Inland 5%": {
|
||||||
|
"account_type": "Tax"
|
||||||
|
},
|
||||||
|
"2515 Vorsteuer Inland 20%": {
|
||||||
|
"account_type": "Tax"
|
||||||
|
},
|
||||||
|
"2520 Vorsteuer aus innergemeinschaftlichem Erwerb 10%": {
|
||||||
|
"account_type": "Tax"
|
||||||
|
},
|
||||||
|
"2525 Vorsteuer aus innergemeinschaftlichem Erwerb 20%": {
|
||||||
|
"account_type": "Tax"
|
||||||
|
},
|
||||||
|
"2530 Vorsteuer \u00a719/Art 19 ( reverse charge ) ": {
|
||||||
|
"account_type": "Tax"
|
||||||
|
},
|
||||||
|
"2690 Wertberichtigungen zu Wertpapieren und Anteilen": {
|
||||||
|
"account_type": "Receivable"
|
||||||
|
},
|
||||||
"root_type": "Asset"
|
"root_type": "Asset"
|
||||||
},
|
},
|
||||||
"Summe Personalaufwand": {
|
"Klasse 4: Betriebliche Erträge": {
|
||||||
"6000 bis 6190 L\u00f6hne": {},
|
"4000 Erlöse 20 %": {"account_type": "Income Account"},
|
||||||
"6200 bis 6390 Geh\u00e4lter": {},
|
"4020 Erl\u00f6se 0 % steuerbefreit": {"account_type": "Income Account"},
|
||||||
"6400 bis 6440 Aufwendungen f\u00fcr Abfertigungen": {},
|
"4010 Erl\u00f6se 10 %": {"account_type": "Income Account"},
|
||||||
"6450 bis 6490 Aufwendungen f\u00fcr Altersversorgung": {},
|
"4030 Erl\u00f6se 13 %": {"account_type": "Income Account"},
|
||||||
"6500 bis 6550 Gesetzlicher Sozialaufwand Arbeiter": {},
|
"4040 Erl\u00f6se 0 % innergemeinschaftliche Lieferungen": {"account_type": "Income Account"},
|
||||||
"6560 bis 6590 Gesetzlicher Sozialaufwand Angestellte": {},
|
"4400 Erl\u00f6sreduktion 0 % steuerbefreit": {"account_type": "Expense Account"},
|
||||||
"6600 bis 6650 Lohnabh\u00e4ngige Abgaben und Pflichtbeitr\u00e4gte": {},
|
"4410 Erl\u00f6sreduktion 10 %": {"account_type": "Expense Account"},
|
||||||
"6660 bis 6690 Gehaltsabh\u00e4ngige Abgaben und Pflichtbeitr\u00e4gte": {},
|
"4420 Erl\u00f6sreduktion 20 %": {"account_type": "Expense Account"},
|
||||||
"6700 bis 6890 Sonstige Sozialaufwendungen": {},
|
"4430 Erl\u00f6sreduktion 13 %": {"account_type": "Expense Account"},
|
||||||
"Aufwandsstellenrechnung": {},
|
"4440 Erl\u00f6sreduktion 0 % innergemeinschaftliche Lieferungen": {"account_type": "Expense Account"},
|
||||||
|
"4500 Ver\u00e4nderungen des Bestandes an fertigen und unfertigen Erzeugn. sowie an noch nicht abrechenbaren Leistungen": {"account_type": "Income Account"},
|
||||||
|
"4580 Aktivierte Eigenleistungen": {"account_type": "Income Account"},
|
||||||
|
"4600 Erl\u00f6se aus dem Abgang vom Anlageverm\u00f6gen, ausgen. Finanzanlagen": {"account_type": "Income Account"},
|
||||||
|
"4630 Ertr\u00e4ge aus dem Abgang vom Anlageverm\u00f6gen, ausgen. Finanzanlagen": {"account_type": "Income Account"},
|
||||||
|
"4660 Ertr\u00e4ge aus der Zuschreibung zum Anlageverm\u00f6gen, ausgen. Finanzanlagen": {"account_type": "Income Account"},
|
||||||
|
"4700 Ertr\u00e4ge aus der Aufl\u00f6sung von R\u00fcckstellungen": {"account_type": "Income Account"},
|
||||||
|
"4800 \u00dcbrige betriebliche Ertr\u00e4ge": {"account_type": "Income Account"},
|
||||||
|
"root_type": "Income"
|
||||||
|
},
|
||||||
|
"Klasse 5: Aufwand f\u00fcr Material und Leistungen": {
|
||||||
|
"5000 Einkauf Partnerleistungen": {"account_type": "Cost of Goods Sold"},
|
||||||
|
"5100 Verbrauch an Rohstoffen": {"account_type": "Cost of Goods Sold"},
|
||||||
|
"5200 Verbrauch von bezogenen Fertig- und Einzelteilen": {"account_type": "Cost of Goods Sold"},
|
||||||
|
"5300 Verbrauch von Hilfsstoffen": {"account_type": "Cost of Goods Sold"},
|
||||||
|
"5340 Verbrauch Verpackungsmaterial": {"account_type": "Cost of Goods Sold"},
|
||||||
|
"5470 Verbrauch von Kleinmaterial": {"account_type": "Cost of Goods Sold"},
|
||||||
|
"5450 Verbrauch von Reinigungsmaterial": {"account_type": "Cost of Goods Sold"},
|
||||||
|
"5400 Verbrauch von Betriebsstoffen": {"account_type": "Cost of Goods Sold"},
|
||||||
|
"5500 Verbrauch von Werkzeugen und anderen Erzeugungshilfsmittel": {"account_type": "Cost of Goods Sold"},
|
||||||
|
"5600 Verbrauch von Brenn- und Treibstoffen, Energie und Wasser": {"account_type": "Cost of Goods Sold"},
|
||||||
|
"5700 Bearbeitung durch Dritte": {"account_type": "Cost of Goods Sold"},
|
||||||
|
"5900 Aufwandsstellenrechnung Material": {"account_type": "Cost of Goods Sold"},
|
||||||
|
"5820 Skontoertr\u00e4ge (20% USt.)": {"account_type": "Income Account"},
|
||||||
|
"5810 Skontoertr\u00e4ge (10% USt.)": {"account_type": "Income Account"},
|
||||||
|
"5010 Handelswareneinkauf 10 %": {"account_type": "Cost of Goods Sold"},
|
||||||
|
"5020 Handelswareneinkauf 20 %": {"account_type": "Cost of Goods Sold"},
|
||||||
|
"5040 Handelswareneinkauf innergemeinschaftlicher Erwerb 10 % VSt/10 % USt": {"account_type": "Cost of Goods Sold"},
|
||||||
|
"5050 Handelswareneinkauf innergemeinschaftlicher Erwerb 20 % VSt/20 % USt": {"account_type": "Cost of Goods Sold"},
|
||||||
|
"5070 Handelswareneinkauf innergemeinschaftlicher Erwerb ohne Vorsteuerabzug und 10 % USt": {"account_type": "Cost of Goods Sold"},
|
||||||
|
"5080 Handelswareneinkauf innergemeinschaftlicher Erwerb ohne Vorsteuerabzug und 20 % USt": {"account_type": "Cost of Goods Sold"},
|
||||||
"root_type": "Expense"
|
"root_type": "Expense"
|
||||||
},
|
},
|
||||||
"Summe Umlaufverm\u00f6gen": {
|
"Klasse 6: Personalaufwand": {
|
||||||
"2000 bis 2007 Forderungen aus Lief. und Leist. Inland": {
|
"6000 L\u00f6hne": {"account_type": "Payable"},
|
||||||
"account_type": "Receivable"
|
"6200 Geh\u00e4lter": {"account_type": "Payable"},
|
||||||
},
|
"6400 Aufwendungen f\u00fcr Abfertigungen": {"account_type": "Payable"},
|
||||||
"2100 bis 2120 Forderungen aus Lief. und Leist. EU": {
|
"6450 Aufwendungen f\u00fcr Altersversorgung": {"account_type": "Payable"},
|
||||||
"account_type": "Receivable"
|
"6500 Gesetzlicher Sozialaufwand Arbeiter": {"account_type": "Payable"},
|
||||||
},
|
"6560 Gesetzlicher Sozialaufwand Angestellte": {"account_type": "Payable"},
|
||||||
"2150 bis 2170 Forderungen aus Lief. und Leist. Ausland": {
|
"6600 Lohnabh\u00e4ngige Abgaben und Pflichtbeitr\u00e4gte": {"account_type": "Payable"},
|
||||||
"account_type": "Receivable"
|
"6660 Gehaltsabh\u00e4ngige Abgaben und Pflichtbeitr\u00e4gte": {"account_type": "Payable"},
|
||||||
},
|
"6700 Sonstige Sozialaufwendungen": {"account_type": "Payable"},
|
||||||
"2200 bis 2220 Forderungen gegen\u00fcber verbundenen Unternehmen": {
|
"6900 Aufwandsstellenrechnung Personal": {"account_type": "Payable"},
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"2250 bis 2270 Forderungen gegen\u00fcber Unternehmen, mit denen ein Beteiligungsverh\u00e4ltnis besteht": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"2300 bis 2460 Sonstige Forderungen und Verm\u00f6gensgegenst\u00e4nde": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"2630 bis 2670 Sonstige Wertpapiere": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"2750 bis 2770 Kassenbest\u00e4nde in Fremdw\u00e4hrung": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Aktive Rechnungsabrenzungsposten": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Anteile an verbundenen Unternehmen": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Bank / Guthaben bei Kreditinstituten": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Besitzwechsel ...": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Disagio": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Eigene Anteile (Wertpapiere)": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Einfuhrumsatzsteuer (bezahlt)": {},
|
|
||||||
"Eingeforderte aber noch nicht eingezahlte Einlagen": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Einzelwertberichtigungen zu Forderungen aus Lief. und Leist. Ausland": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Einzelwertberichtigungen zu Forderungen aus Lief. und Leist. EU": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Einzelwertberichtigungen zu Forderungen aus Lief. und Leist. Inland ": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Einzelwertberichtigungen zu Forderungen gegen\u00fcber Unternehmen mit denen ein Beteiligungsverh\u00e4ltnis besteht": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Einzelwertberichtigungen zu Forderungen gegen\u00fcber verbundenen Unternehmen": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Einzelwertberichtigungen zu sonstigen Forderungen und Verm\u00f6gensgegenst\u00e4nden": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Kassenbestand": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Pauschalwertberichtigungen zu Forderungen aus Lief. und Leist. Ausland": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Pauschalwertberichtigungen zu Forderungen aus Lief. und Leist. EU": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Pauschalwertberichtigungen zu Forderungen aus Lief. und Leist. Inland ": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Pauschalwertberichtigungen zu Forderungen gegen\u00fcber Unternehmen mit denen ein Beteiligungsverh\u00e4ltnis besteht": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Pauschalwertberichtigungen zu Forderungen gegen\u00fcber verbundenen Unternehmen": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Pauschalwertberichtigungen zu sonstigen Forderungen und Verm\u00f6gensgegenst\u00e4nden": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Postwertzeichen": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Schecks in Inlandsw\u00e4hrung": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Sonstige Anteile": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Stempelmarken": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Steuerabgrenzung": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Unterschiedsbetrag gem. Abschnitt XII Pensionskassengesetz": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Unterschiedsbetrag zur gebotenen Pensionsr\u00fcckstellung": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Vorsteuer": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Vorsteuer aus ig. Erwerb 10%": {
|
|
||||||
"account_type": "Tax"
|
|
||||||
},
|
|
||||||
"Vorsteuer aus ig. Erwerb 20%": {
|
|
||||||
"account_type": "Tax"
|
|
||||||
},
|
|
||||||
"Vorsteuer \u00a719/Art 19 ( reverse charge ) ": {
|
|
||||||
"account_type": "Tax"
|
|
||||||
},
|
|
||||||
"Wertberichtigungen": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"root_type": "Asset"
|
|
||||||
},
|
|
||||||
"Summe Vorr\u00e4te": {
|
|
||||||
"1000 bis 1090 Bezugsverrechnung": {},
|
|
||||||
"1100 bis 1190 Rohstoffe": {},
|
|
||||||
"1200 bis 1290 Bezogene Teile": {},
|
|
||||||
"1300 bis 1340 Hilfsstoffe": {},
|
|
||||||
"1350 bis 1390 Betriebsstoffe": {},
|
|
||||||
"1400 bis 1490 Unfertige Erzeugniss": {},
|
|
||||||
"1500 bis 1590 Fertige Erzeugniss": {},
|
|
||||||
"1600 bis 1690 Waren": {},
|
|
||||||
"1700 bis 1790 Noch nicht abgerechenbare Leistungen": {},
|
|
||||||
"1900 bis 1990 Wertberichtigungen": {},
|
|
||||||
"geleistete Anzahlungen": {},
|
|
||||||
"root_type": "Asset"
|
|
||||||
},
|
|
||||||
"Summe Wareneinsatz": {
|
|
||||||
"5100 bis 5190 Verbrauch an Rohstoffen": {},
|
|
||||||
"5200 bis 5290 Verbrauch von bezogenen Fertig- und Einzelteilen": {},
|
|
||||||
"5300 bis 5390 Verbrauch von Hilfsstoffen": {},
|
|
||||||
"5400 bis 5490 Verbrauch von Betriebsstoffen": {},
|
|
||||||
"5500 bis 5590 Verbrauch von Werkzeugen und anderen Erzeugungshilfsmittel": {},
|
|
||||||
"5600 bis 5690 Verbrauch von Brenn- und Treibstoffen, Energie und Wasser": {},
|
|
||||||
"5700 bis 5790 Sonstige bezogene Herstellungsleistungen": {},
|
|
||||||
"Aufwandsstellenrechnung": {},
|
|
||||||
"Skontoertr\u00e4ge auf Materialaufwand": {},
|
|
||||||
"Skontoertr\u00e4ge auf sonstige bezogene Herstellungsleistungen": {},
|
|
||||||
"Wareneinkauf 10 %": {},
|
|
||||||
"Wareneinkauf 20 %": {},
|
|
||||||
"Wareneinkauf igErwerb 10 % VSt/10 % USt": {},
|
|
||||||
"Wareneinkauf igErwerb 20 % VSt/20 % USt": {},
|
|
||||||
"Wareneinkauf igErwerb ohne Vorsteuerabzug und 10 % USt": {},
|
|
||||||
"Wareneinkauf igErwerb ohne Vorsteuerabzug und 20 % USt": {},
|
|
||||||
"root_type": "Expense"
|
"root_type": "Expense"
|
||||||
|
},
|
||||||
|
"Klasse 7: Abschreibungen und sonstige betriebliche Aufwendungen": {
|
||||||
|
"7010 Abschreibungen auf das Anlageverm\u00f6gen (ausgenommen Finanzanlagen)": {"account_type": "Depreciation"},
|
||||||
|
"7100 Sonstige Steuern und Geb\u00fchren": {"account_type": "Tax"},
|
||||||
|
"7200 Instandhaltung u. Reinigung durch Dritte, Entsorgung, Energie": {"account_type": "Expense Account"},
|
||||||
|
"7300 Transporte durch Dritte": {"account_type": "Expense Account"},
|
||||||
|
"7310 Fahrrad - Aufwand": {"account_type": "Expense Account"},
|
||||||
|
"7320 Kfz - Aufwand": {"account_type": "Expense Account"},
|
||||||
|
"7330 LKW - Aufwand": {"account_type": "Expense Account"},
|
||||||
|
"7340 Lastenrad - Aufwand": {"account_type": "Expense Account"},
|
||||||
|
"7350 Reise- und Fahraufwand": {"account_type": "Expense Account"},
|
||||||
|
"7360 Tag- und N\u00e4chtigungsgelder": {"account_type": "Expense Account"},
|
||||||
|
"7380 Nachrichtenaufwand": {"account_type": "Expense Account"},
|
||||||
|
"7400 Miet- und Pachtaufwand": {"account_type": "Expense Account"},
|
||||||
|
"7440 Leasingaufwand": {"account_type": "Expense Account"},
|
||||||
|
"7480 Lizenzaufwand": {"account_type": "Expense Account"},
|
||||||
|
"7500 Aufwand f\u00fcr beigestelltes Personal": {"account_type": "Expense Account"},
|
||||||
|
"7540 Provisionen an Dritte": {"account_type": "Expense Account"},
|
||||||
|
"7580 Aufsichtsratsverg\u00fctungen": {"account_type": "Expense Account"},
|
||||||
|
"7610 Druckerzeugnisse und Vervielf\u00e4ltigungen": {"account_type": "Expense Account"},
|
||||||
|
"7650 Werbung und Repr\u00e4sentationen": {"account_type": "Expense Account"},
|
||||||
|
"7700 Versicherungen": {"account_type": "Expense Account"},
|
||||||
|
"7750 Beratungs- und Pr\u00fcfungsaufwand": {"account_type": "Expense Account"},
|
||||||
|
"7800 Forderungsverluste und Schadensf\u00e4lle": {"account_type": "Expense Account"},
|
||||||
|
"7840 Verschiedene betriebliche Aufwendungen": {"account_type": "Expense Account"},
|
||||||
|
"7910 Aufwandsstellenrechung der Hersteller": {"account_type": "Expense Account"},
|
||||||
|
"7060 Sofortabschreibungen geringwertig": {"account_type": "Expense Account"},
|
||||||
|
"7070 Abschreibungen vom Umlaufverm\u00f6gen, soweit diese die im Unternehmen \u00fcblichen Abschreibungen \u00fcbersteigen": {"account_type": "Depreciation"},
|
||||||
|
"7900 Aufwandsstellenrechnung": {"account_type": "Expense Account"},
|
||||||
|
"7770 Aus- und Fortbildung": {"account_type": "Expense Account"},
|
||||||
|
"7820 Buchwert abgegangener Anlagen, ausgenommen Finanzanlagen": {"account_type": "Expense Account"},
|
||||||
|
"7600 B\u00fcromaterial und Drucksorten": {"account_type": "Expense Account"},
|
||||||
|
"7630 Fachliteratur und Zeitungen ": {"account_type": "Expense Account"},
|
||||||
|
"7960 Herstellungskosten der zur Erzielung der Umsatzerl\u00f6se erbrachten Leistungen": {"account_type": "Expense Account"},
|
||||||
|
"7780 Mitgliedsbeitr\u00e4ge": {"account_type": "Expense Account"},
|
||||||
|
"7880 Skontoertr\u00e4ge auf sonstige betriebliche Aufwendungen": {"account_type": "Expense Account"},
|
||||||
|
"7990 Sonstige betrieblichen Aufwendungen": {"account_type": "Expense Account"},
|
||||||
|
"7680 Spenden und Trinkgelder": {"account_type": "Expense Account"},
|
||||||
|
"7790 Spesen des Geldverkehrs": {"account_type": "Expense Account"},
|
||||||
|
"7830 Verluste aus dem Abgang vom Anlageverm\u00f6gen, ausgenommen Finanzanlagen": {"account_type": "Expense Account"},
|
||||||
|
"7970 Vertriebskosten": {"account_type": "Expense Account"},
|
||||||
|
"7980 Verwaltungskosten": {"account_type": "Expense Account"},
|
||||||
|
"root_type": "Expense"
|
||||||
|
},
|
||||||
|
"Klasse 8: Finanz- und ausserordentliche Ertr\u00e4ge und Aufwendungen": {
|
||||||
|
"8000 Ertr\u00e4ge aus Beteiligungen": {"account_type": "Income Account"},
|
||||||
|
"8050 Ertr\u00e4ge aus anderen Wertpapieren und Ausleihungen des Finanzanlageverm\u00f6gens": {"account_type": "Income Account"},
|
||||||
|
"8100 Zinsen aus Bankguthaben": {"account_type": "Income Account"},
|
||||||
|
"8110 Zinsen aus gewaehrten Darlehen": {"account_type": "Income Account"},
|
||||||
|
"8130 Verzugszinsenertraege": {"account_type": "Income Account"},
|
||||||
|
"8220 Aufwendungen aus Beteiligungen": {"account_type": "Expense Account"},
|
||||||
|
"8260 Aufwendungen aus sonst. Fiananzanlagen und aus Wertpapieren des Umlaufverm\u00f6gens": {},
|
||||||
|
"8280 Zinsen und \u00e4hnliche Aufwendungem": {"account_type": "Expense Account"},
|
||||||
|
"8400 Au\u00dferordentliche Ertr\u00e4ge": {"account_type": "Income Account"},
|
||||||
|
"8450 Au\u00dferordentliche Aufwendungen": {"account_type": "Expense Account"},
|
||||||
|
"8500 Steuern vom Einkommen und vom Ertrag": {
|
||||||
|
"account_type": "Tax"
|
||||||
|
},
|
||||||
|
"8600 Aufl\u00f6sung unversteuerten R\u00fccklagen": {"account_type": "Income Account"},
|
||||||
|
"8700 Aufl\u00f6sung von Kapitalr\u00fccklagen": {"account_type": "Income Account"},
|
||||||
|
"8750 Aufl\u00f6sung von Gewinnr\u00fccklagen": {"account_type": "Income Account"},
|
||||||
|
"8800 Zuweisung zu unversteuerten R\u00fccklagen": {"account_type": "Expense Account"},
|
||||||
|
"8900 Zuweisung zu Gewinnr\u00fccklagen": {"account_type": "Expense Account"},
|
||||||
|
"8100 Buchwert abgegangener Beteiligungen": {"account_type": "Expense Account"},
|
||||||
|
"8130 Buchwert abgegangener Wertpapiere des Umlaufverm\u00f6gens": {"account_type": "Expense Account"},
|
||||||
|
"8120 Buchwert abgegangener sonstiger Finanzanlagen": {"account_type": "Expense Account"},
|
||||||
|
"8990 Gewinnabfuhr bzw. Verlust\u00fcberrechnung aus Ergebnisabf\u00fchrungsvertr\u00e4gen": {"account_type": "Expense Account"},
|
||||||
|
"8350 nicht ausgenutzte Lieferantenskonti": {"account_type": "Expense Account"},
|
||||||
|
"root_type": "Income"
|
||||||
|
},
|
||||||
|
"Klasse 9 Passiva: Eigenkapital, R\u00fccklagen, stille Einlagen, Abschlusskonten": {
|
||||||
|
"9000 Gezeichnetes bzw. gewidmetes Kapital": {
|
||||||
|
"account_type": "Equity"
|
||||||
|
},
|
||||||
|
"9200 Kapitalr\u00fccklagen": {
|
||||||
|
"account_type": "Equity"
|
||||||
|
},
|
||||||
|
"9300 Gewinnr\u00fccklagen": {
|
||||||
|
"account_type": "Equity"
|
||||||
|
},
|
||||||
|
"9400 Bewertungsreserven uns sonst. unversteuerte R\u00fccklagen": {
|
||||||
|
"account_type": "Equity"
|
||||||
|
},
|
||||||
|
"9600 Private Entnahmen": {"account_type": "Equity"},
|
||||||
|
"9610 Privatsteuern": {"account_type": "Equity"},
|
||||||
|
"9700 Einlagen stiller Gesellschafter ": {"account_type": "Equity"},
|
||||||
|
"9900 Evidenzkonto": {"account_type": "Equity"},
|
||||||
|
"9800 Er\u00f6ffnungsbilanzkonto (EBK)": {"account_type": "Equity"},
|
||||||
|
"9880 Jahresergebnis laut Gewinn- und Verlustrechnung (G+V)": {"account_type": "Equity"},
|
||||||
|
"9850 Schlussbilanzkonto (SBK)": {"account_type": "Round Off"},
|
||||||
|
"9190 nicht eingeforderte ausstehende Einlagen und berechtigte Entnahmen von Gesellschaftern": {
|
||||||
|
"account_type": "Equity"
|
||||||
|
},
|
||||||
|
"root_type": "Equity"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -11,11 +11,11 @@
|
|||||||
"account_number": "0027",
|
"account_number": "0027",
|
||||||
"account_type": "Fixed Asset"
|
"account_type": "Fixed Asset"
|
||||||
},
|
},
|
||||||
"Geschäftsausstattung": {
|
"Gesch\u00e4ftsausstattung": {
|
||||||
"account_number": "0410",
|
"account_number": "0410",
|
||||||
"account_type": "Fixed Asset"
|
"account_type": "Fixed Asset"
|
||||||
},
|
},
|
||||||
"Büroeinrichtung": {
|
"B\u00fcroeinrichtung": {
|
||||||
"account_number": "0420",
|
"account_number": "0420",
|
||||||
"account_type": "Fixed Asset"
|
"account_type": "Fixed Asset"
|
||||||
},
|
},
|
||||||
@@ -53,58 +53,43 @@
|
|||||||
},
|
},
|
||||||
"II. Forderungen und sonstige Vermögensgegenstände": {
|
"II. Forderungen und sonstige Vermögensgegenstände": {
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"Forderungen aus Lieferungen und Leistungen mit Kontokorrent": {
|
"Ford. a. Lieferungen und Leistungen": {
|
||||||
"account_number": "1400",
|
"account_number": "1400",
|
||||||
"account_type": "Receivable",
|
|
||||||
"is_group": 1
|
|
||||||
},
|
|
||||||
"Forderungen aus Lieferungen und Leistungen ohne Kontokorrent": {
|
|
||||||
"account_number": "1410",
|
|
||||||
"account_type": "Receivable"
|
"account_type": "Receivable"
|
||||||
},
|
},
|
||||||
"Durchlaufende Posten": {
|
"Durchlaufende Posten": {
|
||||||
"account_number": "1590"
|
"account_number": "1590"
|
||||||
},
|
},
|
||||||
"Verrechnungskonto Gewinnermittlung § 4 Abs. 3 EStG, nicht ergebniswirksam": {
|
"Gewinnermittlung \u00a74/3 nicht Ergebniswirksam": {
|
||||||
"account_number": "1371"
|
"account_number": "1371"
|
||||||
},
|
},
|
||||||
"Abziehbare Vorsteuer": {
|
"Abziehbare Vorsteuer": {
|
||||||
|
"account_type": "Tax",
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"Abziehbare Vorsteuer 7 %": {
|
"Abziehbare Vorsteuer 7%": {
|
||||||
"account_number": "1571",
|
"account_number": "1571"
|
||||||
"account_type": "Tax",
|
|
||||||
"tax_rate": 7.0
|
|
||||||
},
|
},
|
||||||
"Abziehbare Vorsteuer 19 %": {
|
"Abziehbare Vorsteuer 19%": {
|
||||||
"account_number": "1576",
|
"account_number": "1576"
|
||||||
"account_type": "Tax",
|
|
||||||
"tax_rate": 19.0
|
|
||||||
},
|
},
|
||||||
"Abziehbare Vorsteuer nach § 13b UStG 19 %": {
|
"Abziehbare Vorsteuer nach \u00a713b UStG 19%": {
|
||||||
"account_number": "1577",
|
"account_number": "1577"
|
||||||
"account_type": "Tax",
|
},
|
||||||
"tax_rate": 19.0
|
"Leistungen \u00a713b UStG 19% Vorsteuer, 19% Umsatzsteuer": {
|
||||||
|
"account_number": "3120"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"III. Wertpapiere": {
|
"III. Wertpapiere": {
|
||||||
"is_group": 1,
|
"is_group": 1
|
||||||
"Anteile an verbundenen Unternehmen (Umlaufvermögen)": {
|
|
||||||
"account_number": "1340"
|
|
||||||
},
|
|
||||||
"Anteile an herrschender oder mit Mehrheit beteiligter Gesellschaft": {
|
|
||||||
"account_number": "1344"
|
|
||||||
},
|
|
||||||
"Sonstige Wertpapiere": {
|
|
||||||
"account_number": "1348"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"IV. Kassenbestand, Bundesbankguthaben, Guthaben bei Kreditinstituten und Schecks.": {
|
"IV. Kassenbestand, Bundesbankguthaben, Guthaben bei Kreditinstituten und Schecks.": {
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"Kasse": {
|
"Kasse": {
|
||||||
"is_group": 1,
|
|
||||||
"account_type": "Cash",
|
"account_type": "Cash",
|
||||||
|
"is_group": 1,
|
||||||
"Kasse": {
|
"Kasse": {
|
||||||
|
"is_group": 1,
|
||||||
"account_number": "1000",
|
"account_number": "1000",
|
||||||
"account_type": "Cash"
|
"account_type": "Cash"
|
||||||
}
|
}
|
||||||
@@ -185,13 +170,8 @@
|
|||||||
},
|
},
|
||||||
"IV. Verbindlichkeiten aus Lieferungen und Leistungen": {
|
"IV. Verbindlichkeiten aus Lieferungen und Leistungen": {
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"Verbindlichkeiten aus Lieferungen und Leistungen mit Kontokorrent": {
|
"Verbindlichkeiten aus Lieferungen u. Leistungen": {
|
||||||
"account_number": "1600",
|
"account_number": "1600",
|
||||||
"account_type": "Payable",
|
|
||||||
"is_group": 1
|
|
||||||
},
|
|
||||||
"Verbindlichkeiten aus Lieferungen und Leistungen ohne Kontokorrent": {
|
|
||||||
"account_number": "1610",
|
|
||||||
"account_type": "Payable"
|
"account_type": "Payable"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -220,32 +200,26 @@
|
|||||||
},
|
},
|
||||||
"Umsatzsteuer": {
|
"Umsatzsteuer": {
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"Umsatzsteuer 7 %": {
|
|
||||||
"account_number": "1771",
|
|
||||||
"account_type": "Tax",
|
"account_type": "Tax",
|
||||||
"tax_rate": 7.0
|
"Umsatzsteuer 7%": {
|
||||||
|
"account_number": "1771"
|
||||||
},
|
},
|
||||||
"Umsatzsteuer 19 %": {
|
"Umsatzsteuer 19%": {
|
||||||
"account_number": "1776",
|
"account_number": "1776"
|
||||||
"account_type": "Tax",
|
|
||||||
"tax_rate": 19.0
|
|
||||||
},
|
},
|
||||||
"Umsatzsteuer-Vorauszahlung": {
|
"Umsatzsteuer-Vorauszahlung": {
|
||||||
"account_number": "1780",
|
"account_number": "1780"
|
||||||
"account_type": "Tax"
|
|
||||||
},
|
},
|
||||||
"Umsatzsteuer-Vorauszahlung 1/11": {
|
"Umsatzsteuer-Vorauszahlung 1/11": {
|
||||||
"account_number": "1781"
|
"account_number": "1781"
|
||||||
},
|
},
|
||||||
"Umsatzsteuer nach § 13b UStG 19 %": {
|
"Umsatzsteuer \u00a7 13b UStG 19%": {
|
||||||
"account_number": "1787",
|
"account_number": "1787"
|
||||||
"account_type": "Tax",
|
|
||||||
"tax_rate": 19.0
|
|
||||||
},
|
},
|
||||||
"Umsatzsteuer Vorjahr": {
|
"Umsatzsteuer Vorjahr": {
|
||||||
"account_number": "1790"
|
"account_number": "1790"
|
||||||
},
|
},
|
||||||
"Umsatzsteuer frühere Jahre": {
|
"Umsatzsteuer fr\u00fchere Jahre": {
|
||||||
"account_number": "1791"
|
"account_number": "1791"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -261,35 +235,35 @@
|
|||||||
"is_group": 1
|
"is_group": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Erlöse u. Erträge 2/8": {
|
"Erl\u00f6se u. Ertr\u00e4ge 2/8": {
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"root_type": "Income",
|
"root_type": "Income",
|
||||||
"Erlöskonten 8": {
|
"Erl\u00f6skonten 8": {
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"Erlöse": {
|
"Erl\u00f6se": {
|
||||||
"account_number": "8200",
|
"account_number": "8200",
|
||||||
"account_type": "Income Account"
|
"account_type": "Income Account"
|
||||||
},
|
},
|
||||||
"Erlöse USt. 19 %": {
|
"Erl\u00f6se USt. 19%": {
|
||||||
"account_number": "8400",
|
"account_number": "8400",
|
||||||
"account_type": "Income Account"
|
"account_type": "Income Account"
|
||||||
},
|
},
|
||||||
"Erlöse USt. 7 %": {
|
"Erl\u00f6se USt. 7%": {
|
||||||
"account_number": "8300",
|
"account_number": "8300",
|
||||||
"account_type": "Income Account"
|
"account_type": "Income Account"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Ertragskonten 2": {
|
"Ertragskonten 2": {
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"sonstige Zinsen und ähnliche Erträge": {
|
"sonstige Zinsen und \u00e4hnliche Ertr\u00e4ge": {
|
||||||
"account_number": "2650",
|
"account_number": "2650",
|
||||||
"account_type": "Income Account"
|
"account_type": "Income Account"
|
||||||
},
|
},
|
||||||
"Außerordentliche Erträge": {
|
"Au\u00dferordentliche Ertr\u00e4ge": {
|
||||||
"account_number": "2500",
|
"account_number": "2500",
|
||||||
"account_type": "Income Account"
|
"account_type": "Income Account"
|
||||||
},
|
},
|
||||||
"Sonstige Erträge": {
|
"Sonstige Ertr\u00e4ge": {
|
||||||
"account_number": "2700",
|
"account_number": "2700",
|
||||||
"account_type": "Income Account"
|
"account_type": "Income Account"
|
||||||
}
|
}
|
||||||
@@ -298,18 +272,6 @@
|
|||||||
"Aufwendungen 2/4": {
|
"Aufwendungen 2/4": {
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"root_type": "Expense",
|
"root_type": "Expense",
|
||||||
"Fremdleistungen": {
|
|
||||||
"account_number": "3100",
|
|
||||||
"account_type": "Expense Account"
|
|
||||||
},
|
|
||||||
"Fremdleistungen ohne Vorsteuer": {
|
|
||||||
"account_number": "3109",
|
|
||||||
"account_type": "Expense Account"
|
|
||||||
},
|
|
||||||
"Bauleistungen eines im Inland ansässigen Unternehmers 19 % Vorsteuer und 19 % Umsatzsteuer": {
|
|
||||||
"account_number": "3120",
|
|
||||||
"account_type": "Expense Account"
|
|
||||||
},
|
|
||||||
"Wareneingang": {
|
"Wareneingang": {
|
||||||
"account_number": "3200"
|
"account_number": "3200"
|
||||||
},
|
},
|
||||||
@@ -384,7 +346,7 @@
|
|||||||
},
|
},
|
||||||
"Personalkosten": {
|
"Personalkosten": {
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"Gehälter": {
|
"Geh\u00e4lter": {
|
||||||
"account_number": "4120",
|
"account_number": "4120",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
},
|
},
|
||||||
@@ -392,15 +354,15 @@
|
|||||||
"account_number": "4130",
|
"account_number": "4130",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
},
|
},
|
||||||
"Aufwendungen für Altersvorsorge": {
|
"Aufwendungen f\u00fcr Altersvorsorge": {
|
||||||
"account_number": "4165",
|
"account_number": "4165",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
},
|
},
|
||||||
"Vermögenswirksame Leistungen": {
|
"Verm\u00f6genswirksame Leistungen": {
|
||||||
"account_number": "4170",
|
"account_number": "4170",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
},
|
},
|
||||||
"Aushilfslöhne": {
|
"Aushilfsl\u00f6hne": {
|
||||||
"account_number": "4190",
|
"account_number": "4190",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
}
|
}
|
||||||
@@ -422,18 +384,18 @@
|
|||||||
},
|
},
|
||||||
"Reparatur/Instandhaltung": {
|
"Reparatur/Instandhaltung": {
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"Reparaturen und Instandhaltungen von anderen Anlagen und Betriebs- und Geschäftsausstattung": {
|
"Reparatur u. Instandh. von Anlagen/Maschinen u. Betriebs- u. Gesch\u00e4ftsausst.": {
|
||||||
"account_number": "4805",
|
"account_number": "4805",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Versicherungsbeiträge": {
|
"Versicherungsbeitr\u00e4ge": {
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"Versicherungen": {
|
"Versicherungen": {
|
||||||
"account_number": "4360",
|
"account_number": "4360",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
},
|
},
|
||||||
"Beiträge": {
|
"Beitr\u00e4ge": {
|
||||||
"account_number": "4380",
|
"account_number": "4380",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
},
|
},
|
||||||
@@ -441,7 +403,7 @@
|
|||||||
"account_number": "4390",
|
"account_number": "4390",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
},
|
},
|
||||||
"steuerlich abzugsfähige Verspätungszuschläge und Zwangsgelder": {
|
"steuerlich abzugsf\u00e4hige Versp\u00e4tungszuschl\u00e4ge und Zwangsgelder": {
|
||||||
"account_number": "4396",
|
"account_number": "4396",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
}
|
}
|
||||||
@@ -456,7 +418,7 @@
|
|||||||
"account_number": "4653",
|
"account_number": "4653",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
},
|
},
|
||||||
"nicht abzugsfähige Betriebsausg. aus Werbe-, Repräs.- u. Reisekosten": {
|
"nicht abzugsf\u00e4hige Betriebsausg. aus Werbe-, Repr\u00e4s.- u. Reisekosten": {
|
||||||
"account_number": "4665",
|
"account_number": "4665",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
},
|
},
|
||||||
@@ -483,11 +445,11 @@
|
|||||||
"account_number": "4922",
|
"account_number": "4922",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
},
|
},
|
||||||
"Bürobedarf": {
|
"B\u00fcrobedarf": {
|
||||||
"account_number": "4930",
|
"account_number": "4930",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
},
|
},
|
||||||
"Zeitschriften, Bücher": {
|
"Zeitschriften, B\u00fccher": {
|
||||||
"account_number": "4940",
|
"account_number": "4940",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
},
|
},
|
||||||
@@ -495,11 +457,11 @@
|
|||||||
"account_number": "4945",
|
"account_number": "4945",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
},
|
},
|
||||||
"Buchführungskosten": {
|
"Buchf\u00fchrungskosten": {
|
||||||
"account_number": "4955",
|
"account_number": "4955",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
},
|
},
|
||||||
"Abschluß- u. Prüfungskosten": {
|
"Abschlu\u00df- u. Pr\u00fcfungskosten": {
|
||||||
"account_number": "4957",
|
"account_number": "4957",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
},
|
},
|
||||||
@@ -507,18 +469,18 @@
|
|||||||
"account_number": "4970",
|
"account_number": "4970",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
},
|
},
|
||||||
"Werkzeuge und Kleingeräte": {
|
"Werkzeuge und Kleinger\u00e4te": {
|
||||||
"account_number": "4985",
|
"account_number": "4985",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Zinsaufwendungen": {
|
"Zinsaufwendungen": {
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"Zinsaufwendungen für kurzfristige Verbindlichkeiten": {
|
"Zinsaufwendungen f\u00fcr kurzfristige Verbindlichkeiten": {
|
||||||
"account_number": "2110",
|
"account_number": "2110",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
},
|
},
|
||||||
"Zinsaufwendungen für KFZ Finanzierung": {
|
"Zinsaufwendungen f\u00fcr KFZ Finanzierung": {
|
||||||
"account_number": "2121",
|
"account_number": "2121",
|
||||||
"account_type": "Expense Account"
|
"account_type": "Expense Account"
|
||||||
}
|
}
|
||||||
@@ -532,10 +494,10 @@
|
|||||||
"Saldenvortrag Sachkonten": {
|
"Saldenvortrag Sachkonten": {
|
||||||
"account_number": "9000"
|
"account_number": "9000"
|
||||||
},
|
},
|
||||||
"Saldenvorträge Debitoren": {
|
"Saldenvortr\u00e4ge Debitoren": {
|
||||||
"account_number": "9008"
|
"account_number": "9008"
|
||||||
},
|
},
|
||||||
"Saldenvorträge Kreditoren": {
|
"Saldenvortr\u00e4ge Kreditoren": {
|
||||||
"account_number": "9009"
|
"account_number": "9009"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -551,13 +513,13 @@
|
|||||||
"Privatsteuern": {
|
"Privatsteuern": {
|
||||||
"account_number": "1810"
|
"account_number": "1810"
|
||||||
},
|
},
|
||||||
"Sonderausgaben beschränkt abzugsfähig": {
|
"Sonderausgaben beschr\u00e4nkt abzugsf\u00e4hig": {
|
||||||
"account_number": "1820"
|
"account_number": "1820"
|
||||||
},
|
},
|
||||||
"Sonderausgaben unbeschränkt abzugsfähig": {
|
"Sonderausgaben unbeschr\u00e4nkt abzugsf\u00e4hig": {
|
||||||
"account_number": "1830"
|
"account_number": "1830"
|
||||||
},
|
},
|
||||||
"Außergewöhnliche Belastungen": {
|
"Au\u00dfergew\u00f6hnliche Belastungen": {
|
||||||
"account_number": "1850"
|
"account_number": "1850"
|
||||||
},
|
},
|
||||||
"Privateinlagen": {
|
"Privateinlagen": {
|
||||||
|
|||||||
@@ -407,10 +407,13 @@
|
|||||||
"Bewertungskorrektur zu Forderungen aus Lieferungen und Leistungen": {
|
"Bewertungskorrektur zu Forderungen aus Lieferungen und Leistungen": {
|
||||||
"account_number": "9960"
|
"account_number": "9960"
|
||||||
},
|
},
|
||||||
"Forderungen aus Lieferungen und Leistungen mit Kontokorrent": {
|
"Debitoren": {
|
||||||
|
"is_group": 1,
|
||||||
|
"account_number": "10000"
|
||||||
|
},
|
||||||
|
"Forderungen aus Lieferungen und Leistungen": {
|
||||||
"account_number": "1200",
|
"account_number": "1200",
|
||||||
"account_type": "Receivable",
|
"account_type": "Receivable"
|
||||||
"is_group": 1
|
|
||||||
},
|
},
|
||||||
"Forderungen aus Lieferungen und Leistungen ohne Kontokorrent": {
|
"Forderungen aus Lieferungen und Leistungen ohne Kontokorrent": {
|
||||||
"account_number": "1210"
|
"account_number": "1210"
|
||||||
@@ -1135,15 +1138,18 @@
|
|||||||
"Bewertungskorrektur zu Verb. aus Lieferungen und Leistungen": {
|
"Bewertungskorrektur zu Verb. aus Lieferungen und Leistungen": {
|
||||||
"account_number": "9964"
|
"account_number": "9964"
|
||||||
},
|
},
|
||||||
"Verb. aus Lieferungen und Leistungen mit Kontokorrent": {
|
"Kreditoren": {
|
||||||
"account_number": "3300",
|
"account_number": "70000",
|
||||||
"account_type": "Payable",
|
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"Wareneingangs-Verrechnungskonto" : {
|
"Wareneingangs-Verrechnungskonto" : {
|
||||||
"account_number": "70001",
|
"account_number": "70001",
|
||||||
"account_type": "Stock Received But Not Billed"
|
"account_type": "Stock Received But Not Billed"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Verb. aus Lieferungen und Leistungen": {
|
||||||
|
"account_number": "3300",
|
||||||
|
"account_type": "Payable"
|
||||||
|
},
|
||||||
"Verb. aus Lieferungen und Leistungen ohne Kontokorrent": {
|
"Verb. aus Lieferungen und Leistungen ohne Kontokorrent": {
|
||||||
"account_number": "3310"
|
"account_number": "3310"
|
||||||
},
|
},
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,10 @@
|
|||||||
"country_code": "nl",
|
"country_code": "nl",
|
||||||
"name": "Netherlands - Grootboekschema",
|
"name": "Netherlands - Grootboekschema",
|
||||||
"tree": {
|
"tree": {
|
||||||
|
"FABRIKAGEREKENINGEN": {
|
||||||
|
"is_group": 1,
|
||||||
|
"root_type": "Expense"
|
||||||
|
},
|
||||||
"FINANCIELE REKENINGEN, KORTLOPENDE VORDERINGEN EN SCHULDEN": {
|
"FINANCIELE REKENINGEN, KORTLOPENDE VORDERINGEN EN SCHULDEN": {
|
||||||
"Bank": {
|
"Bank": {
|
||||||
"RABO Bank": {
|
"RABO Bank": {
|
||||||
@@ -9,144 +13,6 @@
|
|||||||
},
|
},
|
||||||
"account_type": "Bank"
|
"account_type": "Bank"
|
||||||
},
|
},
|
||||||
"LIQUIDE MIDDELEN": {
|
|
||||||
"ABN-AMRO bank": {},
|
|
||||||
"Bankbetaalkaarten": {},
|
|
||||||
"Effecten": {},
|
|
||||||
"Girobetaalkaarten": {},
|
|
||||||
"Kas": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Kas valuta": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Kleine kas": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Kruisposten": {},
|
|
||||||
"Postbank": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"TUSSENREKENINGEN": {
|
|
||||||
"Betaalwijze cadeaubonnen": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Betaalwijze chipknip": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Betaalwijze contant": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Betaalwijze pin": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Inkopen Nederland hoog": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Inkopen Nederland laag": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Inkopen Nederland onbelast": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Inkopen Nederland overig": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Inkopen Nederland verlegd": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Inkopen binnen EU hoog": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Inkopen binnen EU laag": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Inkopen binnen EU overig": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Inkopen buiten EU hoog": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Inkopen buiten EU laag": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Inkopen buiten EU overig": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Kassa 1": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Kassa 2": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Netto lonen": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Tegenrekening Inkopen": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Tussenrek. autom. betalingen": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Tussenrek. autom. loonbetalingen": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Tussenrek. cadeaubonbetalingen": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Tussenrekening balans": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Tussenrekening chipknip": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Tussenrekening correcties": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Tussenrekening pin": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"Vraagposten": {
|
|
||||||
"account_type": "Cash"
|
|
||||||
},
|
|
||||||
"VOORRAAD GRONDSTOFFEN, HULPMATERIALEN EN HANDELSGOEDEREN": {
|
|
||||||
"Emballage": {},
|
|
||||||
"Gereed product 1": {},
|
|
||||||
"Gereed product 2": {},
|
|
||||||
"Goederen 1": {},
|
|
||||||
"Goederen 2": {},
|
|
||||||
"Goederen in consignatie": {},
|
|
||||||
"Goederen onderweg": {},
|
|
||||||
"Grondstoffen 1": {},
|
|
||||||
"Grondstoffen 2": {},
|
|
||||||
"Halffabrikaten 1": {},
|
|
||||||
"Halffabrikaten 2": {},
|
|
||||||
"Hulpstoffen 1": {},
|
|
||||||
"Hulpstoffen 2": {},
|
|
||||||
"Kantoorbenodigdheden": {},
|
|
||||||
"Onderhanden werk": {},
|
|
||||||
"Verpakkingsmateriaal": {},
|
|
||||||
"Zegels": {},
|
|
||||||
"root_type": "Asset"
|
|
||||||
},
|
|
||||||
"root_type": "Asset"
|
|
||||||
},
|
|
||||||
"VORDERINGEN": {
|
|
||||||
"Debiteuren": {
|
|
||||||
"account_type": "Receivable"
|
|
||||||
},
|
|
||||||
"Dubieuze debiteuren": {},
|
|
||||||
"Overige vorderingen": {},
|
|
||||||
"Rekening-courant directie 1": {},
|
|
||||||
"Te ontvangen ziekengeld": {},
|
|
||||||
"Voorschotten personeel": {},
|
|
||||||
"Vooruitbetaalde kosten": {},
|
|
||||||
"Voorziening dubieuze debiteuren": {}
|
|
||||||
},
|
|
||||||
"root_type": "Asset"
|
|
||||||
},
|
|
||||||
"KORTLOPENDE SCHULDEN": {
|
"KORTLOPENDE SCHULDEN": {
|
||||||
"Af te dragen Btw-verlegd": {
|
"Af te dragen Btw-verlegd": {
|
||||||
"account_type": "Tax"
|
"account_type": "Tax"
|
||||||
@@ -203,13 +69,42 @@
|
|||||||
"Vakantiegeld 1": {},
|
"Vakantiegeld 1": {},
|
||||||
"Vakantiezegels": {},
|
"Vakantiezegels": {},
|
||||||
"Vennootschapsbelasting": {},
|
"Vennootschapsbelasting": {},
|
||||||
"Vooruit ontvangen bedr.": {},
|
"Vooruit ontvangen bedr.": {}
|
||||||
"is_group": 1,
|
},
|
||||||
"root_type": "Liability"
|
"LIQUIDE MIDDELEN": {
|
||||||
|
"ABN-AMRO bank": {},
|
||||||
|
"Bankbetaalkaarten": {},
|
||||||
|
"Effecten": {},
|
||||||
|
"Girobetaalkaarten": {},
|
||||||
|
"Kas": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Kas valuta": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Kleine kas": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Kruisposten": {},
|
||||||
|
"Postbank": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"VORDERINGEN": {
|
||||||
|
"Debiteuren": {
|
||||||
|
"account_type": "Receivable"
|
||||||
|
},
|
||||||
|
"Dubieuze debiteuren": {},
|
||||||
|
"Overige vorderingen": {},
|
||||||
|
"Rekening-courant directie 1": {},
|
||||||
|
"Te ontvangen ziekengeld": {},
|
||||||
|
"Voorschotten personeel": {},
|
||||||
|
"Vooruitbetaalde kosten": {},
|
||||||
|
"Voorziening dubieuze debiteuren": {}
|
||||||
|
},
|
||||||
|
"root_type": "Asset"
|
||||||
},
|
},
|
||||||
"FABRIKAGEREKENINGEN": {
|
|
||||||
"is_group": 1,
|
|
||||||
"root_type": "Expense",
|
|
||||||
"INDIRECTE KOSTEN": {
|
"INDIRECTE KOSTEN": {
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"root_type": "Expense"
|
"root_type": "Expense"
|
||||||
@@ -396,49 +291,91 @@
|
|||||||
"Priv\u00e9-gebruik auto's": {},
|
"Priv\u00e9-gebruik auto's": {},
|
||||||
"Wegenbelasting": {}
|
"Wegenbelasting": {}
|
||||||
},
|
},
|
||||||
"VOORRAAD GEREED PRODUCT EN ONDERHANDEN WERK": {
|
|
||||||
"Betalingskort. crediteuren": {},
|
|
||||||
"Garantiekosten": {},
|
|
||||||
"Hulpmaterialen": {},
|
|
||||||
"Inkomende vrachten": {
|
|
||||||
"account_type": "Expenses Included In Valuation"
|
|
||||||
},
|
|
||||||
"Inkoop import buiten EU hoog": {},
|
|
||||||
"Inkoop import buiten EU laag": {},
|
|
||||||
"Inkoop import buiten EU overig": {},
|
|
||||||
"Inkoopbonussen": {},
|
|
||||||
"Inkoopkosten": {},
|
|
||||||
"Inkoopprovisie": {},
|
|
||||||
"Inkopen BTW verlegd": {},
|
|
||||||
"Inkopen EU hoog tarief": {},
|
|
||||||
"Inkopen EU laag tarief": {},
|
|
||||||
"Inkopen EU overig": {},
|
|
||||||
"Inkopen hoog": {},
|
|
||||||
"Inkopen laag": {},
|
|
||||||
"Inkopen nul": {},
|
|
||||||
"Inkopen overig": {},
|
|
||||||
"Invoerkosten": {},
|
|
||||||
"Kosten inkoopvereniging": {},
|
|
||||||
"Kostprijs omzet grondstoffen": {
|
|
||||||
"account_type": "Cost of Goods Sold"
|
|
||||||
},
|
|
||||||
"Kostprijs omzet handelsgoederen": {},
|
|
||||||
"Onttrekking uitgev.garantie": {},
|
|
||||||
"Priv\u00e9-gebruik goederen": {},
|
|
||||||
"Stock aanpassing": {
|
|
||||||
"account_type": "Stock Adjustment"
|
|
||||||
},
|
|
||||||
"Tegenrekening inkoop": {},
|
|
||||||
"Toev. Voorz. incour. grondst.": {},
|
|
||||||
"Toevoeging garantieverpl.": {},
|
|
||||||
"Toevoeging voorz. incour. handelsgoed.": {},
|
|
||||||
"Uitbesteed werk": {},
|
|
||||||
"Voorz. Incourourant grondst.": {},
|
|
||||||
"Voorz.incour. handelsgoed.": {},
|
|
||||||
"root_type": "Expense"
|
"root_type": "Expense"
|
||||||
},
|
},
|
||||||
"root_type": "Expense"
|
"TUSSENREKENINGEN": {
|
||||||
}
|
"Betaalwijze cadeaubonnen": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Betaalwijze chipknip": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Betaalwijze contant": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Betaalwijze pin": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Inkopen Nederland hoog": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Inkopen Nederland laag": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Inkopen Nederland onbelast": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Inkopen Nederland overig": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Inkopen Nederland verlegd": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Inkopen binnen EU hoog": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Inkopen binnen EU laag": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Inkopen binnen EU overig": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Inkopen buiten EU hoog": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Inkopen buiten EU laag": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Inkopen buiten EU overig": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Kassa 1": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Kassa 2": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Netto lonen": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Tegenrekening Inkopen": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Tussenrek. autom. betalingen": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Tussenrek. autom. loonbetalingen": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Tussenrek. cadeaubonbetalingen": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Tussenrekening balans": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Tussenrekening chipknip": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Tussenrekening correcties": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Tussenrekening pin": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"Vraagposten": {
|
||||||
|
"account_type": "Cash"
|
||||||
|
},
|
||||||
|
"root_type": "Asset"
|
||||||
},
|
},
|
||||||
"VASTE ACTIVA, EIGEN VERMOGEN, LANGLOPEND VREEMD VERMOGEN EN VOORZIENINGEN": {
|
"VASTE ACTIVA, EIGEN VERMOGEN, LANGLOPEND VREEMD VERMOGEN EN VOORZIENINGEN": {
|
||||||
"EIGEN VERMOGEN": {
|
"EIGEN VERMOGEN": {
|
||||||
@@ -665,7 +602,7 @@
|
|||||||
"account_type": "Equity"
|
"account_type": "Equity"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root_type": "Equity"
|
"root_type": "Asset"
|
||||||
},
|
},
|
||||||
"VERKOOPRESULTATEN": {
|
"VERKOOPRESULTATEN": {
|
||||||
"Diensten fabric. 0% niet-EU": {},
|
"Diensten fabric. 0% niet-EU": {},
|
||||||
@@ -690,6 +627,67 @@
|
|||||||
"Verleende Kredietbep. fabricage": {},
|
"Verleende Kredietbep. fabricage": {},
|
||||||
"Verleende Kredietbep. handel": {},
|
"Verleende Kredietbep. handel": {},
|
||||||
"root_type": "Income"
|
"root_type": "Income"
|
||||||
|
},
|
||||||
|
"VOORRAAD GEREED PRODUCT EN ONDERHANDEN WERK": {
|
||||||
|
"Betalingskort. crediteuren": {},
|
||||||
|
"Garantiekosten": {},
|
||||||
|
"Hulpmaterialen": {},
|
||||||
|
"Inkomende vrachten": {
|
||||||
|
"account_type": "Expenses Included In Valuation"
|
||||||
|
},
|
||||||
|
"Inkoop import buiten EU hoog": {},
|
||||||
|
"Inkoop import buiten EU laag": {},
|
||||||
|
"Inkoop import buiten EU overig": {},
|
||||||
|
"Inkoopbonussen": {},
|
||||||
|
"Inkoopkosten": {},
|
||||||
|
"Inkoopprovisie": {},
|
||||||
|
"Inkopen BTW verlegd": {},
|
||||||
|
"Inkopen EU hoog tarief": {},
|
||||||
|
"Inkopen EU laag tarief": {},
|
||||||
|
"Inkopen EU overig": {},
|
||||||
|
"Inkopen hoog": {},
|
||||||
|
"Inkopen laag": {},
|
||||||
|
"Inkopen nul": {},
|
||||||
|
"Inkopen overig": {},
|
||||||
|
"Invoerkosten": {},
|
||||||
|
"Kosten inkoopvereniging": {},
|
||||||
|
"Kostprijs omzet grondstoffen": {
|
||||||
|
"account_type": "Cost of Goods Sold"
|
||||||
|
},
|
||||||
|
"Kostprijs omzet handelsgoederen": {},
|
||||||
|
"Onttrekking uitgev.garantie": {},
|
||||||
|
"Priv\u00e9-gebruik goederen": {},
|
||||||
|
"Stock aanpassing": {
|
||||||
|
"account_type": "Stock Adjustment"
|
||||||
|
},
|
||||||
|
"Tegenrekening inkoop": {},
|
||||||
|
"Toev. Voorz. incour. grondst.": {},
|
||||||
|
"Toevoeging garantieverpl.": {},
|
||||||
|
"Toevoeging voorz. incour. handelsgoed.": {},
|
||||||
|
"Uitbesteed werk": {},
|
||||||
|
"Voorz. Incourourant grondst.": {},
|
||||||
|
"Voorz.incour. handelsgoed.": {},
|
||||||
|
"root_type": "Expense"
|
||||||
|
},
|
||||||
|
"VOORRAAD GRONDSTOFFEN, HULPMATERIALEN EN HANDELSGOEDEREN": {
|
||||||
|
"Emballage": {},
|
||||||
|
"Gereed product 1": {},
|
||||||
|
"Gereed product 2": {},
|
||||||
|
"Goederen 1": {},
|
||||||
|
"Goederen 2": {},
|
||||||
|
"Goederen in consignatie": {},
|
||||||
|
"Goederen onderweg": {},
|
||||||
|
"Grondstoffen 1": {},
|
||||||
|
"Grondstoffen 2": {},
|
||||||
|
"Halffabrikaten 1": {},
|
||||||
|
"Halffabrikaten 2": {},
|
||||||
|
"Hulpstoffen 1": {},
|
||||||
|
"Hulpstoffen 2": {},
|
||||||
|
"Kantoorbenodigdheden": {},
|
||||||
|
"Onderhanden werk": {},
|
||||||
|
"Verpakkingsmateriaal": {},
|
||||||
|
"Zegels": {},
|
||||||
|
"root_type": "Asset"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,17 +5,10 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.test_runner import make_test_records
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.account.account import (
|
from erpnext.accounts.doctype.account.account import merge_account, update_account_number
|
||||||
InvalidAccountMergeError,
|
|
||||||
merge_account,
|
|
||||||
update_account_number,
|
|
||||||
)
|
|
||||||
from erpnext.stock import get_company_default_inventory_account, get_warehouse_account
|
from erpnext.stock import get_company_default_inventory_account, get_warehouse_account
|
||||||
|
|
||||||
test_dependencies = ["Company"]
|
|
||||||
|
|
||||||
|
|
||||||
class TestAccount(unittest.TestCase):
|
class TestAccount(unittest.TestCase):
|
||||||
def test_rename_account(self):
|
def test_rename_account(self):
|
||||||
@@ -51,53 +44,49 @@ class TestAccount(unittest.TestCase):
|
|||||||
frappe.delete_doc("Account", "1211-11-4 - 6 - Debtors 1 - Test - - _TC")
|
frappe.delete_doc("Account", "1211-11-4 - 6 - Debtors 1 - Test - - _TC")
|
||||||
|
|
||||||
def test_merge_account(self):
|
def test_merge_account(self):
|
||||||
create_account(
|
if not frappe.db.exists("Account", "Current Assets - _TC"):
|
||||||
account_name="Current Assets",
|
acc = frappe.new_doc("Account")
|
||||||
is_group=1,
|
acc.account_name = "Current Assets"
|
||||||
parent_account="Application of Funds (Assets) - _TC",
|
acc.is_group = 1
|
||||||
company="_Test Company",
|
acc.parent_account = "Application of Funds (Assets) - _TC"
|
||||||
)
|
acc.company = "_Test Company"
|
||||||
|
acc.insert()
|
||||||
create_account(
|
if not frappe.db.exists("Account", "Securities and Deposits - _TC"):
|
||||||
account_name="Securities and Deposits",
|
acc = frappe.new_doc("Account")
|
||||||
is_group=1,
|
acc.account_name = "Securities and Deposits"
|
||||||
parent_account="Current Assets - _TC",
|
acc.parent_account = "Current Assets - _TC"
|
||||||
company="_Test Company",
|
acc.is_group = 1
|
||||||
)
|
acc.company = "_Test Company"
|
||||||
|
acc.insert()
|
||||||
create_account(
|
if not frappe.db.exists("Account", "Earnest Money - _TC"):
|
||||||
account_name="Earnest Money",
|
acc = frappe.new_doc("Account")
|
||||||
parent_account="Securities and Deposits - _TC",
|
acc.account_name = "Earnest Money"
|
||||||
company="_Test Company",
|
acc.parent_account = "Securities and Deposits - _TC"
|
||||||
)
|
acc.company = "_Test Company"
|
||||||
|
acc.insert()
|
||||||
create_account(
|
if not frappe.db.exists("Account", "Cash In Hand - _TC"):
|
||||||
account_name="Cash In Hand",
|
acc = frappe.new_doc("Account")
|
||||||
is_group=1,
|
acc.account_name = "Cash In Hand"
|
||||||
parent_account="Current Assets - _TC",
|
acc.is_group = 1
|
||||||
company="_Test Company",
|
acc.parent_account = "Current Assets - _TC"
|
||||||
)
|
acc.company = "_Test Company"
|
||||||
|
acc.insert()
|
||||||
create_account(
|
if not frappe.db.exists("Account", "Accumulated Depreciation - _TC"):
|
||||||
account_name="Receivable INR",
|
acc = frappe.new_doc("Account")
|
||||||
parent_account="Current Assets - _TC",
|
acc.account_name = "Accumulated Depreciation"
|
||||||
company="_Test Company",
|
acc.parent_account = "Fixed Assets - _TC"
|
||||||
account_currency="INR",
|
acc.company = "_Test Company"
|
||||||
)
|
acc.account_type = "Accumulated Depreciation"
|
||||||
|
acc.insert()
|
||||||
create_account(
|
|
||||||
account_name="Receivable USD",
|
|
||||||
parent_account="Current Assets - _TC",
|
|
||||||
company="_Test Company",
|
|
||||||
account_currency="USD",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
doc = frappe.get_doc("Account", "Securities and Deposits - _TC")
|
||||||
parent = frappe.db.get_value("Account", "Earnest Money - _TC", "parent_account")
|
parent = frappe.db.get_value("Account", "Earnest Money - _TC", "parent_account")
|
||||||
|
|
||||||
self.assertEqual(parent, "Securities and Deposits - _TC")
|
self.assertEqual(parent, "Securities and Deposits - _TC")
|
||||||
|
|
||||||
merge_account("Securities and Deposits - _TC", "Cash In Hand - _TC")
|
merge_account(
|
||||||
|
"Securities and Deposits - _TC", "Cash In Hand - _TC", doc.is_group, doc.root_type, doc.company
|
||||||
|
)
|
||||||
parent = frappe.db.get_value("Account", "Earnest Money - _TC", "parent_account")
|
parent = frappe.db.get_value("Account", "Earnest Money - _TC", "parent_account")
|
||||||
|
|
||||||
# Parent account of the child account changes after merging
|
# Parent account of the child account changes after merging
|
||||||
@@ -106,28 +95,30 @@ class TestAccount(unittest.TestCase):
|
|||||||
# Old account doesn't exist after merging
|
# Old account doesn't exist after merging
|
||||||
self.assertFalse(frappe.db.exists("Account", "Securities and Deposits - _TC"))
|
self.assertFalse(frappe.db.exists("Account", "Securities and Deposits - _TC"))
|
||||||
|
|
||||||
|
doc = frappe.get_doc("Account", "Current Assets - _TC")
|
||||||
|
|
||||||
# Raise error as is_group property doesn't match
|
# Raise error as is_group property doesn't match
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
InvalidAccountMergeError,
|
frappe.ValidationError,
|
||||||
merge_account,
|
merge_account,
|
||||||
"Current Assets - _TC",
|
"Current Assets - _TC",
|
||||||
"Accumulated Depreciation - _TC",
|
"Accumulated Depreciation - _TC",
|
||||||
|
doc.is_group,
|
||||||
|
doc.root_type,
|
||||||
|
doc.company,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
doc = frappe.get_doc("Account", "Capital Stock - _TC")
|
||||||
|
|
||||||
# Raise error as root_type property doesn't match
|
# Raise error as root_type property doesn't match
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
InvalidAccountMergeError,
|
frappe.ValidationError,
|
||||||
merge_account,
|
merge_account,
|
||||||
"Capital Stock - _TC",
|
"Capital Stock - _TC",
|
||||||
"Softwares - _TC",
|
"Softwares - _TC",
|
||||||
)
|
doc.is_group,
|
||||||
|
doc.root_type,
|
||||||
# Raise error as currency doesn't match
|
doc.company,
|
||||||
self.assertRaises(
|
|
||||||
InvalidAccountMergeError,
|
|
||||||
merge_account,
|
|
||||||
"Receivable INR - _TC",
|
|
||||||
"Receivable USD - _TC",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_account_sync(self):
|
def test_account_sync(self):
|
||||||
@@ -197,58 +188,6 @@ class TestAccount(unittest.TestCase):
|
|||||||
frappe.delete_doc("Account", "1234 - Test Rename Sync Account - _TC4")
|
frappe.delete_doc("Account", "1234 - Test Rename Sync Account - _TC4")
|
||||||
frappe.delete_doc("Account", "1234 - Test Rename Sync Account - _TC5")
|
frappe.delete_doc("Account", "1234 - Test Rename Sync Account - _TC5")
|
||||||
|
|
||||||
def test_account_currency_sync(self):
|
|
||||||
"""
|
|
||||||
In a parent->child company setup, child should inherit parent account currency if explicitly specified.
|
|
||||||
"""
|
|
||||||
|
|
||||||
make_test_records("Company")
|
|
||||||
|
|
||||||
frappe.local.flags.pop("ignore_root_company_validation", None)
|
|
||||||
|
|
||||||
def create_bank_account():
|
|
||||||
acc = frappe.new_doc("Account")
|
|
||||||
acc.account_name = "_Test Bank JPY"
|
|
||||||
|
|
||||||
acc.parent_account = "Temporary Accounts - _TC6"
|
|
||||||
acc.company = "_Test Company 6"
|
|
||||||
return acc
|
|
||||||
|
|
||||||
acc = create_bank_account()
|
|
||||||
# Explicitly set currency
|
|
||||||
acc.account_currency = "JPY"
|
|
||||||
acc.insert()
|
|
||||||
self.assertTrue(
|
|
||||||
frappe.db.exists(
|
|
||||||
{
|
|
||||||
"doctype": "Account",
|
|
||||||
"account_name": "_Test Bank JPY",
|
|
||||||
"account_currency": "JPY",
|
|
||||||
"company": "_Test Company 7",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
frappe.delete_doc("Account", "_Test Bank JPY - _TC6")
|
|
||||||
frappe.delete_doc("Account", "_Test Bank JPY - _TC7")
|
|
||||||
|
|
||||||
acc = create_bank_account()
|
|
||||||
# default currency is used
|
|
||||||
acc.insert()
|
|
||||||
self.assertTrue(
|
|
||||||
frappe.db.exists(
|
|
||||||
{
|
|
||||||
"doctype": "Account",
|
|
||||||
"account_name": "_Test Bank JPY",
|
|
||||||
"account_currency": "USD",
|
|
||||||
"company": "_Test Company 7",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
frappe.delete_doc("Account", "_Test Bank JPY - _TC6")
|
|
||||||
frappe.delete_doc("Account", "_Test Bank JPY - _TC7")
|
|
||||||
|
|
||||||
def test_child_company_account_rename_sync(self):
|
def test_child_company_account_rename_sync(self):
|
||||||
frappe.local.flags.pop("ignore_root_company_validation", None)
|
frappe.local.flags.pop("ignore_root_company_validation", None)
|
||||||
|
|
||||||
@@ -358,7 +297,7 @@ def _make_test_records(verbose=None):
|
|||||||
# fixed asset depreciation
|
# fixed asset depreciation
|
||||||
["_Test Fixed Asset", "Current Assets", 0, "Fixed Asset", None],
|
["_Test Fixed Asset", "Current Assets", 0, "Fixed Asset", None],
|
||||||
["_Test Accumulated Depreciations", "Current Assets", 0, "Accumulated Depreciation", None],
|
["_Test Accumulated Depreciations", "Current Assets", 0, "Accumulated Depreciation", None],
|
||||||
["_Test Depreciations", "Expenses", 0, "Depreciation", None],
|
["_Test Depreciations", "Expenses", 0, None, None],
|
||||||
["_Test Gain/Loss on Asset Disposal", "Expenses", 0, None, None],
|
["_Test Gain/Loss on Asset Disposal", "Expenses", 0, None, None],
|
||||||
# Receivable / Payable Account
|
# Receivable / Payable Account
|
||||||
["_Test Receivable", "Current Assets", 0, "Receivable", None],
|
["_Test Receivable", "Current Assets", 0, "Receivable", None],
|
||||||
@@ -406,20 +345,11 @@ def create_account(**kwargs):
|
|||||||
"Account", filters={"account_name": kwargs.get("account_name"), "company": kwargs.get("company")}
|
"Account", filters={"account_name": kwargs.get("account_name"), "company": kwargs.get("company")}
|
||||||
)
|
)
|
||||||
if account:
|
if account:
|
||||||
account = frappe.get_doc("Account", account)
|
return account
|
||||||
account.update(
|
|
||||||
dict(
|
|
||||||
is_group=kwargs.get("is_group", 0),
|
|
||||||
parent_account=kwargs.get("parent_account"),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
account.save()
|
|
||||||
return account.name
|
|
||||||
else:
|
else:
|
||||||
account = frappe.get_doc(
|
account = frappe.get_doc(
|
||||||
dict(
|
dict(
|
||||||
doctype="Account",
|
doctype="Account",
|
||||||
is_group=kwargs.get("is_group", 0),
|
|
||||||
account_name=kwargs.get("account_name"),
|
account_name=kwargs.get("account_name"),
|
||||||
account_type=kwargs.get("account_type"),
|
account_type=kwargs.get("account_type"),
|
||||||
parent_account=kwargs.get("parent_account"),
|
parent_account=kwargs.get("parent_account"),
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
|
|
||||||
// For license information, please see license.txt
|
|
||||||
|
|
||||||
// frappe.ui.form.on("Account Closing Balance", {
|
|
||||||
// refresh(frm) {
|
|
||||||
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
@@ -1,164 +0,0 @@
|
|||||||
{
|
|
||||||
"actions": [],
|
|
||||||
"creation": "2023-02-21 15:20:59.586811",
|
|
||||||
"default_view": "List",
|
|
||||||
"doctype": "DocType",
|
|
||||||
"document_type": "Document",
|
|
||||||
"engine": "InnoDB",
|
|
||||||
"field_order": [
|
|
||||||
"closing_date",
|
|
||||||
"account",
|
|
||||||
"cost_center",
|
|
||||||
"debit",
|
|
||||||
"credit",
|
|
||||||
"account_currency",
|
|
||||||
"debit_in_account_currency",
|
|
||||||
"credit_in_account_currency",
|
|
||||||
"project",
|
|
||||||
"company",
|
|
||||||
"finance_book",
|
|
||||||
"period_closing_voucher",
|
|
||||||
"is_period_closing_voucher_entry"
|
|
||||||
],
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldname": "closing_date",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"in_filter": 1,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Closing Date",
|
|
||||||
"oldfieldname": "posting_date",
|
|
||||||
"oldfieldtype": "Date",
|
|
||||||
"search_index": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "account",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"in_filter": 1,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 1,
|
|
||||||
"label": "Account",
|
|
||||||
"oldfieldname": "account",
|
|
||||||
"oldfieldtype": "Link",
|
|
||||||
"options": "Account",
|
|
||||||
"search_index": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "cost_center",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"in_filter": 1,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Cost Center",
|
|
||||||
"oldfieldname": "cost_center",
|
|
||||||
"oldfieldtype": "Link",
|
|
||||||
"options": "Cost Center"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "debit",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"label": "Debit Amount",
|
|
||||||
"oldfieldname": "debit",
|
|
||||||
"oldfieldtype": "Currency",
|
|
||||||
"options": "Company:company:default_currency"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "credit",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"label": "Credit Amount",
|
|
||||||
"oldfieldname": "credit",
|
|
||||||
"oldfieldtype": "Currency",
|
|
||||||
"options": "Company:company:default_currency"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "account_currency",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Account Currency",
|
|
||||||
"options": "Currency"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "debit_in_account_currency",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"label": "Debit Amount in Account Currency",
|
|
||||||
"options": "account_currency"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "credit_in_account_currency",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"label": "Credit Amount in Account Currency",
|
|
||||||
"options": "account_currency"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "project",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Project",
|
|
||||||
"options": "Project"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "company",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"in_filter": 1,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 1,
|
|
||||||
"label": "Company",
|
|
||||||
"oldfieldname": "company",
|
|
||||||
"oldfieldtype": "Link",
|
|
||||||
"options": "Company",
|
|
||||||
"search_index": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "finance_book",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Finance Book",
|
|
||||||
"options": "Finance Book"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "period_closing_voucher",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"in_standard_filter": 1,
|
|
||||||
"label": "Period Closing Voucher",
|
|
||||||
"options": "Period Closing Voucher",
|
|
||||||
"search_index": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"fieldname": "is_period_closing_voucher_entry",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Is Period Closing Voucher Entry"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"icon": "fa fa-list",
|
|
||||||
"in_create": 1,
|
|
||||||
"links": [],
|
|
||||||
"modified": "2023-03-06 08:56:36.393237",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Accounts",
|
|
||||||
"name": "Account Closing Balance",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
|
||||||
{
|
|
||||||
"email": 1,
|
|
||||||
"export": 1,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Accounts User"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"email": 1,
|
|
||||||
"export": 1,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Accounts Manager"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"export": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Auditor"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"states": []
|
|
||||||
}
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
|
|
||||||
# For license information, please see license.txt
|
|
||||||
|
|
||||||
import frappe
|
|
||||||
from frappe.model.document import Document
|
|
||||||
from frappe.utils import cint, cstr
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
|
|
||||||
get_accounting_dimensions,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class AccountClosingBalance(Document):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def make_closing_entries(closing_entries, voucher_name, company, closing_date):
|
|
||||||
accounting_dimensions = get_accounting_dimensions()
|
|
||||||
|
|
||||||
previous_closing_entries = get_previous_closing_entries(
|
|
||||||
company, closing_date, accounting_dimensions
|
|
||||||
)
|
|
||||||
combined_entries = closing_entries + previous_closing_entries
|
|
||||||
|
|
||||||
merged_entries = aggregate_with_last_account_closing_balance(
|
|
||||||
combined_entries, accounting_dimensions
|
|
||||||
)
|
|
||||||
|
|
||||||
for key, value in merged_entries.items():
|
|
||||||
cle = frappe.new_doc("Account Closing Balance")
|
|
||||||
cle.update(value)
|
|
||||||
cle.update(value["dimensions"])
|
|
||||||
cle.update(
|
|
||||||
{
|
|
||||||
"period_closing_voucher": voucher_name,
|
|
||||||
"closing_date": closing_date,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
cle.flags.ignore_permissions = True
|
|
||||||
cle.flags.ignore_links = True
|
|
||||||
cle.submit()
|
|
||||||
|
|
||||||
|
|
||||||
def aggregate_with_last_account_closing_balance(entries, accounting_dimensions):
|
|
||||||
merged_entries = {}
|
|
||||||
for entry in entries:
|
|
||||||
key, key_values = generate_key(entry, accounting_dimensions)
|
|
||||||
merged_entries.setdefault(
|
|
||||||
key,
|
|
||||||
{
|
|
||||||
"debit": 0,
|
|
||||||
"credit": 0,
|
|
||||||
"debit_in_account_currency": 0,
|
|
||||||
"credit_in_account_currency": 0,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
merged_entries[key]["dimensions"] = key_values
|
|
||||||
merged_entries[key]["debit"] += entry.get("debit")
|
|
||||||
merged_entries[key]["credit"] += entry.get("credit")
|
|
||||||
merged_entries[key]["debit_in_account_currency"] += entry.get("debit_in_account_currency")
|
|
||||||
merged_entries[key]["credit_in_account_currency"] += entry.get("credit_in_account_currency")
|
|
||||||
|
|
||||||
return merged_entries
|
|
||||||
|
|
||||||
|
|
||||||
def generate_key(entry, accounting_dimensions):
|
|
||||||
key = [
|
|
||||||
cstr(entry.get("account")),
|
|
||||||
cstr(entry.get("account_currency")),
|
|
||||||
cstr(entry.get("cost_center")),
|
|
||||||
cstr(entry.get("project")),
|
|
||||||
cstr(entry.get("finance_book")),
|
|
||||||
cint(entry.get("is_period_closing_voucher_entry")),
|
|
||||||
]
|
|
||||||
|
|
||||||
key_values = {
|
|
||||||
"company": cstr(entry.get("company")),
|
|
||||||
"account": cstr(entry.get("account")),
|
|
||||||
"account_currency": cstr(entry.get("account_currency")),
|
|
||||||
"cost_center": cstr(entry.get("cost_center")),
|
|
||||||
"project": cstr(entry.get("project")),
|
|
||||||
"finance_book": cstr(entry.get("finance_book")),
|
|
||||||
"is_period_closing_voucher_entry": cint(entry.get("is_period_closing_voucher_entry")),
|
|
||||||
}
|
|
||||||
for dimension in accounting_dimensions:
|
|
||||||
key.append(cstr(entry.get(dimension)))
|
|
||||||
key_values[dimension] = cstr(entry.get(dimension))
|
|
||||||
|
|
||||||
return tuple(key), key_values
|
|
||||||
|
|
||||||
|
|
||||||
def get_previous_closing_entries(company, closing_date, accounting_dimensions):
|
|
||||||
entries = []
|
|
||||||
last_period_closing_voucher = frappe.db.get_all(
|
|
||||||
"Period Closing Voucher",
|
|
||||||
filters={"docstatus": 1, "company": company, "posting_date": ("<", closing_date)},
|
|
||||||
fields=["name"],
|
|
||||||
order_by="posting_date desc",
|
|
||||||
limit=1,
|
|
||||||
)
|
|
||||||
|
|
||||||
if last_period_closing_voucher:
|
|
||||||
account_closing_balance = frappe.qb.DocType("Account Closing Balance")
|
|
||||||
query = frappe.qb.from_(account_closing_balance).select(
|
|
||||||
account_closing_balance.company,
|
|
||||||
account_closing_balance.account,
|
|
||||||
account_closing_balance.account_currency,
|
|
||||||
account_closing_balance.debit,
|
|
||||||
account_closing_balance.credit,
|
|
||||||
account_closing_balance.debit_in_account_currency,
|
|
||||||
account_closing_balance.credit_in_account_currency,
|
|
||||||
account_closing_balance.cost_center,
|
|
||||||
account_closing_balance.project,
|
|
||||||
account_closing_balance.finance_book,
|
|
||||||
account_closing_balance.is_period_closing_voucher_entry,
|
|
||||||
)
|
|
||||||
|
|
||||||
for dimension in accounting_dimensions:
|
|
||||||
query = query.select(account_closing_balance[dimension])
|
|
||||||
|
|
||||||
query = query.where(
|
|
||||||
account_closing_balance.period_closing_voucher == last_period_closing_voucher[0].name
|
|
||||||
)
|
|
||||||
entries = query.run(as_dict=1)
|
|
||||||
|
|
||||||
return entries
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors
|
|
||||||
# See license.txt
|
|
||||||
|
|
||||||
# import frappe
|
|
||||||
from frappe.tests.utils import FrappeTestCase
|
|
||||||
|
|
||||||
|
|
||||||
class TestAccountClosingBalance(FrappeTestCase):
|
|
||||||
pass
|
|
||||||
@@ -1,86 +1,63 @@
|
|||||||
// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Accounting Dimension", {
|
frappe.ui.form.on('Accounting Dimension', {
|
||||||
refresh: function (frm) {
|
refresh: function(frm) {
|
||||||
frm.set_query("document_type", () => {
|
frm.set_query('document_type', () => {
|
||||||
let invalid_doctypes = frappe.model.core_doctypes_list;
|
let invalid_doctypes = frappe.model.core_doctypes_list;
|
||||||
invalid_doctypes.push(
|
invalid_doctypes.push('Accounting Dimension', 'Project',
|
||||||
"Accounting Dimension",
|
'Cost Center', 'Accounting Dimension Detail', 'Company');
|
||||||
"Project",
|
|
||||||
"Cost Center",
|
|
||||||
"Accounting Dimension Detail",
|
|
||||||
"Company"
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
name: ["not in", invalid_doctypes],
|
name: ['not in', invalid_doctypes]
|
||||||
},
|
}
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
frm.set_query("offsetting_account", "dimension_defaults", function (doc, cdt, cdn) {
|
|
||||||
let d = locals[cdt][cdn];
|
|
||||||
return {
|
|
||||||
filters: {
|
|
||||||
company: d.company,
|
|
||||||
root_type: ["in", ["Asset", "Liability"]],
|
|
||||||
is_group: 0,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!frm.is_new()) {
|
if (!frm.is_new()) {
|
||||||
frm.add_custom_button(__("Show {0}", [frm.doc.document_type]), function () {
|
frm.add_custom_button(__('Show {0}', [frm.doc.document_type]), function () {
|
||||||
frappe.set_route("List", frm.doc.document_type);
|
frappe.set_route("List", frm.doc.document_type);
|
||||||
});
|
});
|
||||||
|
|
||||||
let button = frm.doc.disabled ? "Enable" : "Disable";
|
let button = frm.doc.disabled ? "Enable" : "Disable";
|
||||||
|
|
||||||
frm.add_custom_button(__(button), function () {
|
frm.add_custom_button(__(button), function() {
|
||||||
frm.set_value("disabled", 1 - frm.doc.disabled);
|
|
||||||
|
frm.set_value('disabled', 1 - frm.doc.disabled);
|
||||||
|
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.disable_dimension",
|
method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.disable_dimension",
|
||||||
args: {
|
args: {
|
||||||
doc: frm.doc,
|
doc: frm.doc
|
||||||
},
|
},
|
||||||
freeze: true,
|
freeze: true,
|
||||||
callback: function (r) {
|
callback: function(r) {
|
||||||
let message = frm.doc.disabled ? "Dimension Disabled" : "Dimension Enabled";
|
let message = frm.doc.disabled ? "Dimension Disabled" : "Dimension Enabled";
|
||||||
frm.save();
|
frm.save();
|
||||||
frappe.show_alert({ message: __(message), indicator: "green" });
|
frappe.show_alert({message:__(message), indicator:'green'});
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
document_type: function (frm) {
|
document_type: function(frm) {
|
||||||
frm.set_value("label", frm.doc.document_type);
|
|
||||||
frm.set_value("fieldname", frappe.model.scrub(frm.doc.document_type));
|
|
||||||
|
|
||||||
frappe.db.get_value(
|
frm.set_value('label', frm.doc.document_type);
|
||||||
"Accounting Dimension",
|
frm.set_value('fieldname', frappe.model.scrub(frm.doc.document_type));
|
||||||
{ document_type: frm.doc.document_type },
|
|
||||||
"document_type",
|
frappe.db.get_value('Accounting Dimension', {'document_type': frm.doc.document_type}, 'document_type', (r) => {
|
||||||
(r) => {
|
|
||||||
if (r && r.document_type) {
|
if (r && r.document_type) {
|
||||||
frm.set_df_property(
|
frm.set_df_property('document_type', 'description', "Document type is already set as dimension");
|
||||||
"document_type",
|
|
||||||
"description",
|
|
||||||
"Document type is already set as dimension"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
frappe.ui.form.on("Accounting Dimension Detail", {
|
frappe.ui.form.on('Accounting Dimension Detail', {
|
||||||
dimension_defaults_add: function (frm, cdt, cdn) {
|
dimension_defaults_add: function(frm, cdt, cdn) {
|
||||||
let row = locals[cdt][cdn];
|
let row = locals[cdt][cdn];
|
||||||
row.reference_document = frm.doc.document_type;
|
row.reference_document = frm.doc.document_type;
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -39,8 +39,6 @@ class AccountingDimension(Document):
|
|||||||
if not self.is_new():
|
if not self.is_new():
|
||||||
self.validate_document_type_change()
|
self.validate_document_type_change()
|
||||||
|
|
||||||
self.validate_dimension_defaults()
|
|
||||||
|
|
||||||
def validate_document_type_change(self):
|
def validate_document_type_change(self):
|
||||||
doctype_before_save = frappe.db.get_value("Accounting Dimension", self.name, "document_type")
|
doctype_before_save = frappe.db.get_value("Accounting Dimension", self.name, "document_type")
|
||||||
if doctype_before_save != self.document_type:
|
if doctype_before_save != self.document_type:
|
||||||
@@ -48,27 +46,17 @@ class AccountingDimension(Document):
|
|||||||
message += _("Please create a new Accounting Dimension if required.")
|
message += _("Please create a new Accounting Dimension if required.")
|
||||||
frappe.throw(message)
|
frappe.throw(message)
|
||||||
|
|
||||||
def validate_dimension_defaults(self):
|
|
||||||
companies = []
|
|
||||||
for default in self.get("dimension_defaults"):
|
|
||||||
if default.company not in companies:
|
|
||||||
companies.append(default.company)
|
|
||||||
else:
|
|
||||||
frappe.throw(_("Company {0} is added more than once").format(frappe.bold(default.company)))
|
|
||||||
|
|
||||||
def after_insert(self):
|
def after_insert(self):
|
||||||
if frappe.flags.in_test:
|
if frappe.flags.in_test:
|
||||||
make_dimension_in_accounting_doctypes(doc=self)
|
make_dimension_in_accounting_doctypes(doc=self)
|
||||||
else:
|
else:
|
||||||
frappe.enqueue(
|
frappe.enqueue(make_dimension_in_accounting_doctypes, doc=self, queue="long")
|
||||||
make_dimension_in_accounting_doctypes, doc=self, queue="long", enqueue_after_commit=True
|
|
||||||
)
|
|
||||||
|
|
||||||
def on_trash(self):
|
def on_trash(self):
|
||||||
if frappe.flags.in_test:
|
if frappe.flags.in_test:
|
||||||
delete_accounting_dimension(doc=self)
|
delete_accounting_dimension(doc=self)
|
||||||
else:
|
else:
|
||||||
frappe.enqueue(delete_accounting_dimension, doc=self, queue="long", enqueue_after_commit=True)
|
frappe.enqueue(delete_accounting_dimension, doc=self, queue="long")
|
||||||
|
|
||||||
def set_fieldname_and_label(self):
|
def set_fieldname_and_label(self):
|
||||||
if not self.label:
|
if not self.label:
|
||||||
@@ -281,12 +269,6 @@ def get_dimensions(with_cost_center_and_project=False):
|
|||||||
as_dict=1,
|
as_dict=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
if isinstance(with_cost_center_and_project, str):
|
|
||||||
if with_cost_center_and_project.lower().strip() == "true":
|
|
||||||
with_cost_center_and_project = True
|
|
||||||
else:
|
|
||||||
with_cost_center_and_project = False
|
|
||||||
|
|
||||||
if with_cost_center_and_project:
|
if with_cost_center_and_project:
|
||||||
dimension_filters.extend(
|
dimension_filters.extend(
|
||||||
[
|
[
|
||||||
@@ -301,30 +283,3 @@ def get_dimensions(with_cost_center_and_project=False):
|
|||||||
default_dimensions_map[dimension.company][dimension.fieldname] = dimension.default_dimension
|
default_dimensions_map[dimension.company][dimension.fieldname] = dimension.default_dimension
|
||||||
|
|
||||||
return dimension_filters, default_dimensions_map
|
return dimension_filters, default_dimensions_map
|
||||||
|
|
||||||
|
|
||||||
def create_accounting_dimensions_for_doctype(doctype):
|
|
||||||
accounting_dimensions = frappe.db.get_all(
|
|
||||||
"Accounting Dimension", fields=["fieldname", "label", "document_type", "disabled"]
|
|
||||||
)
|
|
||||||
|
|
||||||
if not accounting_dimensions:
|
|
||||||
return
|
|
||||||
|
|
||||||
for d in accounting_dimensions:
|
|
||||||
field = frappe.db.get_value("Custom Field", {"dt": doctype, "fieldname": d.fieldname})
|
|
||||||
|
|
||||||
if field:
|
|
||||||
continue
|
|
||||||
|
|
||||||
df = {
|
|
||||||
"fieldname": d.fieldname,
|
|
||||||
"label": d.label,
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"options": d.document_type,
|
|
||||||
"insert_after": "accounting_dimensions_section",
|
|
||||||
}
|
|
||||||
|
|
||||||
create_custom_field(doctype, df, ignore_validate=True)
|
|
||||||
|
|
||||||
frappe.clear_cache(doctype=doctype)
|
|
||||||
|
|||||||
@@ -8,10 +8,7 @@
|
|||||||
"reference_document",
|
"reference_document",
|
||||||
"default_dimension",
|
"default_dimension",
|
||||||
"mandatory_for_bs",
|
"mandatory_for_bs",
|
||||||
"mandatory_for_pl",
|
"mandatory_for_pl"
|
||||||
"column_break_lqns",
|
|
||||||
"automatically_post_balancing_accounting_entry",
|
|
||||||
"offsetting_account"
|
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -53,23 +50,6 @@
|
|||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Mandatory For Profit and Loss Account"
|
"label": "Mandatory For Profit and Loss Account"
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"fieldname": "automatically_post_balancing_accounting_entry",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Automatically post balancing accounting entry"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "offsetting_account",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Offsetting Account",
|
|
||||||
"mandatory_depends_on": "eval: doc.automatically_post_balancing_accounting_entry",
|
|
||||||
"options": "Account"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "column_break_lqns",
|
|
||||||
"fieldtype": "Column Break"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Accounting Dimension Filter", {
|
frappe.ui.form.on('Accounting Dimension Filter', {
|
||||||
refresh: function (frm, cdt, cdn) {
|
refresh: function(frm, cdt, cdn) {
|
||||||
let help_content = `<table class="table table-bordered" style="background-color: var(--scrollbar-track-color);">
|
let help_content =
|
||||||
|
`<table class="table table-bordered" style="background-color: var(--scrollbar-track-color);">
|
||||||
<tr><td>
|
<tr><td>
|
||||||
<p>
|
<p>
|
||||||
<i class="fa fa-hand-right"></i>
|
<i class="fa fa-hand-right"></i>
|
||||||
@@ -12,70 +13,67 @@ frappe.ui.form.on("Accounting Dimension Filter", {
|
|||||||
</td></tr>
|
</td></tr>
|
||||||
</table>`;
|
</table>`;
|
||||||
|
|
||||||
frm.set_df_property("dimension_filter_help", "options", help_content);
|
frm.set_df_property('dimension_filter_help', 'options', help_content);
|
||||||
},
|
},
|
||||||
onload: function (frm) {
|
onload: function(frm) {
|
||||||
frm.set_query("applicable_on_account", "accounts", function () {
|
frm.set_query('applicable_on_account', 'accounts', function() {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
company: frm.doc.company,
|
'company': frm.doc.company
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
frappe.db.get_list("Accounting Dimension", { fields: ["document_type"] }).then((res) => {
|
frappe.db.get_list('Accounting Dimension',
|
||||||
let options = ["Cost Center", "Project"];
|
{fields: ['document_type']}).then((res) => {
|
||||||
|
let options = ['Cost Center', 'Project'];
|
||||||
|
|
||||||
res.forEach((dimension) => {
|
res.forEach((dimension) => {
|
||||||
options.push(dimension.document_type);
|
options.push(dimension.document_type);
|
||||||
});
|
});
|
||||||
|
|
||||||
frm.set_df_property("accounting_dimension", "options", options);
|
frm.set_df_property('accounting_dimension', 'options', options);
|
||||||
});
|
});
|
||||||
|
|
||||||
frm.trigger("setup_filters");
|
frm.trigger('setup_filters');
|
||||||
},
|
},
|
||||||
|
|
||||||
setup_filters: function (frm) {
|
setup_filters: function(frm) {
|
||||||
let filters = {};
|
let filters = {};
|
||||||
|
|
||||||
if (frm.doc.accounting_dimension) {
|
if (frm.doc.accounting_dimension) {
|
||||||
frappe.model.with_doctype(frm.doc.accounting_dimension, function () {
|
frappe.model.with_doctype(frm.doc.accounting_dimension, function() {
|
||||||
if (frappe.model.is_tree(frm.doc.accounting_dimension)) {
|
if (frappe.model.is_tree(frm.doc.accounting_dimension)) {
|
||||||
filters["is_group"] = 0;
|
filters['is_group'] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frappe.meta.has_field(frm.doc.accounting_dimension, "company")) {
|
if (frappe.meta.has_field(frm.doc.accounting_dimension, 'company')) {
|
||||||
filters["company"] = frm.doc.company;
|
filters['company'] = frm.doc.company;
|
||||||
}
|
}
|
||||||
|
|
||||||
frm.set_query("dimension_value", "dimensions", function () {
|
frm.set_query('dimension_value', 'dimensions', function() {
|
||||||
return {
|
return {
|
||||||
filters: filters,
|
filters: filters
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
accounting_dimension: function (frm) {
|
accounting_dimension: function(frm) {
|
||||||
frm.clear_table("dimensions");
|
frm.clear_table("dimensions");
|
||||||
let row = frm.add_child("dimensions");
|
let row = frm.add_child("dimensions");
|
||||||
row.accounting_dimension = frm.doc.accounting_dimension;
|
row.accounting_dimension = frm.doc.accounting_dimension;
|
||||||
frm.fields_dict["dimensions"].grid.update_docfield_property(
|
frm.fields_dict["dimensions"].grid.update_docfield_property("dimension_value", "label", frm.doc.accounting_dimension);
|
||||||
"dimension_value",
|
|
||||||
"label",
|
|
||||||
frm.doc.accounting_dimension
|
|
||||||
);
|
|
||||||
frm.refresh_field("dimensions");
|
frm.refresh_field("dimensions");
|
||||||
frm.trigger("setup_filters");
|
frm.trigger('setup_filters');
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
frappe.ui.form.on("Allowed Dimension", {
|
frappe.ui.form.on('Allowed Dimension', {
|
||||||
dimensions_add: function (frm, cdt, cdn) {
|
dimensions_add: function(frm, cdt, cdn) {
|
||||||
let row = locals[cdt][cdn];
|
let row = locals[cdt][cdn];
|
||||||
row.accounting_dimension = frm.doc.accounting_dimension;
|
row.accounting_dimension = frm.doc.accounting_dimension;
|
||||||
frm.refresh_field("dimensions");
|
frm.refresh_field("dimensions");
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,33 +1,24 @@
|
|||||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Accounting Period", {
|
frappe.ui.form.on('Accounting Period', {
|
||||||
onload: function (frm) {
|
onload: function(frm) {
|
||||||
if (
|
if(frm.doc.closed_documents.length === 0 || (frm.doc.closed_documents.length === 1 && frm.doc.closed_documents[0].document_type == undefined)) {
|
||||||
frm.doc.closed_documents.length === 0 ||
|
|
||||||
(frm.doc.closed_documents.length === 1 && frm.doc.closed_documents[0].document_type == undefined)
|
|
||||||
) {
|
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "get_doctypes_for_closing",
|
method: "get_doctypes_for_closing",
|
||||||
doc: frm.doc,
|
doc:frm.doc,
|
||||||
callback: function (r) {
|
callback: function(r) {
|
||||||
if (r.message) {
|
if(r.message) {
|
||||||
cur_frm.clear_table("closed_documents");
|
cur_frm.clear_table("closed_documents");
|
||||||
r.message.forEach(function (element) {
|
r.message.forEach(function(element) {
|
||||||
var c = frm.add_child("closed_documents");
|
var c = frm.add_child("closed_documents");
|
||||||
c.document_type = element.document_type;
|
c.document_type = element.document_type;
|
||||||
c.closed = element.closed;
|
c.closed = element.closed;
|
||||||
});
|
});
|
||||||
refresh_field("closed_documents");
|
refresh_field("closed_documents");
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
frm.set_query("document_type", "closed_documents", () => {
|
|
||||||
return {
|
|
||||||
query: "erpnext.controllers.queries.get_doctypes_for_closing",
|
|
||||||
};
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,10 +11,6 @@ class OverlapError(frappe.ValidationError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ClosedAccountingPeriod(frappe.ValidationError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class AccountingPeriod(Document):
|
class AccountingPeriod(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_overlap()
|
self.validate_overlap()
|
||||||
@@ -69,42 +65,3 @@ class AccountingPeriod(Document):
|
|||||||
"closed_documents",
|
"closed_documents",
|
||||||
{"document_type": doctype_for_closing.document_type, "closed": doctype_for_closing.closed},
|
{"document_type": doctype_for_closing.document_type, "closed": doctype_for_closing.closed},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def validate_accounting_period_on_doc_save(doc, method=None):
|
|
||||||
if doc.doctype == "Bank Clearance":
|
|
||||||
return
|
|
||||||
elif doc.doctype == "Asset":
|
|
||||||
if doc.is_existing_asset:
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
date = doc.available_for_use_date
|
|
||||||
elif doc.doctype == "Asset Repair":
|
|
||||||
date = doc.completion_date
|
|
||||||
else:
|
|
||||||
date = doc.posting_date
|
|
||||||
|
|
||||||
ap = frappe.qb.DocType("Accounting Period")
|
|
||||||
cd = frappe.qb.DocType("Closed Document")
|
|
||||||
|
|
||||||
accounting_period = (
|
|
||||||
frappe.qb.from_(ap)
|
|
||||||
.from_(cd)
|
|
||||||
.select(ap.name)
|
|
||||||
.where(
|
|
||||||
(ap.name == cd.parent)
|
|
||||||
& (ap.company == doc.company)
|
|
||||||
& (cd.closed == 1)
|
|
||||||
& (cd.document_type == doc.doctype)
|
|
||||||
& (date >= ap.start_date)
|
|
||||||
& (date <= ap.end_date)
|
|
||||||
)
|
|
||||||
).run(as_dict=1)
|
|
||||||
|
|
||||||
if accounting_period:
|
|
||||||
frappe.throw(
|
|
||||||
_("You cannot create a {0} within the closed Accounting Period {1}").format(
|
|
||||||
doc.doctype, frappe.bold(accounting_period[0]["name"])
|
|
||||||
),
|
|
||||||
ClosedAccountingPeriod,
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -6,11 +6,9 @@ import unittest
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import add_months, nowdate
|
from frappe.utils import add_months, nowdate
|
||||||
|
|
||||||
from erpnext.accounts.doctype.accounting_period.accounting_period import (
|
from erpnext.accounts.doctype.accounting_period.accounting_period import OverlapError
|
||||||
ClosedAccountingPeriod,
|
|
||||||
OverlapError,
|
|
||||||
)
|
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
|
from erpnext.accounts.general_ledger import ClosedAccountingPeriod
|
||||||
|
|
||||||
test_dependencies = ["Item"]
|
test_dependencies = ["Item"]
|
||||||
|
|
||||||
@@ -35,9 +33,9 @@ class TestAccountingPeriod(unittest.TestCase):
|
|||||||
ap1.save()
|
ap1.save()
|
||||||
|
|
||||||
doc = create_sales_invoice(
|
doc = create_sales_invoice(
|
||||||
do_not_save=1, cost_center="_Test Company - _TC", warehouse="Stores - _TC"
|
do_not_submit=1, cost_center="_Test Company - _TC", warehouse="Stores - _TC"
|
||||||
)
|
)
|
||||||
self.assertRaises(ClosedAccountingPeriod, doc.save)
|
self.assertRaises(ClosedAccountingPeriod, doc.submit)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
for d in frappe.get_all("Accounting Period"):
|
for d in frappe.get_all("Accounting Period"):
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Accounts Settings", {
|
frappe.ui.form.on('Accounts Settings', {
|
||||||
refresh: function (frm) {},
|
refresh: function(frm) {
|
||||||
|
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,8 +19,6 @@
|
|||||||
"column_break_17",
|
"column_break_17",
|
||||||
"enable_common_party_accounting",
|
"enable_common_party_accounting",
|
||||||
"allow_multi_currency_invoices_against_single_party_account",
|
"allow_multi_currency_invoices_against_single_party_account",
|
||||||
"journals_section",
|
|
||||||
"merge_similar_account_heads",
|
|
||||||
"report_setting_section",
|
"report_setting_section",
|
||||||
"use_custom_cash_flow",
|
"use_custom_cash_flow",
|
||||||
"deferred_accounting_settings_section",
|
"deferred_accounting_settings_section",
|
||||||
@@ -33,16 +31,12 @@
|
|||||||
"determine_address_tax_category_from",
|
"determine_address_tax_category_from",
|
||||||
"column_break_19",
|
"column_break_19",
|
||||||
"add_taxes_from_item_tax_template",
|
"add_taxes_from_item_tax_template",
|
||||||
"book_tax_discount_loss",
|
|
||||||
"print_settings",
|
"print_settings",
|
||||||
"show_inclusive_tax_in_print",
|
"show_inclusive_tax_in_print",
|
||||||
"show_taxes_as_table_in_print",
|
|
||||||
"column_break_12",
|
"column_break_12",
|
||||||
"show_payment_schedule_in_print",
|
"show_payment_schedule_in_print",
|
||||||
"currency_exchange_section",
|
"currency_exchange_section",
|
||||||
"allow_stale",
|
"allow_stale",
|
||||||
"section_break_jpd0",
|
|
||||||
"auto_reconcile_payments",
|
|
||||||
"stale_days",
|
"stale_days",
|
||||||
"invoicing_settings_tab",
|
"invoicing_settings_tab",
|
||||||
"accounts_transactions_settings_section",
|
"accounts_transactions_settings_section",
|
||||||
@@ -60,20 +54,9 @@
|
|||||||
"closing_settings_tab",
|
"closing_settings_tab",
|
||||||
"period_closing_settings_section",
|
"period_closing_settings_section",
|
||||||
"acc_frozen_upto",
|
"acc_frozen_upto",
|
||||||
"ignore_account_closing_balance",
|
|
||||||
"column_break_25",
|
"column_break_25",
|
||||||
"frozen_accounts_modifier",
|
"frozen_accounts_modifier",
|
||||||
"report_settings_sb",
|
"report_settings_sb"
|
||||||
"banking_tab",
|
|
||||||
"enable_party_matching",
|
|
||||||
"enable_fuzzy_matching",
|
|
||||||
"tab_break_dpet",
|
|
||||||
"show_balance_in_coa",
|
|
||||||
"reports_tab",
|
|
||||||
"remarks_section",
|
|
||||||
"general_ledger_remarks_length",
|
|
||||||
"column_break_lvjk",
|
|
||||||
"receivable_payable_remarks_length"
|
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -184,6 +167,11 @@
|
|||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"label": "Stale Days"
|
"label": "Stale Days"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "report_settings_sb",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Report Settings"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"description": "Only select this if you have set up the Cash Flow Mapper documents",
|
"description": "Only select this if you have set up the Cash Flow Mapper documents",
|
||||||
@@ -193,7 +181,6 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"description": "Payment Terms from orders will be fetched into the invoices as is",
|
|
||||||
"fieldname": "automatically_fetch_payment_terms",
|
"fieldname": "automatically_fetch_payment_terms",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Automatically Fetch Payment Terms from Order"
|
"label": "Automatically Fetch Payment Terms from Order"
|
||||||
@@ -360,108 +347,6 @@
|
|||||||
"fieldname": "allow_multi_currency_invoices_against_single_party_account",
|
"fieldname": "allow_multi_currency_invoices_against_single_party_account",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Allow multi-currency invoices against single party account "
|
"label": "Allow multi-currency invoices against single party account "
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"description": "Split Early Payment Discount Loss into Income and Tax Loss",
|
|
||||||
"fieldname": "book_tax_discount_loss",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Book Tax Loss on Early Payment Discount"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "journals_section",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"label": "Journals"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"description": "Rows with Same Account heads will be merged on Ledger",
|
|
||||||
"fieldname": "merge_similar_account_heads",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Merge Similar Account Heads"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "section_break_jpd0",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"label": "Payment Reconciliations"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"fieldname": "auto_reconcile_payments",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Auto Reconcile Payments"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"fieldname": "show_taxes_as_table_in_print",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Show Taxes as Table in Print"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "banking_tab",
|
|
||||||
"fieldtype": "Tab Break",
|
|
||||||
"label": "Banking"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"description": "Auto match and set the Party in Bank Transactions",
|
|
||||||
"fieldname": "enable_party_matching",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Enable Automatic Party Matching"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"depends_on": "enable_party_matching",
|
|
||||||
"description": "Approximately match the description/party name against parties",
|
|
||||||
"fieldname": "enable_fuzzy_matching",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Enable Fuzzy Matching"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"description": "Financial reports will be generated using GL Entry doctypes (should be enabled if Period Closing Voucher is not posted for all years sequentially or missing) ",
|
|
||||||
"fieldname": "ignore_account_closing_balance",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Ignore Account Closing Balance"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "tab_break_dpet",
|
|
||||||
"fieldtype": "Tab Break",
|
|
||||||
"label": "Chart Of Accounts"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "1",
|
|
||||||
"fieldname": "show_balance_in_coa",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Show Balances in Chart Of Accounts"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "reports_tab",
|
|
||||||
"fieldtype": "Tab Break",
|
|
||||||
"label": "Reports"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"description": "Truncates 'Remarks' column to set character length",
|
|
||||||
"fieldname": "general_ledger_remarks_length",
|
|
||||||
"fieldtype": "Int",
|
|
||||||
"label": "General Ledger"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"description": "Truncates 'Remarks' column to set character length",
|
|
||||||
"fieldname": "receivable_payable_remarks_length",
|
|
||||||
"fieldtype": "Int",
|
|
||||||
"label": "Accounts Receivable/Payable"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "column_break_lvjk",
|
|
||||||
"fieldtype": "Column Break"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "remarks_section",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"label": "Remarks Column Length"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "icon-cog",
|
"icon": "icon-cog",
|
||||||
@@ -469,7 +354,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-11-20 09:37:47.650347",
|
"modified": "2022-11-27 21:49:52.538655",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Accounts Settings",
|
"name": "Accounts Settings",
|
||||||
|
|||||||
@@ -14,33 +14,22 @@ from erpnext.stock.utils import check_pending_reposting
|
|||||||
|
|
||||||
|
|
||||||
class AccountsSettings(Document):
|
class AccountsSettings(Document):
|
||||||
def validate(self):
|
def on_update(self):
|
||||||
old_doc = self.get_doc_before_save()
|
frappe.clear_cache()
|
||||||
clear_cache = False
|
|
||||||
|
|
||||||
if old_doc.add_taxes_from_item_tax_template != self.add_taxes_from_item_tax_template:
|
def validate(self):
|
||||||
frappe.db.set_default(
|
frappe.db.set_default(
|
||||||
"add_taxes_from_item_tax_template", self.get("add_taxes_from_item_tax_template", 0)
|
"add_taxes_from_item_tax_template", self.get("add_taxes_from_item_tax_template", 0)
|
||||||
)
|
)
|
||||||
clear_cache = True
|
|
||||||
|
|
||||||
if old_doc.enable_common_party_accounting != self.enable_common_party_accounting:
|
|
||||||
frappe.db.set_default(
|
frappe.db.set_default(
|
||||||
"enable_common_party_accounting", self.get("enable_common_party_accounting", 0)
|
"enable_common_party_accounting", self.get("enable_common_party_accounting", 0)
|
||||||
)
|
)
|
||||||
clear_cache = True
|
|
||||||
|
|
||||||
self.validate_stale_days()
|
self.validate_stale_days()
|
||||||
|
|
||||||
if old_doc.show_payment_schedule_in_print != self.show_payment_schedule_in_print:
|
|
||||||
self.enable_payment_schedule_in_print()
|
self.enable_payment_schedule_in_print()
|
||||||
|
|
||||||
if old_doc.acc_frozen_upto != self.acc_frozen_upto:
|
|
||||||
self.validate_pending_reposts()
|
self.validate_pending_reposts()
|
||||||
|
|
||||||
if clear_cache:
|
|
||||||
frappe.clear_cache()
|
|
||||||
|
|
||||||
def validate_stale_days(self):
|
def validate_stale_days(self):
|
||||||
if not self.allow_stale and cint(self.stale_days) <= 0:
|
if not self.allow_stale and cint(self.stale_days) <= 0:
|
||||||
frappe.msgprint(
|
frappe.msgprint(
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
frappe.ui.form.on("Accounts Settings", {
|
|
||||||
refresh: function (frm) {
|
frappe.ui.form.on('Accounts Settings', {
|
||||||
|
refresh: function(frm) {
|
||||||
frm.set_df_property("acc_frozen_upto", "label", "Books Closed Through");
|
frm.set_df_property("acc_frozen_upto", "label", "Books Closed Through");
|
||||||
frm.set_df_property(
|
frm.set_df_property("frozen_accounts_modifier", "label", "Role Allowed to Close Books & Make Changes to Closed Periods");
|
||||||
"frozen_accounts_modifier",
|
|
||||||
"label",
|
|
||||||
"Role Allowed to Close Books & Make Changes to Closed Periods"
|
|
||||||
);
|
|
||||||
frm.set_df_property("credit_controller", "label", "Credit Manager");
|
frm.set_df_property("credit_controller", "label", "Credit Manager");
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "company",
|
"fieldname": "company",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"ignore_user_permissions": 1,
|
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Company",
|
"label": "Company",
|
||||||
"options": "Company",
|
"options": "Company",
|
||||||
@@ -20,7 +19,7 @@
|
|||||||
],
|
],
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-01-03 11:13:02.669632",
|
"modified": "2020-05-01 12:32:34.044911",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Allowed To Transact With",
|
"name": "Allowed To Transact With",
|
||||||
@@ -29,6 +28,5 @@
|
|||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"states": [],
|
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
@@ -1,39 +1,41 @@
|
|||||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
frappe.provide("erpnext.integrations");
|
frappe.provide('erpnext.integrations');
|
||||||
|
|
||||||
frappe.ui.form.on("Bank", {
|
frappe.ui.form.on('Bank', {
|
||||||
onload: function (frm) {
|
onload: function(frm) {
|
||||||
add_fields_to_mapping_table(frm);
|
add_fields_to_mapping_table(frm);
|
||||||
},
|
},
|
||||||
refresh: function (frm) {
|
refresh: function(frm) {
|
||||||
add_fields_to_mapping_table(frm);
|
add_fields_to_mapping_table(frm);
|
||||||
|
|
||||||
frappe.dynamic_link = { doc: frm.doc, fieldname: "name", doctype: "Bank" };
|
frappe.dynamic_link = { doc: frm.doc, fieldname: 'name', doctype: 'Bank' };
|
||||||
|
|
||||||
frm.toggle_display(["address_html", "contact_html"], !frm.doc.__islocal);
|
frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
|
||||||
|
|
||||||
if (frm.doc.__islocal) {
|
if (frm.doc.__islocal) {
|
||||||
frm.set_df_property("address_and_contact", "hidden", 1);
|
frm.set_df_property('address_and_contact', 'hidden', 1);
|
||||||
frappe.contacts.clear_address_and_contact(frm);
|
frappe.contacts.clear_address_and_contact(frm);
|
||||||
} else {
|
}
|
||||||
frm.set_df_property("address_and_contact", "hidden", 0);
|
else {
|
||||||
|
frm.set_df_property('address_and_contact', 'hidden', 0);
|
||||||
frappe.contacts.render_address_and_contact(frm);
|
frappe.contacts.render_address_and_contact(frm);
|
||||||
}
|
}
|
||||||
if (frm.doc.plaid_access_token) {
|
if (frm.doc.plaid_access_token) {
|
||||||
frm.add_custom_button(__("Refresh Plaid Link"), () => {
|
frm.add_custom_button(__('Refresh Plaid Link'), () => {
|
||||||
new erpnext.integrations.refreshPlaidLink(frm.doc.plaid_access_token);
|
new erpnext.integrations.refreshPlaidLink(frm.doc.plaid_access_token);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
let add_fields_to_mapping_table = function (frm) {
|
let add_fields_to_mapping_table = function (frm) {
|
||||||
let options = [];
|
let options = [];
|
||||||
|
|
||||||
frappe.model.with_doctype("Bank Transaction", function () {
|
frappe.model.with_doctype("Bank Transaction", function() {
|
||||||
let meta = frappe.get_meta("Bank Transaction");
|
let meta = frappe.get_meta("Bank Transaction");
|
||||||
meta.fields.forEach((value) => {
|
meta.fields.forEach(value => {
|
||||||
if (!["Section Break", "Column Break"].includes(value.fieldtype)) {
|
if (!["Section Break", "Column Break"].includes(value.fieldtype)) {
|
||||||
options.push(value.fieldname);
|
options.push(value.fieldname);
|
||||||
}
|
}
|
||||||
@@ -41,32 +43,30 @@ let add_fields_to_mapping_table = function (frm) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
frm.fields_dict.bank_transaction_mapping.grid.update_docfield_property(
|
frm.fields_dict.bank_transaction_mapping.grid.update_docfield_property(
|
||||||
"bank_transaction_field",
|
'bank_transaction_field', 'options', options
|
||||||
"options",
|
|
||||||
options
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
erpnext.integrations.refreshPlaidLink = class refreshPlaidLink {
|
erpnext.integrations.refreshPlaidLink = class refreshPlaidLink {
|
||||||
constructor(access_token) {
|
constructor(access_token) {
|
||||||
this.access_token = access_token;
|
this.access_token = access_token;
|
||||||
this.plaidUrl = "https://cdn.plaid.com/link/v2/stable/link-initialize.js";
|
this.plaidUrl = 'https://cdn.plaid.com/link/v2/stable/link-initialize.js';
|
||||||
this.init_config();
|
this.init_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
async init_config() {
|
async init_config() {
|
||||||
this.plaid_env = await frappe.db.get_single_value("Plaid Settings", "plaid_env");
|
this.plaid_env = await frappe.db.get_single_value('Plaid Settings', 'plaid_env');
|
||||||
this.token = await this.get_link_token_for_update();
|
this.token = await this.get_link_token_for_update();
|
||||||
this.init_plaid();
|
this.init_plaid();
|
||||||
}
|
}
|
||||||
|
|
||||||
async get_link_token_for_update() {
|
async get_link_token_for_update() {
|
||||||
const token = frappe.xcall(
|
const token = frappe.xcall(
|
||||||
"erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.get_link_token_for_update",
|
'erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.get_link_token_for_update',
|
||||||
{ access_token: this.access_token }
|
{ access_token: this.access_token }
|
||||||
);
|
)
|
||||||
if (!token) {
|
if (!token) {
|
||||||
frappe.throw(__("Cannot retrieve link token for update. Check Error Log for more information"));
|
frappe.throw(__('Cannot retrieve link token for update. Check Error Log for more information'));
|
||||||
}
|
}
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
@@ -93,13 +93,13 @@ erpnext.integrations.refreshPlaidLink = class refreshPlaidLink {
|
|||||||
resolve();
|
resolve();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const el = document.createElement("script");
|
const el = document.createElement('script');
|
||||||
el.type = "text/javascript";
|
el.type = 'text/javascript';
|
||||||
el.async = true;
|
el.async = true;
|
||||||
el.src = src;
|
el.src = src;
|
||||||
el.addEventListener("load", resolve);
|
el.addEventListener('load', resolve);
|
||||||
el.addEventListener("error", reject);
|
el.addEventListener('error', reject);
|
||||||
el.addEventListener("abort", reject);
|
el.addEventListener('abort', reject);
|
||||||
document.head.appendChild(el);
|
document.head.appendChild(el);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -108,29 +108,16 @@ erpnext.integrations.refreshPlaidLink = class refreshPlaidLink {
|
|||||||
me.linkHandler = Plaid.create({
|
me.linkHandler = Plaid.create({
|
||||||
env: me.plaid_env,
|
env: me.plaid_env,
|
||||||
token: me.token,
|
token: me.token,
|
||||||
onSuccess: me.plaid_success,
|
onSuccess: me.plaid_success
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onScriptError(error) {
|
onScriptError(error) {
|
||||||
frappe.msgprint(
|
frappe.msgprint(__("There was an issue connecting to Plaid's authentication server. Check browser console for more information"));
|
||||||
__(
|
|
||||||
"There was an issue connecting to Plaid's authentication server. Check browser console for more information"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
plaid_success(token, response) {
|
plaid_success(token, response) {
|
||||||
frappe
|
frappe.show_alert({ message: __('Plaid Link Updated'), indicator: 'green' });
|
||||||
.xcall(
|
|
||||||
"erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.update_bank_account_ids",
|
|
||||||
{
|
|
||||||
response: response,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then(() => {
|
|
||||||
frappe.show_alert({ message: __("Plaid Link Updated"), indicator: "green" });
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,49 +1,45 @@
|
|||||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Bank Account", {
|
frappe.ui.form.on('Bank Account', {
|
||||||
setup: function (frm) {
|
setup: function(frm) {
|
||||||
frm.set_query("account", function () {
|
frm.set_query("account", function() {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
account_type: "Bank",
|
'account_type': 'Bank',
|
||||||
company: frm.doc.company,
|
'company': frm.doc.company,
|
||||||
is_group: 0,
|
'is_group': 0
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
frm.set_query("party_type", function () {
|
frm.set_query("party_type", function() {
|
||||||
return {
|
return {
|
||||||
query: "erpnext.setup.doctype.party_type.party_type.get_party_type",
|
query: "erpnext.setup.doctype.party_type.party_type.get_party_type",
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
refresh: function (frm) {
|
refresh: function(frm) {
|
||||||
frappe.dynamic_link = { doc: frm.doc, fieldname: "name", doctype: "Bank Account" };
|
frappe.dynamic_link = { doc: frm.doc, fieldname: 'name', doctype: 'Bank Account' }
|
||||||
|
|
||||||
frm.toggle_display(["address_html", "contact_html"], !frm.doc.__islocal);
|
frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
|
||||||
|
|
||||||
if (frm.doc.__islocal) {
|
if (frm.doc.__islocal) {
|
||||||
frappe.contacts.clear_address_and_contact(frm);
|
frappe.contacts.clear_address_and_contact(frm);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
frappe.contacts.render_address_and_contact(frm);
|
frappe.contacts.render_address_and_contact(frm);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frm.doc.integration_id) {
|
if (frm.doc.integration_id) {
|
||||||
frm.add_custom_button(__("Unlink external integrations"), function () {
|
frm.add_custom_button(__("Unlink external integrations"), function() {
|
||||||
frappe.confirm(
|
frappe.confirm(__("This action will unlink this account from any external service integrating ERPNext with your bank accounts. It cannot be undone. Are you certain ?"), function() {
|
||||||
__(
|
|
||||||
"This action will unlink this account from any external service integrating ERPNext with your bank accounts. It cannot be undone. Are you certain ?"
|
|
||||||
),
|
|
||||||
function () {
|
|
||||||
frm.set_value("integration_id", "");
|
frm.set_value("integration_id", "");
|
||||||
}
|
});
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
is_company_account: function (frm) {
|
is_company_account: function(frm) {
|
||||||
frm.set_df_property("account", "reqd", frm.doc.is_company_account);
|
frm.set_df_property('account', 'reqd', frm.doc.is_company_account);
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
"account_type",
|
"account_type",
|
||||||
"account_subtype",
|
"account_subtype",
|
||||||
"column_break_7",
|
"column_break_7",
|
||||||
"disabled",
|
|
||||||
"is_default",
|
"is_default",
|
||||||
"is_company_account",
|
"is_company_account",
|
||||||
"company",
|
"company",
|
||||||
@@ -200,16 +199,10 @@
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_global_search": 1,
|
"in_global_search": 1,
|
||||||
"label": "Branch Code"
|
"label": "Branch Code"
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"fieldname": "disabled",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Disabled"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-02-02 17:50:09.768835",
|
"modified": "2022-05-04 15:49:42.620630",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Bank Account",
|
"name": "Bank Account",
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ from frappe.contacts.address_and_contact import (
|
|||||||
load_address_and_contact,
|
load_address_and_contact,
|
||||||
)
|
)
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import comma_and, get_link_to_form
|
|
||||||
|
|
||||||
|
|
||||||
class BankAccount(Document):
|
class BankAccount(Document):
|
||||||
@@ -26,19 +25,6 @@ class BankAccount(Document):
|
|||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_company()
|
self.validate_company()
|
||||||
self.validate_iban()
|
self.validate_iban()
|
||||||
self.validate_account()
|
|
||||||
|
|
||||||
def validate_account(self):
|
|
||||||
if self.account:
|
|
||||||
if accounts := frappe.db.get_all(
|
|
||||||
"Bank Account", filters={"account": self.account, "name": ["!=", self.name]}, as_list=1
|
|
||||||
):
|
|
||||||
frappe.throw(
|
|
||||||
_("'{0}' account is already used by {1}. Use another account.").format(
|
|
||||||
frappe.bold(self.account),
|
|
||||||
frappe.bold(comma_and([get_link_to_form(self.doctype, x[0]) for x in accounts])),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def validate_company(self):
|
def validate_company(self):
|
||||||
if self.is_company_account and not self.company:
|
if self.is_company_account and not self.company:
|
||||||
@@ -91,6 +77,6 @@ def get_party_bank_account(party_type, party):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_bank_account_details(bank_account):
|
def get_bank_account_details(bank_account):
|
||||||
return frappe.db.get_value(
|
return frappe.get_cached_value(
|
||||||
"Bank Account", bank_account, ["account", "bank", "bank_account_no"], as_dict=1
|
"Bank Account", bank_account, ["account", "bank", "bank_account_no"], as_dict=1
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Bank Account Subtype", {
|
frappe.ui.form.on('Bank Account Subtype', {
|
||||||
refresh: function () {},
|
refresh: function() {
|
||||||
|
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Bank Account Type", {
|
frappe.ui.form.on('Bank Account Type', {
|
||||||
// refresh: function(frm) {
|
// refresh: function(frm) {
|
||||||
|
|
||||||
// }
|
// }
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,76 +2,83 @@
|
|||||||
// License: GNU General Public License v3. See license.txt
|
// License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Bank Clearance", {
|
frappe.ui.form.on("Bank Clearance", {
|
||||||
setup: function (frm) {
|
setup: function(frm) {
|
||||||
frm.add_fetch("account", "account_currency", "account_currency");
|
frm.add_fetch("account", "account_currency", "account_currency");
|
||||||
|
|
||||||
frm.set_query("account", function () {
|
frm.set_query("account", function() {
|
||||||
return {
|
return {
|
||||||
filters: {
|
"filters": {
|
||||||
account_type: ["in", ["Bank", "Cash"]],
|
"account_type": ["in",["Bank","Cash"]],
|
||||||
is_group: 0,
|
"is_group": 0,
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
frm.set_query("bank_account", function () {
|
frm.set_query("bank_account", function () {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
is_company_account: 1,
|
'is_company_account': 1
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onload: function (frm) {
|
onload: function(frm) {
|
||||||
let default_bank_account = frappe.defaults.get_user_default("Company")
|
|
||||||
? locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"]
|
let default_bank_account = frappe.defaults.get_user_default("Company")?
|
||||||
: "";
|
locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"]: "";
|
||||||
frm.set_value("account", default_bank_account);
|
frm.set_value("account", default_bank_account);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
frm.set_value("from_date", frappe.datetime.month_start());
|
frm.set_value("from_date", frappe.datetime.month_start());
|
||||||
frm.set_value("to_date", frappe.datetime.month_end());
|
frm.set_value("to_date", frappe.datetime.month_end());
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function (frm) {
|
refresh: function(frm) {
|
||||||
frm.disable_save();
|
frm.disable_save();
|
||||||
frm.add_custom_button(__("Get Payment Entries"), () => frm.trigger("get_payment_entries"));
|
|
||||||
|
|
||||||
frm.change_custom_button_type("Get Payment Entries", null, "primary");
|
if (frm.doc.account && frm.doc.from_date && frm.doc.to_date) {
|
||||||
|
frm.add_custom_button(__('Get Payment Entries'), () =>
|
||||||
|
frm.trigger("get_payment_entries")
|
||||||
|
);
|
||||||
|
|
||||||
|
frm.change_custom_button_type('Get Payment Entries', null, 'primary');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
update_clearance_date: function (frm) {
|
update_clearance_date: function(frm) {
|
||||||
return frappe.call({
|
return frappe.call({
|
||||||
method: "update_clearance_date",
|
method: "update_clearance_date",
|
||||||
doc: frm.doc,
|
doc: frm.doc,
|
||||||
callback: function (r, rt) {
|
callback: function(r, rt) {
|
||||||
frm.refresh_field("payment_entries");
|
frm.refresh_field("payment_entries");
|
||||||
frm.refresh_fields();
|
frm.refresh_fields();
|
||||||
|
|
||||||
if (!frm.doc.payment_entries.length) {
|
if (!frm.doc.payment_entries.length) {
|
||||||
frm.change_custom_button_type("Get Payment Entries", null, "primary");
|
frm.change_custom_button_type('Get Payment Entries', null, 'primary');
|
||||||
frm.change_custom_button_type("Update Clearance Date", null, "default");
|
frm.change_custom_button_type('Update Clearance Date', null, 'default');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
get_payment_entries: function (frm) {
|
get_payment_entries: function(frm) {
|
||||||
return frappe.call({
|
return frappe.call({
|
||||||
method: "get_payment_entries",
|
method: "get_payment_entries",
|
||||||
doc: frm.doc,
|
doc: frm.doc,
|
||||||
callback: function (r, rt) {
|
callback: function(r, rt) {
|
||||||
frm.refresh_field("payment_entries");
|
frm.refresh_field("payment_entries");
|
||||||
|
|
||||||
if (frm.doc.payment_entries.length) {
|
if (frm.doc.payment_entries.length) {
|
||||||
frm.add_custom_button(__("Update Clearance Date"), () =>
|
frm.add_custom_button(__('Update Clearance Date'), () =>
|
||||||
frm.trigger("update_clearance_date")
|
frm.trigger("update_clearance_date")
|
||||||
);
|
);
|
||||||
|
|
||||||
frm.change_custom_button_type("Get Payment Entries", null, "default");
|
frm.change_custom_button_type('Get Payment Entries', null, 'default');
|
||||||
frm.change_custom_button_type("Update Clearance Date", null, "primary");
|
frm.change_custom_button_type('Update Clearance Date', null, 'primary');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class BankClearance(Document):
|
|||||||
select
|
select
|
||||||
"Payment Entry" as payment_document, name as payment_entry,
|
"Payment Entry" as payment_document, name as payment_entry,
|
||||||
reference_no as cheque_number, reference_date as cheque_date,
|
reference_no as cheque_number, reference_date as cheque_date,
|
||||||
if(paid_from=%(account)s, paid_amount + total_taxes_and_charges, 0) as credit,
|
if(paid_from=%(account)s, paid_amount, 0) as credit,
|
||||||
if(paid_from=%(account)s, 0, received_amount) as debit,
|
if(paid_from=%(account)s, 0, received_amount) as debit,
|
||||||
posting_date, ifnull(party,if(paid_from=%(account)s,paid_to,paid_from)) as against_account, clearance_date,
|
posting_date, ifnull(party,if(paid_from=%(account)s,paid_to,paid_from)) as against_account, clearance_date,
|
||||||
if(paid_to=%(account)s, paid_to_account_currency, paid_from_account_currency) as account_currency
|
if(paid_to=%(account)s, paid_to_account_currency, paid_from_account_currency) as account_currency
|
||||||
@@ -81,7 +81,7 @@ class BankClearance(Document):
|
|||||||
|
|
||||||
loan_disbursement = frappe.qb.DocType("Loan Disbursement")
|
loan_disbursement = frappe.qb.DocType("Loan Disbursement")
|
||||||
|
|
||||||
query = (
|
loan_disbursements = (
|
||||||
frappe.qb.from_(loan_disbursement)
|
frappe.qb.from_(loan_disbursement)
|
||||||
.select(
|
.select(
|
||||||
ConstantColumn("Loan Disbursement").as_("payment_document"),
|
ConstantColumn("Loan Disbursement").as_("payment_document"),
|
||||||
@@ -90,22 +90,17 @@ class BankClearance(Document):
|
|||||||
ConstantColumn(0).as_("debit"),
|
ConstantColumn(0).as_("debit"),
|
||||||
loan_disbursement.reference_number.as_("cheque_number"),
|
loan_disbursement.reference_number.as_("cheque_number"),
|
||||||
loan_disbursement.reference_date.as_("cheque_date"),
|
loan_disbursement.reference_date.as_("cheque_date"),
|
||||||
loan_disbursement.clearance_date.as_("clearance_date"),
|
|
||||||
loan_disbursement.disbursement_date.as_("posting_date"),
|
loan_disbursement.disbursement_date.as_("posting_date"),
|
||||||
loan_disbursement.applicant.as_("against_account"),
|
loan_disbursement.applicant.as_("against_account"),
|
||||||
)
|
)
|
||||||
.where(loan_disbursement.docstatus == 1)
|
.where(loan_disbursement.docstatus == 1)
|
||||||
.where(loan_disbursement.disbursement_date >= self.from_date)
|
.where(loan_disbursement.disbursement_date >= self.from_date)
|
||||||
.where(loan_disbursement.disbursement_date <= self.to_date)
|
.where(loan_disbursement.disbursement_date <= self.to_date)
|
||||||
|
.where(loan_disbursement.clearance_date.isnull())
|
||||||
.where(loan_disbursement.disbursement_account.isin([self.bank_account, self.account]))
|
.where(loan_disbursement.disbursement_account.isin([self.bank_account, self.account]))
|
||||||
.orderby(loan_disbursement.disbursement_date)
|
.orderby(loan_disbursement.disbursement_date)
|
||||||
.orderby(loan_disbursement.name, order=frappe.qb.desc)
|
.orderby(loan_disbursement.name, order=frappe.qb.desc)
|
||||||
)
|
).run(as_dict=1)
|
||||||
|
|
||||||
if not self.include_reconciled_entries:
|
|
||||||
query = query.where(loan_disbursement.clearance_date.isnull())
|
|
||||||
|
|
||||||
loan_disbursements = query.run(as_dict=1)
|
|
||||||
|
|
||||||
loan_repayment = frappe.qb.DocType("Loan Repayment")
|
loan_repayment = frappe.qb.DocType("Loan Repayment")
|
||||||
|
|
||||||
@@ -118,19 +113,16 @@ class BankClearance(Document):
|
|||||||
ConstantColumn(0).as_("credit"),
|
ConstantColumn(0).as_("credit"),
|
||||||
loan_repayment.reference_number.as_("cheque_number"),
|
loan_repayment.reference_number.as_("cheque_number"),
|
||||||
loan_repayment.reference_date.as_("cheque_date"),
|
loan_repayment.reference_date.as_("cheque_date"),
|
||||||
loan_repayment.clearance_date.as_("clearance_date"),
|
|
||||||
loan_repayment.applicant.as_("against_account"),
|
loan_repayment.applicant.as_("against_account"),
|
||||||
loan_repayment.posting_date,
|
loan_repayment.posting_date,
|
||||||
)
|
)
|
||||||
.where(loan_repayment.docstatus == 1)
|
.where(loan_repayment.docstatus == 1)
|
||||||
|
.where(loan_repayment.clearance_date.isnull())
|
||||||
.where(loan_repayment.posting_date >= self.from_date)
|
.where(loan_repayment.posting_date >= self.from_date)
|
||||||
.where(loan_repayment.posting_date <= self.to_date)
|
.where(loan_repayment.posting_date <= self.to_date)
|
||||||
.where(loan_repayment.payment_account.isin([self.bank_account, self.account]))
|
.where(loan_repayment.payment_account.isin([self.bank_account, self.account]))
|
||||||
)
|
)
|
||||||
|
|
||||||
if not self.include_reconciled_entries:
|
|
||||||
query = query.where(loan_repayment.clearance_date.isnull())
|
|
||||||
|
|
||||||
if frappe.db.has_column("Loan Repayment", "repay_from_salary"):
|
if frappe.db.has_column("Loan Repayment", "repay_from_salary"):
|
||||||
query = query.where((loan_repayment.repay_from_salary == 0))
|
query = query.where((loan_repayment.repay_from_salary == 0))
|
||||||
|
|
||||||
|
|||||||
@@ -1,39 +1,39 @@
|
|||||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
cur_frm.add_fetch("bank_account", "account", "account");
|
cur_frm.add_fetch('bank_account','account','account');
|
||||||
cur_frm.add_fetch("bank_account", "bank_account_no", "bank_account_no");
|
cur_frm.add_fetch('bank_account','bank_account_no','bank_account_no');
|
||||||
cur_frm.add_fetch("bank_account", "iban", "iban");
|
cur_frm.add_fetch('bank_account','iban','iban');
|
||||||
cur_frm.add_fetch("bank_account", "branch_code", "branch_code");
|
cur_frm.add_fetch('bank_account','branch_code','branch_code');
|
||||||
cur_frm.add_fetch("bank", "swift_number", "swift_number");
|
cur_frm.add_fetch('bank','swift_number','swift_number');
|
||||||
|
|
||||||
frappe.ui.form.on("Bank Guarantee", {
|
frappe.ui.form.on('Bank Guarantee', {
|
||||||
setup: function (frm) {
|
setup: function(frm) {
|
||||||
frm.set_query("bank", function () {
|
frm.set_query("bank", function() {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
company: frm.doc.company
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
frm.set_query("bank_account", function() {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
company: frm.doc.company,
|
company: frm.doc.company,
|
||||||
},
|
bank: frm.doc.bank
|
||||||
};
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
frm.set_query("bank_account", function () {
|
frm.set_query("project", function() {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
company: frm.doc.company,
|
customer: frm.doc.customer
|
||||||
bank: frm.doc.bank,
|
}
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
frm.set_query("project", function () {
|
|
||||||
return {
|
|
||||||
filters: {
|
|
||||||
customer: frm.doc.customer,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
bg_type: function (frm) {
|
bg_type: function(frm) {
|
||||||
if (frm.doc.bg_type == "Receiving") {
|
if (frm.doc.bg_type == "Receiving") {
|
||||||
frm.set_value("reference_doctype", "Sales Order");
|
frm.set_value("reference_doctype", "Sales Order");
|
||||||
} else if (frm.doc.bg_type == "Providing") {
|
} else if (frm.doc.bg_type == "Providing") {
|
||||||
@@ -41,33 +41,34 @@ frappe.ui.form.on("Bank Guarantee", {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
reference_docname: function (frm) {
|
reference_docname: function(frm) {
|
||||||
if (frm.doc.reference_docname && frm.doc.reference_doctype) {
|
if (frm.doc.reference_docname && frm.doc.reference_doctype) {
|
||||||
let party_field = frm.doc.reference_doctype == "Sales Order" ? "customer" : "supplier";
|
let party_field = frm.doc.reference_doctype == "Sales Order" ? "customer" : "supplier";
|
||||||
|
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.accounts.doctype.bank_guarantee.bank_guarantee.get_voucher_details",
|
method: "erpnext.accounts.doctype.bank_guarantee.bank_guarantee.get_voucher_details",
|
||||||
args: {
|
args: {
|
||||||
bank_guarantee_type: frm.doc.bg_type,
|
"bank_guarantee_type": frm.doc.bg_type,
|
||||||
reference_name: frm.doc.reference_docname,
|
"reference_name": frm.doc.reference_docname
|
||||||
},
|
},
|
||||||
callback: function (r) {
|
callback: function(r) {
|
||||||
if (r.message) {
|
if (r.message) {
|
||||||
if (r.message[party_field]) frm.set_value(party_field, r.message[party_field]);
|
if (r.message[party_field]) frm.set_value(party_field, r.message[party_field]);
|
||||||
if (r.message.project) frm.set_value("project", r.message.project);
|
if (r.message.project) frm.set_value("project", r.message.project);
|
||||||
if (r.message.grand_total) frm.set_value("amount", r.message.grand_total);
|
if (r.message.grand_total) frm.set_value("amount", r.message.grand_total);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
start_date: function (frm) {
|
start_date: function(frm) {
|
||||||
var end_date = frappe.datetime.add_days(cur_frm.doc.start_date, cur_frm.doc.validity - 1);
|
var end_date = frappe.datetime.add_days(cur_frm.doc.start_date, cur_frm.doc.validity - 1);
|
||||||
cur_frm.set_value("end_date", end_date);
|
cur_frm.set_value("end_date", end_date);
|
||||||
},
|
},
|
||||||
validity: function (frm) {
|
validity: function(frm) {
|
||||||
var end_date = frappe.datetime.add_days(cur_frm.doc.start_date, cur_frm.doc.validity - 1);
|
var end_date = frappe.datetime.add_days(cur_frm.doc.start_date, cur_frm.doc.validity - 1);
|
||||||
cur_frm.set_value("end_date", end_date);
|
cur_frm.set_value("end_date", end_date);
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,41 +8,29 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
|
|||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
company: frm.doc.company,
|
company: frm.doc.company,
|
||||||
is_company_account: 1,
|
'is_company_account': 1
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
let no_bank_transactions_text = `<div class="text-muted text-center">${__(
|
let no_bank_transactions_text =
|
||||||
"No Matching Bank Transactions Found"
|
`<div class="text-muted text-center">${__("No Matching Bank Transactions Found")}</div>`
|
||||||
)}</div>`;
|
|
||||||
set_field_options("no_bank_transactions", no_bank_transactions_text);
|
set_field_options("no_bank_transactions", no_bank_transactions_text);
|
||||||
},
|
},
|
||||||
|
|
||||||
onload: function (frm) {
|
onload: function (frm) {
|
||||||
// Set default filter dates
|
frm.trigger('bank_account');
|
||||||
let today = frappe.datetime.get_today();
|
|
||||||
frm.doc.bank_statement_from_date = frappe.datetime.add_months(today, -1);
|
|
||||||
frm.doc.bank_statement_to_date = today;
|
|
||||||
frm.trigger("bank_account");
|
|
||||||
},
|
|
||||||
|
|
||||||
filter_by_reference_date: function (frm) {
|
|
||||||
if (frm.doc.filter_by_reference_date) {
|
|
||||||
frm.set_value("bank_statement_from_date", "");
|
|
||||||
frm.set_value("bank_statement_to_date", "");
|
|
||||||
} else {
|
|
||||||
frm.set_value("from_reference_date", "");
|
|
||||||
frm.set_value("to_reference_date", "");
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function (frm) {
|
refresh: function (frm) {
|
||||||
frm.disable_save();
|
frappe.require("bank-reconciliation-tool.bundle.js", () =>
|
||||||
frappe.require("bank-reconciliation-tool.bundle.js", () => frm.trigger("make_reconciliation_tool"));
|
frm.trigger("make_reconciliation_tool")
|
||||||
|
);
|
||||||
frm.add_custom_button(__("Upload Bank Statement"), () =>
|
frm.upload_statement_button = frm.page.set_secondary_action(
|
||||||
|
__("Upload Bank Statement"),
|
||||||
|
() =>
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.accounts.doctype.bank_statement_import.bank_statement_import.upload_bank_statement",
|
method:
|
||||||
|
"erpnext.accounts.doctype.bank_statement_import.bank_statement_import.upload_bank_statement",
|
||||||
args: {
|
args: {
|
||||||
dt: frm.doc.doctype,
|
dt: frm.doc.doctype,
|
||||||
dn: frm.doc.name,
|
dn: frm.doc.name,
|
||||||
@@ -52,39 +40,38 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
|
|||||||
callback: function (r) {
|
callback: function (r) {
|
||||||
if (!r.exc) {
|
if (!r.exc) {
|
||||||
var doc = frappe.model.sync(r.message);
|
var doc = frappe.model.sync(r.message);
|
||||||
frappe.set_route("Form", doc[0].doctype, doc[0].name);
|
frappe.set_route(
|
||||||
|
"Form",
|
||||||
|
doc[0].doctype,
|
||||||
|
doc[0].name
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
frm.add_custom_button(__("Auto Reconcile"), function () {
|
|
||||||
frappe.call({
|
|
||||||
method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.auto_reconcile_vouchers",
|
|
||||||
args: {
|
|
||||||
bank_account: frm.doc.bank_account,
|
|
||||||
from_date: frm.doc.bank_statement_from_date,
|
|
||||||
to_date: frm.doc.bank_statement_to_date,
|
|
||||||
filter_by_reference_date: frm.doc.filter_by_reference_date,
|
|
||||||
from_reference_date: frm.doc.from_reference_date,
|
|
||||||
to_reference_date: frm.doc.to_reference_date,
|
|
||||||
},
|
},
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
frm.add_custom_button(__("Get Unreconciled Entries"), function () {
|
after_save: function (frm) {
|
||||||
frm.trigger("make_reconciliation_tool");
|
frm.trigger("make_reconciliation_tool");
|
||||||
});
|
|
||||||
frm.change_custom_button_type("Get Unreconciled Entries", null, "primary");
|
|
||||||
},
|
},
|
||||||
|
|
||||||
bank_account: function (frm) {
|
bank_account: function (frm) {
|
||||||
frappe.db.get_value("Bank Account", frm.doc.bank_account, "account", (r) => {
|
frappe.db.get_value(
|
||||||
frappe.db.get_value("Account", r.account, "account_currency", (r) => {
|
"Bank Account",
|
||||||
frm.doc.account_currency = r.account_currency;
|
frm.doc.bank_account,
|
||||||
|
"account",
|
||||||
|
(r) => {
|
||||||
|
frappe.db.get_value(
|
||||||
|
"Account",
|
||||||
|
r.account,
|
||||||
|
"account_currency",
|
||||||
|
(r) => {
|
||||||
|
frm.currency = r.account_currency;
|
||||||
frm.trigger("render_chart");
|
frm.trigger("render_chart");
|
||||||
});
|
}
|
||||||
});
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
frm.trigger("get_account_opening_balance");
|
frm.trigger("get_account_opening_balance");
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -103,7 +90,11 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
|
|||||||
) {
|
) {
|
||||||
frm.trigger("render_chart");
|
frm.trigger("render_chart");
|
||||||
frm.trigger("render");
|
frm.trigger("render");
|
||||||
frappe.utils.scroll_to(frm.get_field("reconciliation_tool_cards").$wrapper, true, 30);
|
frappe.utils.scroll_to(
|
||||||
|
frm.get_field("reconciliation_tool_cards").$wrapper,
|
||||||
|
true,
|
||||||
|
30
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -112,10 +103,11 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
|
|||||||
get_account_opening_balance(frm) {
|
get_account_opening_balance(frm) {
|
||||||
if (frm.doc.bank_account && frm.doc.bank_statement_from_date) {
|
if (frm.doc.bank_account && frm.doc.bank_statement_from_date) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_account_balance",
|
method:
|
||||||
|
"erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_account_balance",
|
||||||
args: {
|
args: {
|
||||||
bank_account: frm.doc.bank_account,
|
bank_account: frm.doc.bank_account,
|
||||||
till_date: frappe.datetime.add_days(frm.doc.bank_statement_from_date, -1),
|
till_date: frm.doc.bank_statement_from_date,
|
||||||
},
|
},
|
||||||
callback: (response) => {
|
callback: (response) => {
|
||||||
frm.set_value("account_opening_balance", response.message);
|
frm.set_value("account_opening_balance", response.message);
|
||||||
@@ -127,7 +119,8 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
|
|||||||
get_cleared_balance(frm) {
|
get_cleared_balance(frm) {
|
||||||
if (frm.doc.bank_account && frm.doc.bank_statement_to_date) {
|
if (frm.doc.bank_account && frm.doc.bank_statement_to_date) {
|
||||||
return frappe.call({
|
return frappe.call({
|
||||||
method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_account_balance",
|
method:
|
||||||
|
"erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_account_balance",
|
||||||
args: {
|
args: {
|
||||||
bank_account: frm.doc.bank_account,
|
bank_account: frm.doc.bank_account,
|
||||||
till_date: frm.doc.bank_statement_to_date,
|
till_date: frm.doc.bank_statement_to_date,
|
||||||
@@ -139,31 +132,39 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
render_chart(frm) {
|
render_chart: frappe.utils.debounce((frm) => {
|
||||||
frm.cards_manager = new erpnext.accounts.bank_reconciliation.NumberCardManager({
|
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,
|
$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,
|
cleared_balance: frm.cleared_balance,
|
||||||
currency: frm.doc.account_currency,
|
currency: frm.currency,
|
||||||
});
|
}
|
||||||
},
|
);
|
||||||
|
}, 500),
|
||||||
|
|
||||||
render(frm) {
|
render(frm) {
|
||||||
if (frm.doc.bank_account) {
|
if (frm.doc.bank_account) {
|
||||||
frm.bank_reconciliation_data_table_manager =
|
frm.bank_reconciliation_data_table_manager = new erpnext.accounts.bank_reconciliation.DataTableManager(
|
||||||
new erpnext.accounts.bank_reconciliation.DataTableManager({
|
{
|
||||||
company: frm.doc.company,
|
company: frm.doc.company,
|
||||||
bank_account: frm.doc.bank_account,
|
bank_account: frm.doc.bank_account,
|
||||||
$reconciliation_tool_dt: frm.get_field("reconciliation_tool_dt").$wrapper,
|
$reconciliation_tool_dt: frm.get_field(
|
||||||
$no_bank_transactions: frm.get_field("no_bank_transactions").$wrapper,
|
"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_from_date: frm.doc.bank_statement_from_date,
|
||||||
bank_statement_to_date: frm.doc.bank_statement_to_date,
|
bank_statement_to_date: frm.doc.bank_statement_to_date,
|
||||||
filter_by_reference_date: frm.doc.filter_by_reference_date,
|
bank_statement_closing_balance:
|
||||||
from_reference_date: frm.doc.from_reference_date,
|
frm.doc.bank_statement_closing_balance,
|
||||||
to_reference_date: frm.doc.to_reference_date,
|
|
||||||
bank_statement_closing_balance: frm.doc.bank_statement_closing_balance,
|
|
||||||
cards_manager: frm.cards_manager,
|
cards_manager: frm.cards_manager,
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,11 +10,7 @@
|
|||||||
"column_break_1",
|
"column_break_1",
|
||||||
"bank_statement_from_date",
|
"bank_statement_from_date",
|
||||||
"bank_statement_to_date",
|
"bank_statement_to_date",
|
||||||
"from_reference_date",
|
|
||||||
"to_reference_date",
|
|
||||||
"filter_by_reference_date",
|
|
||||||
"column_break_2",
|
"column_break_2",
|
||||||
"account_currency",
|
|
||||||
"account_opening_balance",
|
"account_opening_balance",
|
||||||
"bank_statement_closing_balance",
|
"bank_statement_closing_balance",
|
||||||
"section_break_1",
|
"section_break_1",
|
||||||
@@ -40,13 +36,13 @@
|
|||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval: doc.bank_account && !doc.filter_by_reference_date",
|
"depends_on": "eval: doc.bank_account",
|
||||||
"fieldname": "bank_statement_from_date",
|
"fieldname": "bank_statement_from_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "From Date"
|
"label": "From Date"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval: doc.bank_account && !doc.filter_by_reference_date",
|
"depends_on": "eval: doc.bank_statement_from_date",
|
||||||
"fieldname": "bank_statement_to_date",
|
"fieldname": "bank_statement_to_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "To Date"
|
"label": "To Date"
|
||||||
@@ -60,7 +56,7 @@
|
|||||||
"fieldname": "account_opening_balance",
|
"fieldname": "account_opening_balance",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Account Opening Balance",
|
"label": "Account Opening Balance",
|
||||||
"options": "account_currency",
|
"options": "Currency",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -68,7 +64,7 @@
|
|||||||
"fieldname": "bank_statement_closing_balance",
|
"fieldname": "bank_statement_closing_balance",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Closing Balance",
|
"label": "Closing Balance",
|
||||||
"options": "account_currency"
|
"options": "Currency"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "section_break_1",
|
"fieldname": "section_break_1",
|
||||||
@@ -85,40 +81,14 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "no_bank_transactions",
|
"fieldname": "no_bank_transactions",
|
||||||
"fieldtype": "HTML",
|
"fieldtype": "HTML"
|
||||||
"options": "<div class=\"text-muted text-center\">No Matching Bank Transactions Found</div>"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"depends_on": "eval:doc.filter_by_reference_date",
|
|
||||||
"fieldname": "from_reference_date",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"label": "From Reference Date"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"depends_on": "eval:doc.filter_by_reference_date",
|
|
||||||
"fieldname": "to_reference_date",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"label": "To Reference Date"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"fieldname": "filter_by_reference_date",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Filter by Reference Date"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "account_currency",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 1,
|
|
||||||
"label": "Account Currency",
|
|
||||||
"options": "Currency"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"hide_toolbar": 1,
|
"hide_toolbar": 1,
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-03-07 11:02:24.535714",
|
"modified": "2021-04-21 11:13:49.831769",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Bank Reconciliation Tool",
|
"name": "Bank Reconciliation Tool",
|
||||||
@@ -137,6 +107,5 @@
|
|||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC"
|
||||||
"states": []
|
|
||||||
}
|
}
|
||||||
@@ -8,16 +8,14 @@ import frappe
|
|||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.query_builder.custom import ConstantColumn
|
from frappe.query_builder.custom import ConstantColumn
|
||||||
from frappe.utils import cint, flt
|
from frappe.utils import flt
|
||||||
|
|
||||||
from erpnext import get_default_cost_center
|
from erpnext.accounts.doctype.bank_transaction.bank_transaction import get_paid_amount
|
||||||
from erpnext.accounts.doctype.bank_transaction.bank_transaction import get_total_allocated_amount
|
|
||||||
from erpnext.accounts.report.bank_reconciliation_statement.bank_reconciliation_statement import (
|
from erpnext.accounts.report.bank_reconciliation_statement.bank_reconciliation_statement import (
|
||||||
get_amounts_not_reflected_in_system,
|
get_amounts_not_reflected_in_system,
|
||||||
get_entries,
|
get_entries,
|
||||||
)
|
)
|
||||||
from erpnext.accounts.utils import get_balance_on
|
from erpnext.accounts.utils import get_balance_on
|
||||||
from erpnext.setup.utils import get_exchange_rate
|
|
||||||
|
|
||||||
|
|
||||||
class BankReconciliationTool(Document):
|
class BankReconciliationTool(Document):
|
||||||
@@ -30,7 +28,7 @@ def get_bank_transactions(bank_account, from_date=None, to_date=None):
|
|||||||
filters = []
|
filters = []
|
||||||
filters.append(["bank_account", "=", bank_account])
|
filters.append(["bank_account", "=", bank_account])
|
||||||
filters.append(["docstatus", "=", 1])
|
filters.append(["docstatus", "=", 1])
|
||||||
filters.append(["unallocated_amount", ">", 0.0])
|
filters.append(["unallocated_amount", ">", 0])
|
||||||
if to_date:
|
if to_date:
|
||||||
filters.append(["date", "<=", to_date])
|
filters.append(["date", "<=", to_date])
|
||||||
if from_date:
|
if from_date:
|
||||||
@@ -52,7 +50,6 @@ def get_bank_transactions(bank_account, from_date=None, to_date=None):
|
|||||||
"party",
|
"party",
|
||||||
],
|
],
|
||||||
filters=filters,
|
filters=filters,
|
||||||
order_by="date",
|
|
||||||
)
|
)
|
||||||
return transactions
|
return transactions
|
||||||
|
|
||||||
@@ -60,7 +57,7 @@ def get_bank_transactions(bank_account, from_date=None, to_date=None):
|
|||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_account_balance(bank_account, till_date):
|
def get_account_balance(bank_account, till_date):
|
||||||
# returns account balance till the specified date
|
# returns account balance till the specified date
|
||||||
account = frappe.db.get_value("Bank Account", bank_account, "account")
|
account = frappe.get_cached_value("Bank Account", bank_account, "account")
|
||||||
filters = frappe._dict(
|
filters = frappe._dict(
|
||||||
{"account": account, "report_date": till_date, "include_pos_transactions": 1}
|
{"account": account, "report_date": till_date, "include_pos_transactions": 1}
|
||||||
)
|
)
|
||||||
@@ -68,7 +65,7 @@ def get_account_balance(bank_account, till_date):
|
|||||||
|
|
||||||
balance_as_per_system = get_balance_on(filters["account"], filters["report_date"])
|
balance_as_per_system = get_balance_on(filters["account"], filters["report_date"])
|
||||||
|
|
||||||
total_debit, total_credit = 0.0, 0.0
|
total_debit, total_credit = 0, 0
|
||||||
for d in data:
|
for d in data:
|
||||||
total_debit += flt(d.debit)
|
total_debit += flt(d.debit)
|
||||||
total_credit += flt(d.credit)
|
total_credit += flt(d.credit)
|
||||||
@@ -130,11 +127,13 @@ def create_journal_entry_bts(
|
|||||||
bank_transaction = frappe.db.get_values(
|
bank_transaction = frappe.db.get_values(
|
||||||
"Bank Transaction",
|
"Bank Transaction",
|
||||||
bank_transaction_name,
|
bank_transaction_name,
|
||||||
fieldname=["name", "deposit", "withdrawal", "bank_account", "currency"],
|
fieldname=["name", "deposit", "withdrawal", "bank_account"],
|
||||||
as_dict=True,
|
as_dict=True,
|
||||||
)[0]
|
)[0]
|
||||||
company_account = frappe.get_value("Bank Account", bank_transaction.bank_account, "account")
|
company_account = frappe.get_cached_value(
|
||||||
account_type = frappe.db.get_value("Account", second_account, "account_type")
|
"Bank Account", bank_transaction.bank_account, "account"
|
||||||
|
)
|
||||||
|
account_type = frappe.get_cached_value("Account", second_account, "account_type")
|
||||||
if account_type in ["Receivable", "Payable"]:
|
if account_type in ["Receivable", "Payable"]:
|
||||||
if not (party_type and party):
|
if not (party_type and party):
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
@@ -142,96 +141,32 @@ def create_journal_entry_bts(
|
|||||||
second_account
|
second_account
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
company = frappe.get_value("Account", company_account, "company")
|
|
||||||
company_default_currency = frappe.get_cached_value("Company", company, "default_currency")
|
|
||||||
company_account_currency = frappe.get_cached_value("Account", company_account, "account_currency")
|
|
||||||
second_account_currency = frappe.get_cached_value("Account", second_account, "account_currency")
|
|
||||||
|
|
||||||
# determine if multi-currency Journal or not
|
|
||||||
is_multi_currency = (
|
|
||||||
True
|
|
||||||
if company_default_currency != company_account_currency
|
|
||||||
or company_default_currency != second_account_currency
|
|
||||||
or company_default_currency != bank_transaction.currency
|
|
||||||
else False
|
|
||||||
)
|
|
||||||
|
|
||||||
accounts = []
|
accounts = []
|
||||||
second_account_dict = {
|
# Multi Currency?
|
||||||
|
accounts.append(
|
||||||
|
{
|
||||||
"account": second_account,
|
"account": second_account,
|
||||||
"account_currency": second_account_currency,
|
"credit_in_account_currency": bank_transaction.deposit if bank_transaction.deposit > 0 else 0,
|
||||||
"credit_in_account_currency": bank_transaction.deposit,
|
"debit_in_account_currency": bank_transaction.withdrawal
|
||||||
"debit_in_account_currency": bank_transaction.withdrawal,
|
if bank_transaction.withdrawal > 0
|
||||||
|
else 0,
|
||||||
"party_type": party_type,
|
"party_type": party_type,
|
||||||
"party": party,
|
"party": party,
|
||||||
"cost_center": get_default_cost_center(company),
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
company_account_dict = {
|
accounts.append(
|
||||||
|
{
|
||||||
"account": company_account,
|
"account": company_account,
|
||||||
"account_currency": company_account_currency,
|
|
||||||
"bank_account": bank_transaction.bank_account,
|
"bank_account": bank_transaction.bank_account,
|
||||||
"credit_in_account_currency": bank_transaction.withdrawal,
|
"credit_in_account_currency": bank_transaction.withdrawal
|
||||||
"debit_in_account_currency": bank_transaction.deposit,
|
if bank_transaction.withdrawal > 0
|
||||||
"cost_center": get_default_cost_center(company),
|
else 0,
|
||||||
}
|
"debit_in_account_currency": bank_transaction.deposit if bank_transaction.deposit > 0 else 0,
|
||||||
|
|
||||||
# convert transaction amount to company currency
|
|
||||||
if is_multi_currency:
|
|
||||||
exc_rate = get_exchange_rate(bank_transaction.currency, company_default_currency, posting_date)
|
|
||||||
withdrawal_in_company_currency = flt(exc_rate * abs(bank_transaction.withdrawal))
|
|
||||||
deposit_in_company_currency = flt(exc_rate * abs(bank_transaction.deposit))
|
|
||||||
else:
|
|
||||||
withdrawal_in_company_currency = bank_transaction.withdrawal
|
|
||||||
deposit_in_company_currency = bank_transaction.deposit
|
|
||||||
|
|
||||||
# if second account is of foreign currency, convert and set debit and credit fields.
|
|
||||||
if second_account_currency != company_default_currency:
|
|
||||||
exc_rate = get_exchange_rate(second_account_currency, company_default_currency, posting_date)
|
|
||||||
second_account_dict.update(
|
|
||||||
{
|
|
||||||
"exchange_rate": exc_rate,
|
|
||||||
"credit": deposit_in_company_currency,
|
|
||||||
"debit": withdrawal_in_company_currency,
|
|
||||||
"credit_in_account_currency": flt(deposit_in_company_currency / exc_rate) or 0,
|
|
||||||
"debit_in_account_currency": flt(withdrawal_in_company_currency / exc_rate) or 0,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
second_account_dict.update(
|
|
||||||
{
|
|
||||||
"exchange_rate": 1,
|
|
||||||
"credit": deposit_in_company_currency,
|
|
||||||
"debit": withdrawal_in_company_currency,
|
|
||||||
"credit_in_account_currency": deposit_in_company_currency,
|
|
||||||
"debit_in_account_currency": withdrawal_in_company_currency,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
# if company account is of foreign currency, convert and set debit and credit fields.
|
company = frappe.get_cached_value("Account", company_account, "company")
|
||||||
if company_account_currency != company_default_currency:
|
|
||||||
exc_rate = get_exchange_rate(company_account_currency, company_default_currency, posting_date)
|
|
||||||
company_account_dict.update(
|
|
||||||
{
|
|
||||||
"exchange_rate": exc_rate,
|
|
||||||
"credit": withdrawal_in_company_currency,
|
|
||||||
"debit": deposit_in_company_currency,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
company_account_dict.update(
|
|
||||||
{
|
|
||||||
"exchange_rate": 1,
|
|
||||||
"credit": withdrawal_in_company_currency,
|
|
||||||
"debit": deposit_in_company_currency,
|
|
||||||
"credit_in_account_currency": withdrawal_in_company_currency,
|
|
||||||
"debit_in_account_currency": deposit_in_company_currency,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
accounts.append(second_account_dict)
|
|
||||||
accounts.append(company_account_dict)
|
|
||||||
|
|
||||||
journal_entry_dict = {
|
journal_entry_dict = {
|
||||||
"voucher_type": entry_type,
|
"voucher_type": entry_type,
|
||||||
@@ -241,9 +176,6 @@ def create_journal_entry_bts(
|
|||||||
"cheque_no": reference_number,
|
"cheque_no": reference_number,
|
||||||
"mode_of_payment": mode_of_payment,
|
"mode_of_payment": mode_of_payment,
|
||||||
}
|
}
|
||||||
if is_multi_currency:
|
|
||||||
journal_entry_dict.update({"multi_currency": True})
|
|
||||||
|
|
||||||
journal_entry = frappe.new_doc("Journal Entry")
|
journal_entry = frappe.new_doc("Journal Entry")
|
||||||
journal_entry.update(journal_entry_dict)
|
journal_entry.update(journal_entry_dict)
|
||||||
journal_entry.set("accounts", accounts)
|
journal_entry.set("accounts", accounts)
|
||||||
@@ -254,22 +186,16 @@ def create_journal_entry_bts(
|
|||||||
journal_entry.insert()
|
journal_entry.insert()
|
||||||
journal_entry.submit()
|
journal_entry.submit()
|
||||||
|
|
||||||
if bank_transaction.deposit > 0.0:
|
if bank_transaction.deposit > 0:
|
||||||
paid_amount = bank_transaction.deposit
|
paid_amount = bank_transaction.deposit
|
||||||
else:
|
else:
|
||||||
paid_amount = bank_transaction.withdrawal
|
paid_amount = bank_transaction.withdrawal
|
||||||
|
|
||||||
vouchers = json.dumps(
|
vouchers = json.dumps(
|
||||||
[
|
[{"payment_doctype": "Journal Entry", "payment_name": journal_entry.name, "amount": paid_amount}]
|
||||||
{
|
|
||||||
"payment_doctype": "Journal Entry",
|
|
||||||
"payment_name": journal_entry.name,
|
|
||||||
"amount": paid_amount,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return reconcile_vouchers(bank_transaction_name, vouchers)
|
return reconcile_vouchers(bank_transaction.name, vouchers)
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@@ -293,10 +219,12 @@ def create_payment_entry_bts(
|
|||||||
as_dict=True,
|
as_dict=True,
|
||||||
)[0]
|
)[0]
|
||||||
paid_amount = bank_transaction.unallocated_amount
|
paid_amount = bank_transaction.unallocated_amount
|
||||||
payment_type = "Receive" if bank_transaction.deposit > 0.0 else "Pay"
|
payment_type = "Receive" if bank_transaction.deposit > 0 else "Pay"
|
||||||
|
|
||||||
company_account = frappe.get_value("Bank Account", bank_transaction.bank_account, "account")
|
company_account = frappe.get_cached_value(
|
||||||
company = frappe.get_value("Account", company_account, "company")
|
"Bank Account", bank_transaction.bank_account, "account"
|
||||||
|
)
|
||||||
|
company = frappe.get_cached_value("Account", company_account, "company")
|
||||||
payment_entry_dict = {
|
payment_entry_dict = {
|
||||||
"company": company,
|
"company": company,
|
||||||
"payment_type": payment_type,
|
"payment_type": payment_type,
|
||||||
@@ -332,52 +260,42 @@ def create_payment_entry_bts(
|
|||||||
|
|
||||||
payment_entry.submit()
|
payment_entry.submit()
|
||||||
vouchers = json.dumps(
|
vouchers = json.dumps(
|
||||||
[
|
[{"payment_doctype": "Payment Entry", "payment_name": payment_entry.name, "amount": paid_amount}]
|
||||||
{
|
|
||||||
"payment_doctype": "Payment Entry",
|
|
||||||
"payment_name": payment_entry.name,
|
|
||||||
"amount": paid_amount,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
return reconcile_vouchers(bank_transaction_name, vouchers)
|
return reconcile_vouchers(bank_transaction.name, vouchers)
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def auto_reconcile_vouchers(
|
def reconcile_vouchers(bank_transaction_name, vouchers):
|
||||||
bank_account,
|
# updated clear date of all the vouchers based on the bank transaction
|
||||||
from_date=None,
|
vouchers = json.loads(vouchers)
|
||||||
to_date=None,
|
transaction = frappe.get_doc("Bank Transaction", bank_transaction_name)
|
||||||
filter_by_reference_date=None,
|
company_account = frappe.get_cached_value("Bank Account", transaction.bank_account, "account")
|
||||||
from_reference_date=None,
|
|
||||||
to_reference_date=None,
|
if transaction.unallocated_amount == 0:
|
||||||
):
|
frappe.throw(_("This bank transaction is already fully reconciled"))
|
||||||
frappe.flags.auto_reconcile_vouchers = True
|
total_amount = 0
|
||||||
document_types = ["payment_entry", "journal_entry"]
|
for voucher in vouchers:
|
||||||
bank_transactions = get_bank_transactions(bank_account)
|
voucher["payment_entry"] = frappe.get_doc(voucher["payment_doctype"], voucher["payment_name"])
|
||||||
matched_transaction = []
|
total_amount += get_paid_amount(
|
||||||
for transaction in bank_transactions:
|
frappe._dict(
|
||||||
linked_payments = get_linked_payments(
|
|
||||||
transaction.name,
|
|
||||||
document_types,
|
|
||||||
from_date,
|
|
||||||
to_date,
|
|
||||||
filter_by_reference_date,
|
|
||||||
from_reference_date,
|
|
||||||
to_reference_date,
|
|
||||||
)
|
|
||||||
vouchers = []
|
|
||||||
for r in linked_payments:
|
|
||||||
vouchers.append(
|
|
||||||
{
|
{
|
||||||
"payment_doctype": r[1],
|
"payment_document": voucher["payment_doctype"],
|
||||||
"payment_name": r[2],
|
"payment_entry": voucher["payment_name"],
|
||||||
"amount": r[4],
|
|
||||||
}
|
}
|
||||||
|
),
|
||||||
|
transaction.currency,
|
||||||
|
company_account,
|
||||||
)
|
)
|
||||||
transaction = frappe.get_doc("Bank Transaction", transaction.name)
|
|
||||||
account = frappe.db.get_value("Bank Account", transaction.bank_account, "account")
|
if total_amount > transaction.unallocated_amount:
|
||||||
matched_trans = 0
|
frappe.throw(
|
||||||
|
_(
|
||||||
|
"The sum total of amounts of all selected vouchers should be less than the unallocated amount of the bank transaction"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
account = frappe.get_cached_value("Bank Account", transaction.bank_account, "account")
|
||||||
|
|
||||||
for voucher in vouchers:
|
for voucher in vouchers:
|
||||||
gl_entry = frappe.db.get_value(
|
gl_entry = frappe.db.get_value(
|
||||||
"GL Entry",
|
"GL Entry",
|
||||||
@@ -393,117 +311,39 @@ def auto_reconcile_vouchers(
|
|||||||
else (gl_entry.debit, transaction.withdrawal)
|
else (gl_entry.debit, transaction.withdrawal)
|
||||||
)
|
)
|
||||||
allocated_amount = gl_amount if gl_amount >= transaction_amount else transaction_amount
|
allocated_amount = gl_amount if gl_amount >= transaction_amount else transaction_amount
|
||||||
|
|
||||||
transaction.append(
|
transaction.append(
|
||||||
"payment_entries",
|
"payment_entries",
|
||||||
{
|
{
|
||||||
"payment_document": voucher["payment_doctype"],
|
"payment_document": voucher["payment_entry"].doctype,
|
||||||
"payment_entry": voucher["payment_name"],
|
"payment_entry": voucher["payment_entry"].name,
|
||||||
"allocated_amount": allocated_amount,
|
"allocated_amount": allocated_amount,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
matched_transaction.append(str(transaction.name))
|
|
||||||
transaction.save()
|
transaction.save()
|
||||||
transaction.update_allocations()
|
transaction.update_allocations()
|
||||||
matched_transaction_len = len(set(matched_transaction))
|
|
||||||
if matched_transaction_len == 0:
|
|
||||||
frappe.msgprint(_("No matching references found for auto reconciliation"))
|
|
||||||
elif matched_transaction_len == 1:
|
|
||||||
frappe.msgprint(_("{0} transaction is reconcilied").format(matched_transaction_len))
|
|
||||||
else:
|
|
||||||
frappe.msgprint(_("{0} transactions are reconcilied").format(matched_transaction_len))
|
|
||||||
|
|
||||||
frappe.flags.auto_reconcile_vouchers = False
|
|
||||||
|
|
||||||
return frappe.get_doc("Bank Transaction", transaction.name)
|
|
||||||
|
|
||||||
|
|
||||||
@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)
|
|
||||||
transaction.add_payment_entries(vouchers)
|
|
||||||
return frappe.get_doc("Bank Transaction", bank_transaction_name)
|
return frappe.get_doc("Bank Transaction", bank_transaction_name)
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_linked_payments(
|
def get_linked_payments(bank_transaction_name, document_types=None):
|
||||||
bank_transaction_name,
|
|
||||||
document_types=None,
|
|
||||||
from_date=None,
|
|
||||||
to_date=None,
|
|
||||||
filter_by_reference_date=None,
|
|
||||||
from_reference_date=None,
|
|
||||||
to_reference_date=None,
|
|
||||||
):
|
|
||||||
# get all matching payments for a bank transaction
|
# get all matching payments for a bank transaction
|
||||||
transaction = frappe.get_doc("Bank Transaction", bank_transaction_name)
|
transaction = frappe.get_doc("Bank Transaction", bank_transaction_name)
|
||||||
bank_account = frappe.db.get_values(
|
bank_account = frappe.db.get_values(
|
||||||
"Bank Account", transaction.bank_account, ["account", "company"], as_dict=True
|
"Bank Account", transaction.bank_account, ["account", "company"], as_dict=True
|
||||||
)[0]
|
)[0]
|
||||||
(gl_account, company) = (bank_account.account, bank_account.company)
|
(account, company) = (bank_account.account, bank_account.company)
|
||||||
matching = check_matching(
|
matching = check_matching(account, company, transaction, document_types)
|
||||||
gl_account,
|
return matching
|
||||||
company,
|
|
||||||
transaction,
|
|
||||||
document_types,
|
|
||||||
from_date,
|
|
||||||
to_date,
|
|
||||||
filter_by_reference_date,
|
|
||||||
from_reference_date,
|
|
||||||
to_reference_date,
|
|
||||||
)
|
|
||||||
return subtract_allocations(gl_account, matching)
|
|
||||||
|
|
||||||
|
|
||||||
def subtract_allocations(gl_account, vouchers):
|
def check_matching(bank_account, company, transaction, document_types):
|
||||||
"Look up & subtract any existing Bank Transaction allocations"
|
|
||||||
copied = []
|
|
||||||
for voucher in vouchers:
|
|
||||||
rows = get_total_allocated_amount(voucher[1], voucher[2])
|
|
||||||
amount = None
|
|
||||||
for row in rows:
|
|
||||||
if row["gl_account"] == gl_account:
|
|
||||||
amount = row["total"]
|
|
||||||
break
|
|
||||||
|
|
||||||
if amount:
|
|
||||||
l = list(voucher)
|
|
||||||
l[3] -= amount
|
|
||||||
copied.append(tuple(l))
|
|
||||||
else:
|
|
||||||
copied.append(voucher)
|
|
||||||
return copied
|
|
||||||
|
|
||||||
|
|
||||||
def check_matching(
|
|
||||||
bank_account,
|
|
||||||
company,
|
|
||||||
transaction,
|
|
||||||
document_types,
|
|
||||||
from_date,
|
|
||||||
to_date,
|
|
||||||
filter_by_reference_date,
|
|
||||||
from_reference_date,
|
|
||||||
to_reference_date,
|
|
||||||
):
|
|
||||||
exact_match = True if "exact_match" in document_types else False
|
|
||||||
# combine all types of vouchers
|
# combine all types of vouchers
|
||||||
subquery = get_queries(
|
subquery = get_queries(bank_account, company, transaction, document_types)
|
||||||
bank_account,
|
|
||||||
company,
|
|
||||||
transaction,
|
|
||||||
document_types,
|
|
||||||
from_date,
|
|
||||||
to_date,
|
|
||||||
filter_by_reference_date,
|
|
||||||
from_reference_date,
|
|
||||||
to_reference_date,
|
|
||||||
exact_match,
|
|
||||||
)
|
|
||||||
filters = {
|
filters = {
|
||||||
"amount": transaction.unallocated_amount,
|
"amount": transaction.unallocated_amount,
|
||||||
"payment_type": "Receive" if transaction.deposit > 0.0 else "Pay",
|
"payment_type": "Receive" if transaction.deposit > 0 else "Pay",
|
||||||
"reference_no": transaction.reference_number,
|
"reference_no": transaction.reference_number,
|
||||||
"party_type": transaction.party_type,
|
"party_type": transaction.party_type,
|
||||||
"party": transaction.party,
|
"party": transaction.party,
|
||||||
@@ -512,9 +352,7 @@ def check_matching(
|
|||||||
|
|
||||||
matching_vouchers = []
|
matching_vouchers = []
|
||||||
|
|
||||||
matching_vouchers.extend(
|
matching_vouchers.extend(get_loan_vouchers(bank_account, transaction, document_types, filters))
|
||||||
get_loan_vouchers(bank_account, transaction, document_types, filters, exact_match)
|
|
||||||
)
|
|
||||||
|
|
||||||
for query in subquery:
|
for query in subquery:
|
||||||
matching_vouchers.extend(
|
matching_vouchers.extend(
|
||||||
@@ -523,23 +361,14 @@ def check_matching(
|
|||||||
filters,
|
filters,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
return sorted(matching_vouchers, key=lambda x: x[0], reverse=True) if matching_vouchers else []
|
return sorted(matching_vouchers, key=lambda x: x[0], reverse=True) if matching_vouchers else []
|
||||||
|
|
||||||
|
|
||||||
def get_queries(
|
def get_queries(bank_account, company, transaction, document_types):
|
||||||
bank_account,
|
|
||||||
company,
|
|
||||||
transaction,
|
|
||||||
document_types,
|
|
||||||
from_date,
|
|
||||||
to_date,
|
|
||||||
filter_by_reference_date,
|
|
||||||
from_reference_date,
|
|
||||||
to_reference_date,
|
|
||||||
exact_match,
|
|
||||||
):
|
|
||||||
# get queries to get matching vouchers
|
# get queries to get matching vouchers
|
||||||
account_from_to = "paid_to" if transaction.deposit > 0.0 else "paid_from"
|
amount_condition = "=" if "exact_match" in document_types else "<="
|
||||||
|
account_from_to = "paid_to" if transaction.deposit > 0 else "paid_from"
|
||||||
queries = []
|
queries = []
|
||||||
|
|
||||||
# get matching queries from all the apps
|
# get matching queries from all the apps
|
||||||
@@ -550,13 +379,8 @@ def get_queries(
|
|||||||
company,
|
company,
|
||||||
transaction,
|
transaction,
|
||||||
document_types,
|
document_types,
|
||||||
exact_match,
|
amount_condition,
|
||||||
account_from_to,
|
account_from_to,
|
||||||
from_date,
|
|
||||||
to_date,
|
|
||||||
filter_by_reference_date,
|
|
||||||
from_reference_date,
|
|
||||||
to_reference_date,
|
|
||||||
)
|
)
|
||||||
or []
|
or []
|
||||||
)
|
)
|
||||||
@@ -565,106 +389,43 @@ def get_queries(
|
|||||||
|
|
||||||
|
|
||||||
def get_matching_queries(
|
def get_matching_queries(
|
||||||
bank_account,
|
bank_account, company, transaction, document_types, amount_condition, account_from_to
|
||||||
company,
|
|
||||||
transaction,
|
|
||||||
document_types,
|
|
||||||
exact_match,
|
|
||||||
account_from_to,
|
|
||||||
from_date,
|
|
||||||
to_date,
|
|
||||||
filter_by_reference_date,
|
|
||||||
from_reference_date,
|
|
||||||
to_reference_date,
|
|
||||||
):
|
):
|
||||||
queries = []
|
queries = []
|
||||||
if "payment_entry" in document_types:
|
if "payment_entry" in document_types:
|
||||||
query = get_pe_matching_query(
|
pe_amount_matching = get_pe_matching_query(amount_condition, account_from_to, transaction)
|
||||||
exact_match,
|
queries.extend([pe_amount_matching])
|
||||||
account_from_to,
|
|
||||||
transaction,
|
|
||||||
from_date,
|
|
||||||
to_date,
|
|
||||||
filter_by_reference_date,
|
|
||||||
from_reference_date,
|
|
||||||
to_reference_date,
|
|
||||||
)
|
|
||||||
queries.append(query)
|
|
||||||
|
|
||||||
if "journal_entry" in document_types:
|
if "journal_entry" in document_types:
|
||||||
query = get_je_matching_query(
|
je_amount_matching = get_je_matching_query(amount_condition, transaction)
|
||||||
exact_match,
|
queries.extend([je_amount_matching])
|
||||||
transaction,
|
|
||||||
from_date,
|
|
||||||
to_date,
|
|
||||||
filter_by_reference_date,
|
|
||||||
from_reference_date,
|
|
||||||
to_reference_date,
|
|
||||||
)
|
|
||||||
queries.append(query)
|
|
||||||
|
|
||||||
if transaction.deposit > 0.0 and "sales_invoice" in document_types:
|
if transaction.deposit > 0 and "sales_invoice" in document_types:
|
||||||
query = get_si_matching_query(exact_match)
|
si_amount_matching = get_si_matching_query(amount_condition)
|
||||||
queries.append(query)
|
queries.extend([si_amount_matching])
|
||||||
|
|
||||||
if transaction.withdrawal > 0.0:
|
if transaction.withdrawal > 0:
|
||||||
if "purchase_invoice" in document_types:
|
if "purchase_invoice" in document_types:
|
||||||
query = get_pi_matching_query(exact_match)
|
pi_amount_matching = get_pi_matching_query(amount_condition)
|
||||||
queries.append(query)
|
queries.extend([pi_amount_matching])
|
||||||
|
|
||||||
if "bank_transaction" in document_types:
|
|
||||||
query = get_bt_matching_query(exact_match, transaction)
|
|
||||||
queries.append(query)
|
|
||||||
|
|
||||||
return queries
|
return queries
|
||||||
|
|
||||||
|
|
||||||
def get_loan_vouchers(bank_account, transaction, document_types, filters, exact_match):
|
def get_loan_vouchers(bank_account, transaction, document_types, filters):
|
||||||
vouchers = []
|
vouchers = []
|
||||||
|
amount_condition = True if "exact_match" in document_types else False
|
||||||
|
|
||||||
if transaction.withdrawal > 0.0 and "loan_disbursement" in document_types:
|
if transaction.withdrawal > 0 and "loan_disbursement" in document_types:
|
||||||
vouchers.extend(get_ld_matching_query(bank_account, exact_match, filters))
|
vouchers.extend(get_ld_matching_query(bank_account, amount_condition, filters))
|
||||||
|
|
||||||
if transaction.deposit > 0.0 and "loan_repayment" in document_types:
|
if transaction.deposit > 0 and "loan_repayment" in document_types:
|
||||||
vouchers.extend(get_lr_matching_query(bank_account, exact_match, filters))
|
vouchers.extend(get_lr_matching_query(bank_account, amount_condition, filters))
|
||||||
|
|
||||||
return vouchers
|
return vouchers
|
||||||
|
|
||||||
|
|
||||||
def get_bt_matching_query(exact_match, transaction):
|
def get_ld_matching_query(bank_account, amount_condition, filters):
|
||||||
# get matching bank transaction query
|
|
||||||
# find bank transactions in the same bank account with opposite sign
|
|
||||||
# same bank account must have same company and currency
|
|
||||||
field = "deposit" if transaction.withdrawal > 0.0 else "withdrawal"
|
|
||||||
|
|
||||||
return f"""
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
(CASE WHEN reference_number = %(reference_no)s THEN 1 ELSE 0 END
|
|
||||||
+ CASE WHEN {field} = %(amount)s THEN 1 ELSE 0 END
|
|
||||||
+ CASE WHEN ( party_type = %(party_type)s AND party = %(party)s ) THEN 1 ELSE 0 END
|
|
||||||
+ CASE WHEN unallocated_amount = %(amount)s THEN 1 ELSE 0 END
|
|
||||||
+ 1) AS rank,
|
|
||||||
'Bank Transaction' AS doctype,
|
|
||||||
name,
|
|
||||||
unallocated_amount AS paid_amount,
|
|
||||||
reference_number AS reference_no,
|
|
||||||
date AS reference_date,
|
|
||||||
party,
|
|
||||||
party_type,
|
|
||||||
date AS posting_date,
|
|
||||||
currency
|
|
||||||
FROM
|
|
||||||
`tabBank Transaction`
|
|
||||||
WHERE
|
|
||||||
status != 'Reconciled'
|
|
||||||
AND name != '{transaction.name}'
|
|
||||||
AND bank_account = '{transaction.bank_account}'
|
|
||||||
AND {field} {'= %(amount)s' if exact_match else '> 0.0'}
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def get_ld_matching_query(bank_account, exact_match, filters):
|
|
||||||
loan_disbursement = frappe.qb.DocType("Loan Disbursement")
|
loan_disbursement = frappe.qb.DocType("Loan Disbursement")
|
||||||
matching_reference = loan_disbursement.reference_number == filters.get("reference_number")
|
matching_reference = loan_disbursement.reference_number == filters.get("reference_number")
|
||||||
matching_party = loan_disbursement.applicant_type == filters.get(
|
matching_party = loan_disbursement.applicant_type == filters.get(
|
||||||
@@ -692,17 +453,17 @@ def get_ld_matching_query(bank_account, exact_match, filters):
|
|||||||
.where(loan_disbursement.disbursement_account == bank_account)
|
.where(loan_disbursement.disbursement_account == bank_account)
|
||||||
)
|
)
|
||||||
|
|
||||||
if exact_match:
|
if amount_condition:
|
||||||
query.where(loan_disbursement.disbursed_amount == filters.get("amount"))
|
query.where(loan_disbursement.disbursed_amount == filters.get("amount"))
|
||||||
else:
|
else:
|
||||||
query.where(loan_disbursement.disbursed_amount > 0.0)
|
query.where(loan_disbursement.disbursed_amount <= filters.get("amount"))
|
||||||
|
|
||||||
vouchers = query.run(as_list=True)
|
vouchers = query.run(as_list=True)
|
||||||
|
|
||||||
return vouchers
|
return vouchers
|
||||||
|
|
||||||
|
|
||||||
def get_lr_matching_query(bank_account, exact_match, filters):
|
def get_lr_matching_query(bank_account, amount_condition, filters):
|
||||||
loan_repayment = frappe.qb.DocType("Loan Repayment")
|
loan_repayment = frappe.qb.DocType("Loan Repayment")
|
||||||
matching_reference = loan_repayment.reference_number == filters.get("reference_number")
|
matching_reference = loan_repayment.reference_number == filters.get("reference_number")
|
||||||
matching_party = loan_repayment.applicant_type == filters.get(
|
matching_party = loan_repayment.applicant_type == filters.get(
|
||||||
@@ -733,44 +494,26 @@ def get_lr_matching_query(bank_account, exact_match, filters):
|
|||||||
if frappe.db.has_column("Loan Repayment", "repay_from_salary"):
|
if frappe.db.has_column("Loan Repayment", "repay_from_salary"):
|
||||||
query = query.where((loan_repayment.repay_from_salary == 0))
|
query = query.where((loan_repayment.repay_from_salary == 0))
|
||||||
|
|
||||||
if exact_match:
|
if amount_condition:
|
||||||
query.where(loan_repayment.amount_paid == filters.get("amount"))
|
query.where(loan_repayment.amount_paid == filters.get("amount"))
|
||||||
else:
|
else:
|
||||||
query.where(loan_repayment.amount_paid > 0.0)
|
query.where(loan_repayment.amount_paid <= filters.get("amount"))
|
||||||
|
|
||||||
vouchers = query.run()
|
vouchers = query.run()
|
||||||
|
|
||||||
return vouchers
|
return vouchers
|
||||||
|
|
||||||
|
|
||||||
def get_pe_matching_query(
|
def get_pe_matching_query(amount_condition, account_from_to, transaction):
|
||||||
exact_match,
|
|
||||||
account_from_to,
|
|
||||||
transaction,
|
|
||||||
from_date,
|
|
||||||
to_date,
|
|
||||||
filter_by_reference_date,
|
|
||||||
from_reference_date,
|
|
||||||
to_reference_date,
|
|
||||||
):
|
|
||||||
# get matching payment entries query
|
# get matching payment entries query
|
||||||
if transaction.deposit > 0.0:
|
if transaction.deposit > 0:
|
||||||
currency_field = "paid_to_account_currency as currency"
|
currency_field = "paid_to_account_currency as currency"
|
||||||
else:
|
else:
|
||||||
currency_field = "paid_from_account_currency as currency"
|
currency_field = "paid_from_account_currency as currency"
|
||||||
filter_by_date = f"AND posting_date between '{from_date}' and '{to_date}'"
|
|
||||||
order_by = " posting_date"
|
|
||||||
filter_by_reference_no = ""
|
|
||||||
if cint(filter_by_reference_date):
|
|
||||||
filter_by_date = f"AND reference_date between '{from_reference_date}' and '{to_reference_date}'"
|
|
||||||
order_by = " reference_date"
|
|
||||||
if frappe.flags.auto_reconcile_vouchers == True:
|
|
||||||
filter_by_reference_no = f"AND reference_no = '{transaction.reference_number}'"
|
|
||||||
return f"""
|
return f"""
|
||||||
SELECT
|
SELECT
|
||||||
(CASE WHEN reference_no=%(reference_no)s THEN 1 ELSE 0 END
|
(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
|
+ CASE WHEN (party_type = %(party_type)s AND party = %(party)s ) THEN 1 ELSE 0 END
|
||||||
+ CASE WHEN paid_amount = %(amount)s THEN 1 ELSE 0 END
|
|
||||||
+ 1 ) AS rank,
|
+ 1 ) AS rank,
|
||||||
'Payment Entry' as doctype,
|
'Payment Entry' as doctype,
|
||||||
name,
|
name,
|
||||||
@@ -784,78 +527,55 @@ def get_pe_matching_query(
|
|||||||
FROM
|
FROM
|
||||||
`tabPayment Entry`
|
`tabPayment Entry`
|
||||||
WHERE
|
WHERE
|
||||||
docstatus = 1
|
paid_amount {amount_condition} %(amount)s
|
||||||
|
AND docstatus = 1
|
||||||
AND payment_type IN (%(payment_type)s, 'Internal Transfer')
|
AND payment_type IN (%(payment_type)s, 'Internal Transfer')
|
||||||
AND ifnull(clearance_date, '') = ""
|
AND ifnull(clearance_date, '') = ""
|
||||||
AND {account_from_to} = %(bank_account)s
|
AND {account_from_to} = %(bank_account)s
|
||||||
AND paid_amount {'= %(amount)s' if exact_match else '> 0.0'}
|
|
||||||
{filter_by_date}
|
|
||||||
{filter_by_reference_no}
|
|
||||||
order by{order_by}
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def get_je_matching_query(
|
def get_je_matching_query(amount_condition, transaction):
|
||||||
exact_match,
|
|
||||||
transaction,
|
|
||||||
from_date,
|
|
||||||
to_date,
|
|
||||||
filter_by_reference_date,
|
|
||||||
from_reference_date,
|
|
||||||
to_reference_date,
|
|
||||||
):
|
|
||||||
# get matching journal entry query
|
# get matching journal entry query
|
||||||
|
|
||||||
# We have mapping at the bank level
|
# We have mapping at the bank level
|
||||||
# So one bank could have both types of bank accounts like asset and liability
|
# So one bank could have both types of bank accounts like asset and liability
|
||||||
# So cr_or_dr should be judged only on basis of withdrawal and deposit and not account type
|
# So cr_or_dr should be judged only on basis of withdrawal and deposit and not account type
|
||||||
cr_or_dr = "credit" if transaction.withdrawal > 0.0 else "debit"
|
cr_or_dr = "credit" if transaction.withdrawal > 0 else "debit"
|
||||||
filter_by_date = f"AND je.posting_date between '{from_date}' and '{to_date}'"
|
|
||||||
order_by = " je.posting_date"
|
|
||||||
filter_by_reference_no = ""
|
|
||||||
if cint(filter_by_reference_date):
|
|
||||||
filter_by_date = f"AND je.cheque_date between '{from_reference_date}' and '{to_reference_date}'"
|
|
||||||
order_by = " je.cheque_date"
|
|
||||||
if frappe.flags.auto_reconcile_vouchers == True:
|
|
||||||
filter_by_reference_no = f"AND je.cheque_no = '{transaction.reference_number}'"
|
|
||||||
return f"""
|
return f"""
|
||||||
|
|
||||||
SELECT
|
SELECT
|
||||||
(CASE WHEN je.cheque_no=%(reference_no)s THEN 1 ELSE 0 END
|
(CASE WHEN je.cheque_no=%(reference_no)s THEN 1 ELSE 0 END
|
||||||
+ CASE WHEN jea.{cr_or_dr}_in_account_currency = %(amount)s THEN 1 ELSE 0 END
|
|
||||||
+ 1) AS rank ,
|
+ 1) AS rank ,
|
||||||
'Journal Entry' AS doctype,
|
'Journal Entry' as doctype,
|
||||||
je.name,
|
je.name,
|
||||||
jea.{cr_or_dr}_in_account_currency AS paid_amount,
|
jea.{cr_or_dr}_in_account_currency as paid_amount,
|
||||||
je.cheque_no AS reference_no,
|
je.cheque_no as reference_no,
|
||||||
je.cheque_date AS reference_date,
|
je.cheque_date as reference_date,
|
||||||
je.pay_to_recd_from AS party,
|
je.pay_to_recd_from as party,
|
||||||
jea.party_type,
|
jea.party_type,
|
||||||
je.posting_date,
|
je.posting_date,
|
||||||
jea.account_currency AS currency
|
jea.account_currency as currency
|
||||||
FROM
|
FROM
|
||||||
`tabJournal Entry Account` AS jea
|
`tabJournal Entry Account` as jea
|
||||||
JOIN
|
JOIN
|
||||||
`tabJournal Entry` AS je
|
`tabJournal Entry` as je
|
||||||
ON
|
ON
|
||||||
jea.parent = je.name
|
jea.parent = je.name
|
||||||
WHERE
|
WHERE
|
||||||
je.docstatus = 1
|
(je.clearance_date is null or je.clearance_date='0000-00-00')
|
||||||
AND je.voucher_type NOT IN ('Opening Entry')
|
|
||||||
AND (je.clearance_date IS NULL OR je.clearance_date='0000-00-00')
|
|
||||||
AND jea.account = %(bank_account)s
|
AND jea.account = %(bank_account)s
|
||||||
AND jea.{cr_or_dr}_in_account_currency {'= %(amount)s' if exact_match else '> 0.0'}
|
AND jea.{cr_or_dr}_in_account_currency {amount_condition} %(amount)s
|
||||||
AND je.docstatus = 1
|
AND je.docstatus = 1
|
||||||
{filter_by_date}
|
|
||||||
{filter_by_reference_no}
|
|
||||||
order by {order_by}
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def get_si_matching_query(exact_match):
|
def get_si_matching_query(amount_condition):
|
||||||
# get matching sales invoice query
|
# get matchin sales invoice query
|
||||||
return f"""
|
return f"""
|
||||||
SELECT
|
SELECT
|
||||||
( CASE WHEN si.customer = %(party)s THEN 1 ELSE 0 END
|
( CASE WHEN si.customer = %(party)s THEN 1 ELSE 0 END
|
||||||
+ CASE WHEN sip.amount = %(amount)s THEN 1 ELSE 0 END
|
|
||||||
+ 1 ) AS rank,
|
+ 1 ) AS rank,
|
||||||
'Sales Invoice' as doctype,
|
'Sales Invoice' as doctype,
|
||||||
si.name,
|
si.name,
|
||||||
@@ -873,20 +593,18 @@ def get_si_matching_query(exact_match):
|
|||||||
`tabSales Invoice` as si
|
`tabSales Invoice` as si
|
||||||
ON
|
ON
|
||||||
sip.parent = si.name
|
sip.parent = si.name
|
||||||
WHERE
|
WHERE (sip.clearance_date is null or sip.clearance_date='0000-00-00')
|
||||||
si.docstatus = 1
|
|
||||||
AND (sip.clearance_date is null or sip.clearance_date='0000-00-00')
|
|
||||||
AND sip.account = %(bank_account)s
|
AND sip.account = %(bank_account)s
|
||||||
AND sip.amount {'= %(amount)s' if exact_match else '> 0.0'}
|
AND sip.amount {amount_condition} %(amount)s
|
||||||
|
AND si.docstatus = 1
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def get_pi_matching_query(exact_match):
|
def get_pi_matching_query(amount_condition):
|
||||||
# get matching purchase invoice query when they are also used as payment entries (is_paid)
|
# get matching purchase invoice query
|
||||||
return f"""
|
return f"""
|
||||||
SELECT
|
SELECT
|
||||||
( CASE WHEN supplier = %(party)s THEN 1 ELSE 0 END
|
( CASE WHEN supplier = %(party)s THEN 1 ELSE 0 END
|
||||||
+ CASE WHEN paid_amount = %(amount)s THEN 1 ELSE 0 END
|
|
||||||
+ 1 ) AS rank,
|
+ 1 ) AS rank,
|
||||||
'Purchase Invoice' as doctype,
|
'Purchase Invoice' as doctype,
|
||||||
name,
|
name,
|
||||||
@@ -900,9 +618,9 @@ def get_pi_matching_query(exact_match):
|
|||||||
FROM
|
FROM
|
||||||
`tabPurchase Invoice`
|
`tabPurchase Invoice`
|
||||||
WHERE
|
WHERE
|
||||||
docstatus = 1
|
paid_amount {amount_condition} %(amount)s
|
||||||
|
AND docstatus = 1
|
||||||
AND is_paid = 1
|
AND is_paid = 1
|
||||||
AND ifnull(clearance_date, '') = ""
|
AND ifnull(clearance_date, '') = ""
|
||||||
AND cash_bank_account = %(bank_account)s
|
AND cash_bank_account = %(bank_account)s
|
||||||
AND paid_amount {'= %(amount)s' if exact_match else '> 0.0'}
|
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -2,22 +2,14 @@
|
|||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Bank Statement Import", {
|
frappe.ui.form.on("Bank Statement Import", {
|
||||||
onload(frm) {
|
|
||||||
frm.set_query("bank_account", function (doc) {
|
|
||||||
return {
|
|
||||||
filters: {
|
|
||||||
company: doc.company,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
setup(frm) {
|
setup(frm) {
|
||||||
frappe.realtime.on("data_import_refresh", ({ data_import }) => {
|
frappe.realtime.on("data_import_refresh", ({ data_import }) => {
|
||||||
frm.import_in_progress = false;
|
frm.import_in_progress = false;
|
||||||
if (data_import !== frm.doc.name) return;
|
if (data_import !== frm.doc.name) return;
|
||||||
frappe.model.clear_doc("Bank Statement Import", frm.doc.name);
|
frappe.model.clear_doc("Bank Statement Import", frm.doc.name);
|
||||||
frappe.model.with_doc("Bank Statement Import", frm.doc.name).then(() => {
|
frappe.model
|
||||||
|
.with_doc("Bank Statement Import", frm.doc.name)
|
||||||
|
.then(() => {
|
||||||
frm.refresh();
|
frm.refresh();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -46,9 +38,20 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
: __("Updating {0} of {1}, {2}", message_args);
|
: __("Updating {0} of {1}, {2}", message_args);
|
||||||
}
|
}
|
||||||
if (data.skipping) {
|
if (data.skipping) {
|
||||||
message = __("Skipping {0} of {1}, {2}", [data.current, data.total, eta_message]);
|
message = __(
|
||||||
|
"Skipping {0} of {1}, {2}",
|
||||||
|
[
|
||||||
|
data.current,
|
||||||
|
data.total,
|
||||||
|
eta_message,
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
frm.dashboard.show_progress(__("Import Progress"), percent, message);
|
frm.dashboard.show_progress(
|
||||||
|
__("Import Progress"),
|
||||||
|
percent,
|
||||||
|
message
|
||||||
|
);
|
||||||
frm.page.set_indicator(__("In Progress"), "orange");
|
frm.page.set_indicator(__("In Progress"), "orange");
|
||||||
|
|
||||||
// hide progress when complete
|
// hide progress when complete
|
||||||
@@ -90,12 +93,15 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
frm.trigger("show_report_error_button");
|
frm.trigger("show_report_error_button");
|
||||||
|
|
||||||
if (frm.doc.status === "Partial Success") {
|
if (frm.doc.status === "Partial Success") {
|
||||||
frm.add_custom_button(__("Export Errored Rows"), () => frm.trigger("export_errored_rows"));
|
frm.add_custom_button(__("Export Errored Rows"), () =>
|
||||||
|
frm.trigger("export_errored_rows")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frm.doc.status.includes("Success")) {
|
if (frm.doc.status.includes("Success")) {
|
||||||
frm.add_custom_button(__("Go to {0} List", [__(frm.doc.reference_doctype)]), () =>
|
frm.add_custom_button(
|
||||||
frappe.set_route("List", frm.doc.reference_doctype)
|
__("Go to {0} List", [__(frm.doc.reference_doctype)]),
|
||||||
|
() => frappe.set_route("List", frm.doc.reference_doctype)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -112,8 +118,13 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
frm.disable_save();
|
frm.disable_save();
|
||||||
if (frm.doc.status !== "Success") {
|
if (frm.doc.status !== "Success") {
|
||||||
if (!frm.is_new() && frm.has_import_file()) {
|
if (!frm.is_new() && frm.has_import_file()) {
|
||||||
let label = frm.doc.status === "Pending" ? __("Start Import") : __("Retry");
|
let label =
|
||||||
frm.page.set_primary_action(label, () => frm.events.start_import(frm));
|
frm.doc.status === "Pending"
|
||||||
|
? __("Start Import")
|
||||||
|
: __("Retry");
|
||||||
|
frm.page.set_primary_action(label, () =>
|
||||||
|
frm.events.start_import(frm)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
frm.page.set_primary_action(__("Save"), () => frm.save());
|
frm.page.set_primary_action(__("Save"), () => frm.save());
|
||||||
}
|
}
|
||||||
@@ -215,7 +226,8 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
download_template() {
|
download_template() {
|
||||||
let method = "/api/method/frappe.core.doctype.data_import.data_import.download_template";
|
let method =
|
||||||
|
"/api/method/frappe.core.doctype.data_import.data_import.download_template";
|
||||||
|
|
||||||
open_url_post(method, {
|
open_url_post(method, {
|
||||||
doctype: "Bank Transaction",
|
doctype: "Bank Transaction",
|
||||||
@@ -228,7 +240,7 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
"description",
|
"description",
|
||||||
"reference_number",
|
"reference_number",
|
||||||
"bank_account",
|
"bank_account",
|
||||||
"currency",
|
"currency"
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -299,7 +311,10 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
show_import_preview(frm, preview_data) {
|
show_import_preview(frm, preview_data) {
|
||||||
let import_log = JSON.parse(frm.doc.statement_import_log || "[]");
|
let import_log = JSON.parse(frm.doc.statement_import_log || "[]");
|
||||||
|
|
||||||
if (frm.import_preview && frm.import_preview.doctype === frm.doc.reference_doctype) {
|
if (
|
||||||
|
frm.import_preview &&
|
||||||
|
frm.import_preview.doctype === frm.doc.reference_doctype
|
||||||
|
) {
|
||||||
frm.import_preview.preview_data = preview_data;
|
frm.import_preview.preview_data = preview_data;
|
||||||
frm.import_preview.import_log = import_log;
|
frm.import_preview.import_log = import_log;
|
||||||
frm.import_preview.refresh();
|
frm.import_preview.refresh();
|
||||||
@@ -315,10 +330,19 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
frm,
|
frm,
|
||||||
events: {
|
events: {
|
||||||
remap_column(changed_map) {
|
remap_column(changed_map) {
|
||||||
let template_options = JSON.parse(frm.doc.template_options || "{}");
|
let template_options = JSON.parse(
|
||||||
template_options.column_to_field_map = template_options.column_to_field_map || {};
|
frm.doc.template_options || "{}"
|
||||||
Object.assign(template_options.column_to_field_map, changed_map);
|
);
|
||||||
frm.set_value("template_options", JSON.stringify(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"));
|
frm.save().then(() => frm.trigger("import_file"));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -328,11 +352,10 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
|
|
||||||
export_errored_rows(frm) {
|
export_errored_rows(frm) {
|
||||||
open_url_post(
|
open_url_post(
|
||||||
"/api/method/erpnext.accounts.doctype.bank_statement_import.bank_statement_import.download_errored_template",
|
"/api/method/frappe.core.doctype.data_import.data_import.download_errored_template",
|
||||||
{
|
{
|
||||||
data_import_name: frm.doc.name,
|
data_import_name: frm.doc.name,
|
||||||
},
|
}
|
||||||
true
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -352,7 +375,8 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
let other_warnings = [];
|
let other_warnings = [];
|
||||||
for (let warning of warnings) {
|
for (let warning of warnings) {
|
||||||
if (warning.row) {
|
if (warning.row) {
|
||||||
warnings_by_row[warning.row] = warnings_by_row[warning.row] || [];
|
warnings_by_row[warning.row] =
|
||||||
|
warnings_by_row[warning.row] || [];
|
||||||
warnings_by_row[warning.row].push(warning);
|
warnings_by_row[warning.row].push(warning);
|
||||||
} else {
|
} else {
|
||||||
other_warnings.push(warning);
|
other_warnings.push(warning);
|
||||||
@@ -367,7 +391,9 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
if (w.field) {
|
if (w.field) {
|
||||||
let label =
|
let label =
|
||||||
w.field.label +
|
w.field.label +
|
||||||
(w.field.parent !== frm.doc.reference_doctype ? ` (${w.field.parent})` : "");
|
(w.field.parent !== frm.doc.reference_doctype
|
||||||
|
? ` (${w.field.parent})`
|
||||||
|
: "");
|
||||||
return `<li>${label}: ${w.message}</li>`;
|
return `<li>${label}: ${w.message}</li>`;
|
||||||
}
|
}
|
||||||
return `<li>${w.message}</li>`;
|
return `<li>${w.message}</li>`;
|
||||||
@@ -386,9 +412,10 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
.map((warning) => {
|
.map((warning) => {
|
||||||
let header = "";
|
let header = "";
|
||||||
if (warning.col) {
|
if (warning.col) {
|
||||||
let column_number = `<span class="text-uppercase">${__("Column {0}", [
|
let column_number = `<span class="text-uppercase">${__(
|
||||||
warning.col,
|
"Column {0}",
|
||||||
])}</span>`;
|
[warning.col]
|
||||||
|
)}</span>`;
|
||||||
let column_header = columns[warning.col].header_title;
|
let column_header = columns[warning.col].header_title;
|
||||||
header = `${column_number} (${column_header})`;
|
header = `${column_number} (${column_header})`;
|
||||||
}
|
}
|
||||||
@@ -427,28 +454,36 @@ frappe.ui.form.on("Bank Statement Import", {
|
|||||||
let html = "";
|
let html = "";
|
||||||
if (log.success) {
|
if (log.success) {
|
||||||
if (frm.doc.import_type === "Insert New Records") {
|
if (frm.doc.import_type === "Insert New Records") {
|
||||||
html = __("Successfully imported {0}", [
|
html = __(
|
||||||
|
"Successfully imported {0}", [
|
||||||
`<span class="underline">${frappe.utils.get_form_link(
|
`<span class="underline">${frappe.utils.get_form_link(
|
||||||
frm.doc.reference_doctype,
|
frm.doc.reference_doctype,
|
||||||
log.docname,
|
log.docname,
|
||||||
true
|
true
|
||||||
)}<span>`,
|
)}<span>`,
|
||||||
]);
|
]
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
html = __("Successfully updated {0}", [
|
html = __(
|
||||||
|
"Successfully updated {0}", [
|
||||||
`<span class="underline">${frappe.utils.get_form_link(
|
`<span class="underline">${frappe.utils.get_form_link(
|
||||||
frm.doc.reference_doctype,
|
frm.doc.reference_doctype,
|
||||||
log.docname,
|
log.docname,
|
||||||
true
|
true
|
||||||
)}<span>`,
|
)}<span>`,
|
||||||
]);
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let messages = log.messages
|
let messages = log.messages
|
||||||
.map(JSON.parse)
|
.map(JSON.parse)
|
||||||
.map((m) => {
|
.map((m) => {
|
||||||
let title = m.title ? `<strong>${m.title}</strong>` : "";
|
let title = m.title
|
||||||
let message = m.message ? `<div>${m.message}</div>` : "";
|
? `<strong>${m.title}</strong>`
|
||||||
|
: "";
|
||||||
|
let message = m.message
|
||||||
|
? `<div>${m.message}</div>`
|
||||||
|
: "";
|
||||||
return title + message;
|
return title + message;
|
||||||
})
|
})
|
||||||
.join("");
|
.join("");
|
||||||
|
|||||||
@@ -53,15 +53,13 @@ class BankStatementImport(DataImport):
|
|||||||
if "Bank Account" not in json.dumps(preview["columns"]):
|
if "Bank Account" not in json.dumps(preview["columns"]):
|
||||||
frappe.throw(_("Please add the Bank Account column"))
|
frappe.throw(_("Please add the Bank Account column"))
|
||||||
|
|
||||||
from frappe.core.page.background_jobs.background_jobs import get_info
|
from frappe.utils.background_jobs import is_job_queued
|
||||||
from frappe.utils.scheduler import is_scheduler_inactive
|
from frappe.utils.scheduler import is_scheduler_inactive
|
||||||
|
|
||||||
if is_scheduler_inactive() and not frappe.flags.in_test:
|
if is_scheduler_inactive() and not frappe.flags.in_test:
|
||||||
frappe.throw(_("Scheduler is inactive. Cannot import data."), title=_("Scheduler Inactive"))
|
frappe.throw(_("Scheduler is inactive. Cannot import data."), title=_("Scheduler Inactive"))
|
||||||
|
|
||||||
enqueued_jobs = [d.get("job_name") for d in get_info()]
|
if not is_job_queued(self.name):
|
||||||
|
|
||||||
if self.name not in enqueued_jobs:
|
|
||||||
enqueue(
|
enqueue(
|
||||||
start_import,
|
start_import,
|
||||||
queue="default",
|
queue="default",
|
||||||
|
|||||||
@@ -1,34 +1,36 @@
|
|||||||
let imports_in_progress = [];
|
let imports_in_progress = [];
|
||||||
|
|
||||||
frappe.listview_settings["Bank Statement Import"] = {
|
frappe.listview_settings['Bank Statement Import'] = {
|
||||||
onload(listview) {
|
onload(listview) {
|
||||||
frappe.realtime.on("data_import_progress", (data) => {
|
frappe.realtime.on('data_import_progress', data => {
|
||||||
if (!imports_in_progress.includes(data.data_import)) {
|
if (!imports_in_progress.includes(data.data_import)) {
|
||||||
imports_in_progress.push(data.data_import);
|
imports_in_progress.push(data.data_import);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
frappe.realtime.on("data_import_refresh", (data) => {
|
frappe.realtime.on('data_import_refresh', data => {
|
||||||
imports_in_progress = imports_in_progress.filter((d) => d !== data.data_import);
|
imports_in_progress = imports_in_progress.filter(
|
||||||
|
d => d !== data.data_import
|
||||||
|
);
|
||||||
listview.refresh();
|
listview.refresh();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
get_indicator: function (doc) {
|
get_indicator: function(doc) {
|
||||||
var colors = {
|
var colors = {
|
||||||
Pending: "orange",
|
'Pending': 'orange',
|
||||||
"Not Started": "orange",
|
'Not Started': 'orange',
|
||||||
"Partial Success": "orange",
|
'Partial Success': 'orange',
|
||||||
Success: "green",
|
'Success': 'green',
|
||||||
"In Progress": "orange",
|
'In Progress': 'orange',
|
||||||
Error: "red",
|
'Error': 'red'
|
||||||
};
|
};
|
||||||
let status = doc.status;
|
let status = doc.status;
|
||||||
if (imports_in_progress.includes(doc.name)) {
|
if (imports_in_progress.includes(doc.name)) {
|
||||||
status = "In Progress";
|
status = 'In Progress';
|
||||||
}
|
}
|
||||||
if (status == "Pending") {
|
if (status == 'Pending') {
|
||||||
status = "Not Started";
|
status = 'Not Started';
|
||||||
}
|
}
|
||||||
return [__(status), colors[status], "status,=," + doc.status];
|
return [__(status), colors[status], 'status,=,' + doc.status];
|
||||||
},
|
},
|
||||||
hide_name_column: true,
|
hide_name_column: true
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,183 +0,0 @@
|
|||||||
from typing import Tuple, Union
|
|
||||||
|
|
||||||
import frappe
|
|
||||||
from frappe.utils import flt
|
|
||||||
from rapidfuzz import fuzz, process
|
|
||||||
|
|
||||||
|
|
||||||
class AutoMatchParty:
|
|
||||||
"""
|
|
||||||
Matches by Account/IBAN and then by Party Name/Description sequentially.
|
|
||||||
Returns when a result is obtained.
|
|
||||||
|
|
||||||
Result (if present) is of the form: (Party Type, Party,)
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, **kwargs) -> None:
|
|
||||||
self.__dict__.update(kwargs)
|
|
||||||
|
|
||||||
def get(self, key):
|
|
||||||
return self.__dict__.get(key, None)
|
|
||||||
|
|
||||||
def match(self) -> Union[Tuple, None]:
|
|
||||||
result = None
|
|
||||||
result = AutoMatchbyAccountIBAN(
|
|
||||||
bank_party_account_number=self.bank_party_account_number,
|
|
||||||
bank_party_iban=self.bank_party_iban,
|
|
||||||
deposit=self.deposit,
|
|
||||||
).match()
|
|
||||||
|
|
||||||
fuzzy_matching_enabled = frappe.db.get_single_value("Accounts Settings", "enable_fuzzy_matching")
|
|
||||||
if not result and fuzzy_matching_enabled:
|
|
||||||
result = AutoMatchbyPartyNameDescription(
|
|
||||||
bank_party_name=self.bank_party_name, description=self.description, deposit=self.deposit
|
|
||||||
).match()
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
class AutoMatchbyAccountIBAN:
|
|
||||||
def __init__(self, **kwargs) -> None:
|
|
||||||
self.__dict__.update(kwargs)
|
|
||||||
|
|
||||||
def get(self, key):
|
|
||||||
return self.__dict__.get(key, None)
|
|
||||||
|
|
||||||
def match(self):
|
|
||||||
if not (self.bank_party_account_number or self.bank_party_iban):
|
|
||||||
return None
|
|
||||||
|
|
||||||
result = self.match_account_in_party()
|
|
||||||
return result
|
|
||||||
|
|
||||||
def match_account_in_party(self) -> Union[Tuple, None]:
|
|
||||||
"""Check if there is a IBAN/Account No. match in Customer/Supplier/Employee"""
|
|
||||||
result = None
|
|
||||||
parties = get_parties_in_order(self.deposit)
|
|
||||||
or_filters = self.get_or_filters()
|
|
||||||
|
|
||||||
for party in parties:
|
|
||||||
party_result = frappe.db.get_all(
|
|
||||||
"Bank Account", or_filters=or_filters, pluck="party", limit_page_length=1
|
|
||||||
)
|
|
||||||
|
|
||||||
if party == "Employee" and not party_result:
|
|
||||||
# Search in Bank Accounts first for Employee, and then Employee record
|
|
||||||
if "bank_account_no" in or_filters:
|
|
||||||
or_filters["bank_ac_no"] = or_filters.pop("bank_account_no")
|
|
||||||
|
|
||||||
party_result = frappe.db.get_all(
|
|
||||||
party, or_filters=or_filters, pluck="name", limit_page_length=1
|
|
||||||
)
|
|
||||||
|
|
||||||
if party_result:
|
|
||||||
result = (
|
|
||||||
party,
|
|
||||||
party_result[0],
|
|
||||||
)
|
|
||||||
break
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def get_or_filters(self) -> dict:
|
|
||||||
or_filters = {}
|
|
||||||
if self.bank_party_account_number:
|
|
||||||
or_filters["bank_account_no"] = self.bank_party_account_number
|
|
||||||
|
|
||||||
if self.bank_party_iban:
|
|
||||||
or_filters["iban"] = self.bank_party_iban
|
|
||||||
|
|
||||||
return or_filters
|
|
||||||
|
|
||||||
|
|
||||||
class AutoMatchbyPartyNameDescription:
|
|
||||||
def __init__(self, **kwargs) -> None:
|
|
||||||
self.__dict__.update(kwargs)
|
|
||||||
|
|
||||||
def get(self, key):
|
|
||||||
return self.__dict__.get(key, None)
|
|
||||||
|
|
||||||
def match(self) -> Union[Tuple, None]:
|
|
||||||
# fuzzy search by customer/supplier & employee
|
|
||||||
if not (self.bank_party_name or self.description):
|
|
||||||
return None
|
|
||||||
|
|
||||||
result = self.match_party_name_desc_in_party()
|
|
||||||
return result
|
|
||||||
|
|
||||||
def match_party_name_desc_in_party(self) -> Union[Tuple, None]:
|
|
||||||
"""Fuzzy search party name and/or description against parties in the system"""
|
|
||||||
result = None
|
|
||||||
parties = get_parties_in_order(self.deposit)
|
|
||||||
|
|
||||||
for party in parties:
|
|
||||||
filters = {"status": "Active"} if party == "Employee" else {"disabled": 0}
|
|
||||||
field = party.lower() + "_name"
|
|
||||||
names = frappe.get_all(party, filters=filters, fields=[f"{field} as party_name", "name"])
|
|
||||||
|
|
||||||
for field in ["bank_party_name", "description"]:
|
|
||||||
if not self.get(field):
|
|
||||||
continue
|
|
||||||
|
|
||||||
result, skip = self.fuzzy_search_and_return_result(party, names, field)
|
|
||||||
if result or skip:
|
|
||||||
break
|
|
||||||
|
|
||||||
if result or skip:
|
|
||||||
# Skip If: It was hard to distinguish between close matches and so match is None
|
|
||||||
# OR if the right match was found
|
|
||||||
break
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def fuzzy_search_and_return_result(self, party, names, field) -> Union[Tuple, None]:
|
|
||||||
skip = False
|
|
||||||
result = process.extract(
|
|
||||||
query=self.get(field),
|
|
||||||
choices={row.get("name"): row.get("party_name") for row in names},
|
|
||||||
scorer=fuzz.token_set_ratio,
|
|
||||||
)
|
|
||||||
party_name, skip = self.process_fuzzy_result(result)
|
|
||||||
|
|
||||||
if not party_name:
|
|
||||||
return None, skip
|
|
||||||
|
|
||||||
return (
|
|
||||||
party,
|
|
||||||
party_name,
|
|
||||||
), skip
|
|
||||||
|
|
||||||
def process_fuzzy_result(self, result: Union[list, None]):
|
|
||||||
"""
|
|
||||||
If there are multiple valid close matches return None as result may be faulty.
|
|
||||||
Return the result only if one accurate match stands out.
|
|
||||||
|
|
||||||
Returns: Result, Skip (whether or not to discontinue matching)
|
|
||||||
"""
|
|
||||||
SCORE, PARTY_ID, CUTOFF = 1, 2, 80
|
|
||||||
|
|
||||||
if not result or not len(result):
|
|
||||||
return None, False
|
|
||||||
|
|
||||||
first_result = result[0]
|
|
||||||
if len(result) == 1:
|
|
||||||
return (first_result[PARTY_ID] if first_result[SCORE] > CUTOFF else None), True
|
|
||||||
|
|
||||||
second_result = result[1]
|
|
||||||
if first_result[SCORE] > CUTOFF:
|
|
||||||
# If multiple matches with the same score, return None but discontinue matching
|
|
||||||
# Matches were found but were too close to distinguish between
|
|
||||||
if first_result[SCORE] == second_result[SCORE]:
|
|
||||||
return None, True
|
|
||||||
|
|
||||||
return first_result[PARTY_ID], True
|
|
||||||
else:
|
|
||||||
return None, False
|
|
||||||
|
|
||||||
|
|
||||||
def get_parties_in_order(deposit: float) -> list:
|
|
||||||
parties = ["Supplier", "Employee", "Customer"] # most -> least likely to receive
|
|
||||||
if flt(deposit) > 0:
|
|
||||||
parties = ["Customer", "Supplier", "Employee"] # most -> least likely to pay
|
|
||||||
|
|
||||||
return parties
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
frappe.ui.form.on("Bank Transaction", {
|
frappe.ui.form.on("Bank Transaction", {
|
||||||
onload(frm) {
|
onload(frm) {
|
||||||
frm.set_query("payment_document", "payment_entries", function () {
|
frm.set_query("payment_document", "payment_entries", function() {
|
||||||
const payment_doctypes = frm.events.get_payment_doctypes(frm);
|
const payment_doctypes = frm.events.get_payment_doctypes(frm);
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
@@ -12,18 +12,12 @@ frappe.ui.form.on("Bank Transaction", {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
refresh(frm) {
|
|
||||||
if (!frm.is_dirty() && frm.doc.payment_entries.length > 0) {
|
bank_account: function(frm) {
|
||||||
frm.add_custom_button(__("Unreconcile Transaction"), () => {
|
|
||||||
frm.call("remove_payment_entries").then(() => frm.refresh());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
bank_account: function (frm) {
|
|
||||||
set_bank_statement_filter(frm);
|
set_bank_statement_filter(frm);
|
||||||
},
|
},
|
||||||
|
|
||||||
setup: function (frm) {
|
setup: function(frm) {
|
||||||
frm.set_query("party_type", function () {
|
frm.set_query("party_type", function () {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
@@ -33,10 +27,15 @@ frappe.ui.form.on("Bank Transaction", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
get_payment_doctypes: function () {
|
get_payment_doctypes: function() {
|
||||||
// get payment doctypes from all the apps
|
// get payment doctypes from all the apps
|
||||||
return ["Payment Entry", "Journal Entry", "Sales Invoice", "Purchase Invoice", "Bank Transaction"];
|
return [
|
||||||
},
|
"Payment Entry",
|
||||||
|
"Journal Entry",
|
||||||
|
"Sales Invoice",
|
||||||
|
"Purchase Invoice",
|
||||||
|
];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
frappe.ui.form.on("Bank Transaction Payments", {
|
frappe.ui.form.on("Bank Transaction Payments", {
|
||||||
@@ -48,11 +47,10 @@ frappe.ui.form.on("Bank Transaction Payments", {
|
|||||||
const update_clearance_date = (frm, cdt, cdn) => {
|
const update_clearance_date = (frm, cdt, cdn) => {
|
||||||
if (frm.doc.docstatus === 1) {
|
if (frm.doc.docstatus === 1) {
|
||||||
frappe
|
frappe
|
||||||
.xcall("erpnext.accounts.doctype.bank_transaction.bank_transaction.unclear_reference_payment", {
|
.xcall(
|
||||||
doctype: cdt,
|
"erpnext.accounts.doctype.bank_transaction.bank_transaction.unclear_reference_payment",
|
||||||
docname: cdn,
|
{ doctype: cdt, docname: cdn }
|
||||||
bt_name: frm.doc.name,
|
)
|
||||||
})
|
|
||||||
.then((e) => {
|
.then((e) => {
|
||||||
if (e == "success") {
|
if (e == "success") {
|
||||||
frappe.show_alert({
|
frappe.show_alert({
|
||||||
|
|||||||
@@ -20,11 +20,9 @@
|
|||||||
"currency",
|
"currency",
|
||||||
"section_break_10",
|
"section_break_10",
|
||||||
"description",
|
"description",
|
||||||
"reference_number",
|
|
||||||
"column_break_10",
|
|
||||||
"transaction_id",
|
|
||||||
"transaction_type",
|
|
||||||
"section_break_14",
|
"section_break_14",
|
||||||
|
"reference_number",
|
||||||
|
"transaction_id",
|
||||||
"payment_entries",
|
"payment_entries",
|
||||||
"section_break_18",
|
"section_break_18",
|
||||||
"allocated_amount",
|
"allocated_amount",
|
||||||
@@ -33,11 +31,7 @@
|
|||||||
"unallocated_amount",
|
"unallocated_amount",
|
||||||
"party_section",
|
"party_section",
|
||||||
"party_type",
|
"party_type",
|
||||||
"party",
|
"party"
|
||||||
"column_break_3czf",
|
|
||||||
"bank_party_name",
|
|
||||||
"bank_party_account_number",
|
|
||||||
"bank_party_iban"
|
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -67,7 +61,7 @@
|
|||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Status",
|
"label": "Status",
|
||||||
"options": "\nPending\nSettled\nUnreconciled\nReconciled\nCancelled"
|
"options": "\nPending\nSettled\nUnreconciled\nReconciled"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "bank_account",
|
"fieldname": "bank_account",
|
||||||
@@ -196,40 +190,11 @@
|
|||||||
"label": "Withdrawal",
|
"label": "Withdrawal",
|
||||||
"oldfieldname": "credit",
|
"oldfieldname": "credit",
|
||||||
"options": "currency"
|
"options": "currency"
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "column_break_10",
|
|
||||||
"fieldtype": "Column Break"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "transaction_type",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"label": "Transaction Type",
|
|
||||||
"length": 50
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "column_break_3czf",
|
|
||||||
"fieldtype": "Column Break"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "bank_party_name",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"label": "Party Name/Account Holder (Bank Statement)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "bank_party_iban",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"label": "Party IBAN (Bank Statement)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "bank_party_account_number",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"label": "Party Account No. (Bank Statement)"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-06-06 13:58:12.821411",
|
"modified": "2022-03-21 19:05:04.208222",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Bank Transaction",
|
"name": "Bank Transaction",
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
|
||||||
|
from functools import reduce
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.model.docstatus import DocStatus
|
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
|
|
||||||
from erpnext.controllers.status_updater import StatusUpdater
|
from erpnext.controllers.status_updater import StatusUpdater
|
||||||
@@ -16,158 +18,72 @@ class BankTransaction(StatusUpdater):
|
|||||||
self.clear_linked_payment_entries()
|
self.clear_linked_payment_entries()
|
||||||
self.set_status()
|
self.set_status()
|
||||||
|
|
||||||
if frappe.db.get_single_value("Accounts Settings", "enable_party_matching"):
|
|
||||||
self.auto_set_party()
|
|
||||||
|
|
||||||
_saving_flag = False
|
|
||||||
|
|
||||||
# nosemgrep: frappe-semgrep-rules.rules.frappe-modifying-but-not-comitting
|
|
||||||
def on_update_after_submit(self):
|
def on_update_after_submit(self):
|
||||||
"Run on save(). Avoid recursion caused by multiple saves"
|
|
||||||
if not self._saving_flag:
|
|
||||||
self._saving_flag = True
|
|
||||||
self.clear_linked_payment_entries()
|
|
||||||
self.update_allocations()
|
self.update_allocations()
|
||||||
self._saving_flag = False
|
self.clear_linked_payment_entries()
|
||||||
|
self.set_status(update=True)
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
self.clear_linked_payment_entries(for_cancel=True)
|
self.clear_linked_payment_entries(for_cancel=True)
|
||||||
self.set_status(update=True)
|
self.set_status(update=True)
|
||||||
|
|
||||||
def update_allocations(self):
|
def update_allocations(self):
|
||||||
"The doctype does not allow modifications after submission, so write to the db direct"
|
|
||||||
if self.payment_entries:
|
if self.payment_entries:
|
||||||
allocated_amount = sum(p.allocated_amount for p in self.payment_entries)
|
allocated_amount = reduce(
|
||||||
|
lambda x, y: flt(x) + flt(y), [x.allocated_amount for x in self.payment_entries]
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
allocated_amount = 0.0
|
allocated_amount = 0
|
||||||
|
|
||||||
unallocated_amount = abs(flt(self.withdrawal) - flt(self.deposit)) - allocated_amount
|
if allocated_amount:
|
||||||
|
frappe.db.set_value(self.doctype, self.name, "allocated_amount", flt(allocated_amount))
|
||||||
self.db_set("allocated_amount", flt(allocated_amount, self.precision("allocated_amount")))
|
frappe.db.set_value(
|
||||||
self.db_set("unallocated_amount", flt(unallocated_amount, self.precision("unallocated_amount")))
|
self.doctype,
|
||||||
self.reload()
|
self.name,
|
||||||
self.set_status(update=True)
|
"unallocated_amount",
|
||||||
|
abs(flt(self.withdrawal) - flt(self.deposit)) - flt(allocated_amount),
|
||||||
def add_payment_entries(self, vouchers):
|
|
||||||
"Add the vouchers with zero allocation. Save() will perform the allocations and clearance"
|
|
||||||
if 0.0 >= self.unallocated_amount:
|
|
||||||
frappe.throw(frappe._("Bank Transaction {0} is already fully reconciled").format(self.name))
|
|
||||||
|
|
||||||
added = False
|
|
||||||
for voucher in vouchers:
|
|
||||||
# Can't add same voucher twice
|
|
||||||
found = False
|
|
||||||
for pe in self.payment_entries:
|
|
||||||
if (
|
|
||||||
pe.payment_document == voucher["payment_doctype"]
|
|
||||||
and pe.payment_entry == voucher["payment_name"]
|
|
||||||
):
|
|
||||||
found = True
|
|
||||||
|
|
||||||
if not found:
|
|
||||||
pe = {
|
|
||||||
"payment_document": voucher["payment_doctype"],
|
|
||||||
"payment_entry": voucher["payment_name"],
|
|
||||||
"allocated_amount": 0.0, # Temporary
|
|
||||||
}
|
|
||||||
self.append("payment_entries", pe)
|
|
||||||
added = True
|
|
||||||
|
|
||||||
# runs on_update_after_submit
|
|
||||||
if added:
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
def allocate_payment_entries(self):
|
|
||||||
"""Refactored from bank reconciliation tool.
|
|
||||||
Non-zero allocations must be amended/cleared manually
|
|
||||||
Get the bank transaction amount (b) and remove as we allocate
|
|
||||||
For each payment_entry if allocated_amount == 0:
|
|
||||||
- get the amount already allocated against all transactions (t), need latest date
|
|
||||||
- get the voucher amount (from gl) (v)
|
|
||||||
- allocate (a = v - t)
|
|
||||||
- a = 0: should already be cleared, so clear & remove payment_entry
|
|
||||||
- 0 < a <= u: allocate a & clear
|
|
||||||
- 0 < a, a > u: allocate u
|
|
||||||
- 0 > a: Error: already over-allocated
|
|
||||||
- clear means: set the latest transaction date as clearance date
|
|
||||||
"""
|
|
||||||
remaining_amount = self.unallocated_amount
|
|
||||||
for payment_entry in self.payment_entries:
|
|
||||||
if payment_entry.allocated_amount == 0.0:
|
|
||||||
unallocated_amount, should_clear, latest_transaction = get_clearance_details(
|
|
||||||
self, payment_entry
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if 0.0 == unallocated_amount:
|
else:
|
||||||
if should_clear:
|
frappe.db.set_value(self.doctype, self.name, "allocated_amount", 0)
|
||||||
latest_transaction.clear_linked_payment_entry(payment_entry)
|
frappe.db.set_value(
|
||||||
self.db_delete_payment_entry(payment_entry)
|
self.doctype, self.name, "unallocated_amount", abs(flt(self.withdrawal) - flt(self.deposit))
|
||||||
|
)
|
||||||
|
|
||||||
elif remaining_amount <= 0.0:
|
amount = self.deposit or self.withdrawal
|
||||||
self.db_delete_payment_entry(payment_entry)
|
if amount == self.allocated_amount:
|
||||||
|
frappe.db.set_value(self.doctype, self.name, "status", "Reconciled")
|
||||||
elif 0.0 < unallocated_amount and unallocated_amount <= remaining_amount:
|
|
||||||
payment_entry.db_set("allocated_amount", unallocated_amount)
|
|
||||||
remaining_amount -= unallocated_amount
|
|
||||||
if should_clear:
|
|
||||||
latest_transaction.clear_linked_payment_entry(payment_entry)
|
|
||||||
|
|
||||||
elif 0.0 < unallocated_amount and unallocated_amount > remaining_amount:
|
|
||||||
payment_entry.db_set("allocated_amount", remaining_amount)
|
|
||||||
remaining_amount = 0.0
|
|
||||||
|
|
||||||
elif 0.0 > unallocated_amount:
|
|
||||||
self.db_delete_payment_entry(payment_entry)
|
|
||||||
frappe.throw(frappe._("Voucher {0} is over-allocated by {1}").format(unallocated_amount))
|
|
||||||
|
|
||||||
self.reload()
|
self.reload()
|
||||||
|
|
||||||
def db_delete_payment_entry(self, payment_entry):
|
|
||||||
frappe.db.delete("Bank Transaction Payments", {"name": payment_entry.name})
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
|
||||||
def remove_payment_entries(self):
|
|
||||||
for payment_entry in self.payment_entries:
|
|
||||||
self.remove_payment_entry(payment_entry)
|
|
||||||
# runs on_update_after_submit
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
def remove_payment_entry(self, payment_entry):
|
|
||||||
"Clear payment entry and clearance"
|
|
||||||
self.clear_linked_payment_entry(payment_entry, for_cancel=True)
|
|
||||||
self.remove(payment_entry)
|
|
||||||
|
|
||||||
def clear_linked_payment_entries(self, for_cancel=False):
|
def clear_linked_payment_entries(self, for_cancel=False):
|
||||||
if for_cancel:
|
|
||||||
for payment_entry in self.payment_entries:
|
for payment_entry in self.payment_entries:
|
||||||
self.clear_linked_payment_entry(payment_entry, for_cancel)
|
if payment_entry.payment_document == "Sales Invoice":
|
||||||
else:
|
self.clear_sales_invoice(payment_entry, for_cancel=for_cancel)
|
||||||
self.allocate_payment_entries()
|
elif payment_entry.payment_document in get_doctypes_for_bank_reconciliation():
|
||||||
|
self.clear_simple_entry(payment_entry, for_cancel=for_cancel)
|
||||||
|
|
||||||
def clear_linked_payment_entry(self, payment_entry, for_cancel=False):
|
def clear_simple_entry(self, payment_entry, for_cancel=False):
|
||||||
clearance_date = None if for_cancel else self.date
|
if payment_entry.payment_document == "Payment Entry":
|
||||||
set_voucher_clearance(
|
if (
|
||||||
payment_entry.payment_document, payment_entry.payment_entry, clearance_date, self
|
frappe.db.get_value("Payment Entry", payment_entry.payment_entry, "payment_type")
|
||||||
)
|
== "Internal Transfer"
|
||||||
|
):
|
||||||
def auto_set_party(self):
|
if len(get_reconciled_bank_transactions(payment_entry)) < 2:
|
||||||
from erpnext.accounts.doctype.bank_transaction.auto_match_party import AutoMatchParty
|
|
||||||
|
|
||||||
if self.party_type and self.party:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
result = AutoMatchParty(
|
clearance_date = self.date if not for_cancel else None
|
||||||
bank_party_account_number=self.bank_party_account_number,
|
|
||||||
bank_party_iban=self.bank_party_iban,
|
|
||||||
bank_party_name=self.bank_party_name,
|
|
||||||
description=self.description,
|
|
||||||
deposit=self.deposit,
|
|
||||||
).match()
|
|
||||||
|
|
||||||
if result:
|
|
||||||
party_type, party = result
|
|
||||||
frappe.db.set_value(
|
frappe.db.set_value(
|
||||||
"Bank Transaction", self.name, field={"party_type": party_type, "party": party}
|
payment_entry.payment_document, payment_entry.payment_entry, "clearance_date", clearance_date
|
||||||
|
)
|
||||||
|
|
||||||
|
def clear_sales_invoice(self, payment_entry, for_cancel=False):
|
||||||
|
clearance_date = self.date if not for_cancel else None
|
||||||
|
frappe.db.set_value(
|
||||||
|
"Sales Invoice Payment",
|
||||||
|
dict(parenttype=payment_entry.payment_document, parent=payment_entry.payment_entry),
|
||||||
|
"clearance_date",
|
||||||
|
clearance_date,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -177,114 +93,38 @@ def get_doctypes_for_bank_reconciliation():
|
|||||||
return frappe.get_hooks("bank_reconciliation_doctypes")
|
return frappe.get_hooks("bank_reconciliation_doctypes")
|
||||||
|
|
||||||
|
|
||||||
def get_clearance_details(transaction, payment_entry):
|
def get_reconciled_bank_transactions(payment_entry):
|
||||||
"""
|
reconciled_bank_transactions = frappe.get_all(
|
||||||
There should only be one bank gle for a voucher.
|
"Bank Transaction Payments",
|
||||||
Could be none for a Bank Transaction.
|
filters={"payment_entry": payment_entry.payment_entry},
|
||||||
But if a JE, could affect two banks.
|
fields=["parent"],
|
||||||
Should only clear the voucher if all bank gles are allocated.
|
|
||||||
"""
|
|
||||||
gl_bank_account = frappe.db.get_value("Bank Account", transaction.bank_account, "account")
|
|
||||||
gles = get_related_bank_gl_entries(payment_entry.payment_document, payment_entry.payment_entry)
|
|
||||||
bt_allocations = get_total_allocated_amount(
|
|
||||||
payment_entry.payment_document, payment_entry.payment_entry
|
|
||||||
)
|
)
|
||||||
|
|
||||||
unallocated_amount = min(
|
return reconciled_bank_transactions
|
||||||
transaction.unallocated_amount,
|
|
||||||
get_paid_amount(payment_entry, transaction.currency, gl_bank_account),
|
|
||||||
)
|
|
||||||
unmatched_gles = len(gles)
|
|
||||||
latest_transaction = transaction
|
|
||||||
for gle in gles:
|
|
||||||
if gle["gl_account"] == gl_bank_account:
|
|
||||||
if gle["amount"] <= 0.0:
|
|
||||||
frappe.throw(
|
|
||||||
frappe._("Voucher {0} value is broken: {1}").format(
|
|
||||||
payment_entry.payment_entry, gle["amount"]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
unmatched_gles -= 1
|
|
||||||
unallocated_amount = gle["amount"]
|
|
||||||
for a in bt_allocations:
|
|
||||||
if a["gl_account"] == gle["gl_account"]:
|
|
||||||
unallocated_amount = gle["amount"] - a["total"]
|
|
||||||
if frappe.utils.getdate(transaction.date) < a["latest_date"]:
|
|
||||||
latest_transaction = frappe.get_doc("Bank Transaction", a["latest_name"])
|
|
||||||
else:
|
|
||||||
# Must be a Journal Entry affecting more than one bank
|
|
||||||
for a in bt_allocations:
|
|
||||||
if a["gl_account"] == gle["gl_account"] and a["total"] == gle["amount"]:
|
|
||||||
unmatched_gles -= 1
|
|
||||||
|
|
||||||
return unallocated_amount, unmatched_gles == 0, latest_transaction
|
|
||||||
|
|
||||||
|
|
||||||
def get_related_bank_gl_entries(doctype, docname):
|
def get_total_allocated_amount(payment_entry):
|
||||||
# nosemgrep: frappe-semgrep-rules.rules.frappe-using-db-sql
|
return frappe.db.sql(
|
||||||
result = frappe.db.sql(
|
|
||||||
"""
|
"""
|
||||||
SELECT
|
SELECT
|
||||||
ABS(gle.credit_in_account_currency - gle.debit_in_account_currency) AS amount,
|
SUM(btp.allocated_amount) as allocated_amount,
|
||||||
gle.account AS gl_account
|
bt.name
|
||||||
FROM
|
FROM
|
||||||
`tabGL Entry` gle
|
`tabBank Transaction Payments` as btp
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
`tabAccount` ac ON ac.name=gle.account
|
`tabBank Transaction` bt ON bt.name=btp.parent
|
||||||
WHERE
|
WHERE
|
||||||
ac.account_type = 'Bank'
|
btp.payment_document = %s
|
||||||
AND gle.voucher_type = %(doctype)s
|
AND
|
||||||
AND gle.voucher_no = %(docname)s
|
btp.payment_entry = %s
|
||||||
AND is_cancelled = 0
|
AND
|
||||||
""",
|
bt.docstatus = 1""",
|
||||||
dict(doctype=doctype, docname=docname),
|
(payment_entry.payment_document, payment_entry.payment_entry),
|
||||||
as_dict=True,
|
as_dict=True,
|
||||||
)
|
)
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def get_total_allocated_amount(doctype, docname):
|
def get_paid_amount(payment_entry, currency, bank_account):
|
||||||
"""
|
|
||||||
Gets the sum of allocations for a voucher on each bank GL account
|
|
||||||
along with the latest bank transaction name & date
|
|
||||||
NOTE: query may also include just saved vouchers/payments but with zero allocated_amount
|
|
||||||
"""
|
|
||||||
# nosemgrep: frappe-semgrep-rules.rules.frappe-using-db-sql
|
|
||||||
result = frappe.db.sql(
|
|
||||||
"""
|
|
||||||
SELECT total, latest_name, latest_date, gl_account FROM (
|
|
||||||
SELECT
|
|
||||||
ROW_NUMBER() OVER w AS rownum,
|
|
||||||
SUM(btp.allocated_amount) OVER(PARTITION BY ba.account) AS total,
|
|
||||||
FIRST_VALUE(bt.name) OVER w AS latest_name,
|
|
||||||
FIRST_VALUE(bt.date) OVER w AS latest_date,
|
|
||||||
ba.account AS gl_account
|
|
||||||
FROM
|
|
||||||
`tabBank Transaction Payments` btp
|
|
||||||
LEFT JOIN `tabBank Transaction` bt ON bt.name=btp.parent
|
|
||||||
LEFT JOIN `tabBank Account` ba ON ba.name=bt.bank_account
|
|
||||||
WHERE
|
|
||||||
btp.payment_document = %(doctype)s
|
|
||||||
AND btp.payment_entry = %(docname)s
|
|
||||||
AND bt.docstatus = 1
|
|
||||||
WINDOW w AS (PARTITION BY ba.account ORDER BY bt.date desc)
|
|
||||||
) temp
|
|
||||||
WHERE
|
|
||||||
rownum = 1
|
|
||||||
""",
|
|
||||||
dict(doctype=doctype, docname=docname),
|
|
||||||
as_dict=True,
|
|
||||||
)
|
|
||||||
for row in result:
|
|
||||||
# Why is this *sometimes* a byte string?
|
|
||||||
if isinstance(row["latest_name"], bytes):
|
|
||||||
row["latest_name"] = row["latest_name"].decode()
|
|
||||||
row["latest_date"] = frappe.utils.getdate(row["latest_date"])
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def get_paid_amount(payment_entry, currency, gl_bank_account):
|
|
||||||
if payment_entry.payment_document in ["Payment Entry", "Sales Invoice", "Purchase Invoice"]:
|
if payment_entry.payment_document in ["Payment Entry", "Sales Invoice", "Purchase Invoice"]:
|
||||||
|
|
||||||
paid_amount_field = "paid_amount"
|
paid_amount_field = "paid_amount"
|
||||||
@@ -297,7 +137,7 @@ def get_paid_amount(payment_entry, currency, gl_bank_account):
|
|||||||
)
|
)
|
||||||
elif doc.payment_type == "Pay":
|
elif doc.payment_type == "Pay":
|
||||||
paid_amount_field = (
|
paid_amount_field = (
|
||||||
"paid_amount" if doc.paid_from_account_currency == currency else "base_paid_amount"
|
"paid_amount" if doc.paid_to_account_currency == currency else "base_paid_amount"
|
||||||
)
|
)
|
||||||
|
|
||||||
return frappe.db.get_value(
|
return frappe.db.get_value(
|
||||||
@@ -305,13 +145,10 @@ def get_paid_amount(payment_entry, currency, gl_bank_account):
|
|||||||
)
|
)
|
||||||
|
|
||||||
elif payment_entry.payment_document == "Journal Entry":
|
elif payment_entry.payment_document == "Journal Entry":
|
||||||
return abs(
|
return frappe.db.get_value(
|
||||||
frappe.db.get_value(
|
|
||||||
"Journal Entry Account",
|
"Journal Entry Account",
|
||||||
{"parent": payment_entry.payment_entry, "account": gl_bank_account},
|
{"parent": payment_entry.payment_entry, "account": bank_account},
|
||||||
"sum(debit_in_account_currency-credit_in_account_currency)",
|
"sum(credit_in_account_currency)",
|
||||||
)
|
|
||||||
or 0
|
|
||||||
)
|
)
|
||||||
|
|
||||||
elif payment_entry.payment_document == "Expense Claim":
|
elif payment_entry.payment_document == "Expense Claim":
|
||||||
@@ -329,12 +166,6 @@ def get_paid_amount(payment_entry, currency, gl_bank_account):
|
|||||||
payment_entry.payment_document, payment_entry.payment_entry, "amount_paid"
|
payment_entry.payment_document, payment_entry.payment_entry, "amount_paid"
|
||||||
)
|
)
|
||||||
|
|
||||||
elif payment_entry.payment_document == "Bank Transaction":
|
|
||||||
dep, wth = frappe.db.get_value(
|
|
||||||
"Bank Transaction", payment_entry.payment_entry, ("deposit", "withdrawal")
|
|
||||||
)
|
|
||||||
return abs(flt(wth) - flt(dep))
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
"Please reconcile {0}: {1} manually".format(
|
"Please reconcile {0}: {1} manually".format(
|
||||||
@@ -343,73 +174,18 @@ def get_paid_amount(payment_entry, currency, gl_bank_account):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def set_voucher_clearance(doctype, docname, clearance_date, self):
|
@frappe.whitelist()
|
||||||
if doctype in [
|
def unclear_reference_payment(doctype, docname):
|
||||||
"Payment Entry",
|
if frappe.db.exists(doctype, docname):
|
||||||
"Journal Entry",
|
doc = frappe.get_doc(doctype, docname)
|
||||||
"Purchase Invoice",
|
if doctype == "Sales Invoice":
|
||||||
"Expense Claim",
|
|
||||||
"Loan Repayment",
|
|
||||||
"Loan Disbursement",
|
|
||||||
]:
|
|
||||||
if (
|
|
||||||
doctype == "Payment Entry"
|
|
||||||
and frappe.db.get_value("Payment Entry", docname, "payment_type") == "Internal Transfer"
|
|
||||||
and len(get_reconciled_bank_transactions(doctype, docname)) < 2
|
|
||||||
):
|
|
||||||
return
|
|
||||||
frappe.db.set_value(doctype, docname, "clearance_date", clearance_date)
|
|
||||||
|
|
||||||
elif doctype == "Sales Invoice":
|
|
||||||
frappe.db.set_value(
|
frappe.db.set_value(
|
||||||
"Sales Invoice Payment",
|
"Sales Invoice Payment",
|
||||||
dict(parenttype=doctype, parent=docname),
|
dict(parenttype=doc.payment_document, parent=doc.payment_entry),
|
||||||
"clearance_date",
|
"clearance_date",
|
||||||
clearance_date,
|
None,
|
||||||
)
|
)
|
||||||
|
|
||||||
elif doctype == "Bank Transaction":
|
|
||||||
# For when a second bank transaction has fixed another, e.g. refund
|
|
||||||
bt = frappe.get_doc(doctype, docname)
|
|
||||||
if clearance_date:
|
|
||||||
vouchers = [{"payment_doctype": "Bank Transaction", "payment_name": self.name}]
|
|
||||||
bt.add_payment_entries(vouchers)
|
|
||||||
else:
|
else:
|
||||||
for pe in bt.payment_entries:
|
frappe.db.set_value(doc.payment_document, doc.payment_entry, "clearance_date", None)
|
||||||
if pe.payment_document == self.doctype and pe.payment_entry == self.name:
|
|
||||||
bt.remove(pe)
|
|
||||||
bt.save()
|
|
||||||
break
|
|
||||||
|
|
||||||
|
return doc.payment_entry
|
||||||
def get_reconciled_bank_transactions(doctype, docname):
|
|
||||||
return frappe.get_all(
|
|
||||||
"Bank Transaction Payments",
|
|
||||||
filters={"payment_document": doctype, "payment_entry": docname},
|
|
||||||
pluck="parent",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
|
||||||
def unclear_reference_payment(doctype, docname, bt_name):
|
|
||||||
bt = frappe.get_doc("Bank Transaction", bt_name)
|
|
||||||
set_voucher_clearance(doctype, docname, None, bt)
|
|
||||||
return docname
|
|
||||||
|
|
||||||
|
|
||||||
def remove_from_bank_transaction(doctype, docname):
|
|
||||||
"""Remove a (cancelled) voucher from all Bank Transactions."""
|
|
||||||
for bt_name in get_reconciled_bank_transactions(doctype, docname):
|
|
||||||
bt = frappe.get_doc("Bank Transaction", bt_name)
|
|
||||||
if bt.docstatus == DocStatus.cancelled():
|
|
||||||
continue
|
|
||||||
|
|
||||||
modified = False
|
|
||||||
|
|
||||||
for pe in bt.payment_entries:
|
|
||||||
if pe.payment_document == doctype and pe.payment_entry == docname:
|
|
||||||
bt.remove(pe)
|
|
||||||
modified = True
|
|
||||||
|
|
||||||
if modified:
|
|
||||||
bt.save()
|
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
// License: GNU General Public License v3. See license.txt
|
// License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
frappe.listview_settings["Bank Transaction"] = {
|
frappe.listview_settings['Bank Transaction'] = {
|
||||||
add_fields: ["unallocated_amount"],
|
add_fields: ["unallocated_amount"],
|
||||||
get_indicator: function (doc) {
|
get_indicator: function(doc) {
|
||||||
if (doc.docstatus == 2) {
|
if(doc.docstatus == 2) {
|
||||||
return [__("Cancelled"), "red", "docstatus,=,2"];
|
return [__("Cancelled"), "red", "docstatus,=,2"];
|
||||||
} else if (flt(doc.unallocated_amount) <= 0) {
|
} else if(flt(doc.unallocated_amount)<=0) {
|
||||||
return [__("Reconciled"), "green", "unallocated_amount,=,0"];
|
return [__("Reconciled"), "green", "unallocated_amount,=,0"];
|
||||||
} else if (flt(doc.unallocated_amount) > 0) {
|
} else if(flt(doc.unallocated_amount)>0) {
|
||||||
return [__("Unreconciled"), "orange", "unallocated_amount,>,0"];
|
return [__("Unreconciled"), "orange", "unallocated_amount,>,0"];
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ def get_header_mapping(columns, bank_account):
|
|||||||
|
|
||||||
|
|
||||||
def get_bank_mapping(bank_account):
|
def get_bank_mapping(bank_account):
|
||||||
bank_name = frappe.db.get_value("Bank Account", bank_account, "bank")
|
bank_name = frappe.get_cached_value("Bank Account", bank_account, "bank")
|
||||||
bank = frappe.get_doc("Bank", bank_name)
|
bank = frappe.get_doc("Bank", bank_name)
|
||||||
|
|
||||||
mapping = {row.file_field: row.bank_transaction_field for row in bank.bank_transaction_mapping}
|
mapping = {row.file_field: row.bank_transaction_field for row in bank.bank_transaction_mapping}
|
||||||
|
|||||||
@@ -1,151 +0,0 @@
|
|||||||
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors
|
|
||||||
# License: GNU General Public License v3. See license.txt
|
|
||||||
|
|
||||||
import frappe
|
|
||||||
from frappe.tests.utils import FrappeTestCase
|
|
||||||
from frappe.utils import nowdate
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.bank_transaction.test_bank_transaction import create_bank_account
|
|
||||||
|
|
||||||
|
|
||||||
class TestAutoMatchParty(FrappeTestCase):
|
|
||||||
@classmethod
|
|
||||||
def setUpClass(cls):
|
|
||||||
create_bank_account()
|
|
||||||
frappe.db.set_single_value("Accounts Settings", "enable_party_matching", 1)
|
|
||||||
frappe.db.set_single_value("Accounts Settings", "enable_fuzzy_matching", 1)
|
|
||||||
return super().setUpClass()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def tearDownClass(cls):
|
|
||||||
frappe.db.set_single_value("Accounts Settings", "enable_party_matching", 0)
|
|
||||||
frappe.db.set_single_value("Accounts Settings", "enable_fuzzy_matching", 0)
|
|
||||||
|
|
||||||
def test_match_by_account_number(self):
|
|
||||||
create_supplier_for_match(account_no="000000003716541159")
|
|
||||||
doc = create_bank_transaction(
|
|
||||||
withdrawal=1200,
|
|
||||||
transaction_id="562213b0ca1bf838dab8f2c6a39bbc3b",
|
|
||||||
account_no="000000003716541159",
|
|
||||||
iban="DE02000000003716541159",
|
|
||||||
)
|
|
||||||
|
|
||||||
self.assertEqual(doc.party_type, "Supplier")
|
|
||||||
self.assertEqual(doc.party, "John Doe & Co.")
|
|
||||||
|
|
||||||
def test_match_by_iban(self):
|
|
||||||
create_supplier_for_match(iban="DE02000000003716541159")
|
|
||||||
doc = create_bank_transaction(
|
|
||||||
withdrawal=1200,
|
|
||||||
transaction_id="c5455a224602afaa51592a9d9250600d",
|
|
||||||
account_no="000000003716541159",
|
|
||||||
iban="DE02000000003716541159",
|
|
||||||
)
|
|
||||||
|
|
||||||
self.assertEqual(doc.party_type, "Supplier")
|
|
||||||
self.assertEqual(doc.party, "John Doe & Co.")
|
|
||||||
|
|
||||||
def test_match_by_party_name(self):
|
|
||||||
create_supplier_for_match(supplier_name="Jackson Ella W.")
|
|
||||||
doc = create_bank_transaction(
|
|
||||||
withdrawal=1200,
|
|
||||||
transaction_id="1f6f661f347ff7b1ea588665f473adb1",
|
|
||||||
party_name="Ella Jackson",
|
|
||||||
iban="DE04000000003716545346",
|
|
||||||
)
|
|
||||||
self.assertEqual(doc.party_type, "Supplier")
|
|
||||||
self.assertEqual(doc.party, "Jackson Ella W.")
|
|
||||||
|
|
||||||
def test_match_by_description(self):
|
|
||||||
create_supplier_for_match(supplier_name="Microsoft")
|
|
||||||
doc = create_bank_transaction(
|
|
||||||
description="Auftraggeber: microsoft payments Buchungstext: msft ..e3006b5hdy. ref. j375979555927627/5536",
|
|
||||||
withdrawal=1200,
|
|
||||||
transaction_id="8df880a2d09c3bed3fea358ca5168c5a",
|
|
||||||
party_name="",
|
|
||||||
)
|
|
||||||
self.assertEqual(doc.party_type, "Supplier")
|
|
||||||
self.assertEqual(doc.party, "Microsoft")
|
|
||||||
|
|
||||||
def test_skip_match_if_multiple_close_results(self):
|
|
||||||
create_supplier_for_match(supplier_name="Adithya Medical & General Stores")
|
|
||||||
create_supplier_for_match(supplier_name="Adithya Medical And General Stores")
|
|
||||||
|
|
||||||
doc = create_bank_transaction(
|
|
||||||
description="Paracetamol Consignment, SINV-0009",
|
|
||||||
withdrawal=24.85,
|
|
||||||
transaction_id="3a1da4ee2dc5a980138d56ef3460cbd9",
|
|
||||||
party_name="Adithya Medical & General",
|
|
||||||
)
|
|
||||||
|
|
||||||
# Mapping is skipped as both Supplier names have the same match score
|
|
||||||
self.assertEqual(doc.party_type, None)
|
|
||||||
self.assertEqual(doc.party, None)
|
|
||||||
|
|
||||||
|
|
||||||
def create_supplier_for_match(supplier_name="John Doe & Co.", iban=None, account_no=None):
|
|
||||||
if frappe.db.exists("Supplier", {"supplier_name": supplier_name}):
|
|
||||||
# Update related Bank Account details
|
|
||||||
if not (iban or account_no):
|
|
||||||
return
|
|
||||||
|
|
||||||
frappe.db.set_value(
|
|
||||||
dt="Bank Account",
|
|
||||||
dn={"party": supplier_name},
|
|
||||||
field={"iban": iban, "bank_account_no": account_no},
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
# Create Supplier and Bank Account for the same
|
|
||||||
supplier = frappe.new_doc("Supplier")
|
|
||||||
supplier.supplier_name = supplier_name
|
|
||||||
supplier.supplier_group = "Services"
|
|
||||||
supplier.supplier_type = "Company"
|
|
||||||
supplier.insert()
|
|
||||||
|
|
||||||
if not frappe.db.exists("Bank", "TestBank"):
|
|
||||||
bank = frappe.new_doc("Bank")
|
|
||||||
bank.bank_name = "TestBank"
|
|
||||||
bank.insert(ignore_if_duplicate=True)
|
|
||||||
|
|
||||||
if not frappe.db.exists("Bank Account", supplier.name + " - " + "TestBank"):
|
|
||||||
bank_account = frappe.new_doc("Bank Account")
|
|
||||||
bank_account.account_name = supplier.name
|
|
||||||
bank_account.bank = "TestBank"
|
|
||||||
bank_account.iban = iban
|
|
||||||
bank_account.bank_account_no = account_no
|
|
||||||
bank_account.party_type = "Supplier"
|
|
||||||
bank_account.party = supplier.name
|
|
||||||
bank_account.insert()
|
|
||||||
|
|
||||||
|
|
||||||
def create_bank_transaction(
|
|
||||||
description=None,
|
|
||||||
withdrawal=0,
|
|
||||||
deposit=0,
|
|
||||||
transaction_id=None,
|
|
||||||
party_name=None,
|
|
||||||
account_no=None,
|
|
||||||
iban=None,
|
|
||||||
):
|
|
||||||
doc = frappe.new_doc("Bank Transaction")
|
|
||||||
doc.update(
|
|
||||||
{
|
|
||||||
"doctype": "Bank Transaction",
|
|
||||||
"description": description or "1512567 BG/000002918 OPSKATTUZWXXX AT776000000098709837 Herr G",
|
|
||||||
"date": nowdate(),
|
|
||||||
"withdrawal": withdrawal,
|
|
||||||
"deposit": deposit,
|
|
||||||
"currency": "INR",
|
|
||||||
"bank_account": "Checking Account - Citi Bank",
|
|
||||||
"transaction_id": transaction_id,
|
|
||||||
"bank_party_name": party_name,
|
|
||||||
"bank_party_account_number": account_no,
|
|
||||||
"bank_party_iban": iban,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
doc.insert()
|
|
||||||
doc.submit()
|
|
||||||
doc.reload()
|
|
||||||
|
|
||||||
return doc
|
|
||||||
@@ -2,10 +2,9 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import unittest
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import utils
|
|
||||||
from frappe.model.docstatus import DocStatus
|
|
||||||
from frappe.tests.utils import FrappeTestCase
|
from frappe.tests.utils import FrappeTestCase
|
||||||
|
|
||||||
from erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool import (
|
from erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool import (
|
||||||
@@ -32,16 +31,8 @@ class TestBankTransaction(FrappeTestCase):
|
|||||||
frappe.db.delete(dt)
|
frappe.db.delete(dt)
|
||||||
|
|
||||||
make_pos_profile()
|
make_pos_profile()
|
||||||
|
add_transactions()
|
||||||
# generate and use a uniq hash identifier for 'Bank Account' and it's linked GL 'Account' to avoid validation error
|
add_vouchers()
|
||||||
uniq_identifier = frappe.generate_hash(length=10)
|
|
||||||
gl_account = create_gl_account("_Test Bank " + uniq_identifier)
|
|
||||||
bank_account = create_bank_account(
|
|
||||||
gl_account=gl_account, bank_account_name="Checking Account " + uniq_identifier
|
|
||||||
)
|
|
||||||
|
|
||||||
add_transactions(bank_account=bank_account)
|
|
||||||
add_vouchers(gl_account=gl_account)
|
|
||||||
|
|
||||||
# This test checks if ERPNext is able to provide a linked payment for a bank transaction based on the amount of the bank transaction.
|
# 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):
|
def test_linked_payments(self):
|
||||||
@@ -49,12 +40,7 @@ class TestBankTransaction(FrappeTestCase):
|
|||||||
"Bank Transaction",
|
"Bank Transaction",
|
||||||
dict(description="Re 95282925234 FE/000002917 AT171513000281183046 Conrad Electronic"),
|
dict(description="Re 95282925234 FE/000002917 AT171513000281183046 Conrad Electronic"),
|
||||||
)
|
)
|
||||||
linked_payments = get_linked_payments(
|
linked_payments = get_linked_payments(bank_transaction.name, ["payment_entry", "exact_match"])
|
||||||
bank_transaction.name,
|
|
||||||
["payment_entry", "exact_match"],
|
|
||||||
from_date=bank_transaction.date,
|
|
||||||
to_date=utils.today(),
|
|
||||||
)
|
|
||||||
self.assertTrue(linked_payments[0][6] == "Conrad Electronic")
|
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
|
# This test validates a simple reconciliation leading to the clearance of the bank transaction and the payment
|
||||||
@@ -89,41 +75,13 @@ class TestBankTransaction(FrappeTestCase):
|
|||||||
clearance_date = frappe.db.get_value("Payment Entry", payment.name, "clearance_date")
|
clearance_date = frappe.db.get_value("Payment Entry", payment.name, "clearance_date")
|
||||||
self.assertFalse(clearance_date)
|
self.assertFalse(clearance_date)
|
||||||
|
|
||||||
def test_cancel_voucher(self):
|
|
||||||
bank_transaction = frappe.get_doc(
|
|
||||||
"Bank Transaction",
|
|
||||||
dict(description="1512567 BG/000003025 OPSKATTUZWXXX AT776000000098709849 Herr G"),
|
|
||||||
)
|
|
||||||
payment = frappe.get_doc("Payment Entry", dict(party="Mr G", paid_amount=1700))
|
|
||||||
vouchers = json.dumps(
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"payment_doctype": "Payment Entry",
|
|
||||||
"payment_name": payment.name,
|
|
||||||
"amount": bank_transaction.unallocated_amount,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
)
|
|
||||||
reconcile_vouchers(bank_transaction.name, vouchers)
|
|
||||||
payment.reload()
|
|
||||||
payment.cancel()
|
|
||||||
bank_transaction.reload()
|
|
||||||
self.assertEqual(bank_transaction.docstatus, DocStatus.submitted())
|
|
||||||
self.assertEqual(bank_transaction.unallocated_amount, 1700)
|
|
||||||
self.assertEqual(bank_transaction.payment_entries, [])
|
|
||||||
|
|
||||||
# Check if ERPNext can correctly filter a linked payments based on the debit/credit amount
|
# Check if ERPNext can correctly filter a linked payments based on the debit/credit amount
|
||||||
def test_debit_credit_output(self):
|
def test_debit_credit_output(self):
|
||||||
bank_transaction = frappe.get_doc(
|
bank_transaction = frappe.get_doc(
|
||||||
"Bank Transaction",
|
"Bank Transaction",
|
||||||
dict(description="Auszahlung Karte MC/000002916 AUTOMAT 698769 K002 27.10. 14:07"),
|
dict(description="Auszahlung Karte MC/000002916 AUTOMAT 698769 K002 27.10. 14:07"),
|
||||||
)
|
)
|
||||||
linked_payments = get_linked_payments(
|
linked_payments = get_linked_payments(bank_transaction.name, ["payment_entry", "exact_match"])
|
||||||
bank_transaction.name,
|
|
||||||
["payment_entry", "exact_match"],
|
|
||||||
from_date=bank_transaction.date,
|
|
||||||
to_date=utils.today(),
|
|
||||||
)
|
|
||||||
self.assertTrue(linked_payments[0][3])
|
self.assertTrue(linked_payments[0][3])
|
||||||
|
|
||||||
# Check error if already reconciled
|
# Check error if already reconciled
|
||||||
@@ -221,9 +179,7 @@ class TestBankTransaction(FrappeTestCase):
|
|||||||
self.assertEqual(linked_payments[0][2], repayment_entry.name)
|
self.assertEqual(linked_payments[0][2], repayment_entry.name)
|
||||||
|
|
||||||
|
|
||||||
def create_bank_account(
|
def create_bank_account(bank_name="Citi Bank", account_name="_Test Bank - _TC"):
|
||||||
bank_name="Citi Bank", gl_account="_Test Bank - _TC", bank_account_name="Checking Account"
|
|
||||||
):
|
|
||||||
try:
|
try:
|
||||||
frappe.get_doc(
|
frappe.get_doc(
|
||||||
{
|
{
|
||||||
@@ -235,35 +191,21 @@ def create_bank_account(
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
bank_account = frappe.get_doc(
|
frappe.get_doc(
|
||||||
{
|
{
|
||||||
"doctype": "Bank Account",
|
"doctype": "Bank Account",
|
||||||
"account_name": bank_account_name,
|
"account_name": "Checking Account",
|
||||||
"bank": bank_name,
|
"bank": bank_name,
|
||||||
"account": gl_account,
|
"account": account_name,
|
||||||
}
|
}
|
||||||
).insert(ignore_if_duplicate=True)
|
).insert(ignore_if_duplicate=True)
|
||||||
except frappe.DuplicateEntryError:
|
except frappe.DuplicateEntryError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return bank_account.name
|
|
||||||
|
|
||||||
|
def add_transactions():
|
||||||
|
create_bank_account()
|
||||||
|
|
||||||
def create_gl_account(gl_account_name="_Test Bank - _TC"):
|
|
||||||
gl_account = frappe.get_doc(
|
|
||||||
{
|
|
||||||
"doctype": "Account",
|
|
||||||
"company": "_Test Company",
|
|
||||||
"parent_account": "Current Assets - _TC",
|
|
||||||
"account_type": "Bank",
|
|
||||||
"is_group": 0,
|
|
||||||
"account_name": gl_account_name,
|
|
||||||
}
|
|
||||||
).insert()
|
|
||||||
return gl_account.name
|
|
||||||
|
|
||||||
|
|
||||||
def add_transactions(bank_account="_Test Bank - _TC"):
|
|
||||||
doc = frappe.get_doc(
|
doc = frappe.get_doc(
|
||||||
{
|
{
|
||||||
"doctype": "Bank Transaction",
|
"doctype": "Bank Transaction",
|
||||||
@@ -271,7 +213,7 @@ def add_transactions(bank_account="_Test Bank - _TC"):
|
|||||||
"date": "2018-10-23",
|
"date": "2018-10-23",
|
||||||
"deposit": 1200,
|
"deposit": 1200,
|
||||||
"currency": "INR",
|
"currency": "INR",
|
||||||
"bank_account": bank_account,
|
"bank_account": "Checking Account - Citi Bank",
|
||||||
}
|
}
|
||||||
).insert()
|
).insert()
|
||||||
doc.submit()
|
doc.submit()
|
||||||
@@ -283,7 +225,7 @@ def add_transactions(bank_account="_Test Bank - _TC"):
|
|||||||
"date": "2018-10-23",
|
"date": "2018-10-23",
|
||||||
"deposit": 1700,
|
"deposit": 1700,
|
||||||
"currency": "INR",
|
"currency": "INR",
|
||||||
"bank_account": bank_account,
|
"bank_account": "Checking Account - Citi Bank",
|
||||||
}
|
}
|
||||||
).insert()
|
).insert()
|
||||||
doc.submit()
|
doc.submit()
|
||||||
@@ -295,7 +237,7 @@ def add_transactions(bank_account="_Test Bank - _TC"):
|
|||||||
"date": "2018-10-26",
|
"date": "2018-10-26",
|
||||||
"withdrawal": 690,
|
"withdrawal": 690,
|
||||||
"currency": "INR",
|
"currency": "INR",
|
||||||
"bank_account": bank_account,
|
"bank_account": "Checking Account - Citi Bank",
|
||||||
}
|
}
|
||||||
).insert()
|
).insert()
|
||||||
doc.submit()
|
doc.submit()
|
||||||
@@ -307,7 +249,7 @@ def add_transactions(bank_account="_Test Bank - _TC"):
|
|||||||
"date": "2018-10-27",
|
"date": "2018-10-27",
|
||||||
"deposit": 3900,
|
"deposit": 3900,
|
||||||
"currency": "INR",
|
"currency": "INR",
|
||||||
"bank_account": bank_account,
|
"bank_account": "Checking Account - Citi Bank",
|
||||||
}
|
}
|
||||||
).insert()
|
).insert()
|
||||||
doc.submit()
|
doc.submit()
|
||||||
@@ -319,13 +261,13 @@ def add_transactions(bank_account="_Test Bank - _TC"):
|
|||||||
"date": "2018-10-27",
|
"date": "2018-10-27",
|
||||||
"withdrawal": 109080,
|
"withdrawal": 109080,
|
||||||
"currency": "INR",
|
"currency": "INR",
|
||||||
"bank_account": bank_account,
|
"bank_account": "Checking Account - Citi Bank",
|
||||||
}
|
}
|
||||||
).insert()
|
).insert()
|
||||||
doc.submit()
|
doc.submit()
|
||||||
|
|
||||||
|
|
||||||
def add_vouchers(gl_account="_Test Bank - _TC"):
|
def add_vouchers():
|
||||||
try:
|
try:
|
||||||
frappe.get_doc(
|
frappe.get_doc(
|
||||||
{
|
{
|
||||||
@@ -341,7 +283,7 @@ def add_vouchers(gl_account="_Test Bank - _TC"):
|
|||||||
|
|
||||||
pi = make_purchase_invoice(supplier="Conrad Electronic", qty=1, rate=690)
|
pi = make_purchase_invoice(supplier="Conrad Electronic", qty=1, rate=690)
|
||||||
|
|
||||||
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account=gl_account)
|
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
|
||||||
pe.reference_no = "Conrad Oct 18"
|
pe.reference_no = "Conrad Oct 18"
|
||||||
pe.reference_date = "2018-10-24"
|
pe.reference_date = "2018-10-24"
|
||||||
pe.insert()
|
pe.insert()
|
||||||
@@ -360,14 +302,14 @@ def add_vouchers(gl_account="_Test Bank - _TC"):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
pi = make_purchase_invoice(supplier="Mr G", qty=1, rate=1200)
|
pi = make_purchase_invoice(supplier="Mr G", qty=1, rate=1200)
|
||||||
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account=gl_account)
|
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
|
||||||
pe.reference_no = "Herr G Oct 18"
|
pe.reference_no = "Herr G Oct 18"
|
||||||
pe.reference_date = "2018-10-24"
|
pe.reference_date = "2018-10-24"
|
||||||
pe.insert()
|
pe.insert()
|
||||||
pe.submit()
|
pe.submit()
|
||||||
|
|
||||||
pi = make_purchase_invoice(supplier="Mr G", qty=1, rate=1700)
|
pi = make_purchase_invoice(supplier="Mr G", qty=1, rate=1700)
|
||||||
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account=gl_account)
|
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
|
||||||
pe.reference_no = "Herr G Nov 18"
|
pe.reference_no = "Herr G Nov 18"
|
||||||
pe.reference_date = "2018-11-01"
|
pe.reference_date = "2018-11-01"
|
||||||
pe.insert()
|
pe.insert()
|
||||||
@@ -398,10 +340,10 @@ def add_vouchers(gl_account="_Test Bank - _TC"):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
pi = make_purchase_invoice(supplier="Poore Simon's", qty=1, rate=3900, is_paid=1, do_not_save=1)
|
pi = make_purchase_invoice(supplier="Poore Simon's", qty=1, rate=3900, is_paid=1, do_not_save=1)
|
||||||
pi.cash_bank_account = gl_account
|
pi.cash_bank_account = "_Test Bank - _TC"
|
||||||
pi.insert()
|
pi.insert()
|
||||||
pi.submit()
|
pi.submit()
|
||||||
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account=gl_account)
|
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
|
||||||
pe.reference_no = "Poore Simon's Oct 18"
|
pe.reference_no = "Poore Simon's Oct 18"
|
||||||
pe.reference_date = "2018-10-28"
|
pe.reference_date = "2018-10-28"
|
||||||
pe.paid_amount = 690
|
pe.paid_amount = 690
|
||||||
@@ -410,7 +352,7 @@ def add_vouchers(gl_account="_Test Bank - _TC"):
|
|||||||
pe.submit()
|
pe.submit()
|
||||||
|
|
||||||
si = create_sales_invoice(customer="Poore Simon's", qty=1, rate=3900)
|
si = create_sales_invoice(customer="Poore Simon's", qty=1, rate=3900)
|
||||||
pe = get_payment_entry("Sales Invoice", si.name, bank_account=gl_account)
|
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC")
|
||||||
pe.reference_no = "Poore Simon's Oct 18"
|
pe.reference_no = "Poore Simon's Oct 18"
|
||||||
pe.reference_date = "2018-10-28"
|
pe.reference_date = "2018-10-28"
|
||||||
pe.insert()
|
pe.insert()
|
||||||
@@ -433,12 +375,16 @@ def add_vouchers(gl_account="_Test Bank - _TC"):
|
|||||||
if not frappe.db.get_value(
|
if not frappe.db.get_value(
|
||||||
"Mode of Payment Account", {"company": "_Test Company", "parent": "Cash"}
|
"Mode of Payment Account", {"company": "_Test Company", "parent": "Cash"}
|
||||||
):
|
):
|
||||||
mode_of_payment.append("accounts", {"company": "_Test Company", "default_account": gl_account})
|
mode_of_payment.append(
|
||||||
|
"accounts", {"company": "_Test Company", "default_account": "_Test Bank - _TC"}
|
||||||
|
)
|
||||||
mode_of_payment.save()
|
mode_of_payment.save()
|
||||||
|
|
||||||
si = create_sales_invoice(customer="Fayva", qty=1, rate=109080, do_not_save=1)
|
si = create_sales_invoice(customer="Fayva", qty=1, rate=109080, do_not_save=1)
|
||||||
si.is_pos = 1
|
si.is_pos = 1
|
||||||
si.append("payments", {"mode_of_payment": "Cash", "account": gl_account, "amount": 109080})
|
si.append(
|
||||||
|
"payments", {"mode_of_payment": "Cash", "account": "_Test Bank - _TC", "amount": 109080}
|
||||||
|
)
|
||||||
si.insert()
|
si.insert()
|
||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
|
|||||||
@@ -2,48 +2,48 @@
|
|||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
frappe.provide("erpnext.accounts.dimensions");
|
frappe.provide("erpnext.accounts.dimensions");
|
||||||
|
|
||||||
frappe.ui.form.on("Budget", {
|
frappe.ui.form.on('Budget', {
|
||||||
onload: function (frm) {
|
onload: function(frm) {
|
||||||
frm.set_query("account", "accounts", function () {
|
frm.set_query("account", "accounts", function() {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
company: frm.doc.company,
|
company: frm.doc.company,
|
||||||
report_type: "Profit and Loss",
|
report_type: "Profit and Loss",
|
||||||
is_group: 0,
|
is_group: 0
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
frm.set_query("monthly_distribution", function () {
|
frm.set_query("monthly_distribution", function() {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
fiscal_year: frm.doc.fiscal_year,
|
fiscal_year: frm.doc.fiscal_year
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype);
|
erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype);
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function (frm) {
|
refresh: function(frm) {
|
||||||
frm.trigger("toggle_reqd_fields");
|
frm.trigger("toggle_reqd_fields")
|
||||||
},
|
},
|
||||||
|
|
||||||
budget_against: function (frm) {
|
budget_against: function(frm) {
|
||||||
frm.trigger("set_null_value");
|
frm.trigger("set_null_value")
|
||||||
frm.trigger("toggle_reqd_fields");
|
frm.trigger("toggle_reqd_fields")
|
||||||
},
|
},
|
||||||
|
|
||||||
set_null_value: function (frm) {
|
set_null_value: function(frm) {
|
||||||
if (frm.doc.budget_against == "Cost Center") {
|
if(frm.doc.budget_against == 'Cost Center') {
|
||||||
frm.set_value("project", null);
|
frm.set_value('project', null)
|
||||||
} else {
|
} else {
|
||||||
frm.set_value("cost_center", null);
|
frm.set_value('cost_center', null)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
toggle_reqd_fields: function (frm) {
|
toggle_reqd_fields: function(frm) {
|
||||||
frm.toggle_reqd("cost_center", frm.doc.budget_against == "Cost Center");
|
frm.toggle_reqd("cost_center", frm.doc.budget_against=="Cost Center");
|
||||||
frm.toggle_reqd("project", frm.doc.budget_against == "Project");
|
frm.toggle_reqd("project", frm.doc.budget_against=="Project");
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class Budget(Document):
|
|||||||
account_list = []
|
account_list = []
|
||||||
for d in self.get("accounts"):
|
for d in self.get("accounts"):
|
||||||
if d.account:
|
if d.account:
|
||||||
account_details = frappe.db.get_value(
|
account_details = frappe.get_cached_value(
|
||||||
"Account", d.account, ["is_group", "company", "report_type"], as_dict=1
|
"Account", d.account, ["is_group", "company", "report_type"], as_dict=1
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -125,27 +125,14 @@ def validate_expense_against_budget(args, expense_amount=0):
|
|||||||
if not args.account:
|
if not args.account:
|
||||||
return
|
return
|
||||||
|
|
||||||
default_dimensions = [
|
for budget_against in ["project", "cost_center"] + get_accounting_dimensions():
|
||||||
{
|
|
||||||
"fieldname": "project",
|
|
||||||
"document_type": "Project",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "cost_center",
|
|
||||||
"document_type": "Cost Center",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
for dimension in default_dimensions + get_accounting_dimensions(as_list=False):
|
|
||||||
budget_against = dimension.get("fieldname")
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
args.get(budget_against)
|
args.get(budget_against)
|
||||||
and args.account
|
and args.account
|
||||||
and frappe.db.get_value("Account", {"name": args.account, "root_type": "Expense"})
|
and frappe.db.get_value("Account", {"name": args.account, "root_type": "Expense"})
|
||||||
):
|
):
|
||||||
|
|
||||||
doctype = dimension.get("document_type")
|
doctype = frappe.unscrub(budget_against)
|
||||||
|
|
||||||
if frappe.get_cached_value("DocType", doctype, "is_tree"):
|
if frappe.get_cached_value("DocType", doctype, "is_tree"):
|
||||||
lft, rgt = frappe.db.get_value(doctype, args.get(budget_against), ["lft", "rgt"])
|
lft, rgt = frappe.db.get_value(doctype, args.get(budget_against), ["lft", "rgt"])
|
||||||
@@ -197,11 +184,6 @@ def validate_budget_records(args, budget_records, expense_amount):
|
|||||||
amount = expense_amount or get_amount(args, budget)
|
amount = expense_amount or get_amount(args, budget)
|
||||||
yearly_action, monthly_action = get_actions(args, budget)
|
yearly_action, monthly_action = get_actions(args, budget)
|
||||||
|
|
||||||
if yearly_action in ("Stop", "Warn"):
|
|
||||||
compare_expense_with_budget(
|
|
||||||
args, flt(budget.budget_amount), _("Annual"), yearly_action, budget.budget_against, amount
|
|
||||||
)
|
|
||||||
|
|
||||||
if monthly_action in ["Stop", "Warn"]:
|
if monthly_action in ["Stop", "Warn"]:
|
||||||
budget_amount = get_accumulated_monthly_budget(
|
budget_amount = get_accumulated_monthly_budget(
|
||||||
budget.monthly_distribution, args.posting_date, args.fiscal_year, budget.budget_amount
|
budget.monthly_distribution, args.posting_date, args.fiscal_year, budget.budget_amount
|
||||||
@@ -213,28 +195,28 @@ def validate_budget_records(args, budget_records, expense_amount):
|
|||||||
args, budget_amount, _("Accumulated Monthly"), monthly_action, budget.budget_against, amount
|
args, budget_amount, _("Accumulated Monthly"), monthly_action, budget.budget_against, amount
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
yearly_action in ("Stop", "Warn")
|
||||||
|
and monthly_action != "Stop"
|
||||||
|
and yearly_action != monthly_action
|
||||||
|
):
|
||||||
|
compare_expense_with_budget(
|
||||||
|
args, flt(budget.budget_amount), _("Annual"), yearly_action, budget.budget_against, amount
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def compare_expense_with_budget(args, budget_amount, action_for, action, budget_against, amount=0):
|
def compare_expense_with_budget(args, budget_amount, action_for, action, budget_against, amount=0):
|
||||||
actual_expense = get_actual_expense(args)
|
actual_expense = amount or get_actual_expense(args)
|
||||||
total_expense = actual_expense + amount
|
|
||||||
|
|
||||||
if total_expense > budget_amount:
|
|
||||||
if actual_expense > budget_amount:
|
if actual_expense > budget_amount:
|
||||||
error_tense = _("is already")
|
|
||||||
diff = actual_expense - budget_amount
|
diff = actual_expense - budget_amount
|
||||||
else:
|
|
||||||
error_tense = _("will be")
|
|
||||||
diff = total_expense - budget_amount
|
|
||||||
|
|
||||||
currency = frappe.get_cached_value("Company", args.company, "default_currency")
|
currency = frappe.get_cached_value("Company", args.company, "default_currency")
|
||||||
|
|
||||||
msg = _("{0} Budget for Account {1} against {2} {3} is {4}. It {5} exceed by {6}").format(
|
msg = _("{0} Budget for Account {1} against {2} {3} is {4}. It will exceed by {5}").format(
|
||||||
_(action_for),
|
_(action_for),
|
||||||
frappe.bold(args.account),
|
frappe.bold(args.account),
|
||||||
frappe.unscrub(args.budget_against_field),
|
args.budget_against_field,
|
||||||
frappe.bold(budget_against),
|
frappe.bold(budget_against),
|
||||||
frappe.bold(fmt_money(budget_amount, currency=currency)),
|
frappe.bold(fmt_money(budget_amount, currency=currency)),
|
||||||
error_tense,
|
|
||||||
frappe.bold(fmt_money(diff, currency=currency)),
|
frappe.bold(fmt_money(diff, currency=currency)),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -245,9 +227,9 @@ def compare_expense_with_budget(args, budget_amount, action_for, action, budget_
|
|||||||
action = "Warn"
|
action = "Warn"
|
||||||
|
|
||||||
if action == "Stop":
|
if action == "Stop":
|
||||||
frappe.throw(msg, BudgetError, title=_("Budget Exceeded"))
|
frappe.throw(msg, BudgetError)
|
||||||
else:
|
else:
|
||||||
frappe.msgprint(msg, indicator="orange", title=_("Budget Exceeded"))
|
frappe.msgprint(msg, indicator="orange")
|
||||||
|
|
||||||
|
|
||||||
def get_actions(args, budget):
|
def get_actions(args, budget):
|
||||||
@@ -324,7 +306,7 @@ def get_other_condition(args, budget, for_doc):
|
|||||||
|
|
||||||
if args.get("fiscal_year"):
|
if args.get("fiscal_year"):
|
||||||
date_field = "schedule_date" if for_doc == "Material Request" else "transaction_date"
|
date_field = "schedule_date" if for_doc == "Material Request" else "transaction_date"
|
||||||
start_date, end_date = frappe.db.get_value(
|
start_date, end_date = frappe.get_cached_value(
|
||||||
"Fiscal Year", args.get("fiscal_year"), ["year_start_date", "year_end_date"]
|
"Fiscal Year", args.get("fiscal_year"), ["year_start_date", "year_end_date"]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -369,9 +351,7 @@ def get_actual_expense(args):
|
|||||||
"""
|
"""
|
||||||
select sum(gle.debit) - sum(gle.credit)
|
select sum(gle.debit) - sum(gle.credit)
|
||||||
from `tabGL Entry` gle
|
from `tabGL Entry` gle
|
||||||
where
|
where gle.account=%(account)s
|
||||||
is_cancelled = 0
|
|
||||||
and gle.account=%(account)s
|
|
||||||
{condition1}
|
{condition1}
|
||||||
and gle.fiscal_year=%(fiscal_year)s
|
and gle.fiscal_year=%(fiscal_year)s
|
||||||
and gle.company=%(company)s
|
and gle.company=%(company)s
|
||||||
@@ -399,7 +379,7 @@ def get_accumulated_monthly_budget(monthly_distribution, posting_date, fiscal_ye
|
|||||||
):
|
):
|
||||||
distribution.setdefault(d.month, d.percentage_allocation)
|
distribution.setdefault(d.month, d.percentage_allocation)
|
||||||
|
|
||||||
dt = frappe.db.get_value("Fiscal Year", fiscal_year, "year_start_date")
|
dt = frappe.get_cached_value("Fiscal Year", fiscal_year, "year_start_date")
|
||||||
accumulated_percentage = 0.0
|
accumulated_percentage = 0.0
|
||||||
|
|
||||||
while dt <= getdate(posting_date):
|
while dt <= getdate(posting_date):
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Cash Flow Mapper", {});
|
frappe.ui.form.on('Cash Flow Mapper', {
|
||||||
|
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,45 +1,43 @@
|
|||||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Cash Flow Mapping", {
|
frappe.ui.form.on('Cash Flow Mapping', {
|
||||||
refresh: function (frm) {
|
refresh: function(frm) {
|
||||||
frm.events.disable_unchecked_fields(frm);
|
frm.events.disable_unchecked_fields(frm);
|
||||||
},
|
},
|
||||||
reset_check_fields: function (frm) {
|
reset_check_fields: function(frm) {
|
||||||
frm.fields
|
frm.fields.filter(field => field.df.fieldtype === 'Check')
|
||||||
.filter((field) => field.df.fieldtype === "Check")
|
.map(field => frm.set_df_property(field.df.fieldname, 'read_only', 0));
|
||||||
.map((field) => frm.set_df_property(field.df.fieldname, "read_only", 0));
|
|
||||||
},
|
},
|
||||||
has_checked_field(frm) {
|
has_checked_field(frm) {
|
||||||
const val = frm.fields.filter((field) => field.value === 1);
|
const val = frm.fields.filter(field => field.value === 1);
|
||||||
return val.length ? 1 : 0;
|
return val.length ? 1 : 0;
|
||||||
},
|
},
|
||||||
_disable_unchecked_fields: function (frm) {
|
_disable_unchecked_fields: function(frm) {
|
||||||
// get value of clicked field
|
// get value of clicked field
|
||||||
frm.fields
|
frm.fields.filter(field => field.value === 0)
|
||||||
.filter((field) => field.value === 0)
|
.map(field => frm.set_df_property(field.df.fieldname, 'read_only', 1));
|
||||||
.map((field) => frm.set_df_property(field.df.fieldname, "read_only", 1));
|
|
||||||
},
|
},
|
||||||
disable_unchecked_fields: function (frm) {
|
disable_unchecked_fields: function(frm) {
|
||||||
frm.events.reset_check_fields(frm);
|
frm.events.reset_check_fields(frm);
|
||||||
const checked = frm.events.has_checked_field(frm);
|
const checked = frm.events.has_checked_field(frm);
|
||||||
if (checked) {
|
if (checked) {
|
||||||
frm.events._disable_unchecked_fields(frm);
|
frm.events._disable_unchecked_fields(frm);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
is_working_capital: function (frm) {
|
is_working_capital: function(frm) {
|
||||||
frm.events.disable_unchecked_fields(frm);
|
frm.events.disable_unchecked_fields(frm);
|
||||||
},
|
},
|
||||||
is_finance_cost: function (frm) {
|
is_finance_cost: function(frm) {
|
||||||
frm.events.disable_unchecked_fields(frm);
|
frm.events.disable_unchecked_fields(frm);
|
||||||
},
|
},
|
||||||
is_income_tax_liability: function (frm) {
|
is_income_tax_liability: function(frm) {
|
||||||
frm.events.disable_unchecked_fields(frm);
|
frm.events.disable_unchecked_fields(frm);
|
||||||
},
|
},
|
||||||
is_income_tax_expense: function (frm) {
|
is_income_tax_expense: function(frm) {
|
||||||
frm.events.disable_unchecked_fields(frm);
|
frm.events.disable_unchecked_fields(frm);
|
||||||
},
|
},
|
||||||
is_finance_cost_adjustment: function (frm) {
|
is_finance_cost_adjustment: function(frm) {
|
||||||
frm.events.disable_unchecked_fields(frm);
|
frm.events.disable_unchecked_fields(frm);
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Cash Flow Mapping Template", {});
|
frappe.ui.form.on('Cash Flow Mapping Template', {
|
||||||
|
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Cash Flow Mapping Template Details", {});
|
frappe.ui.form.on('Cash Flow Mapping Template Details', {
|
||||||
|
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
// License: GNU General Public License v3. See license.txt
|
// License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Cashier Closing", {
|
frappe.ui.form.on('Cashier Closing', {
|
||||||
setup: function (frm) {
|
|
||||||
|
setup: function(frm){
|
||||||
if (frm.doc.user == "" || frm.doc.user == null) {
|
if (frm.doc.user == "" || frm.doc.user == null) {
|
||||||
frm.doc.user = frappe.session.user;
|
frm.doc.user = frappe.session.user;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,152 +1,457 @@
|
|||||||
{
|
{
|
||||||
"actions": [],
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
|
"allow_import": 0,
|
||||||
|
"allow_rename": 0,
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
|
"beta": 0,
|
||||||
"creation": "2018-06-18 16:51:49.994750",
|
"creation": "2018-06-18 16:51:49.994750",
|
||||||
|
"custom": 0,
|
||||||
|
"docstatus": 0,
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
|
"document_type": "",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
|
||||||
"naming_series",
|
|
||||||
"user",
|
|
||||||
"date",
|
|
||||||
"from_time",
|
|
||||||
"time",
|
|
||||||
"expense",
|
|
||||||
"custody",
|
|
||||||
"returns",
|
|
||||||
"outstanding_amount",
|
|
||||||
"payments",
|
|
||||||
"net_amount",
|
|
||||||
"amended_from"
|
|
||||||
],
|
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
"default": "POS-CLO-",
|
"default": "POS-CLO-",
|
||||||
"fieldname": "naming_series",
|
"fieldname": "naming_series",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 1,
|
"in_filter": 1,
|
||||||
"in_global_search": 1,
|
"in_global_search": 1,
|
||||||
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Series",
|
"label": "Series",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
"options": "POS-CLO-",
|
"options": "POS-CLO-",
|
||||||
"read_only": 1
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
"fieldname": "user",
|
"fieldname": "user",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 1,
|
"in_filter": 1,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "User",
|
"label": "User",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
"options": "User",
|
"options": "User",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
"reqd": 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,
|
||||||
"default": "Today",
|
"default": "Today",
|
||||||
"fieldname": "date",
|
"fieldname": "date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 1,
|
"in_filter": 1,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Date",
|
"label": "Date",
|
||||||
"read_only": 1
|
"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": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
"fieldname": "from_time",
|
"fieldname": "from_time",
|
||||||
"fieldtype": "Time",
|
"fieldtype": "Time",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 1,
|
"in_filter": 1,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "From Time",
|
"label": "From Time",
|
||||||
"reqd": 1
|
"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,
|
||||||
|
"default": "",
|
||||||
"fieldname": "time",
|
"fieldname": "time",
|
||||||
"fieldtype": "Time",
|
"fieldtype": "Time",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 1,
|
"in_filter": 1,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "To Time",
|
"label": "To Time",
|
||||||
"reqd": 1
|
"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,
|
||||||
"default": "0.00",
|
"default": "0.00",
|
||||||
"fieldname": "expense",
|
"fieldname": "expense",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 1,
|
"in_filter": 1,
|
||||||
"label": "Expense"
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Expense",
|
||||||
|
"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,
|
||||||
"default": "0.00",
|
"default": "0.00",
|
||||||
"fieldname": "custody",
|
"fieldname": "custody",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 1,
|
"in_filter": 1,
|
||||||
"label": "Custody"
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Custody",
|
||||||
|
"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,
|
||||||
"default": "0.00",
|
"default": "0.00",
|
||||||
"fieldname": "returns",
|
"fieldname": "returns",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 1,
|
"in_filter": 1,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
"label": "Returns",
|
"label": "Returns",
|
||||||
"precision": "2"
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "2",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
"default": "0.00",
|
"default": "0.00",
|
||||||
"fieldname": "outstanding_amount",
|
"fieldname": "outstanding_amount",
|
||||||
"fieldtype": "Float",
|
"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": "Outstanding Amount",
|
"label": "Outstanding Amount",
|
||||||
"read_only": 1
|
"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": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"default": "0.0",
|
||||||
"fieldname": "payments",
|
"fieldname": "payments",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 1,
|
"in_filter": 1,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
"label": "Payments",
|
"label": "Payments",
|
||||||
"options": "Cashier Closing Payments"
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Cashier Closing 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
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
"fieldname": "net_amount",
|
"fieldname": "net_amount",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 1,
|
"in_filter": 1,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Net Amount",
|
"label": "Net Amount",
|
||||||
"read_only": 1
|
"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": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
"fieldname": "amended_from",
|
"fieldname": "amended_from",
|
||||||
"fieldtype": "Link",
|
"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",
|
"label": "Amended From",
|
||||||
|
"length": 0,
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Cashier Closing",
|
"options": "Cashier Closing",
|
||||||
|
"permlevel": 0,
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 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,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"issingle": 0,
|
||||||
"modified": "2023-12-28 13:15:46.858427",
|
"istable": 0,
|
||||||
|
"max_attachments": 0,
|
||||||
|
"modified": "2019-02-19 08:35:24.157327",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Cashier Closing",
|
"name": "Cashier Closing",
|
||||||
"naming_rule": "By \"Naming Series\" field",
|
"name_case": "",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"cancel": 0,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "System Manager",
|
"role": "System Manager",
|
||||||
|
"set_user_permissions": 0,
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 1,
|
"submit": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"quick_entry": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_onload": 0,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"states": [],
|
"track_changes": 1,
|
||||||
"track_changes": 1
|
"track_seen": 0,
|
||||||
|
"track_views": 0
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
frappe.ui.form.on("Chart of Accounts Importer", {
|
frappe.ui.form.on('Chart of Accounts Importer', {
|
||||||
onload: function (frm) {
|
onload: function (frm) {
|
||||||
frm.set_value("company", "");
|
frm.set_value("company", "");
|
||||||
frm.set_value("import_file", "");
|
frm.set_value("import_file", "");
|
||||||
@@ -8,34 +8,31 @@ frappe.ui.form.on("Chart of Accounts Importer", {
|
|||||||
frm.disable_save();
|
frm.disable_save();
|
||||||
|
|
||||||
// make company mandatory
|
// make company mandatory
|
||||||
frm.set_df_property("company", "reqd", frm.doc.company ? 0 : 1);
|
frm.set_df_property('company', 'reqd', frm.doc.company ? 0 : 1);
|
||||||
frm.set_df_property("import_file_section", "hidden", frm.doc.company ? 0 : 1);
|
frm.set_df_property('import_file_section', 'hidden', frm.doc.company ? 0 : 1);
|
||||||
|
|
||||||
if (frm.doc.import_file) {
|
if (frm.doc.import_file) {
|
||||||
frappe.run_serially([
|
frappe.run_serially([
|
||||||
() => generate_tree_preview(frm),
|
() => generate_tree_preview(frm),
|
||||||
() => create_import_button(frm),
|
() => create_import_button(frm),
|
||||||
() => frm.set_df_property("chart_preview", "hidden", 0),
|
() => frm.set_df_property('chart_preview', 'hidden', 0)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
frm.set_df_property(
|
frm.set_df_property('chart_preview', 'hidden',
|
||||||
"chart_preview",
|
$(frm.fields_dict['chart_tree'].wrapper).html()!="" ? 0 : 1);
|
||||||
"hidden",
|
|
||||||
$(frm.fields_dict["chart_tree"].wrapper).html() != "" ? 0 : 1
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
download_template: function (frm) {
|
download_template: function(frm) {
|
||||||
var d = new frappe.ui.Dialog({
|
var d = new frappe.ui.Dialog({
|
||||||
title: __("Download Template"),
|
title: __("Download Template"),
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
label: "File Type",
|
label : "File Type",
|
||||||
fieldname: "file_type",
|
fieldname: "file_type",
|
||||||
fieldtype: "Select",
|
fieldtype: "Select",
|
||||||
reqd: 1,
|
reqd: 1,
|
||||||
options: ["Excel", "CSV"],
|
options: ["Excel", "CSV"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Template Type",
|
label: "Template Type",
|
||||||
@@ -44,53 +41,38 @@ frappe.ui.form.on("Chart of Accounts Importer", {
|
|||||||
reqd: 1,
|
reqd: 1,
|
||||||
options: ["Sample Template", "Blank Template"],
|
options: ["Sample Template", "Blank Template"],
|
||||||
change: () => {
|
change: () => {
|
||||||
let template_type = d.get_value("template_type");
|
let template_type = d.get_value('template_type');
|
||||||
|
|
||||||
if (template_type === "Sample Template") {
|
if (template_type === "Sample Template") {
|
||||||
d.set_df_property(
|
d.set_df_property('template_type', 'description',
|
||||||
"template_type",
|
|
||||||
"description",
|
|
||||||
`The Sample Template contains all the required accounts pre filled in the template.
|
`The Sample Template contains all the required accounts pre filled in the template.
|
||||||
You can add more accounts or change existing accounts in the template as per your choice.`
|
You can add more accounts or change existing accounts in the template as per your choice.`);
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
d.set_df_property(
|
d.set_df_property('template_type', 'description',
|
||||||
"template_type",
|
|
||||||
"description",
|
|
||||||
`The Blank Template contains just the account type and root type required to build the Chart
|
`The Blank Template contains just the account type and root type required to build the Chart
|
||||||
of Accounts. Please enter the account names and add more rows as per your requirement.`
|
of Accounts. Please enter the account names and add more rows as per your requirement.`);
|
||||||
);
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Company",
|
|
||||||
fieldname: "company",
|
|
||||||
fieldtype: "Link",
|
|
||||||
reqd: 1,
|
|
||||||
hidden: 1,
|
|
||||||
default: frm.doc.company,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
primary_action: function () {
|
primary_action: function() {
|
||||||
let data = d.get_values();
|
var data = d.get_values();
|
||||||
|
|
||||||
if (!data.template_type) {
|
if (!data.template_type) {
|
||||||
frappe.throw(__("Please select <b>Template Type</b> to download template"));
|
frappe.throw(__('Please select <b>Template Type</b> to download template'));
|
||||||
}
|
}
|
||||||
|
|
||||||
open_url_post(
|
open_url_post(
|
||||||
"/api/method/erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.download_template",
|
'/api/method/erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.download_template',
|
||||||
{
|
{
|
||||||
file_type: data.file_type,
|
file_type: data.file_type,
|
||||||
template_type: data.template_type,
|
template_type: data.template_type
|
||||||
company: data.company,
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
d.hide();
|
d.hide();
|
||||||
},
|
},
|
||||||
primary_action_label: __("Download"),
|
primary_action_label: __('Download')
|
||||||
});
|
});
|
||||||
d.show();
|
d.show();
|
||||||
},
|
},
|
||||||
@@ -98,7 +80,7 @@ frappe.ui.form.on("Chart of Accounts Importer", {
|
|||||||
import_file: function (frm) {
|
import_file: function (frm) {
|
||||||
if (!frm.doc.import_file) {
|
if (!frm.doc.import_file) {
|
||||||
frm.page.set_indicator("");
|
frm.page.set_indicator("");
|
||||||
$(frm.fields_dict["chart_tree"].wrapper).empty(); // empty wrapper on removing file
|
$(frm.fields_dict['chart_tree'].wrapper).empty(); // empty wrapper on removing file
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -108,97 +90,89 @@ frappe.ui.form.on("Chart of Accounts Importer", {
|
|||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.validate_company",
|
method: "erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.validate_company",
|
||||||
args: {
|
args: {
|
||||||
company: frm.doc.company,
|
company: frm.doc.company
|
||||||
},
|
},
|
||||||
callback: function (r) {
|
callback: function(r) {
|
||||||
if (r.message === false) {
|
if(r.message===false) {
|
||||||
frm.set_value("company", "");
|
frm.set_value("company", "");
|
||||||
frappe.throw(
|
frappe.throw(__("Transactions against the Company already exist! Chart of Accounts can only be imported for a Company with no transactions."));
|
||||||
__(
|
|
||||||
"Transactions against the Company already exist! Chart of Accounts can only be imported for a Company with no transactions."
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
frm.trigger("refresh");
|
frm.trigger("refresh");
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var create_import_button = function (frm) {
|
var create_import_button = function(frm) {
|
||||||
frm.page
|
frm.page.set_primary_action(__("Import"), function () {
|
||||||
.set_primary_action(__("Import"), function () {
|
|
||||||
return frappe.call({
|
return frappe.call({
|
||||||
method: "erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.import_coa",
|
method: "erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.import_coa",
|
||||||
args: {
|
args: {
|
||||||
file_name: frm.doc.import_file,
|
file_name: frm.doc.import_file,
|
||||||
company: frm.doc.company,
|
company: frm.doc.company
|
||||||
},
|
},
|
||||||
freeze: true,
|
freeze: true,
|
||||||
freeze_message: __("Creating Accounts..."),
|
freeze_message: __("Creating Accounts..."),
|
||||||
callback: function (r) {
|
callback: function(r) {
|
||||||
if (!r.exc) {
|
if (!r.exc) {
|
||||||
clearInterval(frm.page["interval"]);
|
clearInterval(frm.page["interval"]);
|
||||||
frm.page.set_indicator(__("Import Successful"), "blue");
|
frm.page.set_indicator(__('Import Successful'), 'blue');
|
||||||
create_reset_button(frm);
|
create_reset_button(frm);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
})
|
}).addClass('btn btn-primary');
|
||||||
.addClass("btn btn-primary");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var create_reset_button = function (frm) {
|
var create_reset_button = function(frm) {
|
||||||
frm.page
|
frm.page.set_primary_action(__("Reset"), function () {
|
||||||
.set_primary_action(__("Reset"), function () {
|
|
||||||
frm.page.clear_primary_action();
|
frm.page.clear_primary_action();
|
||||||
delete frm.page["show_import_button"];
|
delete frm.page["show_import_button"];
|
||||||
frm.reload_doc();
|
frm.reload_doc();
|
||||||
})
|
}).addClass('btn btn-primary');
|
||||||
.addClass("btn btn-primary");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var validate_coa = function (frm) {
|
var validate_coa = function(frm) {
|
||||||
if (frm.doc.import_file) {
|
if (frm.doc.import_file) {
|
||||||
let parent = __("All Accounts");
|
let parent = __('All Accounts');
|
||||||
return frappe.call({
|
return frappe.call({
|
||||||
method: "erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.get_coa",
|
'method': 'erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.get_coa',
|
||||||
args: {
|
'args': {
|
||||||
file_name: frm.doc.import_file,
|
file_name: frm.doc.import_file,
|
||||||
parent: parent,
|
parent: parent,
|
||||||
doctype: "Chart of Accounts Importer",
|
doctype: 'Chart of Accounts Importer',
|
||||||
file_type: frm.doc.file_type,
|
file_type: frm.doc.file_type,
|
||||||
for_validate: 1,
|
for_validate: 1
|
||||||
},
|
},
|
||||||
callback: function (r) {
|
callback: function(r) {
|
||||||
if (r.message["show_import_button"]) {
|
if (r.message['show_import_button']) {
|
||||||
frm.page["show_import_button"] = Boolean(r.message["show_import_button"]);
|
frm.page['show_import_button'] = Boolean(r.message['show_import_button']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var generate_tree_preview = function (frm) {
|
var generate_tree_preview = function(frm) {
|
||||||
let parent = __("All Accounts");
|
let parent = __('All Accounts');
|
||||||
$(frm.fields_dict["chart_tree"].wrapper).empty(); // empty wrapper to load new data
|
$(frm.fields_dict['chart_tree'].wrapper).empty(); // empty wrapper to load new data
|
||||||
|
|
||||||
// generate tree structure based on the csv data
|
// generate tree structure based on the csv data
|
||||||
return new frappe.ui.Tree({
|
return new frappe.ui.Tree({
|
||||||
parent: $(frm.fields_dict["chart_tree"].wrapper),
|
parent: $(frm.fields_dict['chart_tree'].wrapper),
|
||||||
label: parent,
|
label: parent,
|
||||||
expandable: true,
|
expandable: true,
|
||||||
method: "erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.get_coa",
|
method: 'erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.get_coa',
|
||||||
args: {
|
args: {
|
||||||
file_name: frm.doc.import_file,
|
file_name: frm.doc.import_file,
|
||||||
parent: parent,
|
parent: parent,
|
||||||
doctype: "Chart of Accounts Importer",
|
doctype: 'Chart of Accounts Importer',
|
||||||
file_type: frm.doc.file_type,
|
file_type: frm.doc.file_type
|
||||||
},
|
},
|
||||||
onclick: function (node) {
|
onclick: function(node) {
|
||||||
parent = node.value;
|
parent = node.value;
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ from functools import reduce
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.desk.form.linked_with import get_linked_fields
|
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import cint, cstr
|
from frappe.utils import cint, cstr
|
||||||
from frappe.utils.csvutils import UnicodeWriter
|
from frappe.utils.csvutils import UnicodeWriter
|
||||||
@@ -37,7 +36,7 @@ def validate_columns(data):
|
|||||||
|
|
||||||
no_of_columns = max([len(d) for d in data])
|
no_of_columns = max([len(d) for d in data])
|
||||||
|
|
||||||
if no_of_columns > 8:
|
if no_of_columns > 7:
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
_("More columns found than expected. Please compare the uploaded file with standard template"),
|
_("More columns found than expected. Please compare the uploaded file with standard template"),
|
||||||
title=(_("Wrong Template")),
|
title=(_("Wrong Template")),
|
||||||
@@ -46,8 +45,8 @@ def validate_columns(data):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def validate_company(company):
|
def validate_company(company):
|
||||||
parent_company, allow_account_creation_against_child_company = frappe.db.get_value(
|
parent_company, allow_account_creation_against_child_company = frappe.get_cached_value(
|
||||||
"Company", {"name": company}, ["parent_company", "allow_account_creation_against_child_company"]
|
"Company", company, ["parent_company", "allow_account_creation_against_child_company"]
|
||||||
)
|
)
|
||||||
|
|
||||||
if parent_company and (not allow_account_creation_against_child_company):
|
if parent_company and (not allow_account_creation_against_child_company):
|
||||||
@@ -113,7 +112,7 @@ def generate_data_from_csv(file_doc, as_dict=False):
|
|||||||
if as_dict:
|
if as_dict:
|
||||||
data.append({frappe.scrub(header): row[index] for index, header in enumerate(headers)})
|
data.append({frappe.scrub(header): row[index] for index, header in enumerate(headers)})
|
||||||
else:
|
else:
|
||||||
if not row[1] and len(row) > 1:
|
if not row[1]:
|
||||||
row[1] = row[0]
|
row[1] = row[0]
|
||||||
row[3] = row[2]
|
row[3] = row[2]
|
||||||
data.append(row)
|
data.append(row)
|
||||||
@@ -234,7 +233,6 @@ def build_forest(data):
|
|||||||
is_group,
|
is_group,
|
||||||
account_type,
|
account_type,
|
||||||
root_type,
|
root_type,
|
||||||
account_currency,
|
|
||||||
) = i
|
) = i
|
||||||
|
|
||||||
if not account_name:
|
if not account_name:
|
||||||
@@ -255,8 +253,6 @@ def build_forest(data):
|
|||||||
charts_map[account_name]["account_type"] = account_type
|
charts_map[account_name]["account_type"] = account_type
|
||||||
if root_type:
|
if root_type:
|
||||||
charts_map[account_name]["root_type"] = root_type
|
charts_map[account_name]["root_type"] = root_type
|
||||||
if account_currency:
|
|
||||||
charts_map[account_name]["account_currency"] = account_currency
|
|
||||||
path = return_parent(data, account_name)[::-1]
|
path = return_parent(data, account_name)[::-1]
|
||||||
paths.append(path) # List of path is created
|
paths.append(path) # List of path is created
|
||||||
line_no += 1
|
line_no += 1
|
||||||
@@ -295,8 +291,10 @@ def build_response_as_excel(writer):
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def download_template(file_type, template_type, company):
|
def download_template(file_type, template_type):
|
||||||
writer = get_template(template_type, company)
|
data = frappe._dict(frappe.local.form_dict)
|
||||||
|
|
||||||
|
writer = get_template(template_type)
|
||||||
|
|
||||||
if file_type == "CSV":
|
if file_type == "CSV":
|
||||||
# download csv file
|
# download csv file
|
||||||
@@ -307,7 +305,8 @@ def download_template(file_type, template_type, company):
|
|||||||
build_response_as_excel(writer)
|
build_response_as_excel(writer)
|
||||||
|
|
||||||
|
|
||||||
def get_template(template_type, company):
|
def get_template(template_type):
|
||||||
|
|
||||||
fields = [
|
fields = [
|
||||||
"Account Name",
|
"Account Name",
|
||||||
"Parent Account",
|
"Parent Account",
|
||||||
@@ -316,33 +315,49 @@ def get_template(template_type, company):
|
|||||||
"Is Group",
|
"Is Group",
|
||||||
"Account Type",
|
"Account Type",
|
||||||
"Root Type",
|
"Root Type",
|
||||||
"Account Currency",
|
|
||||||
]
|
]
|
||||||
writer = UnicodeWriter()
|
writer = UnicodeWriter()
|
||||||
writer.writerow(fields)
|
writer.writerow(fields)
|
||||||
|
|
||||||
if template_type == "Blank Template":
|
if template_type == "Blank Template":
|
||||||
for root_type in get_root_types():
|
for root_type in get_root_types():
|
||||||
writer.writerow(["", "", "", "", 1, "", root_type])
|
writer.writerow(["", "", "", 1, "", root_type])
|
||||||
|
|
||||||
for account in get_mandatory_group_accounts():
|
for account in get_mandatory_group_accounts():
|
||||||
writer.writerow(["", "", "", "", 1, account, "Asset"])
|
writer.writerow(["", "", "", 1, account, "Asset"])
|
||||||
|
|
||||||
for account_type in get_mandatory_account_types():
|
for account_type in get_mandatory_account_types():
|
||||||
writer.writerow(
|
writer.writerow(
|
||||||
["", "", "", "", 0, account_type.get("account_type"), account_type.get("root_type")]
|
["", "", "", 0, account_type.get("account_type"), account_type.get("root_type")]
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
writer = get_sample_template(writer, company)
|
writer = get_sample_template(writer)
|
||||||
|
|
||||||
return writer
|
return writer
|
||||||
|
|
||||||
|
|
||||||
def get_sample_template(writer, company):
|
def get_sample_template(writer):
|
||||||
currency = frappe.db.get_value("Company", company, "default_currency")
|
template = [
|
||||||
with open(os.path.join(os.path.dirname(__file__), "coa_sample_template.csv"), "r") as f:
|
["Application Of Funds(Assets)", "", "", "", 1, "", "Asset"],
|
||||||
for row in f:
|
["Sources Of Funds(Liabilities)", "", "", "", 1, "", "Liability"],
|
||||||
row = row.strip().split(",") + [currency]
|
["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:
|
||||||
writer.writerow(row)
|
writer.writerow(row)
|
||||||
|
|
||||||
return writer
|
return writer
|
||||||
@@ -434,11 +449,14 @@ def get_mandatory_account_types():
|
|||||||
|
|
||||||
|
|
||||||
def unset_existing_data(company):
|
def unset_existing_data(company):
|
||||||
# remove accounts data from company
|
linked = frappe.db.sql(
|
||||||
|
'''select fieldname from tabDocField
|
||||||
|
where fieldtype="Link" and options="Account" and parent="Company"''',
|
||||||
|
as_dict=True,
|
||||||
|
)
|
||||||
|
|
||||||
fieldnames = get_linked_fields("Account").get("Company", {}).get("fieldname", [])
|
# remove accounts data from company
|
||||||
linked = [{"fieldname": name} for name in fieldnames]
|
update_values = {d.fieldname: "" for d in linked}
|
||||||
update_values = {d.get("fieldname"): "" for d in linked}
|
|
||||||
frappe.db.set_value("Company", company, update_values, update_values)
|
frappe.db.set_value("Company", company, update_values, update_values)
|
||||||
|
|
||||||
# remove accounts data from various doctypes
|
# remove accounts data from various doctypes
|
||||||
@@ -467,10 +485,6 @@ def set_default_accounts(company):
|
|||||||
"default_payable_account": frappe.db.get_value(
|
"default_payable_account": frappe.db.get_value(
|
||||||
"Account", {"company": company.name, "account_type": "Payable", "is_group": 0}
|
"Account", {"company": company.name, "account_type": "Payable", "is_group": 0}
|
||||||
),
|
),
|
||||||
"default_provisional_account": frappe.db.get_value(
|
|
||||||
"Account",
|
|
||||||
{"company": company.name, "account_type": "Service Received But Not Billed", "is_group": 0},
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
Application Of Funds(Assets),,,,1,,Asset
|
|
||||||
Sources Of Funds(Liabilities),,,,1,,Liability
|
|
||||||
Equity,,,,1,,Equity
|
|
||||||
Expenses,,,,1,Expense Account,Expense
|
|
||||||
Income,,,,1,Income Account,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
|
|
||||||
|
@@ -3,20 +3,18 @@
|
|||||||
|
|
||||||
frappe.provide("erpnext.cheque_print");
|
frappe.provide("erpnext.cheque_print");
|
||||||
|
|
||||||
frappe.ui.form.on("Cheque Print Template", {
|
frappe.ui.form.on('Cheque Print Template', {
|
||||||
refresh: function (frm) {
|
refresh: function(frm) {
|
||||||
if (!frm.doc.__islocal) {
|
if(!frm.doc.__islocal) {
|
||||||
frm.add_custom_button(
|
frm.add_custom_button(frm.doc.has_print_format?__("Update Print Format"):__("Create Print Format"),
|
||||||
frm.doc.has_print_format ? __("Update Print Format") : __("Create Print Format"),
|
function() {
|
||||||
function () {
|
|
||||||
erpnext.cheque_print.view_cheque_print(frm);
|
erpnext.cheque_print.view_cheque_print(frm);
|
||||||
}
|
}).addClass("btn-primary");
|
||||||
).addClass("btn-primary");
|
|
||||||
|
|
||||||
$(frm.fields_dict.cheque_print_preview.wrapper).empty();
|
$(frm.fields_dict.cheque_print_preview.wrapper).empty()
|
||||||
|
|
||||||
var template =
|
|
||||||
'<div style="position: relative; overflow-x: scroll;">\
|
var template = '<div style="position: relative; overflow-x: scroll;">\
|
||||||
<div id="cheque_preview" style="width: {{ cheque_width }}cm; \
|
<div id="cheque_preview" style="width: {{ cheque_width }}cm; \
|
||||||
height: {{ cheque_height }}cm;\
|
height: {{ cheque_height }}cm;\
|
||||||
background-repeat: no-repeat;\
|
background-repeat: no-repeat;\
|
||||||
@@ -50,30 +48,30 @@ frappe.ui.form.on("Cheque Print Template", {
|
|||||||
</div>\
|
</div>\
|
||||||
</div>';
|
</div>';
|
||||||
|
|
||||||
$(frappe.render(template, frm.doc)).appendTo(frm.fields_dict.cheque_print_preview.wrapper);
|
$(frappe.render(template, frm.doc)).appendTo(frm.fields_dict.cheque_print_preview.wrapper)
|
||||||
|
|
||||||
if (frm.doc.scanned_cheque) {
|
if (frm.doc.scanned_cheque) {
|
||||||
$(frm.fields_dict.cheque_print_preview.wrapper)
|
$(frm.fields_dict.cheque_print_preview.wrapper).find("#cheque_preview").css('background-image', 'url(' + frm.doc.scanned_cheque + ')');
|
||||||
.find("#cheque_preview")
|
}
|
||||||
.css("background-image", "url(" + frm.doc.scanned_cheque + ")");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
erpnext.cheque_print.view_cheque_print = function (frm) {
|
|
||||||
|
erpnext.cheque_print.view_cheque_print = function(frm) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.accounts.doctype.cheque_print_template.cheque_print_template.create_or_update_cheque_print_format",
|
method: "erpnext.accounts.doctype.cheque_print_template.cheque_print_template.create_or_update_cheque_print_format",
|
||||||
args: {
|
args:{
|
||||||
template_name: frm.doc.name,
|
"template_name": frm.doc.name
|
||||||
},
|
},
|
||||||
callback: function (r) {
|
callback: function(r) {
|
||||||
if (!r.exe && !frm.doc.has_print_format) {
|
if (!r.exe && !frm.doc.has_print_format) {
|
||||||
var doc = frappe.model.sync(r.message);
|
var doc = frappe.model.sync(r.message);
|
||||||
frappe.set_route("Form", r.message.doctype, r.message.name);
|
frappe.set_route("Form", r.message.doctype, r.message.name);
|
||||||
} else {
|
|
||||||
frappe.msgprint(__("Print settings updated in respective print format"));
|
|
||||||
}
|
}
|
||||||
},
|
else {
|
||||||
});
|
frappe.msgprint(__("Print settings updated in respective print format"))
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,80 +3,75 @@
|
|||||||
|
|
||||||
frappe.provide("erpnext.accounts");
|
frappe.provide("erpnext.accounts");
|
||||||
|
|
||||||
frappe.ui.form.on("Cost Center", {
|
|
||||||
onload: function (frm) {
|
|
||||||
frm.set_query("parent_cost_center", function () {
|
frappe.ui.form.on('Cost Center', {
|
||||||
|
onload: function(frm) {
|
||||||
|
frm.set_query("parent_cost_center", function() {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
company: frm.doc.company,
|
company: frm.doc.company,
|
||||||
is_group: 1,
|
is_group: 1
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
refresh: function (frm) {
|
refresh: function(frm) {
|
||||||
if (!frm.is_new()) {
|
if (!frm.is_new()) {
|
||||||
frm.add_custom_button(__("Update Cost Center Name / Number"), function () {
|
frm.add_custom_button(__('Update Cost Center Name / Number'), function () {
|
||||||
frm.trigger("update_cost_center_number");
|
frm.trigger("update_cost_center_number");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let intro_txt = "";
|
let intro_txt = '';
|
||||||
let doc = frm.doc;
|
let doc = frm.doc;
|
||||||
frm.toggle_display("cost_center_name", doc.__islocal);
|
frm.toggle_display('cost_center_name', doc.__islocal);
|
||||||
frm.toggle_enable(["is_group", "company"], doc.__islocal);
|
frm.toggle_enable(['is_group', 'company'], doc.__islocal);
|
||||||
|
|
||||||
if (!doc.__islocal && doc.is_group == 1) {
|
if(!doc.__islocal && doc.is_group==1) {
|
||||||
intro_txt += __(
|
intro_txt += __('Note: This Cost Center is a Group. Cannot make accounting entries against groups.');
|
||||||
"Note: This Cost Center is a Group. Cannot make accounting entries against groups."
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
frm.events.hide_unhide_group_ledger(frm);
|
frm.events.hide_unhide_group_ledger(frm);
|
||||||
|
|
||||||
frm.toggle_display("sb1", doc.is_group == 0);
|
frm.toggle_display('sb1', doc.is_group==0);
|
||||||
frm.set_intro(intro_txt);
|
frm.set_intro(intro_txt);
|
||||||
|
|
||||||
if (!frm.doc.__islocal) {
|
if(!frm.doc.__islocal) {
|
||||||
frm.add_custom_button(__("Chart of Cost Centers"), function () {
|
frm.add_custom_button(__('Chart of Cost Centers'),
|
||||||
frappe.set_route("Tree", "Cost Center");
|
function() { frappe.set_route("Tree", "Cost Center"); });
|
||||||
});
|
|
||||||
|
|
||||||
frm.add_custom_button(__("Budget"), function () {
|
frm.add_custom_button(__('Budget'),
|
||||||
frappe.set_route("List", "Budget", { cost_center: frm.doc.name });
|
function() { frappe.set_route("List", "Budget", {'cost_center': frm.doc.name}); });
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
update_cost_center_number: function (frm) {
|
update_cost_center_number: function(frm) {
|
||||||
var d = new frappe.ui.Dialog({
|
var d = new frappe.ui.Dialog({
|
||||||
title: __("Update Cost Center Name / Number"),
|
title: __('Update Cost Center Name / Number'),
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
label: "Cost Center Name",
|
"label": "Cost Center Name",
|
||||||
fieldname: "cost_center_name",
|
"fieldname": "cost_center_name",
|
||||||
fieldtype: "Data",
|
"fieldtype": "Data",
|
||||||
reqd: 1,
|
"reqd": 1,
|
||||||
default: frm.doc.cost_center_name,
|
"default": frm.doc.cost_center_name
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Cost Center Number",
|
"label": "Cost Center Number",
|
||||||
fieldname: "cost_center_number",
|
"fieldname": "cost_center_number",
|
||||||
fieldtype: "Data",
|
"fieldtype": "Data",
|
||||||
default: frm.doc.cost_center_number,
|
"default": frm.doc.cost_center_number
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: __("Merge with existing"),
|
"label": __("Merge with existing"),
|
||||||
fieldname: "merge",
|
"fieldname": "merge",
|
||||||
fieldtype: "Check",
|
"fieldtype": "Check",
|
||||||
default: 0,
|
"default": 0
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
primary_action: function () {
|
primary_action: function() {
|
||||||
var data = d.get_values();
|
var data = d.get_values();
|
||||||
if (
|
if(data.cost_center_name === frm.doc.cost_center_name && data.cost_center_number === frm.doc.cost_center_number) {
|
||||||
data.cost_center_name === frm.doc.cost_center_name &&
|
|
||||||
data.cost_center_number === frm.doc.cost_center_number
|
|
||||||
) {
|
|
||||||
d.hide();
|
d.hide();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -88,12 +83,12 @@ frappe.ui.form.on("Cost Center", {
|
|||||||
cost_center_name: data.cost_center_name,
|
cost_center_name: data.cost_center_name,
|
||||||
cost_center_number: cstr(data.cost_center_number),
|
cost_center_number: cstr(data.cost_center_number),
|
||||||
company: frm.doc.company,
|
company: frm.doc.company,
|
||||||
merge: data.merge,
|
merge: data.merge
|
||||||
},
|
},
|
||||||
callback: function (r) {
|
callback: function(r) {
|
||||||
frappe.dom.unfreeze();
|
frappe.dom.unfreeze();
|
||||||
if (!r.exc) {
|
if(!r.exc) {
|
||||||
if (r.message) {
|
if(r.message) {
|
||||||
frappe.set_route("Form", "Cost Center", r.message);
|
frappe.set_route("Form", "Cost Center", r.message);
|
||||||
} else {
|
} else {
|
||||||
me.frm.set_value("cost_center_name", data.cost_center_name);
|
me.frm.set_value("cost_center_name", data.cost_center_name);
|
||||||
@@ -101,42 +96,44 @@ frappe.ui.form.on("Cost Center", {
|
|||||||
}
|
}
|
||||||
d.hide();
|
d.hide();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
primary_action_label: __("Update"),
|
primary_action_label: __('Update')
|
||||||
});
|
});
|
||||||
d.show();
|
d.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
parent_cost_center(frm) {
|
parent_cost_center(frm) {
|
||||||
if (!frm.doc.company) {
|
if(!frm.doc.company) {
|
||||||
frappe.msgprint(__("Please enter company name first"));
|
frappe.msgprint(__('Please enter company name first'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
hide_unhide_group_ledger(frm) {
|
hide_unhide_group_ledger(frm) {
|
||||||
let doc = frm.doc;
|
let doc = frm.doc;
|
||||||
if (doc.is_group == 1) {
|
if (doc.is_group == 1) {
|
||||||
frm.add_custom_button(__("Convert to Non-Group"), () => frm.events.convert_to_ledger(frm));
|
frm.add_custom_button(__('Convert to Non-Group'),
|
||||||
|
() => frm.events.convert_to_ledger(frm));
|
||||||
} else if (doc.is_group == 0) {
|
} else if (doc.is_group == 0) {
|
||||||
frm.add_custom_button(__("Convert to Group"), () => frm.events.convert_to_group(frm));
|
frm.add_custom_button(__('Convert to Group'),
|
||||||
|
() => frm.events.convert_to_group(frm));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
convert_to_group(frm) {
|
convert_to_group(frm) {
|
||||||
frm.call("convert_ledger_to_group").then((r) => {
|
frm.call('convert_ledger_to_group').then(r => {
|
||||||
if (r.message === 1) {
|
if(r.message === 1) {
|
||||||
frm.refresh();
|
frm.refresh();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
convert_to_ledger(frm) {
|
convert_to_ledger(frm) {
|
||||||
frm.call("convert_group_to_ledger").then((r) => {
|
frm.call('convert_group_to_ledger').then(r => {
|
||||||
if (r.message === 1) {
|
if(r.message === 1) {
|
||||||
frm.refresh();
|
frm.refresh();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,84 +1,54 @@
|
|||||||
frappe.treeview_settings["Cost Center"] = {
|
frappe.treeview_settings["Cost Center"] = {
|
||||||
breadcrumb: "Accounts",
|
breadcrumb: "Accounts",
|
||||||
get_tree_root: false,
|
get_tree_root: false,
|
||||||
filters: [
|
filters: [{
|
||||||
{
|
|
||||||
fieldname: "company",
|
fieldname: "company",
|
||||||
fieldtype: "Select",
|
fieldtype:"Select",
|
||||||
options: erpnext.utils.get_tree_options("company"),
|
options: erpnext.utils.get_tree_options("company"),
|
||||||
label: __("Company"),
|
label: __("Company"),
|
||||||
default: erpnext.utils.get_tree_default("company"),
|
default: erpnext.utils.get_tree_default("company")
|
||||||
},
|
}],
|
||||||
],
|
|
||||||
root_label: "Cost Centers",
|
root_label: "Cost Centers",
|
||||||
get_tree_nodes: "erpnext.accounts.utils.get_children",
|
get_tree_nodes: 'erpnext.accounts.utils.get_children',
|
||||||
add_tree_node: "erpnext.accounts.utils.add_cc",
|
add_tree_node: 'erpnext.accounts.utils.add_cc',
|
||||||
menu_items: [
|
menu_items:[
|
||||||
{
|
{
|
||||||
label: __("New Company"),
|
label: __('New Company'),
|
||||||
action: function () {
|
action: function() { frappe.new_doc("Company", true) },
|
||||||
frappe.new_doc("Company", true);
|
condition: 'frappe.boot.user.can_create.indexOf("Company") !== -1'
|
||||||
},
|
}
|
||||||
condition: 'frappe.boot.user.can_create.indexOf("Company") !== -1',
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
fields: [
|
fields:[
|
||||||
{ fieldtype: "Data", fieldname: "cost_center_name", label: __("New Cost Center Name"), reqd: true },
|
{fieldtype:'Data', fieldname:'cost_center_name', label:__('New Cost Center Name'), reqd:true},
|
||||||
{
|
{fieldtype:'Check', fieldname:'is_group', label:__('Is Group'),
|
||||||
fieldtype: "Check",
|
description:__('Further cost centers can be made under Groups but entries can be made against non-Groups')},
|
||||||
fieldname: "is_group",
|
{fieldtype:'Data', fieldname:'cost_center_number', label:__('Cost Center Number'),
|
||||||
label: __("Is Group"),
|
description: __("Number of new Cost Center, it will be included in the cost center name as a prefix")}
|
||||||
description: __(
|
|
||||||
"Further cost centers can be made under Groups but entries can be made against non-Groups"
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldtype: "Data",
|
|
||||||
fieldname: "cost_center_number",
|
|
||||||
label: __("Cost Center Number"),
|
|
||||||
description: __(
|
|
||||||
"Number of new Cost Center, it will be included in the cost center name as a prefix"
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
ignore_fields: ["parent_cost_center"],
|
ignore_fields:["parent_cost_center"],
|
||||||
onload: function (treeview) {
|
onload: function(treeview) {
|
||||||
function get_company() {
|
function get_company() {
|
||||||
return treeview.page.fields_dict.company.get_value();
|
return treeview.page.fields_dict.company.get_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
// tools
|
// tools
|
||||||
treeview.page.add_inner_button(
|
treeview.page.add_inner_button(__("Chart of Accounts"), function() {
|
||||||
__("Chart of Accounts"),
|
frappe.set_route('Tree', 'Account', {company: get_company()});
|
||||||
function () {
|
}, __('View'));
|
||||||
frappe.set_route("Tree", "Account", { company: get_company() });
|
|
||||||
},
|
|
||||||
__("View")
|
|
||||||
);
|
|
||||||
|
|
||||||
// make
|
// make
|
||||||
treeview.page.add_inner_button(
|
treeview.page.add_inner_button(__("Budget List"), function() {
|
||||||
__("Budget List"),
|
frappe.set_route('List', 'Budget', {company: get_company()});
|
||||||
function () {
|
}, __('Budget'));
|
||||||
frappe.set_route("List", "Budget", { company: get_company() });
|
|
||||||
},
|
|
||||||
__("Budget")
|
|
||||||
);
|
|
||||||
|
|
||||||
treeview.page.add_inner_button(
|
treeview.page.add_inner_button(__("Monthly Distribution"), function() {
|
||||||
__("Monthly Distribution"),
|
frappe.set_route('List', 'Monthly Distribution', {company: get_company()});
|
||||||
function () {
|
}, __('Budget'));
|
||||||
frappe.set_route("List", "Monthly Distribution", { company: get_company() });
|
|
||||||
},
|
|
||||||
__("Budget")
|
|
||||||
);
|
|
||||||
|
|
||||||
treeview.page.add_inner_button(
|
treeview.page.add_inner_button(__("Budget Variance Report"), function() {
|
||||||
__("Budget Variance Report"),
|
frappe.set_route('query-report', 'Budget Variance Report', {company: get_company()});
|
||||||
function () {
|
}, __('Budget'));
|
||||||
frappe.set_route("query-report", "Budget Variance Report", { company: get_company() });
|
|
||||||
},
|
}
|
||||||
__("Budget")
|
|
||||||
);
|
}
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,24 +1,19 @@
|
|||||||
// Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Cost Center Allocation", {
|
frappe.ui.form.on('Cost Center Allocation', {
|
||||||
setup: function (frm) {
|
setup: function(frm) {
|
||||||
frm.set_query("main_cost_center", function () {
|
let filters = {"is_group": 0};
|
||||||
return {
|
if (frm.doc.company) {
|
||||||
filters: {
|
$.extend(filters, {
|
||||||
company: frm.doc.company,
|
"company": frm.doc.company
|
||||||
is_group: 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
frm.set_query("cost_center", "allocation_percentages", function () {
|
frm.set_query('main_cost_center', function() {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: filters
|
||||||
company: frm.doc.company,
|
|
||||||
is_group: 0,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -28,13 +28,8 @@ class InvalidDateError(frappe.ValidationError):
|
|||||||
|
|
||||||
|
|
||||||
class CostCenterAllocation(Document):
|
class CostCenterAllocation(Document):
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(CostCenterAllocation, self).__init__(*args, **kwargs)
|
|
||||||
self._skip_from_date_validation = False
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_total_allocation_percentage()
|
self.validate_total_allocation_percentage()
|
||||||
if not self._skip_from_date_validation:
|
|
||||||
self.validate_from_date_based_on_existing_gle()
|
self.validate_from_date_based_on_existing_gle()
|
||||||
self.validate_backdated_allocation()
|
self.validate_backdated_allocation()
|
||||||
self.validate_main_cost_center()
|
self.validate_main_cost_center()
|
||||||
|
|||||||
@@ -1,41 +1,44 @@
|
|||||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Coupon Code", {
|
frappe.ui.form.on('Coupon Code', {
|
||||||
setup: function (frm) {
|
setup: function(frm) {
|
||||||
frm.set_query("pricing_rule", function () {
|
frm.set_query("pricing_rule", function() {
|
||||||
return {
|
return {
|
||||||
filters: [["Pricing Rule", "coupon_code_based", "=", "1"]],
|
filters: [
|
||||||
|
["Pricing Rule","coupon_code_based", "=", "1"]
|
||||||
|
]
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
coupon_name: function (frm) {
|
coupon_name:function(frm){
|
||||||
if (frm.doc.__islocal === 1) {
|
if (frm.doc.__islocal===1) {
|
||||||
frm.trigger("make_coupon_code");
|
frm.trigger("make_coupon_code");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
coupon_type: function (frm) {
|
coupon_type:function(frm){
|
||||||
if (frm.doc.__islocal === 1) {
|
if (frm.doc.__islocal===1) {
|
||||||
frm.trigger("make_coupon_code");
|
frm.trigger("make_coupon_code");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
make_coupon_code: function (frm) {
|
make_coupon_code: function(frm) {
|
||||||
var coupon_name = frm.doc.coupon_name;
|
var coupon_name=frm.doc.coupon_name;
|
||||||
var coupon_code;
|
var coupon_code;
|
||||||
if (frm.doc.coupon_type == "Gift Card") {
|
if (frm.doc.coupon_type=='Gift Card') {
|
||||||
coupon_code = Math.random().toString(12).substring(2, 12).toUpperCase();
|
coupon_code=Math.random().toString(12).substring(2, 12).toUpperCase();
|
||||||
} else if (frm.doc.coupon_type == "Promotional") {
|
|
||||||
coupon_name = coupon_name.replace(/\s/g, "");
|
|
||||||
coupon_code = coupon_name.toUpperCase().slice(0, 8);
|
|
||||||
}
|
}
|
||||||
frm.doc.coupon_code = coupon_code;
|
else if(frm.doc.coupon_type=='Promotional'){
|
||||||
frm.refresh_field("coupon_code");
|
coupon_name=coupon_name.replace(/\s/g,'');
|
||||||
|
coupon_code=coupon_name.toUpperCase().slice(0,8);
|
||||||
|
}
|
||||||
|
frm.doc.coupon_code=coupon_code;
|
||||||
|
frm.refresh_field('coupon_code');
|
||||||
},
|
},
|
||||||
refresh: function (frm) {
|
refresh: function(frm) {
|
||||||
if (frm.doc.pricing_rule) {
|
if (frm.doc.pricing_rule) {
|
||||||
frm.add_custom_button(__("Add/Edit Coupon Conditions"), function () {
|
frm.add_custom_button(__("Add/Edit Coupon Conditions"), function(){
|
||||||
frappe.set_route("Form", "Pricing Rule", frm.doc.pricing_rule);
|
frappe.set_route("Form", "Pricing Rule", frm.doc.pricing_rule);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,27 +1,28 @@
|
|||||||
// Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Currency Exchange Settings", {
|
frappe.ui.form.on('Currency Exchange Settings', {
|
||||||
service_provider: function (frm) {
|
service_provider: function(frm) {
|
||||||
if (frm.doc.service_provider == "exchangerate.host") {
|
if (frm.doc.service_provider == "exchangerate.host") {
|
||||||
let result = ["result"];
|
let result = ['result'];
|
||||||
let params = {
|
let params = {
|
||||||
date: "{transaction_date}",
|
date: '{transaction_date}',
|
||||||
from: "{from_currency}",
|
from: '{from_currency}',
|
||||||
to: "{to_currency}",
|
to: '{to_currency}'
|
||||||
};
|
};
|
||||||
add_param(frm, "https://api.exchangerate.host/convert", params, result);
|
add_param(frm, "https://api.exchangerate.host/convert", params, result);
|
||||||
} else if (frm.doc.service_provider == "frankfurter.app") {
|
} else if (frm.doc.service_provider == "frankfurter.app") {
|
||||||
let result = ["rates", "{to_currency}"];
|
let result = ['rates', '{to_currency}'];
|
||||||
let params = {
|
let params = {
|
||||||
base: "{from_currency}",
|
base: '{from_currency}',
|
||||||
symbols: "{to_currency}",
|
symbols: '{to_currency}'
|
||||||
};
|
};
|
||||||
add_param(frm, "https://frankfurter.app/{transaction_date}", params, result);
|
add_param(frm, "https://frankfurter.app/{transaction_date}", params, result);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
function add_param(frm, api, params, result) {
|
function add_param(frm, api, params, result) {
|
||||||
var row;
|
var row;
|
||||||
frm.clear_table("req_params");
|
frm.clear_table("req_params");
|
||||||
@@ -29,13 +30,13 @@ function add_param(frm, api, params, result) {
|
|||||||
|
|
||||||
frm.doc.api_endpoint = api;
|
frm.doc.api_endpoint = api;
|
||||||
|
|
||||||
$.each(params, function (key, value) {
|
$.each(params, function(key, value) {
|
||||||
row = frm.add_child("req_params");
|
row = frm.add_child("req_params");
|
||||||
row.key = key;
|
row.key = key;
|
||||||
row.value = value;
|
row.value = value;
|
||||||
});
|
});
|
||||||
|
|
||||||
$.each(result, function (key, value) {
|
$.each(result, function(key, value) {
|
||||||
row = frm.add_child("result_key");
|
row = frm.add_child("result_key");
|
||||||
row.key = value;
|
row.key = value;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,10 +6,8 @@
|
|||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"api_details_section",
|
"api_details_section",
|
||||||
"disabled",
|
|
||||||
"service_provider",
|
"service_provider",
|
||||||
"api_endpoint",
|
"api_endpoint",
|
||||||
"access_key",
|
|
||||||
"url",
|
"url",
|
||||||
"column_break_3",
|
"column_break_3",
|
||||||
"help",
|
"help",
|
||||||
@@ -79,24 +77,12 @@
|
|||||||
"label": "Service Provider",
|
"label": "Service Provider",
|
||||||
"options": "frankfurter.app\nexchangerate.host\nCustom",
|
"options": "frankfurter.app\nexchangerate.host\nCustom",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"fieldname": "disabled",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Disabled"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"depends_on": "eval:doc.service_provider == 'exchangerate.host';",
|
|
||||||
"fieldname": "access_key",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"label": "Access Key"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-10-04 15:30:25.333860",
|
"modified": "2022-01-10 15:51:14.521174",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Currency Exchange Settings",
|
"name": "Currency Exchange Settings",
|
||||||
|
|||||||
@@ -18,21 +18,11 @@ class CurrencyExchangeSettings(Document):
|
|||||||
|
|
||||||
def set_parameters_and_result(self):
|
def set_parameters_and_result(self):
|
||||||
if self.service_provider == "exchangerate.host":
|
if self.service_provider == "exchangerate.host":
|
||||||
|
|
||||||
if not self.access_key:
|
|
||||||
frappe.throw(
|
|
||||||
_("Access Key is required for Service Provider: {0}").format(
|
|
||||||
frappe.bold(self.service_provider)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.set("result_key", [])
|
self.set("result_key", [])
|
||||||
self.set("req_params", [])
|
self.set("req_params", [])
|
||||||
|
|
||||||
self.api_endpoint = "https://api.exchangerate.host/convert"
|
self.api_endpoint = "https://api.exchangerate.host/convert"
|
||||||
self.append("result_key", {"key": "result"})
|
self.append("result_key", {"key": "result"})
|
||||||
self.append("req_params", {"key": "access_key", "value": self.access_key})
|
|
||||||
self.append("req_params", {"key": "amount", "value": "1"})
|
|
||||||
self.append("req_params", {"key": "date", "value": "{transaction_date}"})
|
self.append("req_params", {"key": "date", "value": "{transaction_date}"})
|
||||||
self.append("req_params", {"key": "from", "value": "{from_currency}"})
|
self.append("req_params", {"key": "from", "value": "{from_currency}"})
|
||||||
self.append("req_params", {"key": "to", "value": "{to_currency}"})
|
self.append("req_params", {"key": "to", "value": "{to_currency}"})
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ frappe.ui.form.on("Dunning", {
|
|||||||
docstatus: 1,
|
docstatus: 1,
|
||||||
company: frm.doc.company,
|
company: frm.doc.company,
|
||||||
outstanding_amount: [">", 0],
|
outstanding_amount: [">", 0],
|
||||||
status: "Overdue",
|
status: "Overdue"
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -18,14 +18,18 @@ frappe.ui.form.on("Dunning", {
|
|||||||
filters: {
|
filters: {
|
||||||
company: frm.doc.company,
|
company: frm.doc.company,
|
||||||
root_type: "Income",
|
root_type: "Income",
|
||||||
is_group: 0,
|
is_group: 0
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
refresh: function (frm) {
|
refresh: function (frm) {
|
||||||
frm.set_df_property("company", "read_only", frm.doc.__islocal ? 0 : 1);
|
frm.set_df_property("company", "read_only", frm.doc.__islocal ? 0 : 1);
|
||||||
frm.set_df_property("sales_invoice", "read_only", frm.doc.__islocal ? 0 : 1);
|
frm.set_df_property(
|
||||||
|
"sales_invoice",
|
||||||
|
"read_only",
|
||||||
|
frm.doc.__islocal ? 0 : 1
|
||||||
|
);
|
||||||
if (frm.doc.docstatus === 1 && frm.doc.status === "Unresolved") {
|
if (frm.doc.docstatus === 1 && frm.doc.status === "Unresolved") {
|
||||||
frm.add_custom_button(__("Resolve"), () => {
|
frm.add_custom_button(__("Resolve"), () => {
|
||||||
frm.set_value("status", "Resolved");
|
frm.set_value("status", "Resolved");
|
||||||
@@ -36,27 +40,22 @@ frappe.ui.form.on("Dunning", {
|
|||||||
__("Payment"),
|
__("Payment"),
|
||||||
function () {
|
function () {
|
||||||
frm.events.make_payment_entry(frm);
|
frm.events.make_payment_entry(frm);
|
||||||
},
|
},__("Create")
|
||||||
__("Create")
|
|
||||||
);
|
);
|
||||||
frm.page.set_inner_btn_group_as_primary(__("Create"));
|
frm.page.set_inner_btn_group_as_primary(__("Create"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frm.doc.docstatus > 0) {
|
if(frm.doc.docstatus > 0) {
|
||||||
frm.add_custom_button(
|
frm.add_custom_button(__('Ledger'), function() {
|
||||||
__("Ledger"),
|
|
||||||
function () {
|
|
||||||
frappe.route_options = {
|
frappe.route_options = {
|
||||||
voucher_no: frm.doc.name,
|
"voucher_no": frm.doc.name,
|
||||||
from_date: frm.doc.posting_date,
|
"from_date": frm.doc.posting_date,
|
||||||
to_date: frm.doc.posting_date,
|
"to_date": frm.doc.posting_date,
|
||||||
company: frm.doc.company,
|
"company": frm.doc.company,
|
||||||
show_cancelled_entries: frm.doc.docstatus === 2,
|
"show_cancelled_entries": frm.doc.docstatus === 2
|
||||||
};
|
};
|
||||||
frappe.set_route("query-report", "General Ledger");
|
frappe.set_route("query-report", "General Ledger");
|
||||||
},
|
}, __('View'));
|
||||||
__("View")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
overdue_days: function (frm) {
|
overdue_days: function (frm) {
|
||||||
@@ -87,7 +86,8 @@ frappe.ui.form.on("Dunning", {
|
|||||||
get_dunning_letter_text: function (frm) {
|
get_dunning_letter_text: function (frm) {
|
||||||
if (frm.doc.dunning_type) {
|
if (frm.doc.dunning_type) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.accounts.doctype.dunning.dunning.get_dunning_letter_text",
|
method:
|
||||||
|
"erpnext.accounts.doctype.dunning.dunning.get_dunning_letter_text",
|
||||||
args: {
|
args: {
|
||||||
dunning_type: frm.doc.dunning_type,
|
dunning_type: frm.doc.dunning_type,
|
||||||
language: frm.doc.language,
|
language: frm.doc.language,
|
||||||
@@ -129,25 +129,26 @@ frappe.ui.form.on("Dunning", {
|
|||||||
},
|
},
|
||||||
calculate_overdue_days: function (frm) {
|
calculate_overdue_days: function (frm) {
|
||||||
if (frm.doc.posting_date && frm.doc.due_date) {
|
if (frm.doc.posting_date && frm.doc.due_date) {
|
||||||
const overdue_days = moment(frm.doc.posting_date).diff(frm.doc.due_date, "days");
|
const overdue_days = moment(frm.doc.posting_date).diff(
|
||||||
|
frm.doc.due_date,
|
||||||
|
"days"
|
||||||
|
);
|
||||||
frm.set_value("overdue_days", overdue_days);
|
frm.set_value("overdue_days", overdue_days);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
calculate_interest_and_amount: function (frm) {
|
calculate_interest_and_amount: function (frm) {
|
||||||
const interest_per_year = (frm.doc.outstanding_amount * frm.doc.rate_of_interest) / 100;
|
const interest_per_year = frm.doc.outstanding_amount * frm.doc.rate_of_interest / 100;
|
||||||
const interest_amount = flt(
|
const interest_amount = flt((interest_per_year * cint(frm.doc.overdue_days)) / 365 || 0, precision('interest_amount'));
|
||||||
(interest_per_year * cint(frm.doc.overdue_days)) / 365 || 0,
|
const dunning_amount = flt(interest_amount + frm.doc.dunning_fee, precision('dunning_amount'));
|
||||||
precision("interest_amount")
|
const grand_total = flt(frm.doc.outstanding_amount + dunning_amount, precision('grand_total'));
|
||||||
);
|
|
||||||
const dunning_amount = flt(interest_amount + frm.doc.dunning_fee, precision("dunning_amount"));
|
|
||||||
const grand_total = flt(frm.doc.outstanding_amount + dunning_amount, precision("grand_total"));
|
|
||||||
frm.set_value("interest_amount", interest_amount);
|
frm.set_value("interest_amount", interest_amount);
|
||||||
frm.set_value("dunning_amount", dunning_amount);
|
frm.set_value("dunning_amount", dunning_amount);
|
||||||
frm.set_value("grand_total", grand_total);
|
frm.set_value("grand_total", grand_total);
|
||||||
},
|
},
|
||||||
make_payment_entry: function (frm) {
|
make_payment_entry: function (frm) {
|
||||||
return frappe.call({
|
return frappe.call({
|
||||||
method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry",
|
method:
|
||||||
|
"erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry",
|
||||||
args: {
|
args: {
|
||||||
dt: frm.doc.doctype,
|
dt: frm.doc.doctype,
|
||||||
dn: frm.doc.name,
|
dn: frm.doc.name,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class Dunning(AccountsController):
|
|||||||
self.validate_overdue_days()
|
self.validate_overdue_days()
|
||||||
self.validate_amount()
|
self.validate_amount()
|
||||||
if not self.income_account:
|
if not self.income_account:
|
||||||
self.income_account = frappe.db.get_value("Company", self.company, "default_income_account")
|
self.income_account = frappe.get_cached_value("Company", self.company, "default_income_account")
|
||||||
|
|
||||||
def validate_overdue_days(self):
|
def validate_overdue_days(self):
|
||||||
self.overdue_days = (getdate(self.posting_date) - getdate(self.due_date)).days or 0
|
self.overdue_days = (getdate(self.posting_date) - getdate(self.due_date)).days or 0
|
||||||
@@ -40,7 +40,7 @@ class Dunning(AccountsController):
|
|||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
if self.dunning_amount:
|
if self.dunning_amount:
|
||||||
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry", "Payment Ledger Entry")
|
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry")
|
||||||
make_reverse_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
|
make_reverse_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
|
||||||
|
|
||||||
def make_gl_entries(self):
|
def make_gl_entries(self):
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Dunning Type", {
|
frappe.ui.form.on('Dunning Type', {
|
||||||
// refresh: function(frm) {
|
// refresh: function(frm) {
|
||||||
|
|
||||||
// }
|
// }
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,82 +1,63 @@
|
|||||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Exchange Rate Revaluation", {
|
frappe.ui.form.on('Exchange Rate Revaluation', {
|
||||||
setup: function (frm) {
|
setup: function(frm) {
|
||||||
frm.set_query("party_type", "accounts", function () {
|
frm.set_query("party_type", "accounts", function() {
|
||||||
return {
|
return {
|
||||||
filters: {
|
"filters": {
|
||||||
name: ["in", Object.keys(frappe.boot.party_account_types)],
|
"name": ["in", Object.keys(frappe.boot.party_account_types)],
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
frm.set_query("account", "accounts", function (doc) {
|
frm.set_query("account", "accounts", function(doc) {
|
||||||
return {
|
return {
|
||||||
filters: {
|
"filters": {
|
||||||
company: doc.company,
|
"company": doc.company
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function (frm) {
|
refresh: function(frm) {
|
||||||
if (frm.doc.docstatus == 1) {
|
if(frm.doc.docstatus==1) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "check_journal_entry_condition",
|
method: 'check_journal_entry_condition',
|
||||||
doc: frm.doc,
|
doc: frm.doc,
|
||||||
callback: function (r) {
|
callback: function(r) {
|
||||||
if (r.message) {
|
if (r.message) {
|
||||||
frm.add_custom_button(
|
frm.add_custom_button(__('Journal Entry'), function() {
|
||||||
__("Journal Entries"),
|
|
||||||
function () {
|
|
||||||
return frm.events.make_jv(frm);
|
return frm.events.make_jv(frm);
|
||||||
},
|
}, __('Create'));
|
||||||
__("Create")
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
validate_rounding_loss: function (frm) {
|
get_entries: function(frm) {
|
||||||
let allowance = frm.doc.rounding_loss_allowance;
|
|
||||||
if (!(allowance >= 0 && allowance < 1)) {
|
|
||||||
frappe.throw(__("Rounding Loss Allowance should be between 0 and 1"));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
rounding_loss_allowance: function (frm) {
|
|
||||||
frm.events.validate_rounding_loss(frm);
|
|
||||||
},
|
|
||||||
|
|
||||||
validate: function (frm) {
|
|
||||||
frm.events.validate_rounding_loss(frm);
|
|
||||||
},
|
|
||||||
|
|
||||||
get_entries: function (frm, account) {
|
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "get_accounts_data",
|
method: "get_accounts_data",
|
||||||
doc: cur_frm.doc,
|
doc: cur_frm.doc,
|
||||||
account: account,
|
callback: function(r){
|
||||||
callback: function (r) {
|
|
||||||
frappe.model.clear_table(frm.doc, "accounts");
|
frappe.model.clear_table(frm.doc, "accounts");
|
||||||
if (r.message) {
|
if(r.message) {
|
||||||
r.message.forEach((d) => {
|
r.message.forEach((d) => {
|
||||||
cur_frm.add_child("accounts", d);
|
cur_frm.add_child("accounts",d);
|
||||||
});
|
});
|
||||||
frm.events.get_total_gain_loss(frm);
|
frm.events.get_total_gain_loss(frm);
|
||||||
refresh_field("accounts");
|
refresh_field("accounts");
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
get_total_gain_loss: function (frm) {
|
get_total_gain_loss: function(frm) {
|
||||||
if (!(frm.doc.accounts && frm.doc.accounts.length)) return;
|
if(!(frm.doc.accounts && frm.doc.accounts.length)) return;
|
||||||
|
|
||||||
let total_gain_loss = 0;
|
let total_gain_loss = 0;
|
||||||
frm.doc.accounts.forEach((d) => {
|
frm.doc.accounts.forEach((d) => {
|
||||||
|
d.gain_loss = flt(d.new_balance_in_base_currency, precision("new_balance_in_base_currency", d)) - flt(d.balance_in_base_currency, precision("balance_in_base_currency", d));
|
||||||
total_gain_loss += flt(d.gain_loss, precision("gain_loss", d));
|
total_gain_loss += flt(d.gain_loss, precision("gain_loss", d));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -84,76 +65,67 @@ frappe.ui.form.on("Exchange Rate Revaluation", {
|
|||||||
frm.refresh_fields();
|
frm.refresh_fields();
|
||||||
},
|
},
|
||||||
|
|
||||||
make_jv: function (frm) {
|
make_jv : function(frm) {
|
||||||
let revaluation_journal = null;
|
|
||||||
let zero_balance_journal = null;
|
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "make_jv_entries",
|
method: "make_jv_entry",
|
||||||
doc: frm.doc,
|
doc: frm.doc,
|
||||||
freeze: true,
|
callback: function(r){
|
||||||
freeze_message: "Making Journal Entries...",
|
|
||||||
callback: function (r) {
|
|
||||||
if (r.message) {
|
if (r.message) {
|
||||||
let response = r.message;
|
var doc = frappe.model.sync(r.message)[0];
|
||||||
if (response["revaluation_jv"] || response["zero_balance_jv"]) {
|
frappe.set_route("Form", doc.doctype, doc.name);
|
||||||
frappe.msgprint(__("Journals have been created"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
frappe.ui.form.on("Exchange Rate Revaluation Account", {
|
frappe.ui.form.on("Exchange Rate Revaluation Account", {
|
||||||
new_exchange_rate: function (frm, cdt, cdn) {
|
new_exchange_rate: function(frm, cdt, cdn) {
|
||||||
var row = frappe.get_doc(cdt, cdn);
|
var row = frappe.get_doc(cdt, cdn);
|
||||||
row.new_balance_in_base_currency = flt(
|
row.new_balance_in_base_currency = flt(row.new_exchange_rate * flt(row.balance_in_account_currency),
|
||||||
row.new_exchange_rate * flt(row.balance_in_account_currency),
|
precision("new_balance_in_base_currency", row));
|
||||||
precision("new_balance_in_base_currency", row)
|
|
||||||
);
|
|
||||||
row.gain_loss = row.new_balance_in_base_currency - flt(row.balance_in_base_currency);
|
row.gain_loss = row.new_balance_in_base_currency - flt(row.balance_in_base_currency);
|
||||||
refresh_field("accounts");
|
refresh_field("accounts");
|
||||||
frm.events.get_total_gain_loss(frm);
|
frm.events.get_total_gain_loss(frm);
|
||||||
},
|
},
|
||||||
|
|
||||||
account: function (frm, cdt, cdn) {
|
account: function(frm, cdt, cdn) {
|
||||||
var row = locals[cdt][cdn];
|
var row = locals[cdt][cdn];
|
||||||
if (row.account) {
|
if (row.account) {
|
||||||
get_account_details(frm, cdt, cdn);
|
get_account_details(frm, cdt, cdn);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
party: function (frm, cdt, cdn) {
|
party: function(frm, cdt, cdn) {
|
||||||
var row = locals[cdt][cdn];
|
var row = locals[cdt][cdn];
|
||||||
if (row.party && row.account) {
|
if (row.party && row.account) {
|
||||||
get_account_details(frm, cdt, cdn);
|
get_account_details(frm, cdt, cdn);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
accounts_remove: function (frm) {
|
accounts_remove: function(frm) {
|
||||||
frm.events.get_total_gain_loss(frm);
|
frm.events.get_total_gain_loss(frm);
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var get_account_details = function (frm, cdt, cdn) {
|
var get_account_details = function(frm, cdt, cdn) {
|
||||||
var row = frappe.get_doc(cdt, cdn);
|
var row = frappe.get_doc(cdt, cdn);
|
||||||
if (!frm.doc.company || !frm.doc.posting_date) {
|
if(!frm.doc.company || !frm.doc.posting_date) {
|
||||||
frappe.throw(__("Please select Company and Posting Date to getting entries"));
|
frappe.throw(__("Please select Company and Posting Date to getting entries"));
|
||||||
}
|
}
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.accounts.doctype.exchange_rate_revaluation.exchange_rate_revaluation.get_account_details",
|
method: "erpnext.accounts.doctype.exchange_rate_revaluation.exchange_rate_revaluation.get_account_details",
|
||||||
args: {
|
args:{
|
||||||
account: row.account,
|
account: row.account,
|
||||||
company: frm.doc.company,
|
company: frm.doc.company,
|
||||||
posting_date: frm.doc.posting_date,
|
posting_date: frm.doc.posting_date,
|
||||||
party_type: row.party_type,
|
party_type: row.party_type,
|
||||||
party: row.party,
|
party: row.party
|
||||||
rounding_loss_allowance: frm.doc.rounding_loss_allowance,
|
|
||||||
},
|
},
|
||||||
callback: function (r) {
|
callback: function(r){
|
||||||
$.extend(row, r.message);
|
$.extend(row, r.message);
|
||||||
refresh_field("accounts");
|
refresh_field("accounts");
|
||||||
frm.events.get_total_gain_loss(frm);
|
frm.events.get_total_gain_loss(frm);
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,16 +8,12 @@
|
|||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"posting_date",
|
"posting_date",
|
||||||
"rounding_loss_allowance",
|
|
||||||
"column_break_2",
|
"column_break_2",
|
||||||
"company",
|
"company",
|
||||||
"section_break_4",
|
"section_break_4",
|
||||||
"get_entries",
|
"get_entries",
|
||||||
"accounts",
|
"accounts",
|
||||||
"section_break_6",
|
"section_break_6",
|
||||||
"gain_loss_unbooked",
|
|
||||||
"gain_loss_booked",
|
|
||||||
"column_break_10",
|
|
||||||
"total_gain_loss",
|
"total_gain_loss",
|
||||||
"amended_from"
|
"amended_from"
|
||||||
],
|
],
|
||||||
@@ -63,30 +59,6 @@
|
|||||||
"fieldname": "section_break_6",
|
"fieldname": "section_break_6",
|
||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "amended_from",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Amended From",
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Exchange Rate Revaluation",
|
|
||||||
"print_hide": 1,
|
|
||||||
"read_only": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "gain_loss_unbooked",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"label": "Gain/Loss from Revaluation",
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"read_only": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Gain/Loss accumulated in foreign currency account. Accounts with '0' balance in either Base or Account currency",
|
|
||||||
"fieldname": "gain_loss_booked",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"label": "Gain/Loss already booked",
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"read_only": 1
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "total_gain_loss",
|
"fieldname": "total_gain_loss",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
@@ -95,21 +67,18 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_10",
|
"fieldname": "amended_from",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Link",
|
||||||
},
|
"label": "Amended From",
|
||||||
{
|
"no_copy": 1,
|
||||||
"default": "0.05",
|
"options": "Exchange Rate Revaluation",
|
||||||
"description": "Only values between [0,1) are allowed. Like {0.00, 0.04, 0.09, ...}\nEx: If allowance is set at 0.07, accounts that have balance of 0.07 in either of the currencies will be considered as zero balance account",
|
"print_hide": 1,
|
||||||
"fieldname": "rounding_loss_allowance",
|
"read_only": 1
|
||||||
"fieldtype": "Float",
|
|
||||||
"label": "Rounding Loss Allowance",
|
|
||||||
"precision": "9"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-06-20 07:29:06.972434",
|
"modified": "2022-11-17 10:28:03.911554",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Exchange Rate Revaluation",
|
"name": "Exchange Rate Revaluation",
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user