Compare commits
356 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
40a43d3260 | ||
|
|
a829b3cc82 | ||
|
|
757c2f692b | ||
|
|
85a9e2ed28 | ||
|
|
f55a33890f | ||
|
|
ec992df81a | ||
|
|
6f191eda99 | ||
|
|
3318926b23 | ||
|
|
360c1efd18 | ||
|
|
a0b85cd1ec | ||
|
|
9ef023b10f | ||
|
|
0d0811ca14 | ||
|
|
39c2f75e6d | ||
|
|
3ab938ea34 | ||
|
|
7da3c46ef2 | ||
|
|
e4be3f8dc9 | ||
|
|
3d5d858933 | ||
|
|
12fd8a6047 | ||
|
|
24ec3c7dcb | ||
|
|
c4c2c56af2 | ||
|
|
705d885b64 | ||
|
|
1c1dd08a34 | ||
|
|
b2dca79d89 | ||
|
|
6960a76adc | ||
|
|
0664d6ed8b | ||
|
|
1bcc6c661a | ||
|
|
9b44c16a32 | ||
|
|
1299d56e85 | ||
|
|
8c88af23ef | ||
|
|
d1d2633658 | ||
|
|
152ba1eccb | ||
|
|
49c52f7639 | ||
|
|
4e0559bc79 | ||
|
|
2b39d5d6d5 | ||
|
|
e4acf763a5 | ||
|
|
f073814635 | ||
|
|
2e4de83df6 | ||
|
|
f551b43a94 | ||
|
|
c15a3bd379 | ||
|
|
caf9891075 | ||
|
|
bd4b80e3d8 | ||
|
|
9930eb0a7a | ||
|
|
703e837125 | ||
|
|
4f0f144142 | ||
|
|
cf36534eed | ||
|
|
d02744b436 | ||
|
|
850eaa73b0 | ||
|
|
e859671eb3 | ||
|
|
d258372f9e | ||
|
|
f6d738b3c5 | ||
|
|
b98359f4a7 | ||
|
|
5c1d15f015 | ||
|
|
a22c94c246 | ||
|
|
aebcb17daf | ||
|
|
6cea73b834 | ||
|
|
bd0beb6c02 | ||
|
|
e78d5a240a | ||
|
|
de3429280b | ||
|
|
8c9f2a1be6 | ||
|
|
9b4f3cf9de | ||
|
|
0396674d0d | ||
|
|
9c334c34a6 | ||
|
|
e716da04ec | ||
|
|
590d401e5f | ||
|
|
9bc197cfd5 | ||
|
|
d7e1869a70 | ||
|
|
3f15bf9828 | ||
|
|
9744aa21af | ||
|
|
91eda6dad4 | ||
|
|
8f957ef6e6 | ||
|
|
11bd5fc3b1 | ||
|
|
2222f10720 | ||
|
|
bc9006ff30 | ||
|
|
70ef09aa8f | ||
|
|
2cb2064c6f | ||
|
|
21617da619 | ||
|
|
628ca2a2ec | ||
|
|
46941e8b35 | ||
|
|
d1ce7bfff4 | ||
|
|
dd092e30fb | ||
|
|
5ac01a2bf7 | ||
|
|
43268bd350 | ||
|
|
2f64f0f5fa | ||
|
|
427172c941 | ||
|
|
41146657de | ||
|
|
092f6d3739 | ||
|
|
f41cff27e6 | ||
|
|
ea832b8157 | ||
|
|
fd39e6f3c8 | ||
|
|
8ea3bb0d90 | ||
|
|
45dce89cae | ||
|
|
bf8e331135 | ||
|
|
a6d78ef842 | ||
|
|
beb2f3c415 | ||
|
|
77b225e021 | ||
|
|
3f583b6dd2 | ||
|
|
d3e22ac09e | ||
|
|
f6b132f78e | ||
|
|
c7c141a5a0 | ||
|
|
f8458ed9e4 | ||
|
|
9a0db392de | ||
|
|
92309afea1 | ||
|
|
242218d2b7 | ||
|
|
c050c6945c | ||
|
|
52ac483368 | ||
|
|
c443c9f05d | ||
|
|
78baebfe0d | ||
|
|
f056974bc5 | ||
|
|
ff667695ad | ||
|
|
f849915c13 | ||
|
|
231c324589 | ||
|
|
f8f29677fd | ||
|
|
50312b54a0 | ||
|
|
e47bd4f477 | ||
|
|
ab64e323cd | ||
|
|
67dfd26639 | ||
|
|
54099e592e | ||
|
|
580f39a12c | ||
|
|
c9e96c15af | ||
|
|
de9eebe51c | ||
|
|
d54d6bc572 | ||
|
|
38830e54d8 | ||
|
|
1a77922e85 | ||
|
|
d0823adf42 | ||
|
|
80b902cea6 | ||
|
|
e5716e3b1e | ||
|
|
47605cae16 | ||
|
|
8a803a2310 | ||
|
|
e2149cb46f | ||
|
|
509bca36b1 | ||
|
|
cfb9310d13 | ||
|
|
4e006b0bc5 | ||
|
|
f5cbb9c7b9 | ||
|
|
336c9b23d6 | ||
|
|
dfeadf876e | ||
|
|
b9d158076e | ||
|
|
438088f69d | ||
|
|
80b2ba2b9a | ||
|
|
197901108e | ||
|
|
425f1df799 | ||
|
|
9bc2b66e14 | ||
|
|
d4e57a38a4 | ||
|
|
06b22e9ac1 | ||
|
|
07b713121b | ||
|
|
1b65575860 | ||
|
|
166b78f022 | ||
|
|
c79d14190f | ||
|
|
2e8e5354e9 | ||
|
|
290e066633 | ||
|
|
134d59949a | ||
|
|
2697e332f3 | ||
|
|
c72d08e8b9 | ||
|
|
ec46e51ed4 | ||
|
|
7419c4b577 | ||
|
|
914fd197fc | ||
|
|
8868ae22be | ||
|
|
ded8d11728 | ||
|
|
6c3618be37 | ||
|
|
6ef741554c | ||
|
|
668d04548a | ||
|
|
68a4146999 | ||
|
|
d4316f0264 | ||
|
|
4bcaeb312c | ||
|
|
e4434d3200 | ||
|
|
62b1dc777e | ||
|
|
799619b6b0 | ||
|
|
3ad045302b | ||
|
|
499fbe90dc | ||
|
|
c929e88b97 | ||
|
|
05885ca184 | ||
|
|
2967d7ed01 | ||
|
|
c872095d76 | ||
|
|
8054d962cf | ||
|
|
22cff25bf5 | ||
|
|
7faac85fff | ||
|
|
d32f08f6ec | ||
|
|
10fdf5a8c3 | ||
|
|
11cf44986b | ||
|
|
95d8fd38f5 | ||
|
|
cf9e986f82 | ||
|
|
fd39d6bd3c | ||
|
|
2e6db4d928 | ||
|
|
21833413b0 | ||
|
|
11355cd3c9 | ||
|
|
2b05e61d58 | ||
|
|
baacf51a00 | ||
|
|
85eeafdccc | ||
|
|
d6922b2de3 | ||
|
|
6ab630371d | ||
|
|
f1881065a8 | ||
|
|
fc1c00716c | ||
|
|
baabb07e00 | ||
|
|
7d868e41a6 | ||
|
|
a9c9b69c22 | ||
|
|
d112ee5244 | ||
|
|
3e43927767 | ||
|
|
60739847ab | ||
|
|
9012a9b414 | ||
|
|
4f939b82b6 | ||
|
|
2965f92be3 | ||
|
|
2a4328b4f5 | ||
|
|
d974bcd2fa | ||
|
|
d7ff9dca1d | ||
|
|
e7e29b7f10 | ||
|
|
84be137b4e | ||
|
|
1252c30edf | ||
|
|
1458d7fea6 | ||
|
|
7f8a259beb | ||
|
|
56e31d05e9 | ||
|
|
3c635e219e | ||
|
|
de278635a3 | ||
|
|
7e752c4ebf | ||
|
|
6163a397df | ||
|
|
1116f96aee | ||
|
|
491108a198 | ||
|
|
5096c45dec | ||
|
|
a896e52489 | ||
|
|
fd6b371dac | ||
|
|
c0f34f454b | ||
|
|
70aaff46be | ||
|
|
1a947dbf6a | ||
|
|
c70bbacd34 | ||
|
|
655f86d5e2 | ||
|
|
b9939a6449 | ||
|
|
6f50b3a5b2 | ||
|
|
ba3f0e6b70 | ||
|
|
6ccb6562f1 | ||
|
|
847f9f80c1 | ||
|
|
7ed4bfe7ee | ||
|
|
8fbc08f91f | ||
|
|
872bebbbf8 | ||
|
|
f8e6c44996 | ||
|
|
5d0c4361ab | ||
|
|
aaec42ebc2 | ||
|
|
95e13ea629 | ||
|
|
d44af40de8 | ||
|
|
2df0788c11 | ||
|
|
914b8463b7 | ||
|
|
7ba2a83182 | ||
|
|
554cf9be44 | ||
|
|
da2164373c | ||
|
|
c3a2204653 | ||
|
|
3ae9e91bcd | ||
|
|
d733b7d7d0 | ||
|
|
5e2d2059fe | ||
|
|
2558daf6b7 | ||
|
|
2f7cb82ca0 | ||
|
|
7dc113e977 | ||
|
|
579c8e68f9 | ||
|
|
e33a1e0515 | ||
|
|
bf4a974124 | ||
|
|
9a04da27b0 | ||
|
|
8de7c0245c | ||
|
|
17b2720f5b | ||
|
|
5d9196960e | ||
|
|
caab582943 | ||
|
|
1010a2a2a4 | ||
|
|
3da5574d79 | ||
|
|
6b651d734e | ||
|
|
e5f6b4d640 | ||
|
|
7e506af0b9 | ||
|
|
72fa958f2c | ||
|
|
641d88fd6b | ||
|
|
6d2f6c2e4d | ||
|
|
4a546e6c18 | ||
|
|
dc9744f353 | ||
|
|
dd8c0febd5 | ||
|
|
26df5b8c00 | ||
|
|
06f5ae0e78 | ||
|
|
b73321c577 | ||
|
|
b69ec059fe | ||
|
|
7379e4e5de | ||
|
|
bb326f2bbd | ||
|
|
34c218b2de | ||
|
|
382f5eb1b1 | ||
|
|
a6a93cbe06 | ||
|
|
a1637d8343 | ||
|
|
5cf3bdd593 | ||
|
|
3b3ab4d574 | ||
|
|
7d9452f4e4 | ||
|
|
6c6e45157b | ||
|
|
52cc08dd2d | ||
|
|
adbf8adfb9 | ||
|
|
78c81d9c6c | ||
|
|
c87c1dbbbf | ||
|
|
575ab3ab70 | ||
|
|
62f0722325 | ||
|
|
196b491ac4 | ||
|
|
dd351c585a | ||
|
|
8fd5b325e0 | ||
|
|
eba50c6860 | ||
|
|
592e8c2e77 | ||
|
|
5a27aead06 | ||
|
|
f03a73466c | ||
|
|
ca63cc6439 | ||
|
|
2890fa74a2 | ||
|
|
97c1bcf14f | ||
|
|
780f11ec16 | ||
|
|
5b266eff89 | ||
|
|
0f3d431476 | ||
|
|
b1daab4284 | ||
|
|
7bcb1cfc42 | ||
|
|
a0f8687945 | ||
|
|
03e7ec29e7 | ||
|
|
6e7db034f2 | ||
|
|
0650d8e155 | ||
|
|
ee9f9863ff | ||
|
|
9727a3fe50 | ||
|
|
df83191ea0 | ||
|
|
13218f7d76 | ||
|
|
bea7d9f919 | ||
|
|
1b43515160 | ||
|
|
48058a88e5 | ||
|
|
f7e42211b9 | ||
|
|
abd3419632 | ||
|
|
b5ed6823d6 | ||
|
|
f37eacdee5 | ||
|
|
9eb8680ec9 | ||
|
|
5fc5b68a49 | ||
|
|
0371d5a326 | ||
|
|
44b088c6b3 | ||
|
|
289400d944 | ||
|
|
21fc26c2a2 | ||
|
|
f6544e95d4 | ||
|
|
4f366e9c38 | ||
|
|
683b015951 | ||
|
|
0973161ae5 | ||
|
|
4ca3e8f70a | ||
|
|
7186131d65 | ||
|
|
1132502e14 | ||
|
|
ea573e2421 | ||
|
|
1fe1a47658 | ||
|
|
6cb14cfc04 | ||
|
|
89505522d3 | ||
|
|
550b0fab84 | ||
|
|
35a4e587ee | ||
|
|
e92b4737e3 | ||
|
|
94c6b7409b | ||
|
|
e9dbafcc10 | ||
|
|
854d335ab1 | ||
|
|
a5cb9ae8bd | ||
|
|
2fa8af3b02 | ||
|
|
67e2ef30c4 | ||
|
|
22baba2cff | ||
|
|
7273cb7f54 | ||
|
|
5a13087939 | ||
|
|
4157b64776 | ||
|
|
9e30969243 | ||
|
|
dbb5154f37 | ||
|
|
f7c7ff4aae | ||
|
|
65c4bd6db6 | ||
|
|
519cc09979 | ||
|
|
5ae39ae79a | ||
|
|
a854ea00a5 | ||
|
|
e97f587411 | ||
|
|
17e5f4132c |
19
.travis.yml
19
.travis.yml
@@ -51,8 +51,17 @@ before_script:
|
||||
- bench start &
|
||||
- sleep 10
|
||||
|
||||
script:
|
||||
- set -e
|
||||
- bench --verbose run-tests
|
||||
- sleep 5
|
||||
- bench --verbose run-ui-tests --app erpnext
|
||||
jobs:
|
||||
include:
|
||||
- stage: test
|
||||
script:
|
||||
- set -e
|
||||
- bench run-tests
|
||||
env: Server Side Test
|
||||
- # stage
|
||||
script:
|
||||
- bench --verbose run-setup-wizard-ui-test
|
||||
- bench execute erpnext.setup.utils.enable_all_roles_and_domains
|
||||
- bench run-ui-tests --app erpnext
|
||||
env: Client Side Test
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import inspect
|
||||
import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
|
||||
__version__ = '8.9.1'
|
||||
__version__ = '8.11.6'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"editable_grid": 0,
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -42,6 +43,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -70,6 +72,7 @@
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -100,6 +103,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -130,6 +134,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -161,6 +166,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -190,6 +196,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -219,6 +226,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -250,6 +258,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -278,6 +287,7 @@
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -309,6 +319,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -341,6 +352,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -372,6 +384,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -404,6 +417,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -433,6 +447,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -461,6 +476,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -489,6 +505,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -528,7 +545,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-04-21 17:22:41.150984",
|
||||
"modified": "2017-08-11 15:28:35.855809",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Account",
|
||||
@@ -641,6 +658,6 @@
|
||||
"search_fields": "",
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_order": "ASC",
|
||||
"track_changes": 0,
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -78,6 +78,7 @@ def get_chart(chart_template, existing_company=None):
|
||||
for folder in folders:
|
||||
path = os.path.join(os.path.dirname(__file__), folder)
|
||||
for fname in os.listdir(path):
|
||||
fname = frappe.as_unicode(fname)
|
||||
if fname.endswith(".json"):
|
||||
with open(os.path.join(path, fname), "r") as f:
|
||||
chart = f.read()
|
||||
@@ -105,6 +106,7 @@ def get_charts_for_country(country):
|
||||
path = os.path.join(os.path.dirname(__file__), folder)
|
||||
|
||||
for fname in os.listdir(path):
|
||||
fname = frappe.as_unicode(fname)
|
||||
if (fname.startswith(country_code) or fname.startswith(country)) and fname.endswith(".json"):
|
||||
with open(os.path.join(path, fname), "r") as f:
|
||||
_get_chart_name(f.read())
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"""
|
||||
Import chart of accounts from OpenERP sources
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import os, json
|
||||
import ast
|
||||
@@ -229,7 +229,7 @@ def make_charts():
|
||||
|
||||
filename = src["id"][5:] + "_" + chart_id
|
||||
|
||||
print "building " + filename
|
||||
print("building " + filename)
|
||||
chart = {}
|
||||
chart["name"] = src["name"]
|
||||
chart["country_code"] = src["id"][5:]
|
||||
|
||||
@@ -1607,4 +1607,4 @@
|
||||
"root_type": "Income"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,722 @@
|
||||
{
|
||||
"country_code": "tw",
|
||||
"name": "Taiwan - Chart of Accounts",
|
||||
"tree": {
|
||||
"1-\u8cc7\u7522": {
|
||||
"11~12-\u6d41\u52d5\u8cc7\u7522": {
|
||||
"111-\u73fe\u91d1\u53ca\u7d04\u7576\u73fe\u91d1": {
|
||||
"1111-\u5eab\u5b58\u73fe\u91d1": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"1112-\u96f6\u7528\u91d1/\u9031\u8f49\u91d1": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"1113-\u9280\u884c\u5b58\u6b3e": {
|
||||
"account_type": "Bank",
|
||||
"\u4e2d\u570b\u4fe1\u8a17": {
|
||||
"account_type": "Bank"
|
||||
},
|
||||
"\u53f0\u5317\u5bcc\u90a6": {
|
||||
"account_type": "Bank"
|
||||
}
|
||||
},
|
||||
"1116-\u5728\u9014\u73fe\u91d1": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"1117-\u7d04\u7576\u73fe\u91d1": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"1118-\u5176\u4ed6\u73fe\u91d1\u53ca\u7d04\u7576\u73fe\u91d1": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"112-\u77ed\u671f\u6295\u8cc7": {
|
||||
"1121-\u77ed\u671f\u6295\u8cc7 \u2014\u80a1\u7968": {}
|
||||
},
|
||||
"113-\u61c9\u6536\u7968\u64da": {
|
||||
"1131-\u61c9\u6536\u7968\u64da": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1132-\u61c9\u6536\u7968\u64da\u8cbc\u73fe ": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1138-\u5176\u4ed6\u61c9\u6536\u7968\u64da ": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1139-\u5099\u62b5\u5446\u5e33 \uff0d\u61c9\u6536\u7968\u64da ": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"114-\u61c9\u6536\u5e33\u6b3e": {
|
||||
"1141-\u61c9\u6536\u5e33\u6b3e ": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1142-\u61c9\u6536\u5206\u671f\u5e33\u6b3e ": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1149-\u5099\u62b5\u5446\u5e33 \uff0d\u61c9\u6536\u5e33\u6b3e ": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"118-\u5176\u4ed6\u61c9\u6536\u6b3e": {
|
||||
"1184-\u61c9\u6536\u6536\u76ca": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1185-\u61c9\u6536\u9000\u7a05\u6b3e": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1189-\u5099\u62b5\u5446\u5e33 \u2014 \u5176\u4ed6\u61c9\u6536\u6b3e ": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"121~122-\u5b58\u8ca8": {
|
||||
"1219-\u5099\u62b5\u5b58\u8ca8\u8dcc\u50f9\u640d\u5931": {},
|
||||
"1229-\u5099\u62b5\u5b58\u8ca8\u8dcc\u50f9\u640d\u5931": {},
|
||||
"account_type": "Stock",
|
||||
"is_group": 1
|
||||
},
|
||||
"125-\u9810\u4ed8\u8cbb\u7528": {
|
||||
"1251-\u9810\u4ed8\u85aa\u8cc7": {},
|
||||
"1252-\u9810\u4ed8\u79df\u91d1": {},
|
||||
"1253-\u9810\u4ed8\u4fdd\u96aa\u8cbb": {},
|
||||
"1254-\u7528\u54c1\u76e4\u5b58": {},
|
||||
"1255-\u9810\u4ed8\u6240\u5f97\u7a05": {},
|
||||
"1258-\u5176\u4ed6\u9810\u4ed8\u8cbb\u7528": {}
|
||||
},
|
||||
"126-\u9810\u4ed8\u6b3e\u9805": {
|
||||
"1261-\u9810\u4ed8\u8ca8\u6b3e": {},
|
||||
"1268-\u5176\u4ed6\u9810\u4ed8\u6b3e\u9805": {}
|
||||
},
|
||||
"128~129-\u5176\u4ed6\u6d41\u52d5\u8cc7\u7522": {
|
||||
"1281-\u9032\u9805\u7a05\u984d": {},
|
||||
"1282-\u7559\u62b5\u7a05\u984d": {},
|
||||
"1283-\u66ab\u4ed8\u6b3e": {},
|
||||
"1284-\u4ee3\u4ed8\u6b3e": {},
|
||||
"1285-\u54e1\u5de5\u501f\u652f": {}
|
||||
}
|
||||
},
|
||||
"13-\u57fa\u91d1\u53ca\u9577\u671f\u6295\u8cc7": {
|
||||
"131-\u57fa\u91d1": {
|
||||
"1311-\u511f\u50b5\u57fa\u91d1": {},
|
||||
"1313-\u610f\u5916\u640d\u5931\u6e96\u5099\u57fa\u91d1": {},
|
||||
"1314-\u9000\u4f11\u57fa\u91d1": {},
|
||||
"1318-\u5176\u4ed6\u57fa\u91d1": {}
|
||||
},
|
||||
"132-\u9577\u671f\u6295\u8cc7": {
|
||||
"1321-\u9577\u671f\u80a1\u6b0a\u6295\u8cc7": {},
|
||||
"1322-\u9577\u671f\u50b5\u5238\u6295\u8cc7": {},
|
||||
"1323-\u9577\u671f\u4e0d\u52d5\u7522\u6295\u8cc7": {},
|
||||
"1328-\u5176\u4ed6\u9577\u671f\u6295\u8cc7": {}
|
||||
}
|
||||
},
|
||||
"14~15-\u56fa\u5b9a\u8cc7\u7522": {
|
||||
"141-\u571f\u5730": {
|
||||
"1411-\u571f\u5730": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"142-\u571f\u5730\u6539\u826f\u7269": {
|
||||
"1421-\u571f\u5730\u6539\u826f\u7269": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"143-\u623f\u5c4b\u53ca\u5efa\u7269": {
|
||||
"1431-\u623f\u5c4b\u53ca\u5efa\u7269": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"144~146-\u6a5f(\u5668)\u5177\u53ca\u8a2d\u5099": {
|
||||
"1441-\u6a5f(\u5668)\u5177": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"151-\u79df\u8cc3\u8cc7\u7522": {
|
||||
"1511-\u79df\u8cc3\u8cc7\u7522": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"152-\u79df\u8cc3\u6b0a\u76ca\u6539\u826f": {
|
||||
"1521-\u79df\u8cc3\u6b0a\u76ca\u6539\u826f": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"156-\u672a\u5b8c\u5de5\u7a0b\u53ca\u9810\u4ed8\u8cfc\u7f6e\u8a2d\u5099\u6b3e": {
|
||||
"1561-\u672a\u5b8c\u5de5\u7a0b": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"158-\u96dc\u9805\u56fa\u5b9a\u8cc7\u7522": {
|
||||
"1581-\u96dc\u9805\u56fa\u5b9a\u8cc7\u7522": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"16-\u905e\u8017\u8cc7\u7522": {
|
||||
"161-\u905e\u8017\u8cc7\u7522": {
|
||||
"is_group": 1
|
||||
}
|
||||
},
|
||||
"17-\u7121\u5f62\u8cc7\u7522": {
|
||||
"171-\u5546\u6a19\u6b0a": {
|
||||
"1711-\u5546\u6a19\u6b0a": {}
|
||||
},
|
||||
"172-\u5c08\u5229\u6b0a": {
|
||||
"1721-\u5c08\u5229\u6b0a": {}
|
||||
},
|
||||
"176-\u5546\u8b7d": {
|
||||
"1761-\u5546\u8b7d": {}
|
||||
},
|
||||
"177-\u958b\u8fa6\u8cbb": {
|
||||
"1771-\u958b\u8fa6\u8cbb": {}
|
||||
},
|
||||
"178-\u5176\u4ed6\u7121\u5f62\u8cc7\u7522": {
|
||||
"1781-\u905e\u5ef6\u9000\u4f11\u91d1\u6210\u672c": {}
|
||||
}
|
||||
},
|
||||
"18-\u5176\u4ed6\u8cc7\u7522": {
|
||||
"181-\u905e\u5ef6\u8cc7\u7522": {
|
||||
"1811-\u50b5\u5238\u767c\u884c\u6210\u672c": {},
|
||||
"1812-\u9577\u671f\u9810\u4ed8\u79df\u91d1": {},
|
||||
"1813-\u9577\u671f\u9810\u4ed8\u4fdd\u96aa\u8cbb": {},
|
||||
"1814-\u905e\u5ef6\u6240\u5f97\u7a05\u8cc7\u7522": {},
|
||||
"1815-\u9810\u4ed8\u9000\u4f11\u91d1": {},
|
||||
"1818-\u5176\u4ed6\u905e\u5ef6\u8cc7\u7522": {}
|
||||
},
|
||||
"182-\u9592\u7f6e\u8cc7\u7522": {
|
||||
"1821-\u9592\u7f6e\u8cc7\u7522": {}
|
||||
},
|
||||
"184-\u9577\u671f\u61c9\u6536\u7968\u64da\u53ca\u6b3e\u9805\u8207\u50ac\u6536\u5e33\u6b3e": {
|
||||
"1841-\u9577\u671f\u61c9\u6536\u7968\u64da": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1842-\u9577\u671f\u61c9\u6536\u5e33\u6b3e": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1843-\u50ac\u6536\u5e33\u6b3e": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1848-\u5176\u4ed6\u9577\u671f\u61c9\u6536\u6b3e\u9805": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1849-\u5099\u62b5\u5446\u5e33\u2014\u9577\u671f\u61c9\u6536\u7968\u64da\u53ca\u6b3e\u9805\u8207\u50ac\u6536\u5e33\u6b3e": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"185-\u51fa\u79df\u8cc7\u7522": {
|
||||
"1851-\u51fa\u79df\u8cc7\u7522": {},
|
||||
"1858-\u51fa\u79df\u8cc7\u7522 \u2014\u91cd\u4f30\u589e\u503c": {},
|
||||
"1859-\u7d2f\u7a4d\u6298\u820a \u2014\u51fa\u79df\u8cc7\u7522": {
|
||||
"account_type": "Accumulated Depreciation"
|
||||
}
|
||||
},
|
||||
"186-\u5b58\u51fa\u4fdd\u8b49\u91d1": {
|
||||
"1861-\u5b58\u51fa\u4fdd\u8b49\u91d1": {}
|
||||
},
|
||||
"188-\u96dc\u9805\u8cc7\u7522": {
|
||||
"1881-\u53d7\u9650\u5236\u5b58\u6b3e": {},
|
||||
"1888-\u96dc\u9805\u8cc7\u7522 \u2014\u5176\u4ed6": {}
|
||||
}
|
||||
},
|
||||
"Temporary Accounts": {
|
||||
"Temporary Opening": {
|
||||
"account_type": "Temporary"
|
||||
},
|
||||
"account_type": "Temporary"
|
||||
},
|
||||
"root_type": "Asset"
|
||||
},
|
||||
"2-\u8ca0\u50b5": {
|
||||
"21~22-\u6d41\u52d5\u8ca0\u50b5": {
|
||||
"211-\u77ed\u671f\u501f\u6b3e": {
|
||||
"2111-\u9280\u884c\u900f\u652f": {},
|
||||
"2112-\u9280\u884c\u501f\u6b3e": {}
|
||||
},
|
||||
"212-\u61c9\u4ed8\u77ed\u671f\u7968\u5238": {
|
||||
"2121-\u61c9\u4ed8\u5546\u696d\u672c\u7968": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"2122-\u9280\u884c\u627f\u514c\u532f\u7968": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"213-\u61c9\u4ed8\u7968\u64da": {
|
||||
"2131-\u61c9\u4ed8\u7968\u64da": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"214-\u61c9\u4ed8\u5e33\u6b3e": {
|
||||
"2141-\u61c9\u4ed8\u5e33\u6b3e": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"216-\u61c9\u4ed8\u6240\u5f97\u7a05": {
|
||||
"2161-\u61c9\u4ed8\u6240\u5f97\u7a05": {
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 5.0
|
||||
},
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 5.0
|
||||
},
|
||||
"217-\u61c9\u4ed8\u8cbb\u7528": {
|
||||
"2171-\u61c9\u4ed8\u85aa\u5de5": {},
|
||||
"2172-\u61c9\u4ed8\u79df\u91d1": {},
|
||||
"2173-\u61c9\u4ed8\u5229\u606f": {},
|
||||
"2174-\u61c9\u4ed8\u71df\u696d\u7a05": {},
|
||||
"2175-\u61c9\u4ed8\u7a05\u6350 \u2014\u5176\u4ed6": {
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 5.0
|
||||
},
|
||||
"2178-\u5176\u4ed6\u61c9\u4ed8\u8cbb\u7528": {}
|
||||
},
|
||||
"218~219-\u5176\u4ed6\u61c9\u4ed8\u6b3e": {
|
||||
"2184-\u61c9\u4ed8\u571f\u5730\u623f\u5c4b\u6b3e": {},
|
||||
"2185-\u61c9\u4ed8\u8a2d\u5099\u6b3e": {},
|
||||
"2192-\u61c9\u4ed8\u80a1\u5229": {}
|
||||
},
|
||||
"226-\u9810\u6536\u6b3e\u9805": {
|
||||
"2261-\u9810\u6536\u8ca8\u6b3e": {},
|
||||
"2262-\u9810\u6536\u6536\u5165": {},
|
||||
"2268-\u5176\u4ed6\u9810\u6536\u6b3e": {}
|
||||
},
|
||||
"227-\u4e00\u5e74\u6216\u4e00\u71df\u696d\u9031\u671f\u5167\u5230\u671f\u9577\u671f\u8ca0\u50b5": {
|
||||
"is_group": 1
|
||||
},
|
||||
"228~229-\u5176\u4ed6\u6d41\u52d5\u8ca0\u50b5": {
|
||||
"2281-\u92b7\u9805\u7a05\u984d": {},
|
||||
"2283-\u66ab\u6536\u6b3e ": {},
|
||||
"2284-\u4ee3\u6536\u6b3e": {},
|
||||
"2285-\u4f30\u8a08\u552e\u5f8c\u670d\u52d9/\u4fdd\u56fa\u8ca0\u50b5": {},
|
||||
"2291-\u905e\u5ef6\u6240\u5f97\u7a05\u8ca0\u50b5": {},
|
||||
"2292-\u905e\u5ef6\u514c\u63db\u5229\u76ca": {}
|
||||
}
|
||||
},
|
||||
"23-\u9577\u671f\u8ca0\u50b5": {
|
||||
"231-\u61c9\u4ed8\u516c\u53f8\u50b5": {
|
||||
"2311-\u61c9\u4ed8\u516c\u53f8\u50b5": {},
|
||||
"2319-\u61c9\u4ed8\u516c\u53f8\u50b5\u6ea2(\u6298)\u50f9": {}
|
||||
},
|
||||
"232-\u9577\u671f\u501f\u6b3e": {
|
||||
"2321-\u9577\u671f\u9280\u884c\u501f\u6b3e": {},
|
||||
"2324-\u9577\u671f\u501f\u6b3e \u2014\u696d\u4e3b": {},
|
||||
"2325-\u9577\u671f\u501f\u6b3e \u2014\u54e1\u5de5": {},
|
||||
"2327-\u9577\u671f\u501f\u6b3e \u2014\u95dc\u4fc2\u4eba": {},
|
||||
"2328-\u9577\u671f\u501f\u6b3e \u2014\u5176\u4ed6": {}
|
||||
},
|
||||
"233-\u9577\u671f\u61c9\u4ed8\u7968\u64da\u53ca\u6b3e\u9805": {
|
||||
"2331-\u9577\u671f\u61c9\u4ed8\u7968\u64da": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"2332-\u9577\u671f\u61c9\u4ed8\u5e33\u6b3e": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"2333-\u9577\u671f\u61c9\u4ed8\u79df\u8cc3\u8ca0\u50b5": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"234-\u4f30\u8a08\u61c9\u4ed8\u571f\u5730\u589e\u503c\u7a05": {
|
||||
"2341-\u4f30\u8a08\u61c9\u4ed8\u571f\u5730\u589e\u503c\u7a05": {}
|
||||
},
|
||||
"235-\u61c9\u8a08\u9000\u4f11\u91d1\u8ca0\u50b5": {
|
||||
"2351-\u61c9\u8a08\u9000\u4f11\u91d1\u8ca0\u50b5": {}
|
||||
},
|
||||
"238-\u5176\u4ed6\u9577\u671f\u8ca0\u50b5": {
|
||||
"2388-\u5176\u4ed6\u9577\u671f\u8ca0\u50b5\u2014\u5176\u4ed6": {}
|
||||
}
|
||||
},
|
||||
"28-\u5176\u4ed6\u8ca0\u50b5": {
|
||||
"281-\u905e\u5ef6\u8ca0\u50b5": {
|
||||
"2811-\u905e\u5ef6\u6536\u5165": {},
|
||||
"2814-\u905e\u5ef6\u6240\u5f97\u7a05\u8ca0\u50b5": {},
|
||||
"2818-\u5176\u4ed6\u905e\u5ef6\u8ca0\u50b5": {}
|
||||
},
|
||||
"286-\u5b58\u5165\u4fdd\u8b49\u91d1": {
|
||||
"2861-\u5b58\u5165\u4fdd\u8b49\u91d1": {}
|
||||
},
|
||||
"288-\u96dc\u9805\u8ca0\u50b5": {
|
||||
"2888-\u96dc\u9805\u8ca0\u50b5 \u2014\u5176\u4ed6": {}
|
||||
}
|
||||
},
|
||||
"Stock Received But Not Billed": {
|
||||
"account_type": "Stock Received But Not Billed"
|
||||
},
|
||||
"root_type": "Liability"
|
||||
},
|
||||
"3-\u696d\u4e3b\u6b0a\u76ca": {
|
||||
"31-\u8cc7\u672c": {
|
||||
"311-\u8cc7\u672c\uff08\u80a1\u672c\uff09 ": {
|
||||
"3111-\u666e\u901a\u80a1\u80a1\u672c": {},
|
||||
"3112-\u7279\u5225\u80a1\u80a1\u672c": {},
|
||||
"3113-\u9810\u6536\u80a1\u672c": {},
|
||||
"3114-\u5f85\u5206\u914d\u80a1\u7968\u80a1\u5229": {},
|
||||
"3115-\u8cc7\u672c": {}
|
||||
}
|
||||
},
|
||||
"32-\u8cc7\u672c\u516c\u7a4d": {
|
||||
"321-\u80a1\u7968\u6ea2\u50f9": {
|
||||
"3211-\u666e\u901a\u80a1\u80a1\u7968\u6ea2\u50f9": {},
|
||||
"3212-\u7279\u5225\u80a1\u80a1\u7968\u6ea2\u50f9": {}
|
||||
},
|
||||
"323-\u8cc7\u7522\u91cd\u4f30\u589e\u503c\u6e96\u5099": {
|
||||
"3231-\u8cc7\u7522\u91cd\u4f30\u589e\u503c\u6e96\u5099": {}
|
||||
},
|
||||
"324-\u8655\u5206\u8cc7\u7522\u6ea2\u50f9\u516c\u7a4d": {
|
||||
"3241-\u8655\u5206\u8cc7\u7522\u6ea2\u50f9\u516c\u7a4d": {}
|
||||
},
|
||||
"325-\u5408\u4f75\u516c\u7a4d": {
|
||||
"3251-\u5408\u4f75\u516c\u7a4d": {}
|
||||
},
|
||||
"326-\u53d7\u8d08\u516c\u7a4d": {
|
||||
"3261-\u53d7\u8d08\u516c\u7a4d": {}
|
||||
},
|
||||
"328-\u5176\u4ed6\u8cc7\u672c\u516c\u7a4d": {
|
||||
"3281-\u6b0a\u76ca\u6cd5\u9577\u671f\u80a1\u6b0a\u6295\u8cc7\u8cc7\u672c\u516c\u7a4d": {},
|
||||
"3282-\u8cc7\u672c\u516c\u7a4d\u2014 \u5eab\u85cf\u80a1\u7968\u4ea4\u6613": {}
|
||||
}
|
||||
},
|
||||
"33-\u4fdd\u7559\u76c8\u9918(\u7d2f\u7a4d\u8667\u640d)": {
|
||||
"331-\u6cd5\u5b9a\u76c8\u9918\u516c\u7a4d": {
|
||||
"3311-\u6cd5\u5b9a\u76c8\u9918\u516c\u7a4d": {}
|
||||
},
|
||||
"332-\u7279\u5225\u76c8\u9918\u516c\u7a4d": {
|
||||
"3321-\u610f\u5916\u640d\u5931\u6e96\u5099": {},
|
||||
"3322-\u6539\u826f\u64f4\u5145\u6e96\u5099": {},
|
||||
"3323-\u511f\u50b5\u6e96\u5099": {},
|
||||
"3328-\u5176\u4ed6\u7279\u5225\u76c8\u9918\u516c\u7a4d": {}
|
||||
},
|
||||
"335-\u672a\u5206\u914d\u76c8\u9918(\u7d2f\u7a4d\u8667\u640d) ": {
|
||||
"is_group": 1
|
||||
}
|
||||
},
|
||||
"34-\u6b0a\u76ca\u8abf\u6574": {
|
||||
"341-\u9577\u671f\u80a1\u6b0a\u6295\u8cc7\u672a\u5be6\u73fe\u8dcc\u50f9\u640d\u5931": {
|
||||
"3411-\u9577\u671f\u80a1\u6b0a\u6295\u8cc7\u672a\u5be6\u73fe\u8dcc\u50f9\u640d\u5931": {}
|
||||
},
|
||||
"342-\u7d2f\u7a4d\u63db\u7b97\u8abf\u6574\u6578": {
|
||||
"3421-\u7d2f\u7a4d\u63db\u7b97\u8abf\u6574\u6578": {}
|
||||
},
|
||||
"343-\u672a\u8a8d\u5217\u70ba\u9000\u4f11\u91d1\u6210\u672c\u4e4b\u6de8\u640d\u5931": {
|
||||
"3431-\u672a\u8a8d\u5217\u70ba\u9000\u4f11\u91d1\u6210\u672c\u4e4b\u6de8\u640d\u5931": {}
|
||||
}
|
||||
},
|
||||
"35-\u5eab\u85cf\u80a1": {
|
||||
"351-\u5eab\u85cf\u80a1": {
|
||||
"3511-\u5eab\u85cf\u80a1": {}
|
||||
}
|
||||
},
|
||||
"36-\u5c11\u6578\u80a1\u6b0a": {
|
||||
"361-\u5c11\u6578\u80a1\u6b0a": {
|
||||
"3611-\u5c11\u6578\u80a1\u6b0a": {}
|
||||
}
|
||||
},
|
||||
"root_type": "Equity"
|
||||
},
|
||||
"4-\u71df\u696d\u6536\u5165": {
|
||||
"41-\u92b7\u8ca8\u6536\u5165": {
|
||||
"411-\u92b7\u8ca8\u6536\u5165": {
|
||||
"4111-\u92b7\u8ca8\u6536\u5165": {},
|
||||
"4112-\u5206\u671f\u4ed8\u6b3e\u92b7\u8ca8\u6536\u5165": {}
|
||||
},
|
||||
"417-\u92b7\u8ca8\u9000\u56de": {
|
||||
"4171-\u92b7\u8ca8\u9000\u56de": {}
|
||||
},
|
||||
"419-\u92b7\u8ca8\u6298\u8b93": {
|
||||
"4191-\u92b7\u8ca8\u6298\u8b93": {}
|
||||
}
|
||||
},
|
||||
"46-\u52de\u52d9\u6536\u5165": {
|
||||
"461-\u52de\u52d9\u6536\u5165": {
|
||||
"4611-\u52de\u52d9\u6536\u5165": {}
|
||||
}
|
||||
},
|
||||
"47-\u696d\u52d9\u6536\u5165": {
|
||||
"471-\u696d\u52d9\u6536\u5165": {
|
||||
"4711-\u696d\u52d9\u6536\u5165": {}
|
||||
}
|
||||
},
|
||||
"48-\u5176\u4ed6\u71df\u696d\u6536\u5165": {
|
||||
"488-\u5176\u4ed6\u71df\u696d\u6536\u5165\u2014\u5176\u4ed6": {
|
||||
"4888-\u5176\u4ed6\u71df\u696d\u6536\u5165\u2014\u5176\u4ed6": {}
|
||||
}
|
||||
},
|
||||
"root_type": "Income"
|
||||
},
|
||||
"5-\u71df\u696d\u6210\u672c": {
|
||||
"51-\u92b7\u8ca8\u6210\u672c": {
|
||||
"511-\u92b7\u8ca8\u6210\u672c": {
|
||||
"5111-\u92b7\u8ca8\u6210\u672c": {
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"5112-\u5206\u671f\u4ed8\u6b3e\u92b7\u8ca8\u6210\u672c": {
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"512-\u9032\u8ca8": {
|
||||
"5121-\u9032\u8ca8": {},
|
||||
"5122-\u9032\u8ca8\u8cbb\u7528": {},
|
||||
"5123-\u9032\u8ca8\u9000\u51fa": {},
|
||||
"5124-\u9032\u8ca8\u6298\u8b93": {}
|
||||
},
|
||||
"513-\u9032\u6599": {
|
||||
"5131-\u9032\u6599": {},
|
||||
"5132-\u9032\u6599\u8cbb\u7528": {},
|
||||
"5133-\u9032\u6599\u9000\u51fa": {},
|
||||
"5134-\u9032\u6599\u6298\u8b93": {}
|
||||
},
|
||||
"514-\u76f4\u63a5\u4eba\u5de5": {
|
||||
"5141-\u76f4\u63a5\u4eba\u5de5": {}
|
||||
},
|
||||
"515~518-\u88fd\u9020\u8cbb\u7528": {
|
||||
"5151-\u9593\u63a5\u4eba\u5de5": {},
|
||||
"5152-\u79df\u91d1\u652f\u51fa": {},
|
||||
"5153-\u6587\u5177\u7528\u54c1": {},
|
||||
"5154-\u65c5\u8cbb": {},
|
||||
"5155-\u904b\u8cbb": {},
|
||||
"5156-\u90f5\u96fb\u8cbb": {},
|
||||
"5157-\u4fee\u7e55\u8cbb": {},
|
||||
"5158-\u5305\u88dd\u8cbb": {},
|
||||
"5161-\u6c34\u96fb\u74e6\u65af\u8cbb": {},
|
||||
"5162-\u4fdd\u96aa\u8cbb": {},
|
||||
"5163-\u52a0\u5de5\u8cbb": {},
|
||||
"5166-\u7a05\u6350": {
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 5.0
|
||||
},
|
||||
"5168-\u6298\u820a ": {
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"5169-\u5404\u9805\u8017\u7aed\u53ca\u6524\u63d0": {},
|
||||
"5172-\u4f19\u98df\u8cbb": {},
|
||||
"5173-\u8077\u5de5\u798f\u5229": {},
|
||||
"5176-\u8a13\u7df4\u8cbb": {},
|
||||
"5177-\u9593\u63a5\u6750\u6599": {},
|
||||
"5188-\u5176\u4ed6\u88fd\u9020\u8cbb\u7528": {}
|
||||
},
|
||||
"Expenses Included In Valuation": {
|
||||
"account_type": "Expenses Included In Valuation"
|
||||
},
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"56-\u52de\u52d9\u6210\u672c\u88fd": {
|
||||
"561-\u52de\u52d9\u6210\u672c": {
|
||||
"5611-\u52de\u52d9\u6210\u672c": {}
|
||||
}
|
||||
},
|
||||
"57-\u696d\u52d9\u6210\u672c": {
|
||||
"571-\u696d\u52d9\u6210\u672c": {
|
||||
"5711-\u696d\u52d9\u6210\u672c": {}
|
||||
}
|
||||
},
|
||||
"58-\u5176\u4ed6\u71df\u696d\u6210\u672c": {
|
||||
"588-\u5176\u4ed6\u71df\u696d\u6210\u672c\u2014\u5176\u4ed6 ": {
|
||||
"5888-\u5176\u4ed6\u71df\u696d\u6210\u672c\u2014\u5176\u4ed6": {}
|
||||
}
|
||||
},
|
||||
"Stock Adjustment": {
|
||||
"account_type": "Stock Adjustment"
|
||||
},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"6-\u71df\u696d\u8cbb\u7528": {
|
||||
"61-\u63a8\u92b7\u8cbb\u7528": {
|
||||
"615~618-\u63a8\u92b7\u8cbb\u7528": {
|
||||
"6151-\u85aa\u8cc7\u652f\u51fa": {},
|
||||
"6152-\u79df\u91d1\u652f\u51fa": {},
|
||||
"6153-\u6587\u5177\u7528\u54c1": {},
|
||||
"6154-\u65c5\u8cbb": {},
|
||||
"6155-\u904b\u8cbb": {},
|
||||
"6156-\u90f5\u96fb\u8cbb": {},
|
||||
"6157-\u4fee\u7e55\u8cbb": {},
|
||||
"6159-\u5ee3\u544a\u8cbb": {},
|
||||
"6161-\u6c34\u96fb\u74e6\u65af\u8cbb": {},
|
||||
"6162-\u4fdd\u96aa\u8cbb": {},
|
||||
"6164-\u4ea4\u969b\u8cbb": {},
|
||||
"6165-\u6350\u8d08": {},
|
||||
"6166-\u7a05\u6350": {
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 5.0
|
||||
},
|
||||
"6167-\u5446\u5e33\u640d\u5931": {},
|
||||
"6168-\u6298\u820a ": {
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"6169-\u5404\u9805\u8017\u7aed\u53ca\u6524\u63d0": {},
|
||||
"6172-\u4f19\u98df\u8cbb": {},
|
||||
"6173-\u8077\u5de5\u798f\u5229": {},
|
||||
"6175-\u4f63\u91d1\u652f\u51fa": {},
|
||||
"6176-\u8a13\u7df4\u8cbb": {},
|
||||
"6188-\u5176\u4ed6\u63a8\u92b7\u8cbb\u7528": {}
|
||||
}
|
||||
},
|
||||
"62-\u7ba1\u7406\u53ca\u7e3d\u52d9\u8cbb\u7528": {
|
||||
"625~628-\u7ba1\u7406\u53ca\u7e3d\u52d9\u8cbb\u7528": {
|
||||
"6251-\u85aa\u8cc7\u652f\u51fa": {},
|
||||
"6252-\u79df\u91d1\u652f\u51fa": {},
|
||||
"6253-\u6587\u5177\u7528\u54c1": {},
|
||||
"6254-\u65c5\u8cbb": {},
|
||||
"6255-\u904b\u8cbb": {},
|
||||
"6256-\u90f5\u96fb\u8cbb": {},
|
||||
"6257-\u4fee\u7e55\u8cbb": {},
|
||||
"6259-\u5ee3\u544a\u8cbb": {},
|
||||
"6261-\u6c34\u96fb\u74e6\u65af\u8cbb": {},
|
||||
"6262-\u4fdd\u96aa\u8cbb": {},
|
||||
"6264-\u4ea4\u969b\u8cbb": {},
|
||||
"6265-\u6350\u8d08": {},
|
||||
"6266-\u7a05\u6350": {
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 5.0
|
||||
},
|
||||
"6267-\u5446\u5e33\u640d\u5931": {},
|
||||
"6268-\u6298\u820a": {
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"6269-\u5404\u9805\u8017\u7aed\u53ca\u6524\u63d0": {},
|
||||
"6271-\u5916\u92b7\u640d\u5931": {},
|
||||
"6272-\u4f19\u98df\u8cbb": {},
|
||||
"6273-\u8077\u5de5\u798f\u5229": {},
|
||||
"6274-\u7814\u7a76\u767c\u5c55\u8cbb\u7528": {},
|
||||
"6275-\u4f63\u91d1\u652f\u51fa": {},
|
||||
"6276-\u8a13\u7df4\u8cbb": {},
|
||||
"6278-\u52de\u52d9\u8cbb": {},
|
||||
"6288-\u5176\u4ed6\u7ba1\u7406\u53ca\u7e3d\u52d9\u8cbb\u7528": {}
|
||||
}
|
||||
},
|
||||
"63-\u7814\u7a76\u767c\u5c55\u8cbb\u7528": {
|
||||
"635~638-\u7814\u7a76\u767c\u5c55\u8cbb\u7528": {
|
||||
"6351-\u85aa\u8cc7\u652f\u51fa": {},
|
||||
"6352-\u79df\u91d1\u652f\u51fa": {},
|
||||
"6353-\u6587\u5177\u7528\u54c1": {},
|
||||
"6354-\u65c5\u8cbb": {},
|
||||
"6355-\u904b\u8cbb": {},
|
||||
"6356-\u90f5\u96fb\u8cbb": {},
|
||||
"6357-\u4fee\u7e55\u8cbb": {},
|
||||
"6361-\u6c34\u96fb\u74e6\u65af\u8cbb": {},
|
||||
"6362-\u4fdd\u96aa\u8cbb": {},
|
||||
"6364-\u4ea4\u969b\u8cbb": {},
|
||||
"6366-\u7a05\u6350": {
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 5.0
|
||||
},
|
||||
"6368-\u6298\u820a": {
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"6369-\u5404\u9805\u8017\u7aed\u53ca\u6524\u63d0": {},
|
||||
"6372-\u4f19\u98df\u8cbb": {},
|
||||
"6373-\u8077\u5de5\u798f\u5229": {},
|
||||
"6376-\u8a13\u7df4\u8cbb": {},
|
||||
"6378-\u5176\u4ed6\u7814\u7a76\u767c\u5c55\u8cbb\u7528": {}
|
||||
}
|
||||
},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"7-\u71df\u696d\u5916\u6536\u5165\u53ca\u8cbb\u7528": {
|
||||
"71~74-\u71df\u696d\u5916\u6536\u5165": {
|
||||
"711-\u5229\u606f\u6536\u5165": {
|
||||
"7111-\u5229\u606f\u6536\u5165": {}
|
||||
},
|
||||
"712-\u6295\u8cc7\u6536\u76ca": {
|
||||
"7121-\u6b0a\u76ca\u6cd5\u8a8d\u5217\u4e4b\u6295\u8cc7\u6536\u76ca": {},
|
||||
"7122-\u80a1\u5229\u6536\u5165": {},
|
||||
"7123-\u77ed\u671f\u6295\u8cc7\u5e02\u50f9\u56de\u5347\u5229\u76ca": {}
|
||||
},
|
||||
"713-\u514c\u63db\u5229\u76ca": {
|
||||
"7131-\u514c\u63db\u5229\u76ca": {}
|
||||
},
|
||||
"714-\u8655\u5206\u6295\u8cc7\u6536\u76ca": {
|
||||
"7141-\u8655\u5206\u6295\u8cc7\u6536\u76ca": {}
|
||||
},
|
||||
"715-\u8655\u5206\u8cc7\u7522\u6ea2\u50f9\u6536\u5165": {
|
||||
"7151-\u8655\u5206\u8cc7\u7522\u6ea2\u50f9\u6536\u5165": {}
|
||||
},
|
||||
"748-\u5176\u4ed6\u71df\u696d\u5916\u6536\u5165": {
|
||||
"7481-\u6350\u8d08\u6536\u5165": {},
|
||||
"7482-\u79df\u91d1\u6536\u5165": {},
|
||||
"7483-\u4f63\u91d1\u6536\u5165": {},
|
||||
"7484-\u51fa\u552e\u4e0b\u8173\u53ca\u5ee2\u6599\u6536\u5165": {},
|
||||
"7485-\u5b58\u8ca8\u76e4\u76c8": {},
|
||||
"7486-\u5b58\u8ca8\u8dcc\u50f9\u56de\u5347\u5229\u76ca": {},
|
||||
"7487-\u58de\u5e33\u8f49\u56de\u5229\u76ca": {},
|
||||
"7488-\u5176\u4ed6\u71df\u696d\u5916\u6536\u5165\u2014\u5176\u4ed6": {}
|
||||
}
|
||||
},
|
||||
"75~78-\u71df\u696d\u5916\u8cbb\u7528": {
|
||||
"751-\u5229\u606f\u8cbb\u7528": {
|
||||
"7511-\u5229\u606f\u8cbb\u7528": {}
|
||||
},
|
||||
"752-\u6295\u8cc7\u640d\u5931": {
|
||||
"7521-\u6b0a\u76ca\u6cd5\u8a8d\u5217\u4e4b\u6295\u8cc7\u640d\u5931": {},
|
||||
"7523-\u77ed\u671f\u6295\u8cc7\u672a\u5be6\u73fe\u8dcc\u50f9\u640d\u5931": {}
|
||||
},
|
||||
"753-\u514c\u63db\u640d\u5931": {
|
||||
"7531-\u514c\u63db\u640d\u5931": {}
|
||||
},
|
||||
"754-\u8655\u5206\u6295\u8cc7\u640d\u5931": {
|
||||
"7541-\u8655\u5206\u6295\u8cc7\u640d\u5931": {}
|
||||
},
|
||||
"755-\u8655\u5206\u8cc7\u7522\u640d\u5931": {
|
||||
"7551-\u8655\u5206\u8cc7\u7522\u640d\u5931 ": {}
|
||||
},
|
||||
"788-\u5176\u4ed6\u71df\u696d\u5916\u8cbb\u7528": {
|
||||
"7881-\u505c\u5de5\u640d\u5931": {},
|
||||
"7882-\u707d\u5bb3\u640d\u5931": {},
|
||||
"7885-\u5b58\u8ca8\u76e4\u640d": {},
|
||||
"7886-\u5b58\u8ca8\u8dcc\u50f9\u53ca\u5446\u6eef\u640d\u5931": {},
|
||||
"7888-\u5176\u4ed6\u71df\u696d\u5916\u8cbb\u7528\u2014\u5176\u4ed6": {}
|
||||
}
|
||||
},
|
||||
"root_type": "Income"
|
||||
},
|
||||
"8-\u6240\u5f97\u7a05\u8cbb\u7528(\u5229\u76ca)": {
|
||||
"81-\u6240\u5f97\u7a05\u8cbb\u7528(\u5229\u76ca)": {
|
||||
"811-\u6240\u5f97\u7a05\u8cbb\u7528(\u5229\u76ca) ": {
|
||||
"8111-\u6240\u5f97\u7a05\u8cbb\u7528(\u5229\u76ca) ": {}
|
||||
}
|
||||
},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"9-\u975e\u7d93\u5e38\u71df\u696d\u640d\u76ca": {
|
||||
"91-\u505c\u696d\u90e8\u9580\u640d\u76ca": {
|
||||
"911-\u505c\u696d\u90e8\u9580\u640d\u76ca\u2014\u505c\u696d\u524d\u71df\u696d\u640d\u76ca": {
|
||||
"9111-\u505c\u696d\u90e8\u9580\u640d\u76ca\u2014\u505c\u696d\u524d\u71df\u696d\u640d\u76ca": {}
|
||||
},
|
||||
"912-\u505c\u696d\u90e8\u9580\u640d\u76ca\u2014\u8655\u5206\u640d\u76ca": {
|
||||
"9121-\u505c\u696d\u90e8\u9580\u640d\u76ca\u2014\u8655\u5206\u640d\u76ca": {}
|
||||
}
|
||||
},
|
||||
"92-\u975e\u5e38\u640d\u76ca": {
|
||||
"921-\u975e\u5e38\u640d\u76ca": {
|
||||
"9211-\u975e\u5e38\u640d\u76ca": {}
|
||||
}
|
||||
},
|
||||
"93-\u6703\u8a08\u539f\u5247\u8b8a\u52d5\u7d2f\u7a4d\u5f71\u97ff\u6578": {
|
||||
"931-\u6703\u8a08\u539f\u5247\u8b8a\u52d5\u7d2f\u7a4d\u5f71\u97ff\u6578": {
|
||||
"9311-\u6703\u8a08\u539f\u5247\u8b8a\u52d5\u7d2f\u7a4d\u5f71\u97ff\u6578": {}
|
||||
}
|
||||
},
|
||||
"94-\u5c11\u6578\u80a1\u6b0a\u6de8\u5229": {
|
||||
"941-\u5c11\u6578\u80a1\u6b0a\u6de8\u5229": {
|
||||
"9411-\u5c11\u6578\u80a1\u6b0a\u6de8\u5229": {}
|
||||
}
|
||||
},
|
||||
"root_type": "Expense"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,9 @@ QUnit.test("test account", function(assert) {
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => frappe.set_route('Tree', 'Account'),
|
||||
() => frappe.timeout(3),
|
||||
() => frappe.click_button('Expand All'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_link('Debtors'),
|
||||
() => frappe.click_button('Edit'),
|
||||
() => frappe.timeout(1),
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
QUnit.module('Account');
|
||||
|
||||
QUnit.test("test Bank Reconciliation", function(assert) {
|
||||
assert.expect(0);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => frappe.set_route('Form', 'Bank Reconciliation'),
|
||||
() => cur_frm.set_value('bank_account','Cash - FT'),
|
||||
() => frappe.click_button('Get Payment Entries'),
|
||||
() => {
|
||||
for(var i=0;i<=cur_frm.doc.payment_entries.length-1;i++){
|
||||
cur_frm.doc.payment_entries[i].clearance_date = frappe.datetime.add_days(frappe.datetime.now_date(), 2);
|
||||
}
|
||||
},
|
||||
() => {cur_frm.refresh_fields('payment_entries');},
|
||||
() => frappe.click_button('Update Clearance Date'),
|
||||
() => frappe.timeout(0.5),
|
||||
() => frappe.click_button('Close'),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -36,7 +36,7 @@ class GLEntry(Document):
|
||||
validate_balance_type(self.account, adv_adj)
|
||||
|
||||
# Update outstanding amt on against voucher
|
||||
if self.against_voucher_type in ['Journal Entry', 'Sales Invoice', 'Purchase Invoice'] \
|
||||
if self.against_voucher_type in ['Journal Entry', 'Sales Invoice', 'Purchase Invoice', 'Fees'] \
|
||||
and self.against_voucher and update_outstanding == 'Yes' and not from_repost:
|
||||
update_outstanding_amt(self.account, self.party_type, self.party, self.against_voucher_type,
|
||||
self.against_voucher)
|
||||
@@ -196,7 +196,7 @@ def update_outstanding_amt(account, party_type, party, against_voucher_type, aga
|
||||
frappe.throw(_("Outstanding for {0} cannot be less than zero ({1})").format(against_voucher, fmt_money(bal)))
|
||||
|
||||
# Update outstanding amt on against voucher
|
||||
if against_voucher_type in ["Sales Invoice", "Purchase Invoice"]:
|
||||
if against_voucher_type in ["Sales Invoice", "Purchase Invoice", "Fees"]:
|
||||
ref_doc = frappe.get_doc(against_voucher_type, against_voucher)
|
||||
ref_doc.db_set('outstanding_amount', bal)
|
||||
ref_doc.set_status(update=True)
|
||||
|
||||
@@ -1337,6 +1337,67 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "subscription_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Subscription Section",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "subscription",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Subscription",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Subscription",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -1382,7 +1443,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-06-13 14:29:09.794076",
|
||||
"modified": "2017-08-31 11:21:09.442695",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Journal Entry",
|
||||
|
||||
39
erpnext/accounts/doctype/journal_entry/test_journal_entry.js
Normal file
39
erpnext/accounts/doctype/journal_entry/test_journal_entry.js
Normal file
@@ -0,0 +1,39 @@
|
||||
QUnit.module('Journal Entry');
|
||||
|
||||
QUnit.test("test journal entry", function(assert) {
|
||||
assert.expect(2);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Journal Entry', [
|
||||
{posting_date:frappe.datetime.add_days(frappe.datetime.nowdate(), 0)},
|
||||
{accounts: [
|
||||
[
|
||||
{'account':'Debtors - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
|
||||
{'party_type':'Customer'},
|
||||
{'party':'Test Customer 1'},
|
||||
{'credit_in_account_currency':1000},
|
||||
{'is_advance':'Yes'},
|
||||
],
|
||||
[
|
||||
{'account':'HDFC - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
|
||||
{'debit_in_account_currency':1000},
|
||||
]
|
||||
]},
|
||||
{cheque_no:1234},
|
||||
{cheque_date: frappe.datetime.add_days(frappe.datetime.nowdate(), -1)},
|
||||
{user_remark: 'Test'},
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.total_debit==1000, "total debit correct");
|
||||
assert.ok(cur_frm.doc.total_credit==1000, "total credit correct");
|
||||
},
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.3),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -12,7 +12,8 @@ frappe.ui.form.on('Payment Entry', {
|
||||
|
||||
setup: function(frm) {
|
||||
frm.set_query("paid_from", function() {
|
||||
var party_account_type = frm.doc.party_type=="Customer" ? "Receivable" : "Payable";
|
||||
var party_account_type = in_list(["Customer", "Student"], frm.doc.party_type) ?
|
||||
"Receivable" : "Payable";
|
||||
var account_types = in_list(["Pay", "Internal Transfer"], frm.doc.payment_type) ?
|
||||
["Bank", "Cash"] : party_account_type;
|
||||
|
||||
@@ -28,13 +29,14 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frm.set_query("party_type", function() {
|
||||
return{
|
||||
"filters": {
|
||||
"name": ["in",["Customer","Supplier", "Employee"]],
|
||||
"name": ["in",["Customer","Supplier", "Employee", "Student"]],
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frm.set_query("paid_to", function() {
|
||||
var party_account_type = frm.doc.party_type=="Customer" ? "Receivable" : "Payable";
|
||||
var party_account_type = in_list(["Customer", "Student"], frm.doc.party_type) ?
|
||||
"Receivable" : "Payable";
|
||||
var account_types = in_list(["Receive", "Internal Transfer"], frm.doc.payment_type) ?
|
||||
["Bank", "Cash"] : party_account_type;
|
||||
|
||||
@@ -72,6 +74,8 @@ frappe.ui.form.on('Payment Entry', {
|
||||
var doctypes = ["Purchase Order", "Purchase Invoice", "Journal Entry"];
|
||||
} else if (frm.doc.party_type=="Employee") {
|
||||
var doctypes = ["Expense Claim", "Journal Entry"];
|
||||
} else if (frm.doc.party_type=="Student") {
|
||||
var doctypes = ["Fees"];
|
||||
} else {
|
||||
var doctypes = ["Journal Entry"];
|
||||
}
|
||||
@@ -85,7 +89,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
child = locals[cdt][cdn];
|
||||
filters = {"docstatus": 1, "company": doc.company};
|
||||
party_type_doctypes = ['Sales Invoice', 'Sales Order', 'Purchase Invoice',
|
||||
'Purchase Order', 'Expense Claim'];
|
||||
'Purchase Order', 'Expense Claim', 'Fees'];
|
||||
|
||||
if (in_list(party_type_doctypes, child.reference_doctype)) {
|
||||
filters[doc.party_type.toLowerCase()] = doc.party;
|
||||
@@ -207,19 +211,13 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frm.set_value(field, null);
|
||||
});
|
||||
} else {
|
||||
if(!frm.doc.party)
|
||||
{
|
||||
if (frm.doc.payment_type=="Receive"){
|
||||
frm.set_value("party_type", "Customer");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
frm.events.party(frm);
|
||||
if(frm.doc.party) {
|
||||
frm.events.party(frm);
|
||||
}
|
||||
|
||||
if(frm.doc.mode_of_payment)
|
||||
if(frm.doc.mode_of_payment) {
|
||||
frm.events.mode_of_payment(frm);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -254,6 +252,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
date: frm.doc.posting_date
|
||||
},
|
||||
callback: function(r, rt) {
|
||||
console.log(r, rt);
|
||||
if(r.message) {
|
||||
if(frm.doc.payment_type == "Receive") {
|
||||
frm.set_value("paid_from", r.message.party_account);
|
||||
@@ -502,6 +501,8 @@ frappe.ui.form.on('Payment Entry', {
|
||||
c.due_date = d.due_date
|
||||
c.total_amount = d.invoice_amount;
|
||||
c.outstanding_amount = d.outstanding_amount;
|
||||
c.bill_no = d.bill_no;
|
||||
|
||||
if(!in_list(["Sales Order", "Purchase Order", "Expense Claim"], d.voucher_type)) {
|
||||
if(flt(d.outstanding_amount) > 0)
|
||||
total_positive_outstanding += flt(d.outstanding_amount);
|
||||
@@ -569,7 +570,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
})
|
||||
|
||||
var allocated_negative_outstanding = 0;
|
||||
if((frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
|
||||
if ((frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee")) {
|
||||
if(total_positive_outstanding_including_order > paid_amount) {
|
||||
@@ -579,7 +580,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
}
|
||||
|
||||
var allocated_positive_outstanding = paid_amount + allocated_negative_outstanding;
|
||||
} else {
|
||||
} else if (in_list(["Customer", "Supplier"], frm.doc.party_type)) {
|
||||
if(paid_amount > total_negative_outstanding) {
|
||||
if(total_negative_outstanding == 0) {
|
||||
frappe.msgprint(__("Cannot {0} {1} {2} without any negative outstanding invoice",
|
||||
@@ -644,16 +645,9 @@ frappe.ui.form.on('Payment Entry', {
|
||||
if(frm.doc.party) {
|
||||
var party_amount = frm.doc.payment_type=="Receive" ?
|
||||
frm.doc.paid_amount : frm.doc.received_amount;
|
||||
|
||||
var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
|
||||
function(d) { return flt(d.amount) }));
|
||||
|
||||
if(frm.doc.total_allocated_amount < party_amount) {
|
||||
if(frm.doc.payment_type == "Receive") {
|
||||
unallocated_amount = party_amount - (frm.doc.total_allocated_amount - total_deductions);
|
||||
} else {
|
||||
unallocated_amount = party_amount - (frm.doc.total_allocated_amount + total_deductions);
|
||||
}
|
||||
unallocated_amount = party_amount - frm.doc.total_allocated_amount;
|
||||
}
|
||||
}
|
||||
frm.set_value("unallocated_amount", unallocated_amount);
|
||||
@@ -672,11 +666,10 @@ frappe.ui.form.on('Payment Entry', {
|
||||
difference_amount = flt(frm.doc.base_paid_amount) - flt(frm.doc.base_received_amount);
|
||||
}
|
||||
|
||||
$.each(frm.doc.deductions || [], function(i, d) {
|
||||
if(d.amount) difference_amount -= flt(d.amount);
|
||||
})
|
||||
var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
|
||||
function(d) { return flt(d.amount) }));
|
||||
|
||||
frm.set_value("difference_amount", difference_amount);
|
||||
frm.set_value("difference_amount", difference_amount - total_deductions);
|
||||
|
||||
frm.events.hide_unhide_fields(frm);
|
||||
},
|
||||
|
||||
@@ -1659,6 +1659,67 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "subscription_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Subscription Section",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "subscription",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Subscription",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Subscription",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -1730,7 +1791,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-06-13 14:29:04.244537",
|
||||
"modified": "2017-08-31 11:20:37.578469",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Entry",
|
||||
|
||||
@@ -100,8 +100,8 @@ class PaymentEntry(AccountsController):
|
||||
if not self.party:
|
||||
frappe.throw(_("Party is mandatory"))
|
||||
|
||||
self.party_name = frappe.db.get_value(self.party_type, self.party,
|
||||
self.party_type.lower() + "_name")
|
||||
_party_name = "title" if self.party_type == "Student" else self.party_type.lower() + "_name"
|
||||
self.party_name = frappe.db.get_value(self.party_type, self.party, _party_name)
|
||||
|
||||
if self.party:
|
||||
if not self.party_balance:
|
||||
@@ -149,7 +149,7 @@ class PaymentEntry(AccountsController):
|
||||
frappe.throw(_("Invalid {0}: {1}").format(self.party_type, self.party))
|
||||
|
||||
if self.party_account:
|
||||
party_account_type = "Receivable" if self.party_type=="Customer" else "Payable"
|
||||
party_account_type = "Receivable" if self.party_type in ("Customer", "Student") else "Payable"
|
||||
self.validate_account_type(self.party_account, [party_account_type])
|
||||
|
||||
def validate_bank_accounts(self):
|
||||
@@ -182,7 +182,9 @@ class PaymentEntry(AccountsController):
|
||||
frappe.throw(_("{0} is mandatory").format(self.meta.get_label(field)))
|
||||
|
||||
def validate_reference_documents(self):
|
||||
if self.party_type == "Customer":
|
||||
if self.party_type == "Student":
|
||||
valid_reference_doctypes = ("Fees")
|
||||
elif self.party_type == "Customer":
|
||||
valid_reference_doctypes = ("Sales Order", "Sales Invoice", "Journal Entry")
|
||||
elif self.party_type == "Supplier":
|
||||
valid_reference_doctypes = ("Purchase Order", "Purchase Invoice", "Journal Entry")
|
||||
@@ -209,17 +211,19 @@ class PaymentEntry(AccountsController):
|
||||
else:
|
||||
self.validate_journal_entry()
|
||||
|
||||
if d.reference_doctype in ("Sales Invoice", "Purchase Invoice", "Expense Claim"):
|
||||
if self.party_type=="Customer":
|
||||
if d.reference_doctype in ("Sales Invoice", "Purchase Invoice", "Expense Claim", "Fees"):
|
||||
if self.party_type == "Customer":
|
||||
ref_party_account = ref_doc.debit_to
|
||||
elif self.party_type == "Student":
|
||||
ref_party_account = ref_doc.receivable_account
|
||||
elif self.party_type=="Supplier":
|
||||
ref_party_account = ref_doc.credit_to
|
||||
elif self.party_type=="Employee":
|
||||
ref_party_account = ref_doc.payable_account
|
||||
|
||||
if ref_party_account != self.party_account:
|
||||
frappe.throw(_("{0} {1} is associated with {2}, but Party Account is {3}")
|
||||
.format(d.reference_doctype, d.reference_name, ref_party_account, self.party_account))
|
||||
frappe.throw(_("{0} {1} is associated with {2}, but Party Account is {3}")
|
||||
.format(d.reference_doctype, d.reference_name, ref_party_account, self.party_account))
|
||||
|
||||
if ref_doc.docstatus != 1:
|
||||
frappe.throw(_("{0} {1} must be submitted")
|
||||
@@ -281,13 +285,8 @@ class PaymentEntry(AccountsController):
|
||||
if self.party:
|
||||
party_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount
|
||||
|
||||
total_deductions = sum([flt(d.amount) for d in self.get("deductions")])
|
||||
|
||||
if self.total_allocated_amount < party_amount:
|
||||
if self.payment_type == "Receive":
|
||||
self.unallocated_amount = party_amount - (self.total_allocated_amount - total_deductions)
|
||||
else:
|
||||
self.unallocated_amount = party_amount - (self.total_allocated_amount + total_deductions)
|
||||
self.unallocated_amount = party_amount - self.total_allocated_amount
|
||||
|
||||
def set_difference_amount(self):
|
||||
base_unallocated_amount = flt(self.unallocated_amount) * (flt(self.source_exchange_rate)
|
||||
@@ -302,11 +301,10 @@ class PaymentEntry(AccountsController):
|
||||
else:
|
||||
self.difference_amount = self.base_paid_amount - flt(self.base_received_amount)
|
||||
|
||||
for d in self.get("deductions"):
|
||||
if d.amount:
|
||||
self.difference_amount -= flt(d.amount)
|
||||
total_deductions = sum([flt(d.amount) for d in self.get("deductions")])
|
||||
|
||||
self.difference_amount = flt(self.difference_amount, self.precision("difference_amount"))
|
||||
self.difference_amount = flt(self.difference_amount - total_deductions,
|
||||
self.precision("difference_amount"))
|
||||
|
||||
def clear_unallocated_reference_document_rows(self):
|
||||
self.set("references", self.get("references", {"allocated_amount": ["not in", [0, None, ""]]}))
|
||||
@@ -393,7 +391,7 @@ class PaymentEntry(AccountsController):
|
||||
if self.payment_type=="Receive":
|
||||
against_account = self.paid_to
|
||||
else:
|
||||
against_account = self.paid_from
|
||||
against_account = self.paid_from
|
||||
|
||||
|
||||
party_gl_dict = self.get_gl_dict({
|
||||
@@ -404,7 +402,7 @@ class PaymentEntry(AccountsController):
|
||||
"account_currency": self.party_account_currency
|
||||
})
|
||||
|
||||
dr_or_cr = "credit" if self.party_type == "Customer" else "debit"
|
||||
dr_or_cr = "credit" if self.party_type in ["Customer", "Student"] else "debit"
|
||||
|
||||
for d in self.get("references"):
|
||||
gle = party_gl_dict.copy()
|
||||
@@ -489,9 +487,14 @@ class PaymentEntry(AccountsController):
|
||||
doc = frappe.get_doc("Expense Claim", d.reference_name)
|
||||
update_reimbursed_amount(doc)
|
||||
|
||||
def on_recurring(self, reference_doc, subscription_doc):
|
||||
self.reference_no = reference_doc.name
|
||||
self.reference_date = nowdate()
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_outstanding_reference_documents(args):
|
||||
args = json.loads(args)
|
||||
if isinstance(args, basestring):
|
||||
args = json.loads(args)
|
||||
|
||||
party_account_currency = get_account_currency(args.get("party_account"))
|
||||
company_currency = frappe.db.get_value("Company", args.get("company"), "default_currency")
|
||||
@@ -499,10 +502,12 @@ def get_outstanding_reference_documents(args):
|
||||
# Get negative outstanding sales /purchase invoices
|
||||
total_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"
|
||||
|
||||
negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"),
|
||||
args.get("party"), args.get("party_account"), total_field)
|
||||
negative_outstanding_invoices = []
|
||||
if (args.get("party_type") != "Student"):
|
||||
negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"),
|
||||
args.get("party"), args.get("party_account"), total_field)
|
||||
|
||||
# Get positive outstanding sales /purchase invoices
|
||||
# Get positive outstanding sales /purchase invoices/ Fees
|
||||
outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"),
|
||||
args.get("party_account"))
|
||||
|
||||
@@ -515,10 +520,14 @@ def get_outstanding_reference_documents(args):
|
||||
d["exchange_rate"] = get_exchange_rate(
|
||||
party_account_currency, company_currency, d.posting_date
|
||||
)
|
||||
if d.voucher_type in ("Purchase Invoice"):
|
||||
d["bill_no"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "bill_no")
|
||||
|
||||
# Get all SO / PO which are not fully billed or aginst which full advance not paid
|
||||
orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"), args.get("party"),
|
||||
party_account_currency, company_currency)
|
||||
orders_to_be_billed = []
|
||||
if (args.get("party_type") != "Student"):
|
||||
orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"),
|
||||
args.get("party"), party_account_currency, company_currency)
|
||||
|
||||
return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
|
||||
|
||||
@@ -633,7 +642,11 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
||||
total_amount = outstanding_amount = exchange_rate = None
|
||||
ref_doc = frappe.get_doc(reference_doctype, reference_name)
|
||||
|
||||
if reference_doctype != "Journal Entry":
|
||||
if reference_doctype == "Fees":
|
||||
total_amount = ref_doc.get("grand_total")
|
||||
exchange_rate = 1
|
||||
outstanding_amount = ref_doc.get("outstanding_amount")
|
||||
elif reference_doctype != "Journal Entry":
|
||||
if party_account_currency == ref_doc.company_currency:
|
||||
if ref_doc.doctype == "Expense Claim":
|
||||
total_amount = ref_doc.total_sanctioned_amount
|
||||
@@ -676,19 +689,23 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
||||
party_type = "Supplier"
|
||||
elif dt in ("Expense Claim"):
|
||||
party_type = "Employee"
|
||||
elif dt in ("Fees"):
|
||||
party_type = "Student"
|
||||
|
||||
# party account
|
||||
if dt == "Sales Invoice":
|
||||
party_account = doc.debit_to
|
||||
elif dt == "Purchase Invoice":
|
||||
party_account = doc.credit_to
|
||||
elif dt == "Fees":
|
||||
party_account = doc.receivable_account
|
||||
else:
|
||||
party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company)
|
||||
|
||||
party_account_currency = doc.get("party_account_currency") or get_account_currency(party_account)
|
||||
|
||||
# payment type
|
||||
if (dt == "Sales Order" or (dt=="Sales Invoice" and doc.outstanding_amount > 0)) \
|
||||
if (dt == "Sales Order" or (dt in ("Sales Invoice", "Fees") and doc.outstanding_amount > 0)) \
|
||||
or (dt=="Purchase Invoice" and doc.outstanding_amount < 0):
|
||||
payment_type = "Receive"
|
||||
else:
|
||||
@@ -704,6 +721,9 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
||||
elif dt in ("Expense Claim"):
|
||||
grand_total = doc.total_sanctioned_amount
|
||||
outstanding_amount = doc.total_sanctioned_amount - doc.total_amount_reimbursed
|
||||
elif dt == "Fees":
|
||||
grand_total = doc.grand_total
|
||||
outstanding_amount = doc.outstanding_amount
|
||||
else:
|
||||
total_field = "base_grand_total" if party_account_currency == doc.company_currency else "grand_total"
|
||||
grand_total = flt(doc.get(total_field))
|
||||
|
||||
@@ -267,3 +267,65 @@ class TestPaymentEntry(unittest.TestCase):
|
||||
return frappe.db.sql("""select account, debit, credit, against_voucher
|
||||
from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s
|
||||
order by account asc""", voucher_no, as_dict=1)
|
||||
|
||||
def test_payment_entry_write_off_difference(self):
|
||||
si = create_sales_invoice()
|
||||
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC")
|
||||
pe.reference_no = "1"
|
||||
pe.reference_date = "2016-01-01"
|
||||
pe.received_amount = pe.paid_amount = 110
|
||||
pe.insert()
|
||||
|
||||
self.assertEqual(pe.unallocated_amount, 10)
|
||||
|
||||
pe.received_amount = pe.paid_amount = 95
|
||||
pe.append("deductions", {
|
||||
"account": "_Test Write Off - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"amount": 5
|
||||
})
|
||||
pe.save()
|
||||
|
||||
self.assertEqual(pe.unallocated_amount, 0)
|
||||
self.assertEqual(pe.difference_amount, 0)
|
||||
|
||||
pe.submit()
|
||||
|
||||
expected_gle = dict((d[0], d) for d in [
|
||||
["Debtors - _TC", 0, 100, si.name],
|
||||
["_Test Cash - _TC", 95, 0, None],
|
||||
["_Test Write Off - _TC", 5, 0, None]
|
||||
])
|
||||
|
||||
self.validate_gl_entries(pe.name, expected_gle)
|
||||
|
||||
def test_payment_entry_exchange_gain_loss(self):
|
||||
si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
||||
currency="USD", conversion_rate=50)
|
||||
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank USD - _TC")
|
||||
pe.reference_no = "1"
|
||||
pe.reference_date = "2016-01-01"
|
||||
pe.target_exchange_rate = 55
|
||||
|
||||
pe.append("deductions", {
|
||||
"account": "_Test Exchange Gain/Loss - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"amount": -500
|
||||
})
|
||||
pe.save()
|
||||
|
||||
self.assertEqual(pe.unallocated_amount, 0)
|
||||
self.assertEqual(pe.difference_amount, 0)
|
||||
|
||||
pe.submit()
|
||||
|
||||
expected_gle = dict((d[0], d) for d in [
|
||||
["_Test Receivable USD - _TC", 0, 5000, si.name],
|
||||
["_Test Bank USD - _TC", 5500, 0, None],
|
||||
["_Test Exchange Gain/Loss - _TC", 0, 500, None],
|
||||
])
|
||||
|
||||
self.validate_gl_entries(pe.name, expected_gle)
|
||||
|
||||
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
|
||||
self.assertEqual(outstanding_amount, 0)
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
QUnit.module('Payment Entry');
|
||||
|
||||
QUnit.test("test payment entry", function(assert) {
|
||||
assert.expect(6);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Sales Invoice', [
|
||||
{customer: 'Test Customer 1'},
|
||||
{items: [
|
||||
[
|
||||
{'item_code': 'Test Product 1'},
|
||||
{'qty': 1},
|
||||
{'rate': 101},
|
||||
]
|
||||
]}
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.tests.click_button('Close'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Make'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_link('Payment'),
|
||||
() => frappe.timeout(2),
|
||||
() => {
|
||||
assert.equal(frappe.get_route()[1], 'Payment Entry',
|
||||
'made payment entry');
|
||||
assert.equal(cur_frm.doc.party, 'Test Customer 1',
|
||||
'customer set in payment entry');
|
||||
assert.equal(cur_frm.doc.paid_amount, 101,
|
||||
'paid amount set in payment entry');
|
||||
assert.equal(cur_frm.doc.references[0].allocated_amount, 101,
|
||||
'amount allocated against sales invoice');
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => cur_frm.set_value('paid_amount', 100),
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
frappe.model.set_value("Payment Entry Reference", cur_frm.doc.references[0].name,
|
||||
"allocated_amount", 101);
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Write Off Difference Amount'),
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.difference_amount, 0, 'difference amount is zero');
|
||||
assert.equal(cur_frm.doc.deductions[0].amount, 1, 'Write off amount = 1');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
QUnit.module('Accounts');
|
||||
|
||||
QUnit.test("test payment entry", function(assert) {
|
||||
assert.expect(1);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Payment Entry', [
|
||||
{payment_type:'Receive'},
|
||||
{mode_of_payment:'Cash'},
|
||||
{party_type:'Customer'},
|
||||
{party:'Test Customer 3'},
|
||||
{paid_amount:675},
|
||||
{reference_no:123},
|
||||
{reference_date: frappe.datetime.add_days(frappe.datetime.nowdate(), 0)},
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.total_allocated_amount==675, "Allocated AmountCorrect");
|
||||
},
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.3),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -0,0 +1,67 @@
|
||||
QUnit.module('Payment Entry');
|
||||
|
||||
QUnit.test("test payment entry", function(assert) {
|
||||
assert.expect(8);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Sales Invoice', [
|
||||
{customer: 'Test Customer 1'},
|
||||
{company: 'For Testing'},
|
||||
{currency: 'INR'},
|
||||
{selling_price_list: '_Test Price List'},
|
||||
{items: [
|
||||
[
|
||||
{'qty': 1},
|
||||
{'item_code': 'Test Product 1'},
|
||||
]
|
||||
]}
|
||||
]);
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => cur_frm.save(),
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(1.5),
|
||||
() => frappe.click_button('Close'),
|
||||
() => frappe.timeout(0.5),
|
||||
() => frappe.click_button('Make'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_link('Payment'),
|
||||
() => frappe.timeout(2),
|
||||
() => cur_frm.set_value("paid_to", "_Test Cash - FT"),
|
||||
() => frappe.timeout(0.5),
|
||||
() => {
|
||||
assert.equal(frappe.get_route()[1], 'Payment Entry', 'made payment entry');
|
||||
assert.equal(cur_frm.doc.party, 'Test Customer 1', 'customer set in payment entry');
|
||||
assert.equal(cur_frm.doc.paid_from, 'Debtors - FT', 'customer account set in payment entry');
|
||||
assert.equal(cur_frm.doc.paid_amount, 100, 'paid amount set in payment entry');
|
||||
assert.equal(cur_frm.doc.references[0].allocated_amount, 100,
|
||||
'amount allocated against sales invoice');
|
||||
},
|
||||
() => cur_frm.set_value('paid_amount', 95),
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
frappe.model.set_value("Payment Entry Reference",
|
||||
cur_frm.doc.references[0].name, "allocated_amount", 100);
|
||||
},
|
||||
() => frappe.timeout(.5),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.difference_amount, 5, 'difference amount is 5');
|
||||
},
|
||||
() => {
|
||||
frappe.db.set_value("Company", "For Testing", "write_off_account", "_Test Write Off - FT");
|
||||
frappe.timeout(1);
|
||||
frappe.db.set_value("Company", "For Testing",
|
||||
"exchange_gain_loss_account", "_Test Exchange Gain/Loss - FT");
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Write Off Difference Amount'),
|
||||
() => frappe.timeout(2),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.difference_amount, 0, 'difference amount is zero');
|
||||
assert.equal(cur_frm.doc.deductions[0].amount, 5, 'Write off amount = 5');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
@@ -12,6 +13,7 @@
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -42,6 +44,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -72,6 +75,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -101,6 +105,38 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "bill_no",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Supplier Invoice No",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -129,6 +165,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -158,6 +195,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -187,6 +225,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -216,10 +255,12 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:(doc.reference_doctype=='Purchase Invoice')",
|
||||
"fieldname": "exchange_rate",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@@ -245,17 +286,17 @@
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-02-17 16:47:17.156256",
|
||||
"modified": "2017-09-04 17:37:01.192312",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Entry Reference",
|
||||
|
||||
@@ -30,8 +30,7 @@ class PaymentReconciliation(Document):
|
||||
return payment_entries
|
||||
|
||||
def get_jv_entries(self):
|
||||
dr_or_cr = "credit_in_account_currency" if self.party_type == "Customer" \
|
||||
else "debit_in_account_currency"
|
||||
dr_or_cr = self.get_dr_or_cr()
|
||||
|
||||
bank_account_condition = "t2.against_account like %(bank_cash_account)s" \
|
||||
if self.bank_cash_account else "1=1"
|
||||
@@ -73,13 +72,13 @@ class PaymentReconciliation(Document):
|
||||
row = self.append('payments', {})
|
||||
row.update(e)
|
||||
|
||||
def get_invoice_entries(self):
|
||||
def get_invoice_entries(self, paying_party=False):
|
||||
#Fetch JVs, Sales and Purchase Invoices for 'invoices' to reconcile against
|
||||
|
||||
condition = self.check_condition()
|
||||
|
||||
non_reconciled_invoices = get_outstanding_invoices(self.party_type, self.party,
|
||||
self.receivable_payable_account, condition=condition)
|
||||
self.receivable_payable_account, condition=condition, paying_party=paying_party)
|
||||
|
||||
self.add_invoice_entries(non_reconciled_invoices)
|
||||
|
||||
@@ -103,8 +102,7 @@ class PaymentReconciliation(Document):
|
||||
|
||||
self.get_invoice_entries()
|
||||
self.validate_invoice()
|
||||
dr_or_cr = "credit_in_account_currency" \
|
||||
if self.party_type == "Customer" else "debit_in_account_currency"
|
||||
dr_or_cr = self.get_dr_or_cr()
|
||||
|
||||
lst = []
|
||||
for e in self.get('payments'):
|
||||
@@ -184,3 +182,12 @@ class PaymentReconciliation(Document):
|
||||
cond += " and `{0}` <= {1}".format(dr_or_cr, flt(self.maximum_amount))
|
||||
|
||||
return cond
|
||||
|
||||
def get_dr_or_cr(self):
|
||||
'''Return credit_in_account_currency if not set and party is customer.'''
|
||||
if hasattr(self, "dr_or_cr"):
|
||||
return self.dr_or_cr
|
||||
if self.party_type == 'Customer':
|
||||
return "credit_in_account_currency"
|
||||
else:
|
||||
return "debit_in_account_currency"
|
||||
|
||||
@@ -35,7 +35,6 @@ class PaymentRequest(Document):
|
||||
|
||||
def on_submit(self):
|
||||
send_mail = True
|
||||
self.make_communication_entry()
|
||||
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
||||
|
||||
if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart") \
|
||||
@@ -45,6 +44,7 @@ class PaymentRequest(Document):
|
||||
if send_mail:
|
||||
self.set_payment_request_url()
|
||||
self.send_email()
|
||||
self.make_communication_entry()
|
||||
|
||||
def on_cancel(self):
|
||||
self.check_if_payment_entry_exists()
|
||||
@@ -69,8 +69,11 @@ class PaymentRequest(Document):
|
||||
self.db_set('status', 'Initiated')
|
||||
|
||||
def get_payment_url(self):
|
||||
data = frappe.db.get_value(self.reference_doctype, self.reference_name,
|
||||
["company", "customer_name"], as_dict=1)
|
||||
if self.reference_doctype != "Fees":
|
||||
data = frappe.db.get_value(self.reference_doctype, self.reference_name, ["company", "customer_name"], as_dict=1)
|
||||
else:
|
||||
data = frappe.db.get_value(self.reference_doctype, self.reference_name, ["student_name"], as_dict=1)
|
||||
data.update({"company": frappe.defaults.get_defaults().company})
|
||||
|
||||
controller = get_payment_gateway_controller(self.payment_gateway)
|
||||
controller.validate_transaction_currency(self.currency)
|
||||
@@ -277,6 +280,9 @@ def get_amount(ref_doc, dt):
|
||||
else:
|
||||
grand_total = flt(ref_doc.outstanding_amount) / ref_doc.conversion_rate
|
||||
|
||||
if dt == "Fees":
|
||||
grand_total = ref_doc.outstanding_amount
|
||||
|
||||
if grand_total > 0 :
|
||||
return grand_total
|
||||
|
||||
|
||||
@@ -8,10 +8,6 @@ frappe.ui.form.on("POS Profile", "onload", function(frm) {
|
||||
return { filters: { selling: 1 } };
|
||||
});
|
||||
|
||||
frm.set_query("print_format", function() {
|
||||
return { filters: { doc_type: "Sales Invoice", print_format_type: "Js"} };
|
||||
});
|
||||
|
||||
erpnext.queries.setup_queries(frm, "Warehouse", function() {
|
||||
return erpnext.queries.warehouse(frm.doc);
|
||||
});
|
||||
@@ -27,6 +23,27 @@ frappe.ui.form.on("POS Profile", "onload", function(frm) {
|
||||
});
|
||||
|
||||
frappe.ui.form.on('POS Profile', {
|
||||
setup: function(frm) {
|
||||
frm.set_query("online_print_format", function() {
|
||||
return {
|
||||
filters: [
|
||||
['Print Format', 'doc_type', '=', 'Sales Invoice'],
|
||||
['Print Format', 'print_format_type', '!=', 'Js'],
|
||||
]
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("print_format", function() {
|
||||
return { filters: { doc_type: "Sales Invoice", print_format_type: "Js"} };
|
||||
});
|
||||
|
||||
frappe.db.get_value('POS Settings', {name: 'POS Settings'}, 'is_online', (r) => {
|
||||
is_online = r && cint(r.is_online)
|
||||
frm.toggle_display('offline_pos_section', !is_online);
|
||||
frm.toggle_display('print_format_for_online', is_online);
|
||||
});
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
if(frm.doc.company) {
|
||||
frm.trigger("toggle_display_account_head");
|
||||
|
||||
@@ -631,8 +631,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Point of Sale",
|
||||
"fieldname": "print_format",
|
||||
"fieldname": "print_format_for_online",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@@ -641,7 +640,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Print Format",
|
||||
"label": "Print Format for Online",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Print Format",
|
||||
@@ -822,7 +821,7 @@
|
||||
"columns": 0,
|
||||
"fieldname": "apply_discount",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
@@ -836,7 +835,7 @@
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
@@ -851,7 +850,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Grand Total",
|
||||
"depends_on": "apply_discount",
|
||||
"depends_on": "",
|
||||
"fieldname": "apply_discount_on",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
@@ -883,7 +882,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "customer_details",
|
||||
"fieldname": "offline_pos_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@@ -892,7 +891,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "New Customer Details",
|
||||
"label": "Offline POS Section",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
@@ -969,6 +968,38 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Point of Sale",
|
||||
"fieldname": "print_format",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Print Format",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Print Format",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -1291,7 +1322,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-07-28 03:40:03.253088",
|
||||
"modified": "2017-09-01 15:55:14.890452",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Profile",
|
||||
|
||||
8
erpnext/accounts/doctype/pos_settings/pos_settings.js
Normal file
8
erpnext/accounts/doctype/pos_settings/pos_settings.js
Normal file
@@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('POS Settings', {
|
||||
refresh: function() {
|
||||
|
||||
}
|
||||
});
|
||||
133
erpnext/accounts/doctype/pos_settings/pos_settings.json
Normal file
133
erpnext/accounts/doctype/pos_settings/pos_settings.json
Normal file
@@ -0,0 +1,133 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2017-08-28 16:46:41.732676",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"fieldname": "use_pos_in_offline_mode",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Use POS in Offline Mode",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-09-11 13:57:28.787023",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Settings",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "Accounts User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "Sales User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
9
erpnext/accounts/doctype/pos_settings/pos_settings.py
Normal file
9
erpnext/accounts/doctype/pos_settings/pos_settings.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from frappe.model.document import Document
|
||||
|
||||
class POSSettings(Document):
|
||||
pass
|
||||
23
erpnext/accounts/doctype/pos_settings/test_pos_settings.js
Normal file
23
erpnext/accounts/doctype/pos_settings/test_pos_settings.js
Normal file
@@ -0,0 +1,23 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: POS Settings", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new POS Settings
|
||||
() => frappe.tests.make('POS Settings', [
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import unittest
|
||||
|
||||
class TestPOSSettings(unittest.TestCase):
|
||||
pass
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:title",
|
||||
@@ -12,6 +13,7 @@
|
||||
"editable_grid": 0,
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -40,6 +42,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -69,6 +72,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -99,6 +103,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -129,6 +134,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -159,6 +165,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -189,6 +196,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -217,6 +225,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -247,6 +256,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -275,6 +285,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -303,6 +314,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -331,6 +343,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -359,6 +372,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -387,6 +401,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -417,6 +432,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -447,6 +463,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -477,6 +494,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -507,6 +525,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -537,6 +556,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -567,6 +587,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -597,6 +618,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -627,6 +649,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -655,6 +678,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -683,6 +707,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -711,6 +736,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -739,6 +765,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -767,6 +794,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -796,6 +824,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -824,6 +853,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -851,6 +881,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -880,6 +911,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -910,6 +942,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -941,6 +974,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -969,6 +1003,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1000,6 +1035,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1028,6 +1064,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1058,6 +1095,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1085,13 +1123,14 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.price_or_discount==\"Price\"",
|
||||
"fieldname": "price",
|
||||
"fieldtype": "Float",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
@@ -1114,6 +1153,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1143,6 +1183,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1173,6 +1214,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1202,6 +1244,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1230,18 +1273,18 @@
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "fa fa-gift",
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-02-17 16:21:28.446208",
|
||||
"modified": "2017-08-31 16:34:41.614743",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Pricing Rule",
|
||||
|
||||
@@ -348,6 +348,7 @@ def apply_internal_priority(pricing_rules, field_set, args):
|
||||
return filtered_rules or pricing_rules
|
||||
|
||||
def set_transaction_type(args):
|
||||
if args.transaction_type:return
|
||||
if args.doctype in ("Opportunity", "Quotation", "Sales Order", "Delivery Note", "Sales Invoice"):
|
||||
args.transaction_type = "selling"
|
||||
elif args.doctype in ("Material Request", "Supplier Quotation", "Purchase Order",
|
||||
|
||||
@@ -46,6 +46,12 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
||||
cur_frm.add_custom_button(__('Return / Debit Note'),
|
||||
this.make_debit_note, __("Make"));
|
||||
}
|
||||
|
||||
if(!doc.subscription) {
|
||||
cur_frm.add_custom_button(__('Subscription'), function() {
|
||||
erpnext.utils.make_subscription(doc.doctype, doc.name)
|
||||
}, __("Make"))
|
||||
}
|
||||
}
|
||||
|
||||
if(doc.docstatus===0) {
|
||||
@@ -343,6 +349,7 @@ frappe.ui.form.on("Purchase Invoice", {
|
||||
'Payment Entry': 'Payment'
|
||||
}
|
||||
},
|
||||
|
||||
onload: function(frm) {
|
||||
$.each(["warehouse", "rejected_warehouse"], function(i, field) {
|
||||
frm.set_query(field, "items", function() {
|
||||
@@ -370,5 +377,5 @@ frappe.ui.form.on("Purchase Invoice", {
|
||||
erpnext.buying.get_default_bom(frm);
|
||||
}
|
||||
frm.toggle_reqd("supplier_warehouse", frm.doc.is_subcontracted==="Yes");
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
@@ -2072,6 +2072,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "base_rounding_adjustment",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Rounding Adjustment (Company Currency)",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2166,6 +2197,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "rounding_adjustment",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Rounding Adjustment",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -3348,6 +3410,67 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "subscription_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Subscription Section",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "subscription",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Subscription",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Subscription",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -3358,7 +3481,7 @@
|
||||
"depends_on": "eval:doc.docstatus<2 && !doc.__islocal",
|
||||
"fieldname": "recurring_invoice",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
@@ -3797,7 +3920,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-07-19 13:53:48.673757",
|
||||
"modified": "2017-09-19 11:22:47.074420",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice",
|
||||
|
||||
@@ -15,6 +15,7 @@ from erpnext.stock import get_warehouse_account_map
|
||||
from erpnext.accounts.general_ledger import make_gl_entries, merge_similar_entries, delete_gl_entries
|
||||
from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt
|
||||
from erpnext.buying.utils import check_for_closed_status
|
||||
from erpnext.accounts.general_ledger import get_round_off_account_and_cost_center
|
||||
|
||||
form_grid_templates = {
|
||||
"items": "templates/form_grid/item_grid.html"
|
||||
@@ -353,6 +354,7 @@ class PurchaseInvoice(BuyingController):
|
||||
|
||||
self.make_payment_gl_entries(gl_entries)
|
||||
self.make_write_off_gl_entry(gl_entries)
|
||||
self.make_gle_for_rounding_adjustment(gl_entries)
|
||||
|
||||
return gl_entries
|
||||
|
||||
@@ -584,6 +586,21 @@ class PurchaseInvoice(BuyingController):
|
||||
})
|
||||
)
|
||||
|
||||
def make_gle_for_rounding_adjustment(self, gl_entries):
|
||||
if self.rounding_adjustment:
|
||||
round_off_account, round_off_cost_center = \
|
||||
get_round_off_account_and_cost_center(self.company)
|
||||
|
||||
gl_entries.append(
|
||||
self.get_gl_dict({
|
||||
"account": round_off_account,
|
||||
"against": self.supplier,
|
||||
"debit_in_account_currency": self.rounding_adjustment,
|
||||
"debit": self.base_rounding_adjustment,
|
||||
"cost_center": round_off_cost_center,
|
||||
}
|
||||
))
|
||||
|
||||
def on_cancel(self):
|
||||
self.check_for_closed_status()
|
||||
|
||||
@@ -667,7 +684,7 @@ class PurchaseInvoice(BuyingController):
|
||||
if account_type != 'Fixed Asset':
|
||||
frappe.throw(_("Row {0}# Account must be of type 'Fixed Asset'").format(d.idx))
|
||||
|
||||
def on_recurring(self, reference_doc):
|
||||
def on_recurring(self, reference_doc, subscription_doc):
|
||||
self.due_date = None
|
||||
|
||||
@frappe.whitelist()
|
||||
|
||||
@@ -8,7 +8,8 @@ def get_data():
|
||||
'Payment Entry': 'reference_name',
|
||||
'Payment Request': 'reference_name',
|
||||
'Landed Cost Voucher': 'receipt_document',
|
||||
'Purchase Invoice': 'return_against'
|
||||
'Purchase Invoice': 'return_against',
|
||||
'Subscription': 'reference_document'
|
||||
},
|
||||
'internal_links': {
|
||||
'Purchase Order': ['items', 'purchase_order'],
|
||||
@@ -27,5 +28,9 @@ def get_data():
|
||||
'label': _('Returns'),
|
||||
'items': ['Purchase Invoice']
|
||||
},
|
||||
{
|
||||
'label': _('Subscription'),
|
||||
'items': ['Subscription']
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
QUnit.module('Purchaes Invoice');
|
||||
|
||||
QUnit.test("test purchase invoice", function(assert) {
|
||||
assert.expect(4);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Invoice', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{items: [
|
||||
[
|
||||
{'qty': 5},
|
||||
{'item_code': 'Test Product 1'},
|
||||
{'rate':100},
|
||||
]
|
||||
]},
|
||||
{update_stock:1},
|
||||
{supplier_address: 'Test1-Billing'},
|
||||
{contact_person: 'Contact 3-Test Supplier'},
|
||||
{taxes_and_charges: 'TEST In State GST'},
|
||||
{tc_name: 'Test Term 1'},
|
||||
{terms: 'This is Test'}
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||
// get tax details
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
||||
// get tax account head details
|
||||
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
||||
// grand_total Calculated
|
||||
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
|
||||
|
||||
},
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.3),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -256,10 +256,6 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
self.assertFalse(frappe.db.sql("""select name from `tabJournal Entry Account`
|
||||
where reference_type='Purchase Invoice' and reference_name=%s""", pi.name))
|
||||
|
||||
def test_recurring_invoice(self):
|
||||
from erpnext.controllers.tests.test_recurring_document import test_recurring_document
|
||||
test_recurring_document(self, test_records)
|
||||
|
||||
def test_total_purchase_cost_for_project(self):
|
||||
existing_purchase_cost = frappe.db.sql("""select sum(base_net_amount)
|
||||
from `tabPurchase Invoice Item` where project = '_Test Project' and docstatus=1""")
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
QUnit.module('Sales Taxes and Charges Template');
|
||||
|
||||
QUnit.test("test sales taxes and charges template", function(assert) {
|
||||
assert.expect(1);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Taxes and Charges Template', [
|
||||
{title: "TEST In State GST"},
|
||||
{taxes:[
|
||||
[
|
||||
{charge_type:"On Net Total"},
|
||||
{account_head:"CGST - "+frappe.get_abbr(frappe.defaults.get_default("Company")) }
|
||||
],
|
||||
[
|
||||
{charge_type:"On Net Total"},
|
||||
{account_head:"SGST - "+frappe.get_abbr(frappe.defaults.get_default("Company")) }
|
||||
]
|
||||
]}
|
||||
]);
|
||||
},
|
||||
() => {assert.ok(cur_frm.doc.title=='TEST In State GST');},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -320,8 +320,7 @@ def make_invoice(doc_list={}, email_queue_list={}, customers_list={}):
|
||||
si_doc.set_posting_time = 1
|
||||
si_doc.customer = get_customer_id(doc)
|
||||
si_doc.due_date = doc.get('posting_date')
|
||||
submit_invoice(si_doc, name, doc)
|
||||
name_list.append(name)
|
||||
name_list = submit_invoice(si_doc, name, doc, name_list)
|
||||
else:
|
||||
name_list.append(name)
|
||||
|
||||
@@ -475,19 +474,29 @@ def validate_item(doc):
|
||||
frappe.db.commit()
|
||||
|
||||
|
||||
def submit_invoice(si_doc, name, doc):
|
||||
def submit_invoice(si_doc, name, doc, name_list):
|
||||
try:
|
||||
si_doc.insert()
|
||||
si_doc.submit()
|
||||
frappe.db.commit()
|
||||
name_list.append(name)
|
||||
except Exception as e:
|
||||
if frappe.message_log: frappe.message_log.pop()
|
||||
frappe.db.rollback()
|
||||
save_invoice(e, si_doc, name)
|
||||
frappe.log_error(frappe.get_traceback())
|
||||
name_list = save_invoice(e, si_doc, name, name_list)
|
||||
|
||||
def save_invoice(e, si_doc, name):
|
||||
if not frappe.db.exists('Sales Invoice', {'offline_pos_name': name}):
|
||||
si_doc.docstatus = 0
|
||||
si_doc.flags.ignore_mandatory = True
|
||||
si_doc.due_date = si_doc.posting_date
|
||||
si_doc.insert()
|
||||
return name_list
|
||||
|
||||
def save_invoice(e, si_doc, name, name_list):
|
||||
try:
|
||||
if not frappe.db.exists('Sales Invoice', {'offline_pos_name': name}):
|
||||
si_doc.docstatus = 0
|
||||
si_doc.flags.ignore_mandatory = True
|
||||
si_doc.due_date = si_doc.posting_date
|
||||
si_doc.insert()
|
||||
name_list.append(name)
|
||||
except Exception:
|
||||
frappe.log_error(frappe.get_traceback())
|
||||
|
||||
return name_list
|
||||
|
||||
@@ -86,7 +86,11 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
this.make_payment_request, __("Make"));
|
||||
}
|
||||
|
||||
|
||||
if(!doc.subscription) {
|
||||
cur_frm.add_custom_button(__('Subscription'), function() {
|
||||
erpnext.utils.make_subscription(doc.doctype, doc.name)
|
||||
}, __("Make"))
|
||||
}
|
||||
}
|
||||
|
||||
// Show buttons only when pos view is active
|
||||
|
||||
@@ -1670,36 +1670,6 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "net_total",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Net Total",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -1731,6 +1701,36 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "net_total",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Net Total",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2337,6 +2337,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "base_rounding_adjustment",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Rounding Adjustment (Company Currency)",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2463,6 +2494,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "rounding_adjustment",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Rounding Adjustment",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -4175,6 +4237,67 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "subscription_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Subscription Section",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "subscription",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Subscription",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Subscription",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -4185,7 +4308,7 @@
|
||||
"depends_on": "eval:doc.docstatus<2 && !doc.__islocal",
|
||||
"fieldname": "recurring_invoice",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
@@ -4688,7 +4811,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-07-07 13:05:37.469682",
|
||||
"modified": "2017-09-19 11:23:08.675028",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice",
|
||||
|
||||
@@ -20,6 +20,7 @@ from erpnext.accounts.doctype.asset.depreciation \
|
||||
from erpnext.stock.doctype.batch.batch import set_batch_nos
|
||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos, get_delivery_note_serial_no
|
||||
from erpnext.setup.doctype.company.company import update_company_current_month_sales
|
||||
from erpnext.accounts.general_ledger import get_round_off_account_and_cost_center
|
||||
|
||||
form_grid_templates = {
|
||||
"items": "templates/form_grid/item_grid.html"
|
||||
@@ -107,9 +108,9 @@ class SalesInvoice(SellingController):
|
||||
def on_submit(self):
|
||||
self.validate_pos_paid_amount()
|
||||
|
||||
if not self.recurring_id:
|
||||
if not self.subscription:
|
||||
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
|
||||
self.company, self.base_grand_total, self)
|
||||
self.company, self.base_grand_total, self)
|
||||
|
||||
self.check_prev_docstatus()
|
||||
|
||||
@@ -313,7 +314,7 @@ class SalesInvoice(SellingController):
|
||||
|
||||
for fieldname in ('territory', 'naming_series', 'currency', 'taxes_and_charges', 'letter_head', 'tc_name',
|
||||
'selling_price_list', 'company', 'select_print_heading', 'cash_bank_account',
|
||||
'write_off_account', 'write_off_cost_center'):
|
||||
'write_off_account', 'write_off_cost_center', 'apply_discount_on'):
|
||||
if (not for_validate) or (for_validate and not self.get(fieldname)):
|
||||
self.set(fieldname, pos.get(fieldname))
|
||||
|
||||
@@ -625,6 +626,7 @@ class SalesInvoice(SellingController):
|
||||
self.make_gle_for_change_amount(gl_entries)
|
||||
|
||||
self.make_write_off_gl_entry(gl_entries)
|
||||
self.make_gle_for_rounding_adjustment(gl_entries)
|
||||
|
||||
return gl_entries
|
||||
|
||||
@@ -784,6 +786,21 @@ class SalesInvoice(SellingController):
|
||||
}, write_off_account_currency)
|
||||
)
|
||||
|
||||
def make_gle_for_rounding_adjustment(self, gl_entries):
|
||||
if self.rounding_adjustment:
|
||||
round_off_account, round_off_cost_center = \
|
||||
get_round_off_account_and_cost_center(self.company)
|
||||
|
||||
gl_entries.append(
|
||||
self.get_gl_dict({
|
||||
"account": round_off_account,
|
||||
"against": self.customer,
|
||||
"credit_in_account_currency": self.rounding_adjustment,
|
||||
"credit": self.base_rounding_adjustment,
|
||||
"cost_center": round_off_cost_center,
|
||||
}
|
||||
))
|
||||
|
||||
def update_billing_status_in_dn(self, update_modified=True):
|
||||
updated_delivery_notes = []
|
||||
for d in self.get("items"):
|
||||
@@ -799,7 +816,7 @@ class SalesInvoice(SellingController):
|
||||
for dn in set(updated_delivery_notes):
|
||||
frappe.get_doc("Delivery Note", dn).update_billing_percentage(update_modified=update_modified)
|
||||
|
||||
def on_recurring(self, reference_doc):
|
||||
def on_recurring(self, reference_doc, subscription_doc):
|
||||
for fieldname in ("c_form_applicable", "c_form_no", "write_off_amount"):
|
||||
self.set(fieldname, reference_doc.get(fieldname))
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ def get_data():
|
||||
'Journal Entry': 'reference_name',
|
||||
'Payment Entry': 'reference_name',
|
||||
'Payment Request': 'reference_name',
|
||||
'Sales Invoice': 'return_against'
|
||||
'Sales Invoice': 'return_against',
|
||||
'Subscription': 'reference_document',
|
||||
},
|
||||
'internal_links': {
|
||||
'Sales Order': ['items', 'sales_order']
|
||||
@@ -26,5 +27,9 @@ def get_data():
|
||||
'label': _('Returns'),
|
||||
'items': ['Sales Invoice']
|
||||
},
|
||||
{
|
||||
'label': _('Subscription'),
|
||||
'items': ['Subscription']
|
||||
},
|
||||
]
|
||||
}
|
||||
43
erpnext/accounts/doctype/sales_invoice/test_sales_invoice.js
Normal file
43
erpnext/accounts/doctype/sales_invoice/test_sales_invoice.js
Normal file
@@ -0,0 +1,43 @@
|
||||
QUnit.module('Sales Invoice');
|
||||
|
||||
QUnit.test("test sales Invoice", function(assert) {
|
||||
assert.expect(4);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Sales Invoice', [
|
||||
{customer: 'Test Customer 1'},
|
||||
{items: [
|
||||
[
|
||||
{'qty': 5},
|
||||
{'item_code': 'Test Product 1'},
|
||||
]
|
||||
]},
|
||||
{update_stock:1},
|
||||
{customer_address: 'Test1-Billing'},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{contact_person: 'Contact 1-Test Customer 1'},
|
||||
{taxes_and_charges: 'TEST In State GST'},
|
||||
{tc_name: 'Test Term 1'},
|
||||
{terms: 'This is Test'}
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||
// get tax details
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
||||
// get tax account head details
|
||||
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
||||
// grand_total Calculated
|
||||
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
|
||||
|
||||
},
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.3),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -215,12 +215,12 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
si.save()
|
||||
|
||||
# with inclusive tax and additional discount
|
||||
self.assertEquals(si.net_total, 4298.24)
|
||||
self.assertEquals(si.net_total, 4298.25)
|
||||
self.assertEquals(si.grand_total, 4900.00)
|
||||
|
||||
def test_sales_invoice_discount_amount(self):
|
||||
si = frappe.copy_doc(test_records[3])
|
||||
si.discount_amount = 104.95
|
||||
si.discount_amount = 104.94
|
||||
si.append("taxes", {
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"account_head": "_Test Account Service Tax - _TC",
|
||||
@@ -285,7 +285,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
"_Test Account Customs Duty - _TC": [125, 116.35, 1585.40],
|
||||
"_Test Account Shipping Charges - _TC": [100, 100, 1685.40],
|
||||
"_Test Account Discount - _TC": [-180.33, -168.54, 1516.86],
|
||||
"_Test Account Service Tax - _TC": [-18.03, -16.86, 1500]
|
||||
"_Test Account Service Tax - _TC": [-18.03, -16.85, 1500.01]
|
||||
}
|
||||
|
||||
for d in si.get("taxes"):
|
||||
@@ -294,10 +294,12 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
self.assertEquals(si.base_grand_total, 1500)
|
||||
self.assertEquals(si.grand_total, 1500)
|
||||
self.assertEquals(si.rounding_adjustment, -0.01)
|
||||
|
||||
def test_discount_amount_gl_entry(self):
|
||||
frappe.db.set_value("Company", "_Test Company", "round_off_account", "Round Off - _TC")
|
||||
si = frappe.copy_doc(test_records[3])
|
||||
si.discount_amount = 104.95
|
||||
si.discount_amount = 104.94
|
||||
si.append("taxes", {
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
@@ -327,7 +329,8 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
[test_records[3]["taxes"][5]["account_head"], 0.0, 116.35],
|
||||
[test_records[3]["taxes"][6]["account_head"], 0.0, 100],
|
||||
[test_records[3]["taxes"][7]["account_head"], 168.54, 0.0],
|
||||
["_Test Account Service Tax - _TC", 16.86, 0.0]
|
||||
["_Test Account Service Tax - _TC", 16.85, 0.0],
|
||||
["Round Off - _TC", 0.01, 0.0]
|
||||
])
|
||||
|
||||
for gle in gl_entries:
|
||||
@@ -423,13 +426,12 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
expected_values = {
|
||||
"keys": ["price_list_rate", "discount_percentage", "rate", "amount",
|
||||
"base_price_list_rate", "base_rate", "base_amount", "net_rate", "net_amount"],
|
||||
"_Test Item Home Desktop 100": [62.5, 0, 62.5, 625.0, 62.5, 62.5, 625.0, 50, 499.98],
|
||||
"_Test Item Home Desktop 200": [190.66, 0, 190.66, 953.3, 190.66, 190.66, 953.3, 150, 750],
|
||||
"_Test Item Home Desktop 100": [62.5, 0, 62.5, 625.0, 62.5, 62.5, 625.0, 50, 499.97600115194473],
|
||||
"_Test Item Home Desktop 200": [190.66, 0, 190.66, 953.3, 190.66, 190.66, 953.3, 150, 749.9968530500239],
|
||||
}
|
||||
|
||||
# check if children are saved
|
||||
self.assertEquals(len(si.get("items")),
|
||||
len(expected_values)-1)
|
||||
self.assertEquals(len(si.get("items")), len(expected_values)-1)
|
||||
|
||||
# check if item values are calculated
|
||||
for d in si.get("items"):
|
||||
@@ -437,28 +439,28 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
self.assertEquals(d.get(k), expected_values[d.item_code][i])
|
||||
|
||||
# check net total
|
||||
self.assertEquals(si.base_net_total, 1249.98)
|
||||
self.assertEquals(si.net_total, 1249.97)
|
||||
self.assertEquals(si.total, 1578.3)
|
||||
|
||||
# check tax calculation
|
||||
expected_values = {
|
||||
"keys": ["tax_amount", "total"],
|
||||
"_Test Account Excise Duty - _TC": [140, 1389.98],
|
||||
"_Test Account Education Cess - _TC": [2.8, 1392.78],
|
||||
"_Test Account S&H Education Cess - _TC": [1.4, 1394.18],
|
||||
"_Test Account CST - _TC": [27.88, 1422.06],
|
||||
"_Test Account VAT - _TC": [156.25, 1578.31],
|
||||
"_Test Account Customs Duty - _TC": [125, 1703.31],
|
||||
"_Test Account Shipping Charges - _TC": [100, 1803.31],
|
||||
"_Test Account Discount - _TC": [-180.33, 1622.98]
|
||||
"_Test Account Excise Duty - _TC": [140, 1389.97],
|
||||
"_Test Account Education Cess - _TC": [2.8, 1392.77],
|
||||
"_Test Account S&H Education Cess - _TC": [1.4, 1394.17],
|
||||
"_Test Account CST - _TC": [27.88, 1422.05],
|
||||
"_Test Account VAT - _TC": [156.25, 1578.30],
|
||||
"_Test Account Customs Duty - _TC": [125, 1703.30],
|
||||
"_Test Account Shipping Charges - _TC": [100, 1803.30],
|
||||
"_Test Account Discount - _TC": [-180.33, 1622.97]
|
||||
}
|
||||
|
||||
for d in si.get("taxes"):
|
||||
for i, k in enumerate(expected_values["keys"]):
|
||||
self.assertEquals(d.get(k), expected_values[d.account_head][i])
|
||||
|
||||
self.assertEquals(si.base_grand_total, 1622.98)
|
||||
self.assertEquals(si.grand_total, 1622.98)
|
||||
self.assertEquals(si.base_grand_total, 1622.97)
|
||||
self.assertEquals(si.grand_total, 1622.97)
|
||||
|
||||
def test_sales_invoice_calculation_export_currency_with_tax_inclusive_price(self):
|
||||
# prepare
|
||||
@@ -486,7 +488,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
"base_rate": 2500,
|
||||
"base_amount": 25000,
|
||||
"net_rate": 40,
|
||||
"net_amount": 399.98,
|
||||
"net_amount": 399.9808009215558,
|
||||
"base_net_rate": 2000,
|
||||
"base_net_amount": 19999
|
||||
},
|
||||
@@ -500,7 +502,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
"base_rate": 7500,
|
||||
"base_amount": 37500,
|
||||
"net_rate": 118.01,
|
||||
"net_amount": 590.05,
|
||||
"net_amount": 590.0531205155963,
|
||||
"base_net_rate": 5900.5,
|
||||
"base_net_amount": 29502.5
|
||||
}
|
||||
@@ -536,8 +538,11 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
for i, k in enumerate(expected_values["keys"]):
|
||||
self.assertEquals(d.get(k), expected_values[d.account_head][i])
|
||||
|
||||
self.assertEquals(si.base_grand_total, 60794.5)
|
||||
self.assertEquals(si.grand_total, 1215.89)
|
||||
self.assertEquals(si.base_grand_total, 60795)
|
||||
self.assertEquals(si.grand_total, 1215.90)
|
||||
self.assertEquals(si.rounding_adjustment, 0.01)
|
||||
self.assertEquals(si.base_rounding_adjustment, 0.50)
|
||||
|
||||
|
||||
def test_outstanding(self):
|
||||
w = self.make()
|
||||
@@ -809,10 +814,6 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
self.assertTrue(not frappe.db.sql("""select name from `tabJournal Entry Account`
|
||||
where reference_name=%s""", si.name))
|
||||
|
||||
def test_recurring_invoice(self):
|
||||
from erpnext.controllers.tests.test_recurring_document import test_recurring_document
|
||||
test_recurring_document(self, test_records)
|
||||
|
||||
def test_serialized(self):
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item
|
||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||
@@ -1167,8 +1168,15 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
self.assertEqual(flt(si.outstanding_amount), flt(si.grand_total + si.total_advance, si.precision("outstanding_amount")))
|
||||
|
||||
def test_multiple_uom_in_selling(self):
|
||||
si = frappe.copy_doc(test_records[1])
|
||||
frappe.db.sql("""delete from `tabItem Price`
|
||||
where price_list='_Test Price List' and item_code='_Test Item'""")
|
||||
item_price = frappe.new_doc("Item Price")
|
||||
item_price.price_list = "_Test Price List"
|
||||
item_price.item_code = "_Test Item"
|
||||
item_price.price_list_rate = 100
|
||||
item_price.insert()
|
||||
|
||||
si = frappe.copy_doc(test_records[1])
|
||||
si.items[0].uom = "_Test UOM 1"
|
||||
si.items[0].conversion_factor = None
|
||||
si.items[0].price_list_rate = None
|
||||
@@ -1283,6 +1291,40 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
current_month_sales = frappe.db.get_value("Company", "_Test Company", "total_monthly_sales")
|
||||
self.assertEqual(current_month_sales, existing_current_month_sales)
|
||||
|
||||
def test_rounding_adjustment(self):
|
||||
si = create_sales_invoice(rate=24900, do_not_save=True)
|
||||
for tax in ["Tax 1", "Tax2"]:
|
||||
si.append("taxes", {
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": "_Test Account Service Tax - _TC",
|
||||
"description": tax,
|
||||
"rate": 14,
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"included_in_print_rate": 1
|
||||
})
|
||||
si.save()
|
||||
|
||||
self.assertEqual(si.net_total, 19453.13)
|
||||
self.assertEqual(si.grand_total, 24900)
|
||||
self.assertEqual(si.total_taxes_and_charges, 5446.88)
|
||||
self.assertEqual(si.rounding_adjustment, -0.01)
|
||||
|
||||
expected_values = dict((d[0], d) for d in [
|
||||
[si.debit_to, 24900, 0.0],
|
||||
["_Test Account Service Tax - _TC", 0.0, 5446.88],
|
||||
["Sales - _TC", 0.0, 19453.13],
|
||||
["Round Off - _TC", 0.01, 0.0]
|
||||
])
|
||||
|
||||
gl_entries = frappe.db.sql("""select account, debit, credit
|
||||
from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
|
||||
order by account asc""", si.name, as_dict=1)
|
||||
|
||||
for gle in gl_entries:
|
||||
self.assertEquals(expected_values[gle.account][0], gle.account)
|
||||
self.assertEquals(expected_values[gle.account][1], gle.debit)
|
||||
self.assertEquals(expected_values[gle.account][2], gle.credit)
|
||||
|
||||
def create_sales_invoice(**args):
|
||||
si = frappe.new_doc("Sales Invoice")
|
||||
args = frappe._dict(args)
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
QUnit.module('Sales Invoice');
|
||||
|
||||
QUnit.test("test sales Invoice", function(assert) {
|
||||
assert.expect(4);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Sales Invoice', [
|
||||
{customer: 'Test Customer 1'},
|
||||
{items: [
|
||||
[
|
||||
{'qty': 5},
|
||||
{'item_code': 'Test Product 1'},
|
||||
]
|
||||
]},
|
||||
{update_stock:1},
|
||||
{customer_address: 'Test1-Billing'},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{contact_person: 'Contact 1-Test Customer 1'},
|
||||
{taxes_and_charges: 'TEST In State GST'},
|
||||
{tc_name: 'Test Term 1'},
|
||||
{terms: 'This is Test'}
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||
// get tax details
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
||||
// get tax account head details
|
||||
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
||||
// grand_total Calculated
|
||||
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
|
||||
|
||||
},
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.3),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
QUnit.module('Sales Invoice');
|
||||
|
||||
QUnit.test("test sales Invoice with payment", function(assert) {
|
||||
assert.expect(4);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Sales Invoice', [
|
||||
{customer: 'Test Customer 1'},
|
||||
{items: [
|
||||
[
|
||||
{'qty': 5},
|
||||
{'item_code': 'Test Product 1'},
|
||||
]
|
||||
]},
|
||||
{update_stock:1},
|
||||
{customer_address: 'Test1-Billing'},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{contact_person: 'Contact 1-Test Customer 1'},
|
||||
{taxes_and_charges: 'TEST In State GST'},
|
||||
{tc_name: 'Test Term 1'},
|
||||
{terms: 'This is Test'}
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||
// get tax details
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
||||
// grand_total Calculated
|
||||
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
|
||||
|
||||
},
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(2),
|
||||
() => frappe.tests.click_button('Close'),
|
||||
() => frappe.tests.click_button('Make'),
|
||||
() => frappe.tests.click_link('Payment'),
|
||||
() => frappe.timeout(0.2),
|
||||
() => { cur_frm.set_value('mode_of_payment','Cash');},
|
||||
() => { cur_frm.set_value('paid_to','Cash - '+frappe.get_abbr(frappe.defaults.get_default('Company')));},
|
||||
() => {cur_frm.set_value('reference_no','TEST1234');},
|
||||
() => {cur_frm.set_value('reference_date',frappe.datetime.add_days(frappe.datetime.nowdate(), 0));},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get payment details
|
||||
assert.ok(cur_frm.doc.paid_amount==590, "Paid Amount Correct");
|
||||
},
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
QUnit.module('Sales Invoice');
|
||||
|
||||
QUnit.test("test sales Invoice with payment request", function(assert) {
|
||||
assert.expect(4);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Sales Invoice', [
|
||||
{customer: 'Test Customer 1'},
|
||||
{items: [
|
||||
[
|
||||
{'qty': 5},
|
||||
{'item_code': 'Test Product 1'},
|
||||
]
|
||||
]},
|
||||
{update_stock:1},
|
||||
{customer_address: 'Test1-Billing'},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{contact_person: 'Contact 1-Test Customer 1'},
|
||||
{taxes_and_charges: 'TEST In State GST'},
|
||||
{tc_name: 'Test Term 1'},
|
||||
{terms: 'This is Test'}
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||
// get tax details
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
||||
// grand_total Calculated
|
||||
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
|
||||
|
||||
},
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(2),
|
||||
() => frappe.tests.click_button('Close'),
|
||||
() => frappe.tests.click_button('Make'),
|
||||
() => frappe.tests.click_link('Payment Request'),
|
||||
() => frappe.timeout(0.2),
|
||||
() => { cur_frm.set_value('print_format','GST Tax Invoice');},
|
||||
() => { cur_frm.set_value('email_to','test@gmail.com');},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get payment details
|
||||
assert.ok(cur_frm.doc.grand_total==590, "grand total Correct");
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
QUnit.module('Sales Invoice');
|
||||
|
||||
QUnit.test("test sales Invoice with serialize item", function(assert) {
|
||||
assert.expect(5);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Sales Invoice', [
|
||||
{customer: 'Test Customer 1'},
|
||||
{items: [
|
||||
[
|
||||
{'qty': 2},
|
||||
{'item_code': 'Test Product 4'},
|
||||
]
|
||||
]},
|
||||
{update_stock:1},
|
||||
{customer_address: 'Test1-Billing'},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{contact_person: 'Contact 1-Test Customer 1'},
|
||||
{taxes_and_charges: 'TEST In State GST'},
|
||||
{tc_name: 'Test Term 1'},
|
||||
{terms: 'This is Test'}
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 4', "Item name correct");
|
||||
// get tax details
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
||||
// get tax account head details
|
||||
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
||||
// get batch number
|
||||
assert.ok(cur_frm.doc.items[0].batch_no=='TEST-BATCH-001', " Batch Details correct");
|
||||
// grand_total Calculated
|
||||
assert.ok(cur_frm.doc.grand_total==218, "Grad Total correct");
|
||||
|
||||
},
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.3),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -54,13 +54,15 @@ class ShippingRule(Document):
|
||||
d.idx = i + 1
|
||||
|
||||
def validate_overlapping_shipping_rule_conditions(self):
|
||||
def overlap_exists_between((x1, x2), (y1, y2)):
|
||||
def overlap_exists_between(num_range1, num_range2):
|
||||
"""
|
||||
(x1, x2) and (y1, y2) are two ranges
|
||||
if condition x = 100 to 300
|
||||
then condition y can only be like 50 to 99 or 301 to 400
|
||||
num_range1 and num_range2 are two ranges
|
||||
ranges are represented as a tuple e.g. range 100 to 300 is represented as (100, 300)
|
||||
if condition num_range1 = 100 to 300
|
||||
then condition num_range2 can only be like 50 to 99 or 301 to 400
|
||||
hence, non-overlapping condition = (x1 <= x2 < y1 <= y2) or (y1 <= y2 < x1 <= x2)
|
||||
"""
|
||||
(x1, x2), (y1, y2) = num_range1, num_range2
|
||||
separate = (x1 <= x2 <= y1 <= y2) or (y1 <= y2 <= x1 <= x2)
|
||||
return (not separate)
|
||||
|
||||
|
||||
68
erpnext/accounts/doctype/subscription/subscription.js
Normal file
68
erpnext/accounts/doctype/subscription/subscription.js
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Subscription', {
|
||||
setup: function(frm) {
|
||||
frm.fields_dict['reference_document'].get_query = function() {
|
||||
return {
|
||||
filters: {
|
||||
"docstatus": 1
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
frm.fields_dict['print_format'].get_query = function() {
|
||||
return {
|
||||
filters: {
|
||||
"doc_type": frm.doc.reference_doctype
|
||||
}
|
||||
};
|
||||
};
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
if(frm.doc.docstatus == 1) {
|
||||
let label = __('View {0}', [frm.doc.reference_doctype]);
|
||||
frm.add_custom_button(__(label),
|
||||
function() {
|
||||
frappe.route_options = {
|
||||
"subscription": frm.doc.name,
|
||||
};
|
||||
frappe.set_route("List", frm.doc.reference_doctype);
|
||||
}
|
||||
);
|
||||
|
||||
if(frm.doc.status != 'Stopped') {
|
||||
frm.add_custom_button(__("Stop"),
|
||||
function() {
|
||||
frm.events.stop_resume_subscription(frm, "Stopped");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if(frm.doc.status == 'Stopped') {
|
||||
frm.add_custom_button(__("Resume"),
|
||||
function() {
|
||||
frm.events.stop_resume_subscription(frm, "Resumed");
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
stop_resume_subscription: function(frm, status) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.subscription.subscription.stop_resume_subscription",
|
||||
args: {
|
||||
subscription: frm.doc.name,
|
||||
status: status
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
frm.set_value("status", r.message);
|
||||
frm.reload_doc();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
771
erpnext/accounts/doctype/subscription/subscription.json
Normal file
771
erpnext/accounts/doctype/subscription/subscription.json
Normal file
@@ -0,0 +1,771 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "naming_series:",
|
||||
"beta": 0,
|
||||
"creation": "2017-07-18 17:50:43.967266",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_1",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Series",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "SUB-",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "reference_doctype",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reference Doctype",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "reference_document",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reference Document",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "reference_doctype",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "disabled",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Disabled",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "submit_on_creation",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Submit on Creation",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_5",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "start_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Start Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "end_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "End Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "next_schedule_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Next Schedule Date",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "frequency_detail",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "frequency",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Frequency",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nDaily\nWeekly\nMonthly\nQuarterly\nHalf-yearly\nYearly",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_12",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval: in_list([\"Monthly\", \"Quarterly\", \"Yearly\"], doc.frequency)",
|
||||
"fieldname": "repeat_on_day",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Repeat on Day",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "notification",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Notification",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "notify_by_email",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Notify by Email",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_17",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "notify_by_email",
|
||||
"fieldname": "recipients",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Recipients",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "notify_by_email",
|
||||
"fieldname": "print_format",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Print Format",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Print Format",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_16",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Draft",
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Status",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nDraft\nStopped\nSubmitted\nCancelled\nCompleted",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Amended From",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Subscription",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 1,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-09-14 12:09:38.471458",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Subscription",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"search_fields": "reference_document",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "reference_document",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
228
erpnext/accounts/doctype/subscription/subscription.py
Normal file
228
erpnext/accounts/doctype/subscription/subscription.py
Normal file
@@ -0,0 +1,228 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import calendar
|
||||
from frappe import _
|
||||
from frappe.desk.form import assign_to
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from frappe.utils.user import get_system_managers
|
||||
from frappe.utils import cstr, getdate, split_emails, add_days, today
|
||||
from frappe.model.document import Document
|
||||
|
||||
month_map = {'Monthly': 1, 'Quarterly': 3, 'Half-yearly': 6, 'Yearly': 12}
|
||||
class Subscription(Document):
|
||||
def validate(self):
|
||||
self.update_status()
|
||||
self.validate_dates()
|
||||
self.validate_next_schedule_date()
|
||||
self.validate_email_id()
|
||||
|
||||
def before_submit(self):
|
||||
self.set_next_schedule_date()
|
||||
|
||||
def on_submit(self):
|
||||
self.update_subscription_id()
|
||||
|
||||
def on_update_after_submit(self):
|
||||
self.validate_dates()
|
||||
self.set_next_schedule_date()
|
||||
|
||||
def validate_dates(self):
|
||||
if self.end_date and getdate(self.start_date) > getdate(self.end_date):
|
||||
frappe.throw(_("End date must be greater than start date"))
|
||||
|
||||
def validate_next_schedule_date(self):
|
||||
if self.repeat_on_day and self.next_schedule_date:
|
||||
next_date = getdate(self.next_schedule_date)
|
||||
if next_date.day != self.repeat_on_day:
|
||||
# if the repeat day is the last day of the month (31)
|
||||
# and the current month does not have as many days,
|
||||
# then the last day of the current month is a valid date
|
||||
lastday = calendar.monthrange(next_date.year, next_date.month)[1]
|
||||
if self.repeat_on_day < lastday:
|
||||
|
||||
# the specified day of the month is not same as the day specified
|
||||
# or the last day of the month
|
||||
frappe.throw(_("Next Date's day and Repeat on Day of Month must be equal"))
|
||||
|
||||
def validate_email_id(self):
|
||||
if self.notify_by_email:
|
||||
if self.recipients:
|
||||
email_list = split_emails(self.recipients.replace("\n", ""))
|
||||
|
||||
from frappe.utils import validate_email_add
|
||||
for email in email_list:
|
||||
if not validate_email_add(email):
|
||||
frappe.throw(_("{0} is an invalid email address in 'Recipients'").format(email))
|
||||
else:
|
||||
frappe.throw(_("'Recipients' not specified"))
|
||||
|
||||
def set_next_schedule_date(self):
|
||||
self.next_schedule_date = get_next_schedule_date(self.start_date,
|
||||
self.frequency, self.repeat_on_day)
|
||||
|
||||
def update_subscription_id(self):
|
||||
doc = frappe.get_doc(self.reference_doctype, self.reference_document)
|
||||
if not doc.meta.get_field('subscription'):
|
||||
frappe.throw(_("Add custom field Subscription Id in the doctype {0}").format(self.reference_doctype))
|
||||
|
||||
doc.db_set('subscription', self.name)
|
||||
|
||||
def update_status(self, status=None):
|
||||
self.status = {
|
||||
'0': 'Draft',
|
||||
'1': 'Submitted',
|
||||
'2': 'Cancelled'
|
||||
}[cstr(self.docstatus or 0)]
|
||||
|
||||
if status and status != 'Resumed':
|
||||
self.status = status
|
||||
|
||||
def get_next_schedule_date(start_date, frequency, repeat_on_day):
|
||||
mcount = month_map.get(frequency)
|
||||
if mcount:
|
||||
next_date = get_next_date(start_date, mcount, repeat_on_day)
|
||||
else:
|
||||
days = 7 if frequency == 'Weekly' else 1
|
||||
next_date = add_days(start_date, days)
|
||||
return next_date
|
||||
|
||||
def make_subscription_entry(date=None):
|
||||
date = date or today()
|
||||
for data in get_subscription_entries(date):
|
||||
schedule_date = getdate(data.next_schedule_date)
|
||||
while schedule_date <= getdate(today()):
|
||||
create_documents(data, schedule_date)
|
||||
schedule_date = get_next_schedule_date(schedule_date,
|
||||
data.frequency, data.repeat_on_day)
|
||||
|
||||
if schedule_date and not frappe.db.get_value('Subscription', data.name, 'disabled'):
|
||||
frappe.db.set_value('Subscription', data.name, 'next_schedule_date', schedule_date)
|
||||
|
||||
def get_subscription_entries(date):
|
||||
return frappe.db.sql(""" select * from `tabSubscription`
|
||||
where docstatus = 1 and next_schedule_date <=%s
|
||||
and reference_document is not null and reference_document != ''
|
||||
and next_schedule_date <= ifnull(end_date, '2199-12-31')
|
||||
and ifnull(disabled, 0) = 0 and status != 'Stopped' """, (date), as_dict=1)
|
||||
|
||||
def create_documents(data, schedule_date):
|
||||
try:
|
||||
doc = make_new_document(data, schedule_date)
|
||||
if data.notify_by_email and data.recipients:
|
||||
print_format = data.print_format or "Standard"
|
||||
send_notification(doc, print_format, data.recipients)
|
||||
|
||||
frappe.db.commit()
|
||||
except Exception:
|
||||
frappe.db.rollback()
|
||||
frappe.db.begin()
|
||||
frappe.log_error(frappe.get_traceback())
|
||||
disabled_subscription(data)
|
||||
frappe.db.commit()
|
||||
if data.reference_document and not frappe.flags.in_test:
|
||||
notify_error_to_user(data)
|
||||
|
||||
def disabled_subscription(data):
|
||||
subscription = frappe.get_doc('Subscription', data.name)
|
||||
subscription.db_set('disabled', 1)
|
||||
|
||||
def notify_error_to_user(data):
|
||||
party = ''
|
||||
party_type = ''
|
||||
|
||||
if data.reference_doctype in ['Sales Order', 'Sales Invoice', 'Delivery Note']:
|
||||
party_type = 'customer'
|
||||
elif data.reference_doctype in ['Purchase Order', 'Purchase Invoice', 'Purchase Receipt']:
|
||||
party_type = 'supplier'
|
||||
|
||||
if party_type:
|
||||
party = frappe.db.get_value(data.reference_doctype, data.reference_document, party_type)
|
||||
|
||||
notify_errors(data.reference_document, data.reference_doctype, party, data.owner, data.name)
|
||||
|
||||
def make_new_document(args, schedule_date):
|
||||
doc = frappe.get_doc(args.reference_doctype, args.reference_document)
|
||||
new_doc = frappe.copy_doc(doc, ignore_no_copy=False)
|
||||
update_doc(new_doc, doc , args, schedule_date)
|
||||
new_doc.insert(ignore_permissions=True)
|
||||
|
||||
if args.submit_on_creation:
|
||||
new_doc.submit()
|
||||
|
||||
return new_doc
|
||||
|
||||
def update_doc(new_document, reference_doc, args, schedule_date):
|
||||
new_document.docstatus = 0
|
||||
if new_document.meta.get_field('set_posting_time'):
|
||||
new_document.set('set_posting_time', 1)
|
||||
|
||||
if new_document.meta.get_field('subscription'):
|
||||
new_document.set('subscription', args.name)
|
||||
|
||||
new_document.run_method("on_recurring", reference_doc=reference_doc, subscription_doc=args)
|
||||
for data in new_document.meta.fields:
|
||||
if data.fieldtype == 'Date' and data.reqd:
|
||||
new_document.set(data.fieldname, schedule_date)
|
||||
|
||||
def get_next_date(dt, mcount, day=None):
|
||||
dt = getdate(dt)
|
||||
dt += relativedelta(months=mcount, day=day)
|
||||
|
||||
return dt
|
||||
|
||||
def send_notification(new_rv, print_format='Standard', recipients=None):
|
||||
"""Notify concerned persons about recurring document generation"""
|
||||
print_format = print_format
|
||||
|
||||
frappe.sendmail(recipients,
|
||||
subject= _("New {0}: #{1}").format(new_rv.doctype, new_rv.name),
|
||||
message = _("Please find attached {0} #{1}").format(new_rv.doctype, new_rv.name),
|
||||
attachments = [frappe.attach_print(new_rv.doctype, new_rv.name, file_name=new_rv.name, print_format=print_format)])
|
||||
|
||||
def notify_errors(doc, doctype, party, owner, name):
|
||||
recipients = get_system_managers(only_name=True)
|
||||
frappe.sendmail(recipients + [frappe.db.get_value("User", owner, "email")],
|
||||
subject=_("[Urgent] Error while creating recurring %s for %s" % (doctype, doc)),
|
||||
message = frappe.get_template("templates/emails/recurring_document_failed.html").render({
|
||||
"type": _(doctype),
|
||||
"name": doc,
|
||||
"party": party or "",
|
||||
"subscription": name
|
||||
}))
|
||||
|
||||
assign_task_to_owner(name, "Recurring Documents Failed", recipients)
|
||||
|
||||
def assign_task_to_owner(name, msg, users):
|
||||
for d in users:
|
||||
args = {
|
||||
'doctype' : 'Subscription',
|
||||
'assign_to' : d,
|
||||
'name' : name,
|
||||
'description' : msg,
|
||||
'priority' : 'High'
|
||||
}
|
||||
assign_to.add(args)
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_subscription(doctype, docname):
|
||||
doc = frappe.new_doc('Subscription')
|
||||
doc.reference_doctype = doctype
|
||||
doc.reference_document = docname
|
||||
return doc
|
||||
|
||||
@frappe.whitelist()
|
||||
def stop_resume_subscription(subscription, status):
|
||||
doc = frappe.get_doc('Subscription', subscription)
|
||||
frappe.msgprint(_("Subscription has been {0}").format(status))
|
||||
if status == 'Resumed':
|
||||
doc.next_schedule_date = get_next_schedule_date(today(),
|
||||
doc.frequency, doc.repeat_on_day)
|
||||
|
||||
doc.update_status(status)
|
||||
doc.save()
|
||||
|
||||
return doc.status
|
||||
16
erpnext/accounts/doctype/subscription/subscription_list.js
Normal file
16
erpnext/accounts/doctype/subscription/subscription_list.js
Normal file
@@ -0,0 +1,16 @@
|
||||
frappe.listview_settings['Subscription'] = {
|
||||
add_fields: ["next_schedule_date"],
|
||||
get_indicator: function(doc) {
|
||||
if(doc.disabled) {
|
||||
return [__("Disabled"), "red"];
|
||||
} else if(doc.next_schedule_date >= frappe.datetime.get_today() && doc.status != 'Stopped') {
|
||||
return [__("Active"), "green"];
|
||||
} else if(doc.docstatus === 0) {
|
||||
return [__("Draft"), "red", "docstatus,=,0"];
|
||||
} else if(doc.status === 'Stopped') {
|
||||
return [__("Stopped"), "red"];
|
||||
} else {
|
||||
return [__("Expired"), "darkgrey"];
|
||||
}
|
||||
}
|
||||
};
|
||||
32
erpnext/accounts/doctype/subscription/test_subscription.js
Normal file
32
erpnext/accounts/doctype/subscription/test_subscription.js
Normal file
@@ -0,0 +1,32 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Subscription", function (assert) {
|
||||
assert.expect(4);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
// insert a new Subscription
|
||||
() => {
|
||||
return frappe.tests.make("Subscription", [
|
||||
{reference_doctype: 'Sales Invoice'},
|
||||
{reference_document: 'SINV-00004'},
|
||||
{start_date: frappe.datetime.month_start()},
|
||||
{end_date: frappe.datetime.month_end()},
|
||||
{frequency: 'Weekly'}
|
||||
]);
|
||||
},
|
||||
() => cur_frm.savesubmit(),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Yes'),
|
||||
() => frappe.timeout(2),
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.frequency.includes("Weekly"), "Set frequency Weekly");
|
||||
assert.ok(cur_frm.doc.reference_doctype.includes("Sales Invoice"), "Set base doctype Sales Invoice");
|
||||
assert.equal(cur_frm.doc.docstatus, 1, "Submitted subscription");
|
||||
assert.equal(cur_frm.doc.next_schedule_date,
|
||||
frappe.datetime.add_days(frappe.datetime.get_today(), 7), "Set schedule date");
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
93
erpnext/accounts/doctype/subscription/test_subscription.py
Normal file
93
erpnext/accounts/doctype/subscription/test_subscription.py
Normal file
@@ -0,0 +1,93 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
from frappe.utils import today, add_days, getdate
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
from erpnext.accounts.report.financial_statements import get_months
|
||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||
from erpnext.accounts.doctype.subscription.subscription import make_subscription_entry
|
||||
|
||||
class TestSubscription(unittest.TestCase):
|
||||
def test_daily_subscription(self):
|
||||
qo = frappe.copy_doc(quotation_records[0])
|
||||
qo.submit()
|
||||
|
||||
doc = make_subscription(reference_document=qo.name)
|
||||
self.assertEquals(doc.next_schedule_date, today())
|
||||
make_subscription_entry()
|
||||
frappe.db.commit()
|
||||
|
||||
quotation = frappe.get_doc(doc.reference_doctype, doc.reference_document)
|
||||
self.assertEquals(quotation.subscription, doc.name)
|
||||
|
||||
new_quotation = frappe.db.get_value('Quotation',
|
||||
{'subscription': doc.name, 'name': ('!=', quotation.name)}, 'name')
|
||||
|
||||
new_quotation = frappe.get_doc('Quotation', new_quotation)
|
||||
|
||||
for fieldname in ['customer', 'company', 'order_type', 'total', 'grand_total']:
|
||||
self.assertEquals(quotation.get(fieldname), new_quotation.get(fieldname))
|
||||
|
||||
for fieldname in ['item_code', 'qty', 'rate', 'amount']:
|
||||
self.assertEquals(quotation.items[0].get(fieldname),
|
||||
new_quotation.items[0].get(fieldname))
|
||||
|
||||
def test_monthly_subscription_for_so(self):
|
||||
current_fiscal_year = get_fiscal_year(today(), as_dict=True)
|
||||
start_date = current_fiscal_year.year_start_date
|
||||
end_date = current_fiscal_year.year_end_date
|
||||
|
||||
for doctype in ['Sales Order', 'Sales Invoice']:
|
||||
if doctype == 'Sales Invoice':
|
||||
docname = create_sales_invoice(posting_date=start_date)
|
||||
else:
|
||||
docname = make_sales_order()
|
||||
|
||||
self.monthly_subscription(doctype, docname.name, start_date, end_date)
|
||||
|
||||
def monthly_subscription(self, doctype, docname, start_date, end_date):
|
||||
doc = make_subscription(reference_doctype=doctype, frequency = 'Monthly',
|
||||
reference_document = docname, start_date=start_date, end_date=end_date)
|
||||
|
||||
doc.disabled = 1
|
||||
doc.save()
|
||||
frappe.db.commit()
|
||||
|
||||
make_subscription_entry()
|
||||
docnames = frappe.get_all(doc.reference_doctype, {'subscription': doc.name})
|
||||
self.assertEquals(len(docnames), 1)
|
||||
|
||||
doc = frappe.get_doc('Subscription', doc.name)
|
||||
doc.disabled = 0
|
||||
doc.save()
|
||||
|
||||
months = get_months(getdate(start_date), getdate(today()))
|
||||
make_subscription_entry()
|
||||
|
||||
docnames = frappe.get_all(doc.reference_doctype, {'subscription': doc.name})
|
||||
self.assertEquals(len(docnames), months)
|
||||
|
||||
quotation_records = frappe.get_test_records('Quotation')
|
||||
|
||||
def make_subscription(**args):
|
||||
args = frappe._dict(args)
|
||||
doc = frappe.get_doc({
|
||||
'doctype': 'Subscription',
|
||||
'reference_doctype': args.reference_doctype or 'Quotation',
|
||||
'reference_document': args.reference_document or \
|
||||
frappe.db.get_value('Quotation', {'docstatus': 1}, 'name'),
|
||||
'frequency': args.frequency or 'Daily',
|
||||
'start_date': args.start_date or add_days(today(), -1),
|
||||
'end_date': args.end_date or add_days(today(), 1),
|
||||
'submit_on_creation': args.submit_on_creation or 0
|
||||
}).insert(ignore_permissions=True)
|
||||
|
||||
if not args.do_not_submit:
|
||||
doc.submit()
|
||||
|
||||
return doc
|
||||
@@ -135,7 +135,8 @@ def get_tax_template(posting_date, args):
|
||||
for key, value in args.iteritems():
|
||||
if key=="use_for_shopping_cart":
|
||||
conditions.append("use_for_shopping_cart = {0}".format(1 if value else 0))
|
||||
if key == 'customer_group' and value:
|
||||
if key == 'customer_group':
|
||||
if not value: value = _("All Customer Groups")
|
||||
customer_group_condition = get_customer_group_condition(value)
|
||||
conditions.append("ifnull({0}, '') in ('', {1})".format(key, customer_group_condition))
|
||||
else:
|
||||
|
||||
@@ -39,7 +39,7 @@ class TestTaxRule(unittest.TestCase):
|
||||
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-01")
|
||||
tax_rule1.save()
|
||||
|
||||
self.assertEquals(get_tax_template("2015-01-01", {"customer_group" : "Commercial"}),
|
||||
self.assertEquals(get_tax_template("2015-01-01", {"customer_group" : "Commercial", "use_for_shopping_cart":0}),
|
||||
"_Test Sales Taxes and Charges Template")
|
||||
|
||||
def test_conflict_with_overlapping_dates(self):
|
||||
|
||||
@@ -136,14 +136,7 @@ def round_off_debit_credit(gl_map):
|
||||
make_round_off_gle(gl_map, debit_credit_diff)
|
||||
|
||||
def make_round_off_gle(gl_map, debit_credit_diff):
|
||||
round_off_account, round_off_cost_center = frappe.db.get_value("Company", gl_map[0].company,
|
||||
["round_off_account", "round_off_cost_center"]) or [None, None]
|
||||
if not round_off_account:
|
||||
frappe.throw(_("Please mention Round Off Account in Company"))
|
||||
|
||||
if not round_off_cost_center:
|
||||
frappe.throw(_("Please mention Round Off Cost Center in Company"))
|
||||
|
||||
round_off_account, round_off_cost_center = get_round_off_account_and_cost_center(gl_map[0].company)
|
||||
|
||||
round_off_gle = frappe._dict()
|
||||
for k in ["voucher_type", "voucher_no", "company",
|
||||
@@ -165,6 +158,17 @@ def make_round_off_gle(gl_map, debit_credit_diff):
|
||||
|
||||
gl_map.append(round_off_gle)
|
||||
|
||||
def get_round_off_account_and_cost_center(company):
|
||||
round_off_account, round_off_cost_center = frappe.db.get_value("Company", company,
|
||||
["round_off_account", "round_off_cost_center"]) or [None, None]
|
||||
if not round_off_account:
|
||||
frappe.throw(_("Please mention Round Off Account in Company"))
|
||||
|
||||
if not round_off_cost_center:
|
||||
frappe.throw(_("Please mention Round Off Cost Center in Company"))
|
||||
|
||||
return round_off_account, round_off_cost_center
|
||||
|
||||
def delete_gl_entries(gl_entries=None, voucher_type=None, voucher_no=None,
|
||||
adv_adj=False, update_outstanding="Yes"):
|
||||
|
||||
|
||||
@@ -8,7 +8,16 @@ frappe.pages['pos'].on_page_load = function (wrapper) {
|
||||
single_column: true
|
||||
});
|
||||
|
||||
wrapper.pos = new erpnext.pos.PointOfSale(wrapper)
|
||||
frappe.db.get_value('POS Settings', {name: 'POS Settings'}, 'is_online', (r) => {
|
||||
if (r && r.use_pos_in_offline_mode && cint(r.use_pos_in_offline_mode)) {
|
||||
// offline
|
||||
wrapper.pos = new erpnext.pos.PointOfSale(wrapper);
|
||||
cur_pos = wrapper.pos;
|
||||
} else {
|
||||
// online
|
||||
frappe.set_route('point-of-sale');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
frappe.pages['pos'].refresh = function (wrapper) {
|
||||
@@ -260,9 +269,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
this.calculate_outstanding_amount();
|
||||
}
|
||||
|
||||
if (this.frm.doc.customer) {
|
||||
this.party_field.$input.val(this.frm.doc.customer);
|
||||
}
|
||||
this.set_customer_value_in_party_field();
|
||||
|
||||
if (!this.frm.doc.write_off_account) {
|
||||
this.frm.doc.write_off_account = doc.write_off_account
|
||||
@@ -273,6 +280,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
}
|
||||
},
|
||||
|
||||
set_customer_value_in_party_field: function() {
|
||||
if (this.frm.doc.customer) {
|
||||
this.party_field.$input.val(this.frm.doc.customer);
|
||||
}
|
||||
},
|
||||
|
||||
get_invoice_doc: function (si_docs) {
|
||||
var me = this;
|
||||
this.si_docs = this.get_doc_from_localstorage();
|
||||
@@ -426,11 +439,16 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
});
|
||||
|
||||
this.serach_item.make_input();
|
||||
this.serach_item.$input.on("keyup", function () {
|
||||
setTimeout(function () {
|
||||
me.items = me.get_items();
|
||||
me.make_item_list();
|
||||
}, 1000);
|
||||
|
||||
this.serach_item.$input.on("keypress", function (event) {
|
||||
|
||||
clearTimeout(me.last_search_timeout);
|
||||
me.last_search_timeout = setTimeout(() => {
|
||||
if((me.serach_item.$input.val() != "") || (event.which == 13)) {
|
||||
me.items = me.get_items();
|
||||
me.make_item_list();
|
||||
}
|
||||
}, 400);
|
||||
});
|
||||
|
||||
this.search_item_group = this.wrapper.find('.search-item-group');
|
||||
@@ -681,6 +699,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
|
||||
set_focus: function () {
|
||||
if (this.default_customer || this.frm.doc.customer) {
|
||||
this.set_customer_value_in_party_field();
|
||||
this.serach_item.$input.focus();
|
||||
} else {
|
||||
this.party_field.$input.focus();
|
||||
@@ -727,14 +746,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
|
||||
input = input.toLowerCase();
|
||||
item = this.get_item(item.value);
|
||||
var searchtext =
|
||||
Object.keys(item)
|
||||
.filter(key => ['customer_name', 'customer_group', 'value', 'label', 'email_id', 'phone', 'mobile_no'].includes(key))
|
||||
.map(key => item[key])
|
||||
.join(" ")
|
||||
.toLowerCase();
|
||||
|
||||
return searchtext.includes(input)
|
||||
result = item ? item.searchtext.includes(input) : '';
|
||||
if(!result) {
|
||||
me.prepare_customer_mapper(input);
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
},
|
||||
item: function (item, input) {
|
||||
var d = this.get_item(item.value);
|
||||
@@ -755,6 +772,9 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
|
||||
this.party_field.$input
|
||||
.on('input', function (e) {
|
||||
if(me.customers_mapper.length <= 1) {
|
||||
me.prepare_customer_mapper(e.target.value);
|
||||
}
|
||||
me.party_field.awesomeplete.list = me.customers_mapper;
|
||||
})
|
||||
.on('awesomplete-select', function (e) {
|
||||
@@ -795,20 +815,56 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
});
|
||||
},
|
||||
|
||||
prepare_customer_mapper: function() {
|
||||
prepare_customer_mapper: function(key) {
|
||||
var me = this;
|
||||
var customer_data = '';
|
||||
|
||||
this.customers_mapper = this.customers.map(function (c) {
|
||||
contact = me.contacts[c.name];
|
||||
return {
|
||||
label: c.name,
|
||||
value: c.name,
|
||||
customer_name: c.customer_name,
|
||||
customer_group: c.customer_group,
|
||||
territory: c.territory,
|
||||
phone: contact ? contact["phone"] : '',
|
||||
mobile_no: contact ? contact["mobile_no"] : '',
|
||||
email_id: contact ? contact["email_id"] : ''
|
||||
if (key) {
|
||||
key = key.toLowerCase().trim();
|
||||
var re = new RegExp('%', 'g');
|
||||
var reg = new RegExp(key.replace(re, '\\w*\\s*[a-zA-Z0-9]*'));
|
||||
|
||||
customer_data = $.grep(this.customers, function(data) {
|
||||
contact = me.contacts[data.name];
|
||||
if(reg.test(data.name.toLowerCase())
|
||||
|| reg.test(data.customer_name.toLowerCase())
|
||||
|| (contact && reg.test(contact["mobile_no"]))
|
||||
|| (contact && reg.test(contact["phone"]))
|
||||
|| (data.customer_group && reg.test(data.customer_group.toLowerCase()))){
|
||||
return data;
|
||||
}
|
||||
})
|
||||
} else {
|
||||
customer_data = this.customers;
|
||||
}
|
||||
|
||||
this.customers_mapper = [];
|
||||
|
||||
customer_data.forEach(function (c, index) {
|
||||
if(index < 30) {
|
||||
contact = me.contacts[c.name];
|
||||
if(contact && !c['phone']) {
|
||||
c["phone"] = contact["phone"];
|
||||
c["email_id"] = contact["email_id"];
|
||||
c["mobile_no"] = contact["mobile_no"];
|
||||
}
|
||||
|
||||
me.customers_mapper.push({
|
||||
label: c.name,
|
||||
value: c.name,
|
||||
customer_name: c.customer_name,
|
||||
customer_group: c.customer_group,
|
||||
territory: c.territory,
|
||||
phone: contact ? contact["phone"] : '',
|
||||
mobile_no: contact ? contact["mobile_no"] : '',
|
||||
email_id: contact ? contact["email_id"] : '',
|
||||
searchtext: ['customer_name', 'customer_group', 'name', 'value',
|
||||
'label', 'email_id', 'phone', 'mobile_no']
|
||||
.map(key => c[key]).join(' ')
|
||||
.toLowerCase()
|
||||
});
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
QUnit.test("test:POS Profile", function(assert) {
|
||||
assert.expect(1);
|
||||
QUnit.test("test:Sales Invoice", function(assert) {
|
||||
assert.expect(3);
|
||||
let done = assert.async();
|
||||
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make("POS Profile", [
|
||||
{naming_series: "SINV"},
|
||||
{company: "_Test Company"},
|
||||
{country: "India"},
|
||||
{currency: "INR"},
|
||||
{write_off_account: "Write Off - _TC"},
|
||||
{write_off_cost_center: "Main - _TC"},
|
||||
{write_off_account: "Write Off - FT"},
|
||||
{write_off_cost_center: "Main - FT"},
|
||||
{payments: [
|
||||
[
|
||||
{"default": 1},
|
||||
@@ -24,26 +23,18 @@ QUnit.test("test:POS Profile", function(assert) {
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.payments[0].default, 1, "Default mode of payment tested");
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
QUnit.test("test:Sales Invoice", function(assert) {
|
||||
assert.expect(2);
|
||||
let done = assert.async();
|
||||
|
||||
frappe.run_serially([
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
return frappe.tests.make("Sales Invoice", [
|
||||
{customer: "_Test Customer 2"},
|
||||
{company: "_Test Company"},
|
||||
{customer: "Test Customer 2"},
|
||||
{is_pos: 1},
|
||||
{posting_date: frappe.datetime.get_today()},
|
||||
{due_date: frappe.datetime.get_today()},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": "_Test Item"},
|
||||
{"qty": 5}
|
||||
{"item_code": "Test Product 1"},
|
||||
{"qty": 5},
|
||||
{"warehouse":'Stores - FT'}
|
||||
]]
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"align_labels_right": 0,
|
||||
"creation": "2017-08-08 12:33:04.773099",
|
||||
"custom_format": 1,
|
||||
"disabled": 0,
|
||||
"doc_type": "Sales Invoice",
|
||||
"docstatus": 0,
|
||||
"doctype": "Print Format",
|
||||
"font": "Default",
|
||||
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t<b>{{ _(\"GSTIN\") }}:</b>{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"<br>GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t<br>\n\t<b>{{ doc.select_print_heading or _(\"Invoice\") }}</b><br>\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t<b>{{ _(\"Customer\") }}:</b><br>\n\t\t{{ doc.customer_name }}<br>\n\t\t{{ customer_address }}\n\t{% endif %}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"40%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t<br><b>{{ _(\"HSN/SAC\") }}:</b> {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t<br><b>{{ _(\"Serial No\") }}:</b> {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.rate }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ _(\"Net Total\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"net_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t{%- if not row.included_in_print_rate -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ row.description }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n<p><b>Tax Breakup:</b></p>\n<div style=\"font-size: 8px\">\n\t{{ doc.other_charges_calculation }}\n</div>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>",
|
||||
"idx": 0,
|
||||
"line_breaks": 0,
|
||||
"modified": "2017-09-14 15:54:19.467642",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "GST POS Invoice",
|
||||
"owner": "Administrator",
|
||||
"print_format_builder": 0,
|
||||
"print_format_type": "Server",
|
||||
"show_section_headings": 0,
|
||||
"standard": "Yes"
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"align_labels_left": 0,
|
||||
"align_labels_right": 0,
|
||||
"creation": "2016-05-05 17:16:18.564460",
|
||||
"custom_format": 1,
|
||||
"disabled": 0,
|
||||
@@ -10,7 +10,7 @@
|
||||
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ company }}<br>\n\t{{ __(\"POS No : \") }} {{ offline_pos_name }}<br>\n</p>\n<p>\n\t<b>{{ __(\"Customer\") }}:</b> {{ customer }}<br>\n</p>\n\n<p>\n\t<b>{{ __(\"Date\") }}:</b> {{ dateutil.global_date_format(posting_date) }}<br>\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"50%\">{{ __(\"Item\") }}</b></th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ __(\"Qty\") }}</th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ __(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{% for item in items %}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_name }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ format_number(item.qty, null,precision(\"difference\")) }}<br>@ {{ format_currency(item.rate, currency) }}</td>\n\t\t\t<td class=\"text-right\">{{ format_currency(item.amount, currency) }}</td>\n\t\t</tr>\n\t\t{% endfor %}\n\t</tbody>\n</table>\n\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ __(\"Net Total\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(total, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% for row in taxes %}\n\t\t{% if not row.included_in_print_rate %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ row.description }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(row.tax_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% endif %}\n\t\t{% endfor %}\n\t\t{% if discount_amount %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ __(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(discount_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% endif %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ __(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(grand_total, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ __(\"Paid Amount\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(paid_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n\n\n<hr>\n<p>{{ terms }}</p>\n<p class=\"text-center\">{{ __(\"Thank you, please visit again.\") }}</p>",
|
||||
"idx": 0,
|
||||
"line_breaks": 0,
|
||||
"modified": "2017-05-19 14:36:04.740728",
|
||||
"modified": "2017-09-14 14:36:04.740728",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Point of Sale",
|
||||
|
||||
@@ -10,15 +10,15 @@
|
||||
<thead>
|
||||
<tr>
|
||||
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
|
||||
<th style="width: 15%">{%= __("Date") %}</th>
|
||||
<th style="width: 15%">{%= __("Ref") %}</th>
|
||||
<th style="width: 40%">{%= __("Party") %}</th>
|
||||
<th style="width: 15%">{%= __("Invoiced Amount") %}</th>
|
||||
<th style="width: 15%">{%= __("Paid Amount") %}</th>
|
||||
<th style="width: 15%">{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}</th>
|
||||
<th style="width: 15%">{%= __("Outstanding Amount") %}</th>
|
||||
<th style="width: 14%">{%= __("Date") %}</th>
|
||||
<th style="width: 16%">{%= __("Ref") %}</th>
|
||||
<th style="width: 30%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
|
||||
<th style="width: 10%">{%= __("Invoiced Amount") %}</th>
|
||||
<th style="width: 10%">{%= __("Paid Amount") %}</th>
|
||||
<th style="width: 10%">{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}</th>
|
||||
<th style="width: 10%">{%= __("Outstanding Amount") %}</th>
|
||||
{% } else { %}
|
||||
<th style="width: 40%">{%= __("Party") %}</th>
|
||||
<th style="width: 40%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
|
||||
<th style="width: 15%">{%= __("Total Invoiced Amount") %}</th>
|
||||
<th style="width: 15%">{%= __("Total Paid Amount") %}</th>
|
||||
<th style="width: 15%">{%= report.report_name === "Accounts Receivable Summary" ? __('Credit Note Amount') : __('Debit Note Amount') %}</th>
|
||||
@@ -34,8 +34,12 @@
|
||||
<td>{%= dateutil.str_to_user(data[i][__("Posting Date")]) %}</td>
|
||||
<td>{%= data[i][__("Voucher Type")] %}
|
||||
<br>{%= data[i][__("Voucher No")] %}</td>
|
||||
<td>{%= data[i][__("Customer Name")] || data[i][__("Customer")] || data[i][__("Supplier Name")] || data[i][__("Supplier")] %}
|
||||
<br>{%= __("Remarks") %}: {%= data[i][__("Remarks")] %}</td>
|
||||
<td>
|
||||
{% if(!(filters.customer || filters.supplier)) { %}
|
||||
{%= data[i][__("Customer Name")] || data[i][__("Customer")] || data[i][__("Supplier Name")] || data[i][__("Supplier")] %}<br>{%= __("Remarks") %}:
|
||||
{% } %}
|
||||
{%= data[i][__("Remarks")] %}
|
||||
</td>
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">
|
||||
@@ -59,8 +63,13 @@
|
||||
{% } else { %}
|
||||
{% if(data[i][__("Customer")] || data[i][__("Supplier")]|| " ") { %}
|
||||
{% if((data[i][__("Customer")] || data[i][__("Supplier")]) != __("'Total'")) { %}
|
||||
<td>{%= data[i][__("Customer")] || data[i][__("Supplier")] %}
|
||||
<br>{%= __("Remarks") %}: {%= data[i][__("Remarks")] %}</td>
|
||||
<td>
|
||||
{% if(!(filters.customer || filters.supplier)) { %}
|
||||
{%= data[i][__("Customer")] || data[i][__("Supplier")] %}
|
||||
<br>{%= __("Remarks") %}:
|
||||
{% } %}
|
||||
{%= data[i][__("Remarks")] %}
|
||||
</td>
|
||||
{% } else { %}
|
||||
<td><b>{%= __("Total") %}</b></td>
|
||||
{% } %}
|
||||
|
||||
@@ -99,7 +99,8 @@ def get_actual_details(name, filters):
|
||||
where
|
||||
b.name = ba.parent
|
||||
and b.docstatus = 1
|
||||
and ba.account=gl.account
|
||||
and ba.account=gl.account
|
||||
and b.{budget_against} = gl.{budget_against}
|
||||
and gl.fiscal_year=%s
|
||||
and b.{budget_against}=%s
|
||||
and exists(select name from `tab{tab}` where name=gl.{budget_against} and {cond})
|
||||
|
||||
@@ -142,10 +142,16 @@ def get_data(company, root_type, balance_must_be, period_list, filters=None,
|
||||
|
||||
return out
|
||||
|
||||
|
||||
def calculate_values(accounts_by_name, gl_entries_by_account, period_list, accumulated_values, ignore_accumulated_values_for_fy):
|
||||
for entries in gl_entries_by_account.values():
|
||||
for entry in entries:
|
||||
d = accounts_by_name.get(entry.account)
|
||||
if not d:
|
||||
frappe.msgprint(
|
||||
_("Could not retrieve information for {0}.".format(entry.account)), title="Error",
|
||||
raise_exception=1
|
||||
)
|
||||
for period in period_list:
|
||||
# check if posting date is within the period
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ frappe.query_reports["General Ledger"] = {
|
||||
return;
|
||||
}
|
||||
|
||||
var fieldname = party_type.toLowerCase() + "_name";
|
||||
var fieldname = frappe.model.scrub(party_type)+"_name";
|
||||
frappe.db.get_value(party_type, party, fieldname, function(value) {
|
||||
frappe.query_report_filters_by_name.party_name.set_value(value[fieldname]);
|
||||
});
|
||||
|
||||
@@ -17,7 +17,6 @@ def execute(filters=None):
|
||||
gross_profit_data = GrossProfitGenerator(filters)
|
||||
|
||||
data = []
|
||||
source = gross_profit_data.grouped_data if filters.get("group_by") != "Invoice" else gross_profit_data.data
|
||||
|
||||
group_wise_columns = frappe._dict({
|
||||
"invoice": ["parent", "customer", "customer_group", "posting_date","item_code", "item_name","item_group", "brand", "description", \
|
||||
@@ -45,7 +44,7 @@ def execute(filters=None):
|
||||
|
||||
columns = get_columns(group_wise_columns, filters)
|
||||
|
||||
for src in source:
|
||||
for src in gross_profit_data.grouped_data:
|
||||
row = []
|
||||
for col in group_wise_columns.get(scrub(filters.group_by)):
|
||||
row.append(src.get(col))
|
||||
@@ -103,6 +102,7 @@ class GrossProfitGenerator(object):
|
||||
self.load_stock_ledger_entries()
|
||||
self.load_product_bundle()
|
||||
self.load_non_stock_items()
|
||||
self.get_returned_invoice_items()
|
||||
self.process()
|
||||
|
||||
def process(self):
|
||||
@@ -143,40 +143,68 @@ class GrossProfitGenerator(object):
|
||||
row.gross_profit_percent = 0.0
|
||||
|
||||
# add to grouped
|
||||
if self.filters.group_by != "Invoice":
|
||||
self.grouped.setdefault(row.get(scrub(self.filters.group_by)), []).append(row)
|
||||
|
||||
self.data.append(row)
|
||||
self.grouped.setdefault(row.get(scrub(self.filters.group_by)), []).append(row)
|
||||
|
||||
if self.grouped:
|
||||
self.get_average_rate_based_on_group_by()
|
||||
else:
|
||||
self.grouped_data = []
|
||||
|
||||
def get_average_rate_based_on_group_by(self):
|
||||
# sum buying / selling totals for group
|
||||
self.grouped_data = []
|
||||
for key in self.grouped.keys():
|
||||
for i, row in enumerate(self.grouped[key]):
|
||||
if i==0:
|
||||
new_row = row
|
||||
else:
|
||||
new_row.qty += row.qty
|
||||
new_row.buying_amount += row.buying_amount
|
||||
new_row.base_amount += row.base_amount
|
||||
if self.filters.get("group_by") != "Invoice":
|
||||
for i, row in enumerate(self.grouped[key]):
|
||||
if i==0:
|
||||
new_row = row
|
||||
else:
|
||||
new_row.qty += row.qty
|
||||
new_row.buying_amount += row.buying_amount
|
||||
new_row.base_amount += row.base_amount
|
||||
new_row = self.set_average_rate(new_row)
|
||||
self.grouped_data.append(new_row)
|
||||
else:
|
||||
for i, row in enumerate(self.grouped[key]):
|
||||
if row.parent in self.returned_invoices \
|
||||
and row.item_code in self.returned_invoices[row.parent]:
|
||||
returned_item_rows = self.returned_invoices[row.parent][row.item_code]
|
||||
for returned_item_row in returned_item_rows:
|
||||
row.qty += returned_item_row.qty
|
||||
row.base_amount += returned_item_row.base_amount
|
||||
row.buying_amount = row.qty * row.buying_rate
|
||||
if row.qty:
|
||||
row = self.set_average_rate(row)
|
||||
self.grouped_data.append(row)
|
||||
|
||||
new_row.gross_profit = new_row.base_amount - new_row.buying_amount
|
||||
new_row.gross_profit_percent = ((new_row.gross_profit / new_row.base_amount) * 100.0) \
|
||||
if new_row.base_amount else 0
|
||||
new_row.buying_rate = (new_row.buying_amount / new_row.qty) \
|
||||
if new_row.qty else 0
|
||||
new_row.base_rate = (new_row.base_amount / new_row.qty) \
|
||||
if new_row.qty else 0
|
||||
def set_average_rate(self, new_row):
|
||||
new_row.gross_profit = new_row.base_amount - new_row.buying_amount
|
||||
new_row.gross_profit_percent = ((new_row.gross_profit / new_row.base_amount) * 100.0) \
|
||||
if new_row.base_amount else 0
|
||||
new_row.buying_rate = (new_row.buying_amount / new_row.qty) if new_row.qty else 0
|
||||
new_row.base_rate = (new_row.base_amount / new_row.qty) if new_row.qty else 0
|
||||
return new_row
|
||||
|
||||
self.grouped_data.append(new_row)
|
||||
def get_returned_invoice_items(self):
|
||||
returned_invoices = frappe.db.sql("""
|
||||
select
|
||||
si.name, si_item.item_code, si_item.qty, si_item.base_amount, si.return_against
|
||||
from
|
||||
`tabSales Invoice` si, `tabSales Invoice Item` si_item
|
||||
where
|
||||
si.name = si_item.parent
|
||||
and si.docstatus = 1
|
||||
and si.is_return = 1
|
||||
""", as_dict=1)
|
||||
|
||||
self.returned_invoices = frappe._dict()
|
||||
for inv in returned_invoices:
|
||||
self.returned_invoices.setdefault(inv.return_against, frappe._dict())\
|
||||
.setdefault(inv.item_code, []).append(inv)
|
||||
|
||||
def skip_row(self, row, product_bundles):
|
||||
if self.filters.get("group_by") != "Invoice" and not row.get(scrub(self.filters.get("group_by"))):
|
||||
if self.filters.get("group_by") != "Invoice":
|
||||
if not row.get(scrub(self.filters.get("group_by"))):
|
||||
return True
|
||||
elif row.get("is_return") == 1:
|
||||
return True
|
||||
|
||||
def get_buying_amount_from_product_bundle(self, row, product_bundle):
|
||||
@@ -268,20 +296,26 @@ class GrossProfitGenerator(object):
|
||||
sales_person_cols = ""
|
||||
sales_team_table = ""
|
||||
|
||||
self.si_list = frappe.db.sql("""select `tabSales Invoice Item`.parenttype, `tabSales Invoice Item`.parent,
|
||||
`tabSales Invoice`.posting_date, `tabSales Invoice`.posting_time, `tabSales Invoice`.project, `tabSales Invoice`.update_stock,
|
||||
`tabSales Invoice`.customer, `tabSales Invoice`.customer_group, `tabSales Invoice`.territory,
|
||||
`tabSales Invoice Item`.item_code, `tabSales Invoice Item`.item_name, `tabSales Invoice Item`.description,
|
||||
`tabSales Invoice Item`.warehouse, `tabSales Invoice Item`.item_group, `tabSales Invoice Item`.brand,
|
||||
`tabSales Invoice Item`.dn_detail, `tabSales Invoice Item`.delivery_note, `tabSales Invoice Item`.stock_qty as qty,
|
||||
`tabSales Invoice Item`.base_net_rate, `tabSales Invoice Item`.base_net_amount, `tabSales Invoice Item`.name as "item_row"
|
||||
self.si_list = frappe.db.sql("""
|
||||
select
|
||||
`tabSales Invoice Item`.parenttype, `tabSales Invoice Item`.parent,
|
||||
`tabSales Invoice`.posting_date, `tabSales Invoice`.posting_time,
|
||||
`tabSales Invoice`.project, `tabSales Invoice`.update_stock,
|
||||
`tabSales Invoice`.customer, `tabSales Invoice`.customer_group,
|
||||
`tabSales Invoice`.territory, `tabSales Invoice Item`.item_code,
|
||||
`tabSales Invoice Item`.item_name, `tabSales Invoice Item`.description,
|
||||
`tabSales Invoice Item`.warehouse, `tabSales Invoice Item`.item_group,
|
||||
`tabSales Invoice Item`.brand, `tabSales Invoice Item`.dn_detail,
|
||||
`tabSales Invoice Item`.delivery_note, `tabSales Invoice Item`.stock_qty as qty,
|
||||
`tabSales Invoice Item`.base_net_rate, `tabSales Invoice Item`.base_net_amount,
|
||||
`tabSales Invoice Item`.name as "item_row", `tabSales Invoice`.is_return
|
||||
{sales_person_cols}
|
||||
from
|
||||
`tabSales Invoice`
|
||||
inner join `tabSales Invoice Item` on `tabSales Invoice Item`.parent = `tabSales Invoice`.name
|
||||
`tabSales Invoice` inner join `tabSales Invoice Item`
|
||||
on `tabSales Invoice Item`.parent = `tabSales Invoice`.name
|
||||
{sales_team_table}
|
||||
where
|
||||
`tabSales Invoice`.docstatus = 1 {conditions} {match_cond}
|
||||
`tabSales Invoice`.docstatus=1 {conditions} {match_cond}
|
||||
order by
|
||||
`tabSales Invoice`.posting_date desc, `tabSales Invoice`.posting_time desc"""
|
||||
.format(conditions=conditions, sales_person_cols=sales_person_cols,
|
||||
|
||||
@@ -7,7 +7,7 @@ frappe.query_reports["Item-wise Purchase Register"] = {
|
||||
"fieldname":"from_date",
|
||||
"label": __("From Date"),
|
||||
"fieldtype": "Date",
|
||||
"default": frappe.defaults.get_user_default("year_start_date"),
|
||||
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
|
||||
"width": "80"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import frappe, erpnext
|
||||
from frappe import _
|
||||
from frappe.utils import flt
|
||||
from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import get_tax_accounts
|
||||
@@ -14,10 +14,12 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
if not filters: filters = {}
|
||||
columns = get_columns(additional_table_columns)
|
||||
|
||||
company_currency = erpnext.get_company_currency(filters.company)
|
||||
|
||||
item_list = get_items(filters, additional_query_columns)
|
||||
aii_account_map = get_aii_accounts()
|
||||
if item_list:
|
||||
itemised_tax, tax_columns = get_tax_accounts(item_list, columns,
|
||||
itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency,
|
||||
doctype="Purchase Invoice", tax_doctype="Purchase Taxes and Charges")
|
||||
|
||||
columns.append({
|
||||
@@ -26,7 +28,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
"fieldtype": "Data",
|
||||
"width": 80
|
||||
})
|
||||
company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
|
||||
|
||||
po_pr_map = get_purchase_receipts_against_purchase_order(item_list)
|
||||
|
||||
data = []
|
||||
@@ -47,7 +49,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
|
||||
row += [
|
||||
d.credit_to, d.mode_of_payment, d.project, d.company, d.purchase_order,
|
||||
purchase_receipt, expense_account, d.qty, d.stock_uom, d.base_net_rate, d.base_net_amount
|
||||
purchase_receipt, expense_account, d.stock_qty, d.stock_uom, d.base_net_rate, d.base_net_amount
|
||||
]
|
||||
|
||||
total_tax = 0
|
||||
@@ -79,7 +81,7 @@ def get_columns(additional_table_columns):
|
||||
_("Mode of Payment") + ":Link/Mode of Payment:80", _("Project") + ":Link/Project:80",
|
||||
_("Company") + ":Link/Company:100", _("Purchase Order") + ":Link/Purchase Order:100",
|
||||
_("Purchase Receipt") + ":Link/Purchase Receipt:100", _("Expense Account") + ":Link/Account:140",
|
||||
_("Qty") + ":Float:120", _("Stock UOM") + "::100",
|
||||
_("Stock Qty") + ":Float:120", _("Stock UOM") + "::100",
|
||||
_("Rate") + ":Currency/currency:120", _("Amount") + ":Currency/currency:120"
|
||||
]
|
||||
|
||||
@@ -89,10 +91,10 @@ def get_conditions(filters):
|
||||
conditions = ""
|
||||
|
||||
for opts in (("company", " and company=%(company)s"),
|
||||
("supplier", " and pi.supplier = %(supplier)s"),
|
||||
("item_code", " and pi_item.item_code = %(item_code)s"),
|
||||
("from_date", " and pi.posting_date>=%(from_date)s"),
|
||||
("to_date", " and pi.posting_date<=%(to_date)s"),
|
||||
("supplier", " and `tabPurchase Invoice`.supplier = %(supplier)s"),
|
||||
("item_code", " and `tabPurchase Invoice Item`.item_code = %(item_code)s"),
|
||||
("from_date", " and `tabPurchase Invoice`.posting_date>=%(from_date)s"),
|
||||
("to_date", " and `tabPurchase Invoice`.posting_date<=%(to_date)s"),
|
||||
("mode_of_payment", " and ifnull(mode_of_payment, '') = %(mode_of_payment)s")):
|
||||
if filters.get(opts[0]):
|
||||
conditions += opts[1]
|
||||
@@ -102,20 +104,29 @@ def get_conditions(filters):
|
||||
def get_items(filters, additional_query_columns):
|
||||
conditions = get_conditions(filters)
|
||||
match_conditions = frappe.build_match_conditions("Purchase Invoice")
|
||||
|
||||
if match_conditions:
|
||||
match_conditions = " and {0} ".format(match_conditions)
|
||||
|
||||
if additional_query_columns:
|
||||
additional_query_columns = ', ' + ', '.join(additional_query_columns)
|
||||
|
||||
return frappe.db.sql("""
|
||||
select
|
||||
pi_item.name, pi_item.parent, pi.posting_date, pi.credit_to, pi.company,
|
||||
pi.supplier, pi.remarks, pi.base_net_total, pi_item.item_code, pi_item.item_name,
|
||||
pi_item.item_group, pi_item.project, pi_item.purchase_order, pi_item.purchase_receipt,
|
||||
pi_item.po_detail, pi_item.expense_account, pi_item.qty, pi_item.stock_uom,
|
||||
pi_item.base_net_rate, pi_item.base_net_amount,
|
||||
pi.supplier_name, pi.mode_of_payment {0}
|
||||
from `tabPurchase Invoice` pi, `tabPurchase Invoice Item` pi_item
|
||||
where pi.name = pi_item.parent and pi.docstatus = 1 %s %s
|
||||
order by pi.posting_date desc, pi_item.item_code desc
|
||||
`tabPurchase Invoice Item`.`name`, `tabPurchase Invoice Item`.`parent`,
|
||||
`tabPurchase Invoice`.posting_date, `tabPurchase Invoice`.credit_to, `tabPurchase Invoice`.company,
|
||||
`tabPurchase Invoice`.supplier, `tabPurchase Invoice`.remarks, `tabPurchase Invoice`.base_net_total, `tabPurchase Invoice Item`.`item_code`,
|
||||
`tabPurchase Invoice Item`.`item_name`, `tabPurchase Invoice Item`.`item_group`,
|
||||
`tabPurchase Invoice Item`.`project`, `tabPurchase Invoice Item`.`purchase_order`,
|
||||
`tabPurchase Invoice Item`.`purchase_receipt`, `tabPurchase Invoice Item`.`po_detail`,
|
||||
`tabPurchase Invoice Item`.`expense_account`, `tabPurchase Invoice Item`.`stock_qty`,
|
||||
`tabPurchase Invoice Item`.`stock_uom`, `tabPurchase Invoice Item`.`base_net_rate`,
|
||||
`tabPurchase Invoice Item`.`base_net_amount`,
|
||||
`tabPurchase Invoice`.supplier_name, `tabPurchase Invoice`.mode_of_payment {0}
|
||||
from `tabPurchase Invoice`, `tabPurchase Invoice Item`
|
||||
where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and
|
||||
`tabPurchase Invoice`.docstatus = 1 %s %s
|
||||
order by `tabPurchase Invoice`.posting_date desc, `tabPurchase Invoice Item`.item_code desc
|
||||
""".format(additional_query_columns) % (conditions, match_conditions), filters, as_dict=1)
|
||||
|
||||
def get_aii_accounts():
|
||||
|
||||
@@ -7,7 +7,7 @@ frappe.query_reports["Item-wise Sales Register"] = frappe.query_reports["Sales R
|
||||
"fieldname":"from_date",
|
||||
"label": __("From Date"),
|
||||
"fieldtype": "Date",
|
||||
"default": frappe.defaults.get_default("year_start_date"),
|
||||
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
|
||||
"width": "80"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import frappe, erpnext
|
||||
from frappe import _
|
||||
from frappe.utils import flt
|
||||
from frappe.model.meta import get_field_precision
|
||||
from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments
|
||||
|
||||
def execute(filters=None):
|
||||
@@ -14,16 +15,17 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
if not filters: filters = {}
|
||||
columns = get_columns(additional_table_columns)
|
||||
|
||||
company_currency = erpnext.get_company_currency(filters.company)
|
||||
|
||||
item_list = get_items(filters, additional_query_columns)
|
||||
if item_list:
|
||||
itemised_tax, tax_columns = get_tax_accounts(item_list, columns)
|
||||
itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency)
|
||||
columns.append({
|
||||
"fieldname": "currency",
|
||||
"label": _("Currency"),
|
||||
"fieldtype": "Data",
|
||||
"width": 80
|
||||
})
|
||||
company_currency = frappe.db.get_value("Company", filters.get("company"), "default_currency")
|
||||
mode_of_payments = get_mode_of_payments(set([d.parent for d in item_list]))
|
||||
so_dn_map = get_delivery_notes_against_sales_order(item_list)
|
||||
|
||||
@@ -47,7 +49,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
row += [
|
||||
d.customer_group, d.debit_to, ", ".join(mode_of_payments.get(d.parent, [])),
|
||||
d.territory, d.project, d.company, d.sales_order,
|
||||
delivery_note, d.income_account, d.cost_center, d.qty, d.stock_uom,
|
||||
delivery_note, d.income_account, d.cost_center, d.stock_qty, d.stock_uom,
|
||||
d.base_net_rate, d.base_net_amount
|
||||
]
|
||||
|
||||
@@ -80,7 +82,7 @@ def get_columns(additional_table_columns):
|
||||
_("Project") + ":Link/Project:80", _("Company") + ":Link/Company:100",
|
||||
_("Sales Order") + ":Link/Sales Order:100", _("Delivery Note") + ":Link/Delivery Note:100",
|
||||
_("Income Account") + ":Link/Account:140", _("Cost Center") + ":Link/Cost Center:140",
|
||||
_("Qty") + ":Float:120", _("Stock UOM") + "::100",
|
||||
_("Stock Qty") + ":Float:120", _("Stock UOM") + "::100",
|
||||
_("Rate") + ":Currency/currency:120",
|
||||
_("Amount") + ":Currency/currency:120"
|
||||
]
|
||||
@@ -91,37 +93,49 @@ def get_conditions(filters):
|
||||
conditions = ""
|
||||
|
||||
for opts in (("company", " and company=%(company)s"),
|
||||
("customer", " and si.customer = %(customer)s"),
|
||||
("item_code", " and si_item.item_code = %(item_code)s"),
|
||||
("from_date", " and si.posting_date>=%(from_date)s"),
|
||||
("to_date", " and si.posting_date<=%(to_date)s")):
|
||||
("customer", " and `tabSales Invoice`.customer = %(customer)s"),
|
||||
("item_code", " and `tabSales Invoice Item`.item_code = %(item_code)s"),
|
||||
("from_date", " and `tabSales Invoice`.posting_date>=%(from_date)s"),
|
||||
("to_date", " and `tabSales Invoice`.posting_date<=%(to_date)s")):
|
||||
if filters.get(opts[0]):
|
||||
conditions += opts[1]
|
||||
|
||||
if filters.get("mode_of_payment"):
|
||||
conditions += """ and exists(select name from `tabSales Invoice Payment`
|
||||
where parent=si.name
|
||||
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
|
||||
where parent=si.name
|
||||
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
|
||||
|
||||
return conditions
|
||||
|
||||
def get_items(filters, additional_query_columns):
|
||||
conditions = get_conditions(filters)
|
||||
match_conditions = frappe.build_match_conditions("Sales Invoice")
|
||||
|
||||
if match_conditions:
|
||||
match_conditions = " and {0} ".format(match_conditions)
|
||||
|
||||
if additional_query_columns:
|
||||
additional_query_columns = ', ' + ', '.join(additional_query_columns)
|
||||
|
||||
conditions = get_conditions(filters)
|
||||
return frappe.db.sql("""
|
||||
select
|
||||
si_item.name, si_item.parent, si.posting_date, si.debit_to, si.project,
|
||||
si.customer, si.remarks, si.territory, si.company, si.base_net_total,
|
||||
si_item.item_code, si_item.item_name, si_item.item_group, si_item.sales_order,
|
||||
si_item.delivery_note, si_item.income_account, si_item.cost_center,
|
||||
si_item.qty, si_item.stock_uom, si_item.base_net_rate, si_item.base_net_amount,
|
||||
si.customer_name, si.customer_group, si_item.so_detail, si.update_stock {0}
|
||||
from `tabSales Invoice` si, `tabSales Invoice Item` si_item
|
||||
where si.name = si_item.parent and si.docstatus = 1 %s
|
||||
order by si.posting_date desc, si_item.item_code desc
|
||||
""".format(additional_query_columns or '') % conditions, filters, as_dict=1)
|
||||
`tabSales Invoice Item`.name, `tabSales Invoice Item`.parent,
|
||||
`tabSales Invoice`.posting_date, `tabSales Invoice`.debit_to,
|
||||
`tabSales Invoice`.project, `tabSales Invoice`.customer, `tabSales Invoice`.remarks,
|
||||
`tabSales Invoice`.territory, `tabSales Invoice`.company, `tabSales Invoice`.base_net_total,
|
||||
`tabSales Invoice Item`.item_code, `tabSales Invoice Item`.item_name,
|
||||
`tabSales Invoice Item`.item_group, `tabSales Invoice Item`.sales_order,
|
||||
`tabSales Invoice Item`.delivery_note, `tabSales Invoice Item`.income_account,
|
||||
`tabSales Invoice Item`.cost_center, `tabSales Invoice Item`.stock_qty,
|
||||
`tabSales Invoice Item`.stock_uom, `tabSales Invoice Item`.base_net_rate,
|
||||
`tabSales Invoice Item`.base_net_amount, `tabSales Invoice`.customer_name,
|
||||
`tabSales Invoice`.customer_group, `tabSales Invoice Item`.so_detail,
|
||||
`tabSales Invoice`.update_stock {0}
|
||||
from `tabSales Invoice`, `tabSales Invoice Item`
|
||||
where `tabSales Invoice`.name = `tabSales Invoice Item`.parent
|
||||
and `tabSales Invoice`.docstatus = 1 %s %s
|
||||
order by `tabSales Invoice`.posting_date desc, `tabSales Invoice Item`.item_code desc
|
||||
""".format(additional_query_columns or '') % (conditions, match_conditions), filters, as_dict=1)
|
||||
|
||||
def get_delivery_notes_against_sales_order(item_list):
|
||||
so_dn_map = frappe._dict()
|
||||
@@ -140,16 +154,25 @@ def get_delivery_notes_against_sales_order(item_list):
|
||||
|
||||
return so_dn_map
|
||||
|
||||
def get_tax_accounts(item_list, columns, doctype="Sales Invoice", tax_doctype="Sales Taxes and Charges"):
|
||||
def get_tax_accounts(item_list, columns, company_currency,
|
||||
doctype="Sales Invoice", tax_doctype="Sales Taxes and Charges"):
|
||||
import json
|
||||
item_row_map = {}
|
||||
tax_columns = []
|
||||
invoice_item_row = {}
|
||||
itemised_tax = {}
|
||||
|
||||
tax_amount_precision = get_field_precision(frappe.get_meta(tax_doctype).get_field("tax_amount"),
|
||||
currency=company_currency) or 2
|
||||
|
||||
for d in item_list:
|
||||
invoice_item_row.setdefault(d.parent, []).append(d)
|
||||
item_row_map.setdefault(d.parent, {}).setdefault(d.item_code, []).append(d)
|
||||
|
||||
conditions = ""
|
||||
if doctype == "Purchase Invoice":
|
||||
conditions = " and category in ('Total', 'Valuation and Total')"
|
||||
|
||||
tax_details = frappe.db.sql("""
|
||||
select
|
||||
parent, description, item_wise_tax_detail,
|
||||
@@ -159,8 +182,9 @@ def get_tax_accounts(item_list, columns, doctype="Sales Invoice", tax_doctype="S
|
||||
parenttype = %s and docstatus = 1
|
||||
and (description is not null and description != '')
|
||||
and parent in (%s)
|
||||
%s
|
||||
order by description
|
||||
""" % (tax_doctype, '%s', ', '.join(['%s']*len(invoice_item_row))),
|
||||
""" % (tax_doctype, '%s', ', '.join(['%s']*len(invoice_item_row)), conditions),
|
||||
tuple([doctype] + invoice_item_row.keys()))
|
||||
|
||||
for parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details:
|
||||
@@ -192,7 +216,7 @@ def get_tax_accounts(item_list, columns, doctype="Sales Invoice", tax_doctype="S
|
||||
if item_tax_amount:
|
||||
itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
|
||||
"tax_rate": tax_rate,
|
||||
"tax_amount": item_tax_amount
|
||||
"tax_amount": flt(item_tax_amount, tax_amount_precision)
|
||||
})
|
||||
|
||||
except ValueError:
|
||||
@@ -201,7 +225,8 @@ def get_tax_accounts(item_list, columns, doctype="Sales Invoice", tax_doctype="S
|
||||
for d in invoice_item_row.get(parent, []):
|
||||
itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
|
||||
"tax_rate": "NA",
|
||||
"tax_amount": flt((tax_amount * d.base_net_amount) / d.base_net_total)
|
||||
"tax_amount": flt((tax_amount * d.base_net_amount) / d.base_net_total,
|
||||
tax_amount_precision)
|
||||
})
|
||||
|
||||
tax_columns.sort()
|
||||
|
||||
@@ -7,7 +7,7 @@ frappe.query_reports["Purchase Register"] = {
|
||||
"fieldname":"from_date",
|
||||
"label": __("From Date"),
|
||||
"fieldtype": "Date",
|
||||
"default": frappe.defaults.get_user_default("year_start_date"),
|
||||
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
|
||||
"width": "80"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ frappe.query_reports["Sales Register"] = {
|
||||
"fieldname":"from_date",
|
||||
"label": __("From Date"),
|
||||
"fieldtype": "Date",
|
||||
"default": frappe.defaults.get_default("year_start_date"),
|
||||
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
|
||||
"width": "80"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -569,11 +569,11 @@ def get_stock_rbnb_difference(posting_date, company):
|
||||
# Amount should be credited
|
||||
return flt(stock_rbnb) + flt(sys_bal)
|
||||
|
||||
def get_outstanding_invoices(party_type, party, account, condition=None):
|
||||
def get_outstanding_invoices(party_type, party, account, condition=None, paying_party=False):
|
||||
outstanding_invoices = []
|
||||
precision = frappe.get_precision("Sales Invoice", "outstanding_amount")
|
||||
|
||||
if party_type=="Customer":
|
||||
if party_type=="Customer" or paying_party:
|
||||
dr_or_cr = "debit_in_account_currency - credit_in_account_currency"
|
||||
payment_dr_or_cr = "payment_gl_entry.credit_in_account_currency - payment_gl_entry.debit_in_account_currency"
|
||||
else:
|
||||
|
||||
@@ -13,6 +13,7 @@ frappe.ui.form.on("Purchase Order", {
|
||||
'Stock Entry': 'Material to Supplier'
|
||||
}
|
||||
},
|
||||
|
||||
onload: function(frm) {
|
||||
erpnext.queries.setup_queries(frm, "Warehouse", function() {
|
||||
return erpnext.queries.warehouse(frm.doc);
|
||||
@@ -20,8 +21,7 @@ frappe.ui.form.on("Purchase Order", {
|
||||
|
||||
frm.set_indicator_formatter('item_code',
|
||||
function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" })
|
||||
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend({
|
||||
@@ -86,8 +86,13 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
||||
if(flt(doc.per_billed)==0 && doc.status != "Delivered") {
|
||||
cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_payment_entry, __("Make"));
|
||||
}
|
||||
cur_frm.page.set_inner_btn_group_as_primary(__("Make"));
|
||||
|
||||
if(!doc.subscription) {
|
||||
cur_frm.add_custom_button(__('Subscription'), function() {
|
||||
erpnext.utils.make_subscription(doc.doctype, doc.name)
|
||||
}, __("Make"))
|
||||
}
|
||||
cur_frm.page.set_inner_btn_group_as_primary(__("Make"));
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -2102,6 +2102,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "base_rounding_adjustment",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Rounding Adjustment (Company Currency)",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2227,6 +2258,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "rounding_adjustment",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Rounding Adjustment",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2856,6 +2918,67 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "subscription_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Subscription Section",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "subscription",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Subscription",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Subscription",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2866,7 +2989,7 @@
|
||||
"depends_on": "eval:doc.docstatus<2 && !doc.__islocal",
|
||||
"fieldname": "recurring_order",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
@@ -3335,7 +3458,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-07-19 14:03:51.838328",
|
||||
"modified": "2017-09-19 11:22:30.190589",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order",
|
||||
|
||||
@@ -295,6 +295,7 @@ def make_purchase_receipt(source_name, target_doc=None):
|
||||
"field_map": {
|
||||
"name": "purchase_order_item",
|
||||
"parent": "purchase_order",
|
||||
"bom": "bom"
|
||||
},
|
||||
"postprocess": update_item,
|
||||
"condition": lambda doc: abs(doc.received_qty) < abs(doc.qty) and doc.delivered_by_supplier!=1
|
||||
|
||||
@@ -5,7 +5,8 @@ def get_data():
|
||||
'fieldname': 'purchase_order',
|
||||
'non_standard_fieldnames': {
|
||||
'Journal Entry': 'reference_name',
|
||||
'Payment Entry': 'reference_name'
|
||||
'Payment Entry': 'reference_name',
|
||||
'Subscription': 'reference_document'
|
||||
},
|
||||
'internal_links': {
|
||||
'Material Request': ['items', 'material_request'],
|
||||
@@ -23,11 +24,11 @@ def get_data():
|
||||
},
|
||||
{
|
||||
'label': _('Reference'),
|
||||
'items': ['Material Request', 'Supplier Quotation', 'Project']
|
||||
'items': ['Material Request', 'Supplier Quotation', 'Project', 'Subscription']
|
||||
},
|
||||
{
|
||||
'label': _('Sub-contracting'),
|
||||
'items': ['Stock Entry']
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
23
erpnext/buying/doctype/purchase_order/test_purchase_order.js
Normal file
23
erpnext/buying/doctype/purchase_order/test_purchase_order.js
Normal file
@@ -0,0 +1,23 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Purchase Order", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially('Purchase Order', [
|
||||
// insert a new Purchase Order
|
||||
() => frappe.tests.make([
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
@@ -0,0 +1,65 @@
|
||||
QUnit.module('Buying');
|
||||
|
||||
QUnit.test("test: purchase order", function(assert) {
|
||||
assert.expect(11);
|
||||
let done = assert.async();
|
||||
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{is_subcontracted: 'No'},
|
||||
{currency: 'INR'},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": 'Test Product 4'},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"qty": 5},
|
||||
{"uom": 'Unit'},
|
||||
{"rate": 100},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]},
|
||||
|
||||
{tc_name: 'Test Term 1'},
|
||||
{terms: 'This is a term.'}
|
||||
]);
|
||||
},
|
||||
|
||||
() => {
|
||||
// Get supplier details
|
||||
assert.ok(cur_frm.doc.supplier_name == 'Test Supplier', "Supplier name correct");
|
||||
assert.ok($('div.control-value.like-disabled-input.for-description').text().includes('Contact 3'), "Contact display correct");
|
||||
assert.ok(cur_frm.doc.contact_email == 'test@supplier.com', "Contact email correct");
|
||||
// Get item details
|
||||
assert.ok(cur_frm.doc.items[0].item_name == 'Test Product 4', "Item name correct");
|
||||
assert.ok(cur_frm.doc.items[0].description == 'Test Product 4', "Description correct");
|
||||
assert.ok(cur_frm.doc.items[0].qty == 5, "Quantity correct");
|
||||
// Calculate total
|
||||
assert.ok(cur_frm.doc.total == 500, "Total correct");
|
||||
// Get terms
|
||||
assert.ok(cur_frm.doc.terms == 'This is a term.', "Terms correct");
|
||||
},
|
||||
|
||||
() => cur_frm.print_doc(),
|
||||
() => frappe.timeout(2),
|
||||
() => {
|
||||
assert.ok($('.btn-print-print').is(':visible'), "Print Format Available");
|
||||
assert.ok($('div > div:nth-child(5) > div > div > table > tbody > tr > td:nth-child(4) > div').text().includes('Test Product 4'), "Print Preview Works");
|
||||
},
|
||||
|
||||
() => cur_frm.print_doc(),
|
||||
() => frappe.timeout(1),
|
||||
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.3),
|
||||
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.status == 'To Receive and Bill', "Submitted successfully");
|
||||
},
|
||||
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -0,0 +1,61 @@
|
||||
QUnit.module('Buying');
|
||||
|
||||
QUnit.test("test: purchase order with get items", function(assert) {
|
||||
assert.expect(4);
|
||||
let done = assert.async();
|
||||
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{is_subcontracted: 'No'},
|
||||
{buying_price_list: 'Test-Buying-USD'},
|
||||
{currency: 'USD'},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": 'Test Product 4'},
|
||||
{"qty": 5},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]}
|
||||
]);
|
||||
},
|
||||
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.supplier_name == 'Test Supplier', "Supplier name correct");
|
||||
},
|
||||
|
||||
() => frappe.timeout(0.3),
|
||||
() => frappe.click_button('Get items from'),
|
||||
() => frappe.timeout(0.3),
|
||||
|
||||
() => frappe.click_link('Product Bundle'),
|
||||
() => frappe.timeout(0.5),
|
||||
|
||||
() => cur_dialog.set_value('product_bundle', 'Computer'),
|
||||
() => frappe.click_button('Get Items'),
|
||||
() => frappe.timeout(1),
|
||||
|
||||
// Check if items are fetched from Product Bundle
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.items[1].item_name == 'CPU', "Product bundle item 1 correct");
|
||||
assert.ok(cur_frm.doc.items[2].item_name == 'Screen', "Product bundle item 2 correct");
|
||||
assert.ok(cur_frm.doc.items[3].item_name == 'Keyboard', "Product bundle item 3 correct");
|
||||
},
|
||||
|
||||
() => cur_frm.doc.items[1].warehouse = 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company")),
|
||||
() => cur_frm.doc.items[2].warehouse = 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company")),
|
||||
() => cur_frm.doc.items[3].warehouse = 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company")),
|
||||
|
||||
() => cur_frm.save(),
|
||||
() => frappe.timeout(1),
|
||||
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.3),
|
||||
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -0,0 +1,74 @@
|
||||
QUnit.module('Buying');
|
||||
|
||||
QUnit.test("test: purchase order receipt", function(assert) {
|
||||
assert.expect(5);
|
||||
let done = assert.async();
|
||||
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{is_subcontracted: 'No'},
|
||||
{buying_price_list: 'Test-Buying-USD'},
|
||||
{currency: 'USD'},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": 'Test Product 1'},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"qty": 5},
|
||||
{"uom": 'Unit'},
|
||||
{"rate": 100},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]},
|
||||
]);
|
||||
},
|
||||
|
||||
() => {
|
||||
|
||||
// Check supplier and item details
|
||||
assert.ok(cur_frm.doc.supplier_name == 'Test Supplier', "Supplier name correct");
|
||||
assert.ok(cur_frm.doc.items[0].item_name == 'Test Product 1', "Item name correct");
|
||||
assert.ok(cur_frm.doc.items[0].description == 'Test Product 1', "Description correct");
|
||||
assert.ok(cur_frm.doc.items[0].qty == 5, "Quantity correct");
|
||||
|
||||
},
|
||||
|
||||
() => frappe.timeout(1),
|
||||
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
|
||||
() => frappe.timeout(1.5),
|
||||
() => frappe.click_button('Close'),
|
||||
() => frappe.timeout(0.3),
|
||||
|
||||
// Make Purchase Receipt
|
||||
() => frappe.click_button('Make'),
|
||||
() => frappe.timeout(0.3),
|
||||
|
||||
() => frappe.click_link('Receipt'),
|
||||
() => frappe.timeout(2),
|
||||
|
||||
() => cur_frm.save(),
|
||||
|
||||
// Save and submit Purchase Receipt
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(1),
|
||||
|
||||
// View Purchase order in Stock Ledger
|
||||
() => frappe.click_button('View'),
|
||||
() => frappe.timeout(0.3),
|
||||
|
||||
() => frappe.click_link('Stock Ledger'),
|
||||
() => frappe.timeout(2),
|
||||
() => {
|
||||
assert.ok($('div.slick-cell.l2.r2 > a').text().includes('Test Product 1')
|
||||
&& $('div.slick-cell.l9.r9 > div').text().includes(5), "Stock ledger entry correct");
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -0,0 +1,47 @@
|
||||
QUnit.module('Buying');
|
||||
|
||||
QUnit.test("test: purchase order with discount on grand total", function(assert) {
|
||||
assert.expect(4);
|
||||
let done = assert.async();
|
||||
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{is_subcontracted: 'No'},
|
||||
{buying_price_list: 'Test-Buying-EUR'},
|
||||
{currency: 'EUR'},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": 'Test Product 4'},
|
||||
{"qty": 5},
|
||||
{"uom": 'Unit'},
|
||||
{"rate": 500 },
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]},
|
||||
{apply_discount_on: 'Grand Total'},
|
||||
{additional_discount_percentage: 10}
|
||||
]);
|
||||
},
|
||||
|
||||
() => frappe.timeout(1),
|
||||
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.supplier_name == 'Test Supplier', "Supplier name correct");
|
||||
assert.ok(cur_frm.doc.items[0].rate == 500, "Rate correct");
|
||||
// Calculate total
|
||||
assert.ok(cur_frm.doc.total == 2500, "Total correct");
|
||||
// Calculate grand total after discount
|
||||
assert.ok(cur_frm.doc.grand_total == 2250, "Grand total correct");
|
||||
},
|
||||
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.3),
|
||||
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
QUnit.module('Buying');
|
||||
|
||||
QUnit.test("test: purchase order with item wise discount", function(assert) {
|
||||
assert.expect(4);
|
||||
let done = assert.async();
|
||||
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{is_subcontracted: 'No'},
|
||||
{buying_price_list: 'Test-Buying-EUR'},
|
||||
{currency: 'EUR'},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": 'Test Product 4'},
|
||||
{"qty": 5},
|
||||
{"uom": 'Unit'},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))},
|
||||
{"discount_percentage": 20}
|
||||
]
|
||||
]}
|
||||
]);
|
||||
},
|
||||
|
||||
() => frappe.timeout(1),
|
||||
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.supplier_name == 'Test Supplier', "Supplier name correct");
|
||||
assert.ok(cur_frm.doc.items[0].discount_percentage == 20, "Discount correct");
|
||||
// Calculate totals after discount
|
||||
assert.ok(cur_frm.doc.total == 2000, "Total correct");
|
||||
assert.ok(cur_frm.doc.grand_total == 2000, "Grand total correct");
|
||||
},
|
||||
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.3),
|
||||
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -0,0 +1,39 @@
|
||||
QUnit.module('Buying');
|
||||
|
||||
QUnit.test("test: purchase order with multi UOM", function(assert) {
|
||||
assert.expect(3);
|
||||
let done = assert.async();
|
||||
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{is_subcontracted: 'No'},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": 'Test Product 4'},
|
||||
{"qty": 5},
|
||||
{"uom": 'Unit'},
|
||||
{"rate": 100},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]}
|
||||
]);
|
||||
},
|
||||
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.supplier_name == 'Test Supplier', "Supplier name correct");
|
||||
assert.ok(cur_frm.doc.items[0].item_name == 'Test Product 4', "Item name correct");
|
||||
assert.ok(cur_frm.doc.items[0].uom == 'Unit', "Multi UOM correct");
|
||||
},
|
||||
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.3),
|
||||
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
QUnit.module('Buying');
|
||||
|
||||
QUnit.test("test: purchase order with taxes and charges", function(assert) {
|
||||
assert.expect(3);
|
||||
let done = assert.async();
|
||||
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{is_subcontracted: 'No'},
|
||||
{buying_price_list: 'Test-Buying-USD'},
|
||||
{currency: 'USD'},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": 'Test Product 4'},
|
||||
{"qty": 5},
|
||||
{"uom": 'Unit'},
|
||||
{"rate": 500 },
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]},
|
||||
|
||||
{taxes_and_charges: 'TEST In State GST'}
|
||||
]);
|
||||
},
|
||||
|
||||
() => {
|
||||
// Check taxes and calculate grand total
|
||||
assert.ok(cur_frm.doc.taxes[1].account_head=='SGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), "Account Head abbr correct");
|
||||
assert.ok(cur_frm.doc.total_taxes_and_charges == 225, "Taxes and charges correct");
|
||||
assert.ok(cur_frm.doc.grand_total == 2725, "Grand total correct");
|
||||
},
|
||||
|
||||
() => frappe.timeout(0.3),
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.3),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -12,11 +12,11 @@ frappe.ui.form.on("Request for Quotation",{
|
||||
'Supplier Quotation': 'Supplier Quotation'
|
||||
}
|
||||
|
||||
frm.fields_dict["suppliers"].grid.get_field("contact").get_query = function(doc, cdt, cdn){
|
||||
var d =locals[cdt][cdn];
|
||||
frm.fields_dict["suppliers"].grid.get_field("contact").get_query = function(doc, cdt, cdn) {
|
||||
let d = locals[cdt][cdn];
|
||||
return {
|
||||
query: "erpnext.buying.doctype.request_for_quotation.request_for_quotation.get_supplier_contacts",
|
||||
filters: {'supplier': doc.supplier}
|
||||
filters: {'supplier': d.supplier}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -138,7 +138,6 @@ frappe.ui.form.on("Request for Quotation",{
|
||||
dialog.show();
|
||||
|
||||
},
|
||||
|
||||
make_suppplier_quotation: function(frm) {
|
||||
var doc = frm.doc;
|
||||
var dialog = new frappe.ui.Dialog({
|
||||
@@ -207,6 +206,29 @@ frappe.ui.form.on("Request for Quotation Supplier",{
|
||||
if(!w) {
|
||||
frappe.msgprint(__("Please enable pop-ups")); return;
|
||||
}
|
||||
},
|
||||
no_quote: function(frm, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if (d.no_quote) {
|
||||
if (d.quote_status != __('Received')) {
|
||||
frappe.model.set_value(cdt, cdn, 'quote_status', 'No Quote');
|
||||
} else {
|
||||
frappe.msgprint(__("Cannot set a received RFQ to No Quote"));
|
||||
frappe.model.set_value(cdt, cdn, 'no_quote', 0);
|
||||
}
|
||||
} else {
|
||||
d.quote_status = __('Pending');
|
||||
frm.call({
|
||||
method:"update_rfq_supplier_status",
|
||||
doc: frm.doc,
|
||||
args: {
|
||||
sup_name: d.supplier
|
||||
},
|
||||
callback: function(r) {
|
||||
frm.refresh_field("suppliers");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ class RequestforQuotation(BuyingController):
|
||||
frappe.db.set(self, 'status', 'Submitted')
|
||||
for supplier in self.suppliers:
|
||||
supplier.email_sent = 0
|
||||
supplier.quote_status = 'Pending'
|
||||
|
||||
def on_cancel(self):
|
||||
frappe.db.set(self, 'status', 'Cancelled')
|
||||
@@ -157,6 +158,28 @@ class RequestforQuotation(BuyingController):
|
||||
attachments.append(frappe.attach_print(self.doctype, self.name, doc=self))
|
||||
return attachments
|
||||
|
||||
def update_rfq_supplier_status(self, sup_name=None):
|
||||
for supplier in self.suppliers:
|
||||
if sup_name == None or supplier.supplier == sup_name:
|
||||
if supplier.quote_status != _('No Quote'):
|
||||
quote_status = _('Received')
|
||||
for item in self.items:
|
||||
sqi_count = frappe.db.sql("""
|
||||
SELECT
|
||||
COUNT(sqi.name) as count
|
||||
FROM
|
||||
`tabSupplier Quotation Item` as sqi,
|
||||
`tabSupplier Quotation` as sq
|
||||
WHERE sq.supplier = %(supplier)s
|
||||
AND sqi.docstatus = 1
|
||||
AND sqi.request_for_quotation_item = %(rqi)s
|
||||
AND sqi.parent = sq.name""",
|
||||
{"supplier": supplier.supplier, "rqi": item.name}, as_dict=1)[0]
|
||||
if (sqi_count.count) == 0:
|
||||
quote_status = _('Pending')
|
||||
supplier.quote_status = quote_status
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def send_supplier_emails(rfq_name):
|
||||
check_portal_enabled('Request for Quotation')
|
||||
@@ -172,13 +195,18 @@ def check_portal_enabled(reference_doctype):
|
||||
def get_list_context(context=None):
|
||||
from erpnext.controllers.website_list_for_contact import get_list_context
|
||||
list_context = get_list_context(context)
|
||||
list_context["show_sidebar"] = True
|
||||
list_context.update({
|
||||
'show_sidebar': True,
|
||||
'show_search': True,
|
||||
'no_breadcrumbs': True,
|
||||
'title': _('Request for Quotation'),
|
||||
})
|
||||
return list_context
|
||||
|
||||
def get_supplier_contacts(doctype, txt, searchfield, start, page_len, filters):
|
||||
return frappe.db.sql(""" select `tabContact`.name from `tabContact`, `tabDynamic Link`
|
||||
where `tabDynamic Link`.link_doctype = 'Supplier' and (`tabDynamic Link`.link_name = %(name)s
|
||||
or `tabDynamic Link`.link_name like %(txt)s) and `tabContact`.name = `tabDynamic Link`.parent
|
||||
return frappe.db.sql("""select `tabContact`.name from `tabContact`, `tabDynamic Link`
|
||||
where `tabDynamic Link`.link_doctype = 'Supplier' and (`tabDynamic Link`.link_name=%(name)s
|
||||
and `tabDynamic Link`.link_name like %(txt)s) and `tabContact`.name = `tabDynamic Link`.parent
|
||||
limit %(start)s, %(page_len)s""", {"start": start, "page_len":page_len, "txt": "%%%s%%" % txt, "name": filters.get('supplier')})
|
||||
|
||||
# This method is used to make supplier quotation from material request form.
|
||||
|
||||
@@ -10,21 +10,41 @@ from erpnext.templates.pages.rfq import check_supplier_has_docname_access
|
||||
from frappe.utils import nowdate
|
||||
|
||||
class TestRequestforQuotation(unittest.TestCase):
|
||||
def test_quote_status(self):
|
||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
|
||||
rfq = make_request_for_quotation()
|
||||
|
||||
self.assertEquals(rfq.get('suppliers')[0].quote_status, 'Pending')
|
||||
self.assertEquals(rfq.get('suppliers')[1].quote_status, 'Pending')
|
||||
|
||||
# Submit the first supplier quotation
|
||||
sq = make_supplier_quotation(rfq.name, rfq.get('suppliers')[0].supplier)
|
||||
sq.submit()
|
||||
|
||||
# No Quote first supplier quotation
|
||||
rfq.get('suppliers')[1].no_quote = 1
|
||||
rfq.get('suppliers')[1].quote_status = 'No Quote'
|
||||
|
||||
rfq.update_rfq_supplier_status() #rfq.get('suppliers')[1].supplier)
|
||||
|
||||
self.assertEquals(rfq.get('suppliers')[0].quote_status, 'Received')
|
||||
self.assertEquals(rfq.get('suppliers')[1].quote_status, 'No Quote')
|
||||
|
||||
def test_make_supplier_quotation(self):
|
||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
|
||||
rfq = make_request_for_quotation()
|
||||
|
||||
|
||||
sq = make_supplier_quotation(rfq.name, rfq.get('suppliers')[0].supplier)
|
||||
sq.submit()
|
||||
|
||||
|
||||
sq1 = make_supplier_quotation(rfq.name, rfq.get('suppliers')[1].supplier)
|
||||
sq1.submit()
|
||||
|
||||
|
||||
self.assertEquals(sq.supplier, rfq.get('suppliers')[0].supplier)
|
||||
self.assertEquals(sq.get('items')[0].request_for_quotation, rfq.name)
|
||||
self.assertEquals(sq.get('items')[0].item_code, "_Test Item")
|
||||
self.assertEquals(sq.get('items')[0].qty, 5)
|
||||
|
||||
|
||||
self.assertEquals(sq1.supplier, rfq.get('suppliers')[1].supplier)
|
||||
self.assertEquals(sq1.get('items')[0].request_for_quotation, rfq.name)
|
||||
self.assertEquals(sq1.get('items')[0].item_code, "_Test Item")
|
||||
@@ -61,15 +81,15 @@ class TestRequestforQuotation(unittest.TestCase):
|
||||
rfq.get('items')[0].rate = 100
|
||||
rfq.supplier = rfq.suppliers[0].supplier
|
||||
supplier_quotation_name = create_supplier_quotation(rfq)
|
||||
|
||||
|
||||
supplier_quotation_doc = frappe.get_doc('Supplier Quotation', supplier_quotation_name)
|
||||
|
||||
|
||||
self.assertEquals(supplier_quotation_doc.supplier, rfq.get('suppliers')[0].supplier)
|
||||
self.assertEquals(supplier_quotation_doc.get('items')[0].request_for_quotation, rfq.name)
|
||||
self.assertEquals(supplier_quotation_doc.get('items')[0].item_code, "_Test Item")
|
||||
self.assertEquals(supplier_quotation_doc.get('items')[0].qty, 5)
|
||||
self.assertEquals(supplier_quotation_doc.get('items')[0].amount, 500)
|
||||
|
||||
|
||||
|
||||
def make_request_for_quotation(supplier_data=None):
|
||||
"""
|
||||
@@ -81,10 +101,10 @@ def make_request_for_quotation(supplier_data=None):
|
||||
rfq.status = 'Draft'
|
||||
rfq.company = '_Test Company'
|
||||
rfq.message_for_supplier = 'Please supply the specified items at the best possible rates.'
|
||||
|
||||
|
||||
for data in supplier_data:
|
||||
rfq.append('suppliers', data)
|
||||
|
||||
|
||||
rfq.append("items", {
|
||||
"item_code": "_Test Item",
|
||||
"description": "_Test Item",
|
||||
@@ -93,11 +113,11 @@ def make_request_for_quotation(supplier_data=None):
|
||||
"warehouse": "_Test Warehouse - _TC",
|
||||
"schedule_date": nowdate()
|
||||
})
|
||||
|
||||
|
||||
rfq.submit()
|
||||
|
||||
|
||||
return rfq
|
||||
|
||||
|
||||
def get_supplier_data():
|
||||
return [{
|
||||
"supplier": "_Test Supplier",
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
QUnit.module('Buying');
|
||||
|
||||
QUnit.test("test: request_for_quotation", function(assert) {
|
||||
assert.expect(14);
|
||||
let done = assert.async();
|
||||
let date;
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
date = frappe.datetime.add_days(frappe.datetime.now_date(), 10);
|
||||
return frappe.tests.make('Request for Quotation', [
|
||||
{transaction_date: date},
|
||||
{suppliers: [
|
||||
[
|
||||
{"supplier": 'Test Supplier'},
|
||||
{"email_id": 'test@supplier.com'}
|
||||
]
|
||||
]},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": 'Test Product 4'},
|
||||
{"qty": 5},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(),20)},
|
||||
{"warehouse": 'All Warehouses - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]},
|
||||
{message_for_supplier: 'Please supply the specified items at the best possible rates'},
|
||||
{tc_name: 'Test Term 1'}
|
||||
]);
|
||||
},
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.transaction_date == date, "Date correct");
|
||||
assert.ok(cur_frm.doc.company == cur_frm.doc.company, "Company correct");
|
||||
assert.ok(cur_frm.doc.suppliers[0].supplier_name == 'Test Supplier', "Supplier name correct");
|
||||
assert.ok(cur_frm.doc.suppliers[0].contact == 'Contact 3-Test Supplier', "Contact correct");
|
||||
assert.ok(cur_frm.doc.suppliers[0].email_id == 'test@supplier.com', "Email id correct");
|
||||
assert.ok(cur_frm.doc.items[0].item_name == 'Test Product 4', "Item Name correct");
|
||||
assert.ok(cur_frm.doc.items[0].warehouse == 'All Warehouses - '+frappe.get_abbr(frappe.defaults.get_default("Company")), "Warehouse correct");
|
||||
assert.ok(cur_frm.doc.message_for_supplier == 'Please supply the specified items at the best possible rates', "Reply correct");
|
||||
assert.ok(cur_frm.doc.tc_name == 'Test Term 1', "Term name correct");
|
||||
},
|
||||
() => frappe.timeout(0.3),
|
||||
() => cur_frm.print_doc(),
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
assert.ok($('.btn-print-print').is(':visible'), "Print Format Available");
|
||||
assert.ok($('.section-break+ .section-break .column-break:nth-child(1) .value').text().includes("Test Product 4"), "Print Preview Works");
|
||||
},
|
||||
() => cur_frm.print_doc(),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Get items from'),
|
||||
() => frappe.timeout(0.3),
|
||||
() => frappe.click_link('Material Request'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Get Items'),
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.items[1].item_name == 'Test Product 1', "Getting items from material requests work");
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.docstatus == 1, "Quotation request submitted");
|
||||
},
|
||||
() => frappe.click_button('Send Supplier Emails'),
|
||||
() => frappe.timeout(4),
|
||||
() => {
|
||||
assert.ok($('div.modal.fade.in > div.modal-dialog > div > div.modal-body.ui-front > div.msgprint').text().includes("Email sent to supplier Test Supplier"), "Send emails working");
|
||||
},
|
||||
() => frappe.click_button('Close'),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -0,0 +1,132 @@
|
||||
QUnit.module('buying');
|
||||
|
||||
QUnit.test("Test: Request for Quotation", function (assert) {
|
||||
assert.expect(5);
|
||||
let done = assert.async();
|
||||
let rfq_name = "";
|
||||
|
||||
frappe.run_serially([
|
||||
// Go to RFQ list
|
||||
() => frappe.set_route("List", "Request for Quotation"),
|
||||
// Create a new RFQ
|
||||
() => frappe.new_doc("Request for Quotation"),
|
||||
() => frappe.timeout(1),
|
||||
() => cur_frm.set_value("transaction_date", "04-04-2017"),
|
||||
() => cur_frm.set_value("company", "For Testing"),
|
||||
// Add Suppliers
|
||||
() => {
|
||||
cur_frm.fields_dict.suppliers.grid.grid_rows[0].toggle_view();
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
cur_frm.fields_dict.suppliers.grid.grid_rows[0].doc.supplier = "_Test Supplier";
|
||||
frappe.click_check('Send Email');
|
||||
cur_frm.cur_grid.frm.script_manager.trigger('supplier');
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
cur_frm.cur_grid.toggle_view();
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Add Row',0),
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
cur_frm.fields_dict.suppliers.grid.grid_rows[1].toggle_view();
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
cur_frm.fields_dict.suppliers.grid.grid_rows[1].doc.supplier = "_Test Supplier 1";
|
||||
frappe.click_check('Send Email');
|
||||
cur_frm.cur_grid.frm.script_manager.trigger('supplier');
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
cur_frm.cur_grid.toggle_view();
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
// Add Item
|
||||
() => {
|
||||
cur_frm.fields_dict.items.grid.grid_rows[0].toggle_view();
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
cur_frm.fields_dict.items.grid.grid_rows[0].doc.item_code = "_Test Item";
|
||||
frappe.set_control('item_code',"_Test Item");
|
||||
frappe.set_control('qty',5);
|
||||
frappe.set_control('schedule_date', "05-05-2017");
|
||||
cur_frm.cur_grid.frm.script_manager.trigger('supplier');
|
||||
},
|
||||
() => frappe.timeout(2),
|
||||
() => {
|
||||
cur_frm.cur_grid.toggle_view();
|
||||
},
|
||||
() => frappe.timeout(2),
|
||||
() => {
|
||||
cur_frm.fields_dict.items.grid.grid_rows[0].doc.warehouse = "_Test Warehouse - FT";
|
||||
},
|
||||
() => frappe.click_button('Save'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Submit'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Yes'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Menu'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_link('Reload'),
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.docstatus, 1);
|
||||
rfq_name = cur_frm.doc.name;
|
||||
assert.ok(cur_frm.fields_dict.suppliers.grid.grid_rows[0].doc.quote_status == "Pending");
|
||||
assert.ok(cur_frm.fields_dict.suppliers.grid.grid_rows[1].doc.quote_status == "Pending");
|
||||
},
|
||||
() => {
|
||||
cur_frm.fields_dict.suppliers.grid.grid_rows[0].toggle_view();
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
frappe.click_check('No Quote');
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
cur_frm.cur_grid.toggle_view();
|
||||
},
|
||||
() => frappe.click_button('Update'),
|
||||
() => frappe.timeout(1),
|
||||
|
||||
() => frappe.click_button('Supplier Quotation'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_link('Make'),
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
frappe.set_control('supplier',"_Test Supplier 1");
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Make Supplier Quotation'),
|
||||
() => frappe.timeout(1),
|
||||
() => cur_frm.set_value("company", "For Testing"),
|
||||
() => cur_frm.fields_dict.items.grid.grid_rows[0].doc.rate = 4.99,
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Save'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Submit'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Yes'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.set_route("List", "Request for Quotation"),
|
||||
() => frappe.timeout(2),
|
||||
() => frappe.set_route("List", "Request for Quotation"),
|
||||
() => frappe.timeout(2),
|
||||
() => frappe.click_link(rfq_name),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Menu'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_link('Reload'),
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
assert.ok(cur_frm.fields_dict.suppliers.grid.grid_rows[1].doc.quote_status == "Received");
|
||||
assert.ok(cur_frm.fields_dict.suppliers.grid.grid_rows[0].doc.no_quote == 1);
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -137,6 +137,69 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.docstatus >= 1 && doc.quote_status != 'Received'",
|
||||
"fieldname": "no_quote",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "No Quote",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.docstatus >= 1 && !doc.no_quote",
|
||||
"fieldname": "quote_status",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Quote Status",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Pending\nReceived\nNo Quote",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -269,7 +332,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-07-24 06:52:19.542717",
|
||||
"modified": "2017-07-26 22:25:58.096584",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Request for Quotation Supplier",
|
||||
|
||||
@@ -16,7 +16,7 @@ class Supplier(TransactionBase):
|
||||
|
||||
def onload(self):
|
||||
"""Load address and contacts in `__onload`"""
|
||||
load_address_and_contact(self, "supplier")
|
||||
load_address_and_contact(self)
|
||||
self.load_dashboard_info()
|
||||
|
||||
def load_dashboard_info(self):
|
||||
|
||||
@@ -8,14 +8,13 @@ QUnit.test("test: supplier", function(assert) {
|
||||
return frappe.tests.make('Supplier', [
|
||||
{supplier_name: 'Test Supplier'},
|
||||
{supplier_type: 'Hardware'},
|
||||
{country: 'United States'},
|
||||
{default_currency: 'USD'},
|
||||
{default_price_list: 'Test-Buying-USD'},
|
||||
{country: 'India'},
|
||||
{default_currency: 'INR'},
|
||||
{credit_days_based_on: 'Fixed Days'},
|
||||
{accounts: [
|
||||
[
|
||||
{'company': "Test Company"},
|
||||
{'account': "Creditors - TC"}
|
||||
{'company': "For Testing"},
|
||||
{'account': "Creditors - FT"}
|
||||
]]
|
||||
}
|
||||
]);
|
||||
@@ -68,8 +67,8 @@ QUnit.test("test: supplier", function(assert) {
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.supplier_name == 'Test Supplier', "Name correct");
|
||||
assert.ok(cur_frm.doc.supplier_type == 'Hardware', "Type correct");
|
||||
assert.ok(cur_frm.doc.default_currency == 'USD', "Currency correct");
|
||||
assert.ok(cur_frm.doc.accounts[0].account == 'Creditors - '+frappe.get_abbr('Test Company'), " Account Head abbr correct");
|
||||
assert.ok(cur_frm.doc.default_currency == 'INR', "Currency correct");
|
||||
assert.ok(cur_frm.doc.accounts[0].account == 'Creditors - '+frappe.get_abbr('For Testing'), " Account Head abbr correct");
|
||||
assert.ok($('.address-box:nth-child(3) p').text().includes('Shipping City 3'), "Address correct");
|
||||
assert.ok($('.col-sm-6+ .col-sm-6 .h6').text().includes('Contact 3'), "Contact correct");
|
||||
},
|
||||
|
||||
@@ -22,7 +22,9 @@ erpnext.buying.SupplierQuotationController = erpnext.buying.BuyingController.ext
|
||||
cur_frm.page.set_inner_btn_group_as_primary(__("Make"));
|
||||
cur_frm.add_custom_button(__("Quotation"), this.make_quotation,
|
||||
__("Make"));
|
||||
|
||||
cur_frm.add_custom_button(__('Subscription'), function() {
|
||||
erpnext.utils.make_subscription(me.frm.doc.doctype, me.frm.doc.name)
|
||||
}, __("Make"))
|
||||
}
|
||||
else if (this.frm.doc.docstatus===0) {
|
||||
|
||||
|
||||
@@ -1676,6 +1676,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "base_rounding_adjustment",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Rounding Adjustment (Company Currency",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -1801,6 +1832,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "rounding_adjustment",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Rounding Adjustment",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2051,6 +2113,67 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "subscription_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Subscription Section",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "subscription",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Subscription",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Subscription",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2247,7 +2370,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-07-19 13:51:18.929697",
|
||||
"modified": "2017-09-19 11:23:25.268924",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Supplier Quotation",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user