Compare commits
168 Commits
rohitwaghc
...
v14.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7235c3f88f | ||
|
|
15733c14e8 | ||
|
|
22b2386aa1 | ||
|
|
6ab0637b0b | ||
|
|
76ae4d87ca | ||
|
|
3c688dfa6d | ||
|
|
8b8d054ded | ||
|
|
121ec83562 | ||
|
|
26536da74b | ||
|
|
f605564094 | ||
|
|
b7e8fbe43f | ||
|
|
00a73c7a57 | ||
|
|
edb100274b | ||
|
|
6976316ada | ||
|
|
357f74a580 | ||
|
|
aedd0397b8 | ||
|
|
4cb685a326 | ||
|
|
afcc0cbccd | ||
|
|
29bca45b1e | ||
|
|
784fb47197 | ||
|
|
5520c6b2f3 | ||
|
|
f873547447 | ||
|
|
d65d2f617d | ||
|
|
0438433a4f | ||
|
|
055556b7f1 | ||
|
|
60fa421409 | ||
|
|
dd2fd12d5f | ||
|
|
319ee41403 | ||
|
|
b96526eefd | ||
|
|
78a992c086 | ||
|
|
f871dd4ef6 | ||
|
|
79ecf7751f | ||
|
|
4698dba402 | ||
|
|
f55881aef8 | ||
|
|
f1b2ba5a84 | ||
|
|
4409f11282 | ||
|
|
84865a8421 | ||
|
|
d9632e8138 | ||
|
|
4bbd0ec985 | ||
|
|
92f8f0ec74 | ||
|
|
aea484be1f | ||
|
|
52fc10d00c | ||
|
|
1b9082e07b | ||
|
|
0e9a1fb40e | ||
|
|
32abf67c80 | ||
|
|
52b42e9492 | ||
|
|
77ac7f06d4 | ||
|
|
8717235a34 | ||
|
|
670426f428 | ||
|
|
1b5a1cbaad | ||
|
|
7ca1beb15d | ||
|
|
c660db145b | ||
|
|
0aaf9c4f05 | ||
|
|
b3b0272ec9 | ||
|
|
f7898b4954 | ||
|
|
b067eae38c | ||
|
|
cee867f941 | ||
|
|
6c4fcd80c6 | ||
|
|
11657effa5 | ||
|
|
d3b7942f32 | ||
|
|
f407c972d1 | ||
|
|
0b72295fa2 | ||
|
|
204b6c0272 | ||
|
|
1118e25b6d | ||
|
|
9b9df70632 | ||
|
|
39ff0cc6d8 | ||
|
|
c407d1e51a | ||
|
|
4d8ced6c87 | ||
|
|
4f832678cf | ||
|
|
f0f7afa669 | ||
|
|
cb6cbf7818 | ||
|
|
3aec1175df | ||
|
|
c645995ae3 | ||
|
|
f772c17f3f | ||
|
|
193502ce03 | ||
|
|
abd637a238 | ||
|
|
4cf9fb08e1 | ||
|
|
e4ca20654f | ||
|
|
bc873939eb | ||
|
|
c6d3e9f432 | ||
|
|
54f4504df6 | ||
|
|
309da96442 | ||
|
|
94ebfa765c | ||
|
|
2577747c5c | ||
|
|
fb387426d6 | ||
|
|
15915d7053 | ||
|
|
362976fa42 | ||
|
|
a7d23abc2f | ||
|
|
4b609322ba | ||
|
|
5778f227ee | ||
|
|
7ac75aab1a | ||
|
|
e831b6e054 | ||
|
|
856a64b77c | ||
|
|
3afb625ff8 | ||
|
|
b6d2de2cc1 | ||
|
|
0bfb774bdf | ||
|
|
d7a8db04a1 | ||
|
|
2d5ae811d2 | ||
|
|
be9607e27b | ||
|
|
fd45a7afbe | ||
|
|
0c73af6ee2 | ||
|
|
981add9b6f | ||
|
|
8f5736c500 | ||
|
|
052f7c3345 | ||
|
|
fa4a40812c | ||
|
|
a76732613e | ||
|
|
dd602989a8 | ||
|
|
78b39d6ca4 | ||
|
|
77fa64e100 | ||
|
|
ac04fc60ef | ||
|
|
6be77d5729 | ||
|
|
37e5b93e2d | ||
|
|
19d29d1861 | ||
|
|
0db912998a | ||
|
|
200a971743 | ||
|
|
c0f0986539 | ||
|
|
376293326b | ||
|
|
9a29e3c9f2 | ||
|
|
e099e10c8e | ||
|
|
3b222339b8 | ||
|
|
9e60dd32e8 | ||
|
|
7ff5414571 | ||
|
|
d48487ada2 | ||
|
|
da69cc5477 | ||
|
|
b2a720d847 | ||
|
|
6656d23e45 | ||
|
|
ae5c05081d | ||
|
|
028e939cca | ||
|
|
216cb9b07b | ||
|
|
50ad612453 | ||
|
|
6b71af9008 | ||
|
|
3c8412efdb | ||
|
|
623f56a95c | ||
|
|
b637d4d5f1 | ||
|
|
601bc64618 | ||
|
|
04d3571dd9 | ||
|
|
aa5aaa113e | ||
|
|
354a9d6169 | ||
|
|
c7e2217c92 | ||
|
|
ce5fc5b457 | ||
|
|
abe18945a6 | ||
|
|
010a0ca0a9 | ||
|
|
74664a34c0 | ||
|
|
82f1dd268d | ||
|
|
1aa96defda | ||
|
|
8fdbbf374d | ||
|
|
66e5202642 | ||
|
|
35e9bfca38 | ||
|
|
735a60807a | ||
|
|
c3fd802351 | ||
|
|
6046f8bc5e | ||
|
|
d7db8ed12e | ||
|
|
adcd21724b | ||
|
|
04bdff736b | ||
|
|
65bb1d8cc2 | ||
|
|
ebf766cf62 | ||
|
|
80bf47170f | ||
|
|
0faa7b0432 | ||
|
|
1d1f12f949 | ||
|
|
4c82533239 | ||
|
|
5a28ba8537 | ||
|
|
8737c10ce4 | ||
|
|
2defb89962 | ||
|
|
53b9d61c46 | ||
|
|
3092131913 | ||
|
|
6dce122825 | ||
|
|
248cc48842 | ||
|
|
ebd8f2f45b |
@@ -9,13 +9,6 @@ trim_trailing_whitespace = true
|
||||
charset = utf-8
|
||||
|
||||
# python, js indentation settings
|
||||
[{*.py,*.js,*.vue,*.css,*.scss,*.html}]
|
||||
[{*.py,*.js}]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
max_line_length = 110
|
||||
|
||||
# JSON files - mostly doctype schema files
|
||||
[{*.json}]
|
||||
insert_final_newline = false
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
69
.eslintrc
69
.eslintrc
@@ -2,32 +2,65 @@
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"es2022": true
|
||||
"es6": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 11,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"rules": {
|
||||
"indent": "off",
|
||||
"brace-style": "off",
|
||||
"no-mixed-spaces-and-tabs": "off",
|
||||
"no-useless-escape": "off",
|
||||
"space-unary-ops": ["error", { "words": true }],
|
||||
"linebreak-style": "off",
|
||||
"quotes": ["off"],
|
||||
"semi": "off",
|
||||
"camelcase": "off",
|
||||
"no-unused-vars": "off",
|
||||
"no-console": ["warn"],
|
||||
"no-extra-boolean-cast": ["off"],
|
||||
"no-control-regex": ["off"]
|
||||
"indent": [
|
||||
"error",
|
||||
"tab",
|
||||
{ "SwitchCase": 1 }
|
||||
],
|
||||
"brace-style": [
|
||||
"error",
|
||||
"1tbs"
|
||||
],
|
||||
"space-unary-ops": [
|
||||
"error",
|
||||
{ "words": true }
|
||||
],
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"unix"
|
||||
],
|
||||
"quotes": [
|
||||
"off"
|
||||
],
|
||||
"semi": [
|
||||
"warn",
|
||||
"always"
|
||||
],
|
||||
"camelcase": [
|
||||
"off"
|
||||
],
|
||||
"no-unused-vars": [
|
||||
"warn"
|
||||
],
|
||||
"no-redeclare": [
|
||||
"warn"
|
||||
],
|
||||
"no-console": [
|
||||
"warn"
|
||||
],
|
||||
"no-extra-boolean-cast": [
|
||||
"off"
|
||||
],
|
||||
"no-control-regex": [
|
||||
"off"
|
||||
],
|
||||
"space-before-blocks": "warn",
|
||||
"keyword-spacing": "warn",
|
||||
"comma-spacing": "warn",
|
||||
"key-spacing": "warn"
|
||||
},
|
||||
"root": true,
|
||||
"globals": {
|
||||
"frappe": true,
|
||||
"Vue": true,
|
||||
"SetVueGlobals": true,
|
||||
"erpnext": true,
|
||||
"hub": true,
|
||||
"$": true,
|
||||
@@ -64,10 +97,8 @@
|
||||
"is_null": true,
|
||||
"in_list": true,
|
||||
"has_common": true,
|
||||
"posthog": true,
|
||||
"has_words": true,
|
||||
"validate_email": true,
|
||||
"open_web_template_values_editor": true,
|
||||
"get_number_format": true,
|
||||
"format_number": true,
|
||||
"format_currency": true,
|
||||
@@ -123,8 +154,8 @@
|
||||
"before": true,
|
||||
"beforeEach": true,
|
||||
"onScan": true,
|
||||
"html2canvas": true,
|
||||
"extend_cscript": true,
|
||||
"localforage": true,
|
||||
"Plaid": true
|
||||
"localforage": true
|
||||
}
|
||||
}
|
||||
|
||||
3
.github/helper/.flake8_strict
vendored
3
.github/helper/.flake8_strict
vendored
@@ -66,8 +66,7 @@ ignore =
|
||||
F841,
|
||||
E713,
|
||||
E712,
|
||||
B023,
|
||||
B028
|
||||
B023
|
||||
|
||||
|
||||
max-line-length = 200
|
||||
|
||||
99
.github/helper/documentation.py
vendored
99
.github/helper/documentation.py
vendored
@@ -3,71 +3,52 @@ import requests
|
||||
from urllib.parse import urlparse
|
||||
|
||||
|
||||
WEBSITE_REPOS = [
|
||||
docs_repos = [
|
||||
"frappe_docs",
|
||||
"erpnext_documentation",
|
||||
"erpnext_com",
|
||||
"frappe_io",
|
||||
]
|
||||
|
||||
DOCUMENTATION_DOMAINS = [
|
||||
"docs.erpnext.com",
|
||||
"frappeframework.com",
|
||||
]
|
||||
|
||||
def uri_validator(x):
|
||||
result = urlparse(x)
|
||||
return all([result.scheme, result.netloc, result.path])
|
||||
|
||||
def is_valid_url(url: str) -> bool:
|
||||
parts = urlparse(url)
|
||||
return all((parts.scheme, parts.netloc, parts.path))
|
||||
|
||||
|
||||
def is_documentation_link(word: str) -> bool:
|
||||
if not word.startswith("http") or not is_valid_url(word):
|
||||
return False
|
||||
|
||||
parsed_url = urlparse(word)
|
||||
if parsed_url.netloc in DOCUMENTATION_DOMAINS:
|
||||
return True
|
||||
|
||||
if parsed_url.netloc == "github.com":
|
||||
parts = parsed_url.path.split("/")
|
||||
if len(parts) == 5 and parts[1] == "frappe" and parts[2] in WEBSITE_REPOS:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def contains_documentation_link(body: str) -> bool:
|
||||
return any(
|
||||
is_documentation_link(word)
|
||||
for line in body.splitlines()
|
||||
for word in line.split()
|
||||
)
|
||||
|
||||
|
||||
def check_pull_request(number: str) -> "tuple[int, str]":
|
||||
response = requests.get(f"https://api.github.com/repos/frappe/erpnext/pulls/{number}")
|
||||
if not response.ok:
|
||||
return 1, "Pull Request Not Found! ⚠️"
|
||||
|
||||
payload = response.json()
|
||||
title = (payload.get("title") or "").lower().strip()
|
||||
head_sha = (payload.get("head") or {}).get("sha")
|
||||
body = (payload.get("body") or "").lower()
|
||||
|
||||
if (
|
||||
not title.startswith("feat")
|
||||
or not head_sha
|
||||
or "no-docs" in body
|
||||
or "backport" in body
|
||||
):
|
||||
return 0, "Skipping documentation checks... 🏃"
|
||||
|
||||
if contains_documentation_link(body):
|
||||
return 0, "Documentation Link Found. You're Awesome! 🎉"
|
||||
|
||||
return 1, "Documentation Link Not Found! ⚠️"
|
||||
def docs_link_exists(body):
|
||||
for line in body.splitlines():
|
||||
for word in line.split():
|
||||
if word.startswith('http') and uri_validator(word):
|
||||
parsed_url = urlparse(word)
|
||||
if parsed_url.netloc == "github.com":
|
||||
parts = parsed_url.path.split('/')
|
||||
if len(parts) == 5 and parts[1] == "frappe" and parts[2] in docs_repos:
|
||||
return True
|
||||
elif parsed_url.netloc == "docs.erpnext.com":
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
exit_code, message = check_pull_request(sys.argv[1])
|
||||
print(message)
|
||||
sys.exit(exit_code)
|
||||
pr = sys.argv[1]
|
||||
response = requests.get("https://api.github.com/repos/frappe/erpnext/pulls/{}".format(pr))
|
||||
|
||||
if response.ok:
|
||||
payload = response.json()
|
||||
title = (payload.get("title") or "").lower().strip()
|
||||
head_sha = (payload.get("head") or {}).get("sha")
|
||||
body = (payload.get("body") or "").lower()
|
||||
|
||||
if (title.startswith("feat")
|
||||
and head_sha
|
||||
and "no-docs" not in body
|
||||
and "backport" not in body
|
||||
):
|
||||
if docs_link_exists(body):
|
||||
print("Documentation Link Found. You're Awesome! 🎉")
|
||||
|
||||
else:
|
||||
print("Documentation Link Not Found! ⚠️")
|
||||
sys.exit(1)
|
||||
|
||||
else:
|
||||
print("Skipping documentation checks... 🏃")
|
||||
|
||||
39
.github/helper/install.sh
vendored
39
.github/helper/install.sh
vendored
@@ -4,15 +4,12 @@ set -e
|
||||
|
||||
cd ~ || exit
|
||||
|
||||
sudo apt update
|
||||
sudo apt remove mysql-server mysql-client
|
||||
sudo apt install libcups2-dev redis-server mariadb-client-10.6
|
||||
sudo apt update && sudo apt install redis-server libcups2-dev
|
||||
|
||||
pip install frappe-bench
|
||||
|
||||
githubbranch=${GITHUB_BASE_REF:-${GITHUB_REF##*/}}
|
||||
frappeuser=${FRAPPE_USER:-"frappe"}
|
||||
frappebranch=${FRAPPE_BRANCH:-$githubbranch}
|
||||
frappebranch=${FRAPPE_BRANCH:-${GITHUB_BASE_REF:-${GITHUB_REF##*/}}}
|
||||
|
||||
git clone "https://github.com/${frappeuser}/frappe" --branch "${frappebranch}" --depth 1
|
||||
bench init --skip-assets --frappe-path ~/frappe --python "$(which python)" frappe-bench
|
||||
@@ -27,14 +24,15 @@ fi
|
||||
|
||||
|
||||
if [ "$DB" == "mariadb" ];then
|
||||
mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL character_set_server = 'utf8mb4'"
|
||||
mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'"
|
||||
mysql --host 127.0.0.1 --port 3306 -u root -e "SET GLOBAL character_set_server = 'utf8mb4'"
|
||||
mysql --host 127.0.0.1 --port 3306 -u root -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'"
|
||||
|
||||
mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "CREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe'"
|
||||
mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "CREATE DATABASE test_frappe"
|
||||
mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "GRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'localhost'"
|
||||
mysql --host 127.0.0.1 --port 3306 -u root -e "CREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe'"
|
||||
mysql --host 127.0.0.1 --port 3306 -u root -e "CREATE DATABASE test_frappe"
|
||||
mysql --host 127.0.0.1 --port 3306 -u root -e "GRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'localhost'"
|
||||
|
||||
mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "FLUSH PRIVILEGES"
|
||||
mysql --host 127.0.0.1 --port 3306 -u root -e "UPDATE mysql.user SET Password=PASSWORD('travis') WHERE User='root'"
|
||||
mysql --host 127.0.0.1 --port 3306 -u root -e "FLUSH PRIVILEGES"
|
||||
fi
|
||||
|
||||
if [ "$DB" == "postgres" ];then
|
||||
@@ -44,17 +42,12 @@ fi
|
||||
|
||||
|
||||
install_whktml() {
|
||||
if [ "$(lsb_release -rs)" = "22.04" ]; then
|
||||
wget -O /tmp/wkhtmltox.deb https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.jammy_amd64.deb
|
||||
sudo apt install /tmp/wkhtmltox.deb
|
||||
else
|
||||
echo "Please update this script to support wkhtmltopdf for $(lsb_release -ds)"
|
||||
exit 1
|
||||
fi
|
||||
wget -O /tmp/wkhtmltox.tar.xz https://github.com/frappe/wkhtmltopdf/raw/master/wkhtmltox-0.12.3_linux-generic-amd64.tar.xz
|
||||
tar -xf /tmp/wkhtmltox.tar.xz -C /tmp
|
||||
sudo mv /tmp/wkhtmltox/bin/wkhtmltopdf /usr/local/bin/wkhtmltopdf
|
||||
sudo chmod o+x /usr/local/bin/wkhtmltopdf
|
||||
}
|
||||
install_whktml &
|
||||
wkpid=$!
|
||||
|
||||
|
||||
cd ~/frappe-bench || exit
|
||||
|
||||
@@ -63,13 +56,11 @@ sed -i 's/schedule:/# schedule:/g' Procfile
|
||||
sed -i 's/socketio:/# socketio:/g' Procfile
|
||||
sed -i 's/redis_socketio:/# redis_socketio:/g' Procfile
|
||||
|
||||
bench get-app payments --branch ${githubbranch%"-hotfix"}
|
||||
bench get-app payments
|
||||
bench get-app erpnext "${GITHUB_WORKSPACE}"
|
||||
|
||||
if [ "$TYPE" == "server" ]; then bench setup requirements --dev; fi
|
||||
|
||||
wait $wkpid
|
||||
|
||||
bench start &>> ~/frappe-bench/bench_start.log &
|
||||
bench start &> bench_run_logs.txt &
|
||||
CI=Yes bench build --app frappe &
|
||||
bench --site test_site reinstall --yes
|
||||
|
||||
4
.github/helper/site_config_mariadb.json
vendored
4
.github/helper/site_config_mariadb.json
vendored
@@ -9,8 +9,8 @@
|
||||
"mail_password": "test",
|
||||
"admin_password": "admin",
|
||||
"root_login": "root",
|
||||
"root_password": "root",
|
||||
"root_password": "travis",
|
||||
"host_name": "http://test_site:8000",
|
||||
"install_apps": ["payments", "erpnext"],
|
||||
"install_apps": ["erpnext"],
|
||||
"throttle_user_limit": 100
|
||||
}
|
||||
|
||||
60
.github/helper/translation.py
vendored
Normal file
60
.github/helper/translation.py
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
import re
|
||||
import sys
|
||||
|
||||
errors_encounter = 0
|
||||
pattern = re.compile(r"_\(([\"']{,3})(?P<message>((?!\1).)*)\1(\s*,\s*context\s*=\s*([\"'])(?P<py_context>((?!\5).)*)\5)*(\s*,(\s*?.*?\n*?)*(,\s*([\"'])(?P<js_context>((?!\11).)*)\11)*)*\)")
|
||||
words_pattern = re.compile(r"_{1,2}\([\"'`]{1,3}.*?[a-zA-Z]")
|
||||
start_pattern = re.compile(r"_{1,2}\([f\"'`]{1,3}")
|
||||
f_string_pattern = re.compile(r"_\(f[\"']")
|
||||
starts_with_f_pattern = re.compile(r"_\(f")
|
||||
|
||||
# skip first argument
|
||||
files = sys.argv[1:]
|
||||
files_to_scan = [_file for _file in files if _file.endswith(('.py', '.js'))]
|
||||
|
||||
for _file in files_to_scan:
|
||||
with open(_file, 'r') as f:
|
||||
print(f'Checking: {_file}')
|
||||
file_lines = f.readlines()
|
||||
for line_number, line in enumerate(file_lines, 1):
|
||||
if 'frappe-lint: disable-translate' in line:
|
||||
continue
|
||||
|
||||
start_matches = start_pattern.search(line)
|
||||
if start_matches:
|
||||
starts_with_f = starts_with_f_pattern.search(line)
|
||||
|
||||
if starts_with_f:
|
||||
has_f_string = f_string_pattern.search(line)
|
||||
if has_f_string:
|
||||
errors_encounter += 1
|
||||
print(f'\nF-strings are not supported for translations at line number {line_number}\n{line.strip()[:100]}')
|
||||
continue
|
||||
else:
|
||||
continue
|
||||
|
||||
match = pattern.search(line)
|
||||
error_found = False
|
||||
|
||||
if not match and line.endswith((',\n', '[\n')):
|
||||
# concat remaining text to validate multiline pattern
|
||||
line = "".join(file_lines[line_number - 1:])
|
||||
line = line[start_matches.start() + 1:]
|
||||
match = pattern.match(line)
|
||||
|
||||
if not match:
|
||||
error_found = True
|
||||
print(f'\nTranslation syntax error at line number {line_number}\n{line.strip()[:100]}')
|
||||
|
||||
if not error_found and not words_pattern.search(line):
|
||||
error_found = True
|
||||
print(f'\nTranslation is useless because it has no words at line number {line_number}\n{line.strip()[:100]}')
|
||||
|
||||
if error_found:
|
||||
errors_encounter += 1
|
||||
|
||||
if errors_encounter > 0:
|
||||
print('\nVisit "https://frappeframework.com/docs/user/en/translations" to learn about valid translation strings.')
|
||||
sys.exit(1)
|
||||
else:
|
||||
print('\nGood To Go!')
|
||||
26
.github/workflows/backport.yml
vendored
Normal file
26
.github/workflows/backport.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: Backport
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- closed
|
||||
- labeled
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: Checkout Actions
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: "frappe/backport"
|
||||
path: ./actions
|
||||
ref: develop
|
||||
- name: Install Actions
|
||||
run: npm install --production --prefix ./actions
|
||||
- name: Run backport
|
||||
uses: ./actions/backport
|
||||
with:
|
||||
token: ${{secrets.BACKPORT_BOT_TOKEN}}
|
||||
labelsToAdd: "backport"
|
||||
title: "{{originalTitle}}"
|
||||
9
.github/workflows/linters.yml
vendored
9
.github/workflows/linters.yml
vendored
@@ -9,22 +9,21 @@ jobs:
|
||||
name: linters
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@v4
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.10'
|
||||
cache: pip
|
||||
|
||||
- name: Install and Run Pre-commit
|
||||
uses: pre-commit/action@v3.0.0
|
||||
uses: pre-commit/action@v2.0.3
|
||||
|
||||
- name: Download Semgrep rules
|
||||
run: git clone --depth 1 https://github.com/frappe/semgrep-rules.git frappe-semgrep-rules
|
||||
|
||||
- name: Download semgrep
|
||||
run: pip install semgrep
|
||||
run: pip install semgrep==0.97.0
|
||||
|
||||
- name: Run Semgrep rules
|
||||
run: semgrep ci --config ./frappe-semgrep-rules/rules --config r/python.lang.correctness
|
||||
|
||||
73
.github/workflows/patch.yml
vendored
73
.github/workflows/patch.yml
vendored
@@ -11,7 +11,7 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: patch-develop-${{ github.event_name }}-${{ github.event.number || github.event_name == 'workflow_dispatch' && github.run_id || '' }}
|
||||
group: patch-develop-${{ github.event.number }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -23,12 +23,12 @@ jobs:
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: mariadb:10.6
|
||||
image: mariadb:10.3
|
||||
env:
|
||||
MARIADB_ROOT_PASSWORD: 'root'
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: YES
|
||||
ports:
|
||||
- 3306:3306
|
||||
options: --health-cmd="mariadb-admin ping" --health-interval=5s --health-timeout=2s --health-retries=3
|
||||
options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
|
||||
|
||||
steps:
|
||||
- name: Clone
|
||||
@@ -43,14 +43,14 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Setup Python
|
||||
uses: "actions/setup-python@v4"
|
||||
uses: "gabrielfalcao/pyenv-action@v9"
|
||||
with:
|
||||
python-version: '3.10'
|
||||
versions: 3.10:latest, 3.7:latest
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 14
|
||||
check-latest: true
|
||||
|
||||
- name: Add to Hosts
|
||||
@@ -92,6 +92,7 @@ jobs:
|
||||
- name: Install
|
||||
run: |
|
||||
pip install frappe-bench
|
||||
pyenv global $(pyenv versions | grep '3.10')
|
||||
bash ${GITHUB_WORKSPACE}/.github/helper/install.sh
|
||||
env:
|
||||
DB: mariadb
|
||||
@@ -100,60 +101,42 @@ jobs:
|
||||
- name: Run Patch Tests
|
||||
run: |
|
||||
cd ~/frappe-bench/
|
||||
bench remove-app payments --force
|
||||
jq 'del(.install_apps)' ~/frappe-bench/sites/test_site/site_config.json > tmp.json
|
||||
mv tmp.json ~/frappe-bench/sites/test_site/site_config.json
|
||||
|
||||
wget https://erpnext.com/files/v13-erpnext.sql.gz
|
||||
bench --site test_site --force restore ~/frappe-bench/v13-erpnext.sql.gz
|
||||
wget https://erpnext.com/files/v10-erpnext.sql.gz
|
||||
bench --site test_site --force restore ~/frappe-bench/v10-erpnext.sql.gz
|
||||
|
||||
git -C "apps/frappe" remote set-url upstream https://github.com/frappe/frappe.git
|
||||
git -C "apps/erpnext" remote set-url upstream https://github.com/frappe/erpnext.git
|
||||
|
||||
pyenv global $(pyenv versions | grep '3.7')
|
||||
for version in $(seq 12 13)
|
||||
do
|
||||
echo "Updating to v$version"
|
||||
branch_name="version-$version-hotfix"
|
||||
|
||||
function update_to_version() {
|
||||
version=$1
|
||||
git -C "apps/frappe" fetch --depth 1 upstream $branch_name:$branch_name
|
||||
git -C "apps/erpnext" fetch --depth 1 upstream $branch_name:$branch_name
|
||||
|
||||
branch_name="version-$version-hotfix"
|
||||
echo "Updating to v$version"
|
||||
git -C "apps/frappe" checkout -q -f $branch_name
|
||||
git -C "apps/erpnext" checkout -q -f $branch_name
|
||||
|
||||
# Fetch and checkout branches
|
||||
git -C "apps/frappe" fetch --depth 1 upstream $branch_name:$branch_name
|
||||
git -C "apps/erpnext" fetch --depth 1 upstream $branch_name:$branch_name
|
||||
git -C "apps/frappe" checkout -q -f $branch_name
|
||||
git -C "apps/erpnext" checkout -q -f $branch_name
|
||||
rm -rf ~/frappe-bench/env
|
||||
bench setup env
|
||||
bench pip install -e ./apps/payments
|
||||
bench pip install -e ./apps/erpnext
|
||||
|
||||
# Resetup env and install apps
|
||||
pgrep honcho | xargs kill
|
||||
rm -rf ~/frappe-bench/env
|
||||
bench -v setup env
|
||||
bench pip install -e ./apps/erpnext
|
||||
bench start &>> ~/frappe-bench/bench_start.log &
|
||||
bench --site test_site migrate
|
||||
done
|
||||
|
||||
bench --site test_site migrate
|
||||
}
|
||||
|
||||
update_to_version 14
|
||||
|
||||
echo "Updating to latest version"
|
||||
git -C "apps/frappe" checkout -q -f "${GITHUB_BASE_REF:-${GITHUB_REF##*/}}"
|
||||
git -C "apps/erpnext" checkout -q -f "$GITHUB_SHA"
|
||||
|
||||
pgrep honcho | xargs kill
|
||||
pyenv global $(pyenv versions | grep '3.10')
|
||||
rm -rf ~/frappe-bench/env
|
||||
bench -v setup env
|
||||
bench pip install -e ./apps/payments
|
||||
bench pip install -e ./apps/erpnext
|
||||
bench start &>> ~/frappe-bench/bench_start.log &
|
||||
|
||||
bench --site test_site migrate
|
||||
|
||||
- name: Show bench output
|
||||
if: ${{ always() }}
|
||||
run: |
|
||||
cd ~/frappe-bench
|
||||
cat bench_start.log || true
|
||||
cd logs
|
||||
for f in ./*.log*; do
|
||||
echo "Printing log: $f";
|
||||
cat $f
|
||||
done
|
||||
bench --site test_site install-app payments
|
||||
|
||||
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -2,14 +2,14 @@ name: Generate Semantic Release
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- version-15
|
||||
- version-14
|
||||
jobs:
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Entire Repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 20
|
||||
node-version: 16
|
||||
|
||||
- name: Setup dependencies
|
||||
run: |
|
||||
|
||||
38
.github/workflows/release_notes.yml
vendored
38
.github/workflows/release_notes.yml
vendored
@@ -1,38 +0,0 @@
|
||||
# This action:
|
||||
#
|
||||
# 1. Generates release notes using github API.
|
||||
# 2. Strips unnecessary info like chore/style etc from notes.
|
||||
# 3. Updates release info.
|
||||
|
||||
# This action needs to be maintained on all branches that do releases.
|
||||
|
||||
name: 'Release Notes'
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag_name:
|
||||
description: 'Tag of release like v13.0.0'
|
||||
required: true
|
||||
type: string
|
||||
release:
|
||||
types: [released]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
regen-notes:
|
||||
name: 'Regenerate release notes'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Update notes
|
||||
run: |
|
||||
NEW_NOTES=$(gh api --method POST -H "Accept: application/vnd.github+json" /repos/frappe/erpnext/releases/generate-notes -f tag_name=$RELEASE_TAG | jq -r '.body' | sed -E '/^\* (chore|ci|test|docs|style)/d' )
|
||||
RELEASE_ID=$(gh api -H "Accept: application/vnd.github+json" /repos/frappe/erpnext/releases/tags/$RELEASE_TAG | jq -r '.id')
|
||||
gh api --method PATCH -H "Accept: application/vnd.github+json" /repos/frappe/erpnext/releases/$RELEASE_ID -f body="$NEW_NOTES"
|
||||
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
RELEASE_TAG: ${{ github.event.inputs.tag_name || github.event.release.tag_name }}
|
||||
2
.github/workflows/semantic-commits.yml
vendored
2
.github/workflows/semantic-commits.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 14
|
||||
check-latest: true
|
||||
|
||||
- name: Check commit titles
|
||||
|
||||
53
.github/workflows/server-tests-mariadb.yml
vendored
53
.github/workflows/server-tests-mariadb.yml
vendored
@@ -7,24 +7,27 @@ on:
|
||||
- '**.css'
|
||||
- '**.md'
|
||||
- '**.html'
|
||||
schedule:
|
||||
# Run everday at midnight UTC / 5:30 IST
|
||||
- cron: "0 0 * * *"
|
||||
- '**.csv'
|
||||
push:
|
||||
branches: [ develop ]
|
||||
paths-ignore:
|
||||
- '**.js'
|
||||
- '**.md'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
user:
|
||||
description: 'Frappe Framework repository user (add your username for forks)'
|
||||
description: 'user'
|
||||
required: true
|
||||
default: 'frappe'
|
||||
type: string
|
||||
branch:
|
||||
description: 'Frappe Framework branch'
|
||||
description: 'Branch name'
|
||||
default: 'develop'
|
||||
required: false
|
||||
type: string
|
||||
|
||||
concurrency:
|
||||
group: server-mariadb-develop-${{ github.event_name }}-${{ github.event.number || github.event_name == 'workflow_dispatch' && github.run_id || '' }}
|
||||
group: server-mariadb-develop-${{ github.event.number }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -42,12 +45,12 @@ jobs:
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: mariadb:10.6
|
||||
image: mariadb:10.3
|
||||
env:
|
||||
MARIADB_ROOT_PASSWORD: 'root'
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: YES
|
||||
ports:
|
||||
- 3306:3306
|
||||
options: --health-cmd="mariadb-admin ping" --health-interval=5s --health-timeout=2s --health-retries=3
|
||||
options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
|
||||
|
||||
steps:
|
||||
- name: Clone
|
||||
@@ -56,7 +59,7 @@ jobs:
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.11'
|
||||
python-version: '3.10'
|
||||
|
||||
- name: Check for valid Python & Merge Conflicts
|
||||
run: |
|
||||
@@ -69,7 +72,7 @@ jobs:
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 14
|
||||
check-latest: true
|
||||
|
||||
- name: Add to Hosts
|
||||
@@ -117,12 +120,32 @@ jobs:
|
||||
FRAPPE_BRANCH: ${{ github.event.inputs.branch }}
|
||||
|
||||
- name: Run Tests
|
||||
run: 'cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --app erpnext --total-builds 4 --build-number ${{ matrix.container }}'
|
||||
run: cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --app erpnext --use-orchestrator --with-coverage
|
||||
env:
|
||||
TYPE: server
|
||||
CI_BUILD_ID: ${{ github.run_id }}
|
||||
ORCHESTRATOR_URL: http://test-orchestrator.frappe.io
|
||||
|
||||
- name: Show bench output
|
||||
if: ${{ always() }}
|
||||
run: cat ~/frappe-bench/bench_start.log || true
|
||||
- name: Upload coverage data
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: coverage-${{ matrix.container }}
|
||||
path: /home/runner/frappe-bench/sites/coverage.xml
|
||||
|
||||
coverage:
|
||||
name: Coverage Wrap Up
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
|
||||
- name: Upload coverage data
|
||||
uses: codecov/codecov-action@v2
|
||||
with:
|
||||
name: MariaDB
|
||||
fail_ci_if_error: true
|
||||
verbose: true
|
||||
|
||||
4
.github/workflows/server-tests-postgres.yml
vendored
4
.github/workflows/server-tests-postgres.yml
vendored
@@ -9,7 +9,7 @@ on:
|
||||
types: [opened, labelled, synchronize, reopened]
|
||||
|
||||
concurrency:
|
||||
group: server-postgres-develop-${{ github.event_name }}-${{ github.event.number || github.event_name == 'workflow_dispatch' && github.run_id || '' }}
|
||||
group: server-postgres-develop-${{ github.event.number }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -59,7 +59,7 @@ jobs:
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 14
|
||||
check-latest: true
|
||||
|
||||
- name: Add to Hosts
|
||||
|
||||
@@ -9,14 +9,11 @@ pull_request_rules:
|
||||
- author!=nabinhait
|
||||
- author!=ankush
|
||||
- author!=deepeshgarg007
|
||||
- author!=frappe-pr-bot
|
||||
- author!=mergify[bot]
|
||||
|
||||
- or:
|
||||
- base=version-13
|
||||
- base=version-12
|
||||
- base=version-14
|
||||
- base=version-15
|
||||
actions:
|
||||
close:
|
||||
comment:
|
||||
|
||||
@@ -5,7 +5,7 @@ fail_fast: false
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.3.0
|
||||
rev: v4.0.1
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
files: "erpnext.*"
|
||||
@@ -15,53 +15,13 @@ repos:
|
||||
args: ['--branch', 'develop']
|
||||
- id: check-merge-conflict
|
||||
- id: check-ast
|
||||
- id: check-json
|
||||
- id: check-toml
|
||||
- id: check-yaml
|
||||
- id: debug-statements
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||
rev: v2.7.1
|
||||
hooks:
|
||||
- id: prettier
|
||||
types_or: [javascript, vue, scss]
|
||||
# Ignore any files that might contain jinja / bundles
|
||||
exclude: |
|
||||
(?x)^(
|
||||
erpnext/public/dist/.*|
|
||||
cypress/.*|
|
||||
.*node_modules.*|
|
||||
.*boilerplate.*|
|
||||
erpnext/public/js/controllers/.*|
|
||||
erpnext/templates/pages/order.js|
|
||||
erpnext/templates/includes/.*
|
||||
)$
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-eslint
|
||||
rev: v8.44.0
|
||||
hooks:
|
||||
- id: eslint
|
||||
types_or: [javascript]
|
||||
args: ['--quiet']
|
||||
# Ignore any files that might contain jinja / bundles
|
||||
exclude: |
|
||||
(?x)^(
|
||||
erpnext/public/dist/.*|
|
||||
cypress/.*|
|
||||
.*node_modules.*|
|
||||
.*boilerplate.*|
|
||||
erpnext/public/js/controllers/.*|
|
||||
erpnext/templates/pages/order.js|
|
||||
erpnext/templates/includes/.*
|
||||
)$
|
||||
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 6.0.0
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 3.9.2
|
||||
hooks:
|
||||
- id: flake8
|
||||
additional_dependencies: [
|
||||
'flake8-bugbear',
|
||||
'flake8-tuple',
|
||||
]
|
||||
args: ['--config', '.github/helper/.flake8_strict']
|
||||
exclude: ".*setup.py$"
|
||||
@@ -72,8 +32,8 @@ repos:
|
||||
- id: black
|
||||
additional_dependencies: ['click==8.0.4']
|
||||
|
||||
- repo: https://github.com/PyCQA/isort
|
||||
rev: 5.12.0
|
||||
- repo: https://github.com/timothycrosley/isort
|
||||
rev: 5.9.1
|
||||
hooks:
|
||||
- id: isort
|
||||
exclude: ".*setup.py$"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"branches": ["version-15"],
|
||||
"branches": ["version-14"],
|
||||
"plugins": [
|
||||
"@semantic-release/commit-analyzer", {
|
||||
"preset": "angular",
|
||||
@@ -10,7 +10,7 @@
|
||||
"@semantic-release/release-notes-generator",
|
||||
[
|
||||
"@semantic-release/exec", {
|
||||
"prepareCmd": 'sed -ir "s/[0-9]*\.[0-9]*\.[0-9]*/${nextRelease.version}/" erpnext/__init__.py'
|
||||
"prepareCmd": 'sed -ir -E "s/\"[0-9]+\.[0-9]+\.[0-9]+\"/\"${nextRelease.version}\"/" erpnext/__init__.py'
|
||||
}
|
||||
],
|
||||
[
|
||||
|
||||
40
CODEOWNERS
40
CODEOWNERS
@@ -3,22 +3,30 @@
|
||||
# These owners will be the default owners for everything in
|
||||
# the repo. Unless a later match takes precedence,
|
||||
|
||||
erpnext/accounts/ @deepeshgarg007 @ruthra-kumar
|
||||
erpnext/assets/ @anandbaburajan @deepeshgarg007
|
||||
erpnext/regional @deepeshgarg007 @ruthra-kumar
|
||||
erpnext/selling @deepeshgarg007 @ruthra-kumar
|
||||
erpnext/support/ @deepeshgarg007
|
||||
pos*
|
||||
erpnext/accounts/ @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
||||
erpnext/assets/ @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
||||
erpnext/loan_management/ @nextchamp-saqib @deepeshgarg007
|
||||
erpnext/regional @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
||||
erpnext/selling @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
|
||||
erpnext/support/ @nextchamp-saqib @deepeshgarg007
|
||||
pos* @nextchamp-saqib
|
||||
|
||||
erpnext/buying/ @rohitwaghchaure @s-aga-r
|
||||
erpnext/maintenance/ @rohitwaghchaure @s-aga-r
|
||||
erpnext/manufacturing/ @rohitwaghchaure @s-aga-r
|
||||
erpnext/quality_management/ @rohitwaghchaure @s-aga-r
|
||||
erpnext/stock/ @rohitwaghchaure @s-aga-r
|
||||
erpnext/subcontracting @rohitwaghchaure @s-aga-r
|
||||
erpnext/buying/ @marination @rohitwaghchaure @s-aga-r
|
||||
erpnext/e_commerce/ @marination
|
||||
erpnext/maintenance/ @marination @rohitwaghchaure @s-aga-r
|
||||
erpnext/manufacturing/ @marination @rohitwaghchaure @s-aga-r
|
||||
erpnext/portal/ @marination
|
||||
erpnext/quality_management/ @marination @rohitwaghchaure @s-aga-r
|
||||
erpnext/shopping_cart/ @marination
|
||||
erpnext/stock/ @marination @rohitwaghchaure @s-aga-r
|
||||
|
||||
erpnext/controllers/ @deepeshgarg007 @rohitwaghchaure
|
||||
erpnext/patches/ @deepeshgarg007
|
||||
erpnext/crm/ @NagariaHussain
|
||||
erpnext/education/ @rutwikhdev
|
||||
erpnext/projects/ @ruchamahabal
|
||||
|
||||
.github/ @deepeshgarg007
|
||||
pyproject.toml @phot0n
|
||||
erpnext/controllers/ @deepeshgarg007 @nextchamp-saqib @rohitwaghchaure @marination
|
||||
erpnext/patches/ @deepeshgarg007 @nextchamp-saqib @marination
|
||||
erpnext/public/ @nextchamp-saqib @marination
|
||||
|
||||
.github/ @ankush
|
||||
pyproject.toml @gavindsouza @ankush
|
||||
|
||||
@@ -65,7 +65,7 @@ New passwords will be created for the ERPNext "Administrator" user, the MariaDB
|
||||
1. [Frappe School](https://frappe.school) - Learn Frappe Framework and ERPNext from the various courses by the maintainers or from the community.
|
||||
2. [Official documentation](https://docs.erpnext.com/) - Extensive documentation for ERPNext.
|
||||
3. [Discussion Forum](https://discuss.erpnext.com/) - Engage with community of ERPNext users and service providers.
|
||||
4. [Telegram Group](https://erpnext_public.t.me) - Get instant help from huge community of users.
|
||||
4. [Telegram Group](https://t.me/erpnexthelp) - Get instant help from huge community of users.
|
||||
|
||||
|
||||
## Contributing
|
||||
@@ -82,8 +82,6 @@ GNU/General Public License (see [license.txt](license.txt))
|
||||
|
||||
The ERPNext code is licensed as GNU General Public License (v3) and the Documentation is licensed as Creative Commons (CC-BY-SA-3.0) and the copyright is owned by Frappe Technologies Pvt Ltd (Frappe) and Contributors.
|
||||
|
||||
By contributing to ERPNext, you agree that your contributions will be licensed under its GNU General Public License (v3).
|
||||
|
||||
## Logo and Trademark Policy
|
||||
|
||||
Please read our [Logo and Trademark Policy](TRADEMARK_POLICY.md).
|
||||
|
||||
@@ -1,13 +1,25 @@
|
||||
module.exports = {
|
||||
parserPreset: "conventional-changelog-conventionalcommits",
|
||||
parserPreset: 'conventional-changelog-conventionalcommits',
|
||||
rules: {
|
||||
"subject-empty": [2, "never"],
|
||||
"type-case": [2, "always", "lower-case"],
|
||||
"type-empty": [2, "never"],
|
||||
"type-enum": [
|
||||
'subject-empty': [2, 'never'],
|
||||
'type-case': [2, 'always', 'lower-case'],
|
||||
'type-empty': [2, 'never'],
|
||||
'type-enum': [
|
||||
2,
|
||||
"always",
|
||||
["build", "chore", "ci", "docs", "feat", "fix", "perf", "refactor", "revert", "style", "test"],
|
||||
'always',
|
||||
[
|
||||
'build',
|
||||
'chore',
|
||||
'ci',
|
||||
'docs',
|
||||
'feat',
|
||||
'fix',
|
||||
'perf',
|
||||
'refactor',
|
||||
'revert',
|
||||
'style',
|
||||
'test',
|
||||
],
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import functools
|
||||
import inspect
|
||||
|
||||
import frappe
|
||||
|
||||
__version__ = "15.16.2"
|
||||
__version__ = "14.1.0"
|
||||
|
||||
|
||||
def get_default_company(user=None):
|
||||
@@ -13,7 +12,7 @@ def get_default_company(user=None):
|
||||
if not user:
|
||||
user = frappe.session.user
|
||||
|
||||
companies = get_user_default_as_list("company", user)
|
||||
companies = get_user_default_as_list(user, "company")
|
||||
if companies:
|
||||
default_company = companies[0]
|
||||
else:
|
||||
@@ -121,14 +120,12 @@ def get_region(company=None):
|
||||
|
||||
You can also set global company flag in `frappe.flags.company`
|
||||
"""
|
||||
|
||||
if not company:
|
||||
company = frappe.local.flags.company
|
||||
|
||||
if company:
|
||||
return frappe.get_cached_value("Company", company, "country")
|
||||
|
||||
return frappe.flags.country or frappe.get_system_settings("country")
|
||||
if company or frappe.flags.company:
|
||||
return frappe.get_cached_value("Company", company or frappe.flags.company, "country")
|
||||
elif frappe.flags.country:
|
||||
return frappe.flags.country
|
||||
else:
|
||||
return frappe.get_system_settings("country")
|
||||
|
||||
|
||||
def allow_regional(fn):
|
||||
@@ -139,7 +136,6 @@ def allow_regional(fn):
|
||||
def myfunction():
|
||||
pass"""
|
||||
|
||||
@functools.wraps(fn)
|
||||
def caller(*args, **kwargs):
|
||||
overrides = frappe.get_hooks("regional_overrides", {}).get(get_region())
|
||||
function_path = f"{inspect.getmodule(fn).__name__}.{fn.__name__}"
|
||||
|
||||
@@ -4,19 +4,18 @@
|
||||
"creation": "2020-07-17 11:25:34.593061",
|
||||
"docstatus": 0,
|
||||
"doctype": "Dashboard Chart",
|
||||
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"from_fiscal_year\":\"erpnext.utils.get_fiscal_year()\",\"to_fiscal_year\":\"erpnext.utils.get_fiscal_year()\"}",
|
||||
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"from_fiscal_year\":\"frappe.sys_defaults.fiscal_year\",\"to_fiscal_year\":\"frappe.sys_defaults.fiscal_year\"}",
|
||||
"filters_json": "{\"period\":\"Monthly\",\"budget_against\":\"Cost Center\",\"show_cumulative\":0}",
|
||||
"idx": 0,
|
||||
"is_public": 1,
|
||||
"is_standard": 1,
|
||||
"modified": "2023-07-19 13:13:13.307073",
|
||||
"modified": "2020-07-22 12:24:49.144210",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Budget Variance",
|
||||
"number_of_groups": 0,
|
||||
"owner": "Administrator",
|
||||
"report_name": "Budget Variance Report",
|
||||
"roles": [],
|
||||
"timeseries": 0,
|
||||
"type": "Bar",
|
||||
"use_report_chart": 1,
|
||||
|
||||
@@ -4,19 +4,18 @@
|
||||
"creation": "2020-07-17 11:25:34.448572",
|
||||
"docstatus": 0,
|
||||
"doctype": "Dashboard Chart",
|
||||
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"from_fiscal_year\":\"erpnext.utils.get_fiscal_year()\",\"to_fiscal_year\":\"erpnext.utils.get_fiscal_year()\"}",
|
||||
"dynamic_filters_json": "{\"company\":\"frappe.defaults.get_user_default(\\\"Company\\\")\",\"from_fiscal_year\":\"frappe.sys_defaults.fiscal_year\",\"to_fiscal_year\":\"frappe.sys_defaults.fiscal_year\"}",
|
||||
"filters_json": "{\"filter_based_on\":\"Fiscal Year\",\"period_start_date\":\"2020-04-01\",\"period_end_date\":\"2021-03-31\",\"periodicity\":\"Yearly\",\"include_default_book_entries\":1}",
|
||||
"idx": 0,
|
||||
"is_public": 1,
|
||||
"is_standard": 1,
|
||||
"modified": "2023-07-19 13:08:56.470390",
|
||||
"modified": "2020-07-22 12:33:48.888943",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Profit and Loss",
|
||||
"number_of_groups": 0,
|
||||
"owner": "Administrator",
|
||||
"report_name": "Profit and Loss Statement",
|
||||
"roles": [],
|
||||
"timeseries": 0,
|
||||
"type": "Bar",
|
||||
"use_report_chart": 1,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
frappe.provide("frappe.dashboards.chart_sources");
|
||||
frappe.provide('frappe.dashboards.chart_sources');
|
||||
|
||||
frappe.dashboards.chart_sources["Account Balance Timeline"] = {
|
||||
method: "erpnext.accounts.dashboard_chart_source.account_balance_timeline.account_balance_timeline.get",
|
||||
@@ -9,14 +9,14 @@ frappe.dashboards.chart_sources["Account Balance Timeline"] = {
|
||||
fieldtype: "Link",
|
||||
options: "Company",
|
||||
default: frappe.defaults.get_user_default("Company"),
|
||||
reqd: 1,
|
||||
reqd: 1
|
||||
},
|
||||
{
|
||||
fieldname: "account",
|
||||
label: __("Account"),
|
||||
fieldtype: "Link",
|
||||
options: "Account",
|
||||
reqd: 1,
|
||||
reqd: 1
|
||||
},
|
||||
],
|
||||
]
|
||||
};
|
||||
|
||||
@@ -76,7 +76,7 @@ def get(
|
||||
|
||||
def build_result(account, dates, gl_entries):
|
||||
result = [[getdate(date), 0.0] for date in dates]
|
||||
root_type = frappe.get_cached_value("Account", account, "root_type")
|
||||
root_type = frappe.db.get_value("Account", account, "root_type")
|
||||
|
||||
# start with the first date
|
||||
date_index = 0
|
||||
|
||||
@@ -136,7 +136,7 @@ def convert_deferred_revenue_to_income(
|
||||
send_mail(deferred_process)
|
||||
|
||||
|
||||
def get_booking_dates(doc, item, posting_date=None, prev_posting_date=None):
|
||||
def get_booking_dates(doc, item, posting_date=None):
|
||||
if not posting_date:
|
||||
posting_date = add_days(today(), -1)
|
||||
|
||||
@@ -146,42 +146,39 @@ def get_booking_dates(doc, item, posting_date=None, prev_posting_date=None):
|
||||
"deferred_revenue_account" if doc.doctype == "Sales Invoice" else "deferred_expense_account"
|
||||
)
|
||||
|
||||
if not prev_posting_date:
|
||||
prev_gl_entry = frappe.db.sql(
|
||||
"""
|
||||
select name, posting_date from `tabGL Entry` where company=%s and account=%s and
|
||||
voucher_type=%s and voucher_no=%s and voucher_detail_no=%s
|
||||
and is_cancelled = 0
|
||||
order by posting_date desc limit 1
|
||||
""",
|
||||
(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name),
|
||||
as_dict=True,
|
||||
)
|
||||
prev_gl_entry = frappe.db.sql(
|
||||
"""
|
||||
select name, posting_date from `tabGL Entry` where company=%s and account=%s and
|
||||
voucher_type=%s and voucher_no=%s and voucher_detail_no=%s
|
||||
and is_cancelled = 0
|
||||
order by posting_date desc limit 1
|
||||
""",
|
||||
(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name),
|
||||
as_dict=True,
|
||||
)
|
||||
|
||||
prev_gl_via_je = frappe.db.sql(
|
||||
"""
|
||||
SELECT p.name, p.posting_date FROM `tabJournal Entry` p, `tabJournal Entry Account` c
|
||||
WHERE p.name = c.parent and p.company=%s and c.account=%s
|
||||
and c.reference_type=%s and c.reference_name=%s
|
||||
and c.reference_detail_no=%s and c.docstatus < 2 order by posting_date desc limit 1
|
||||
""",
|
||||
(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name),
|
||||
as_dict=True,
|
||||
)
|
||||
prev_gl_via_je = frappe.db.sql(
|
||||
"""
|
||||
SELECT p.name, p.posting_date FROM `tabJournal Entry` p, `tabJournal Entry Account` c
|
||||
WHERE p.name = c.parent and p.company=%s and c.account=%s
|
||||
and c.reference_type=%s and c.reference_name=%s
|
||||
and c.reference_detail_no=%s and c.docstatus < 2 order by posting_date desc limit 1
|
||||
""",
|
||||
(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name),
|
||||
as_dict=True,
|
||||
)
|
||||
|
||||
if prev_gl_via_je:
|
||||
if (not prev_gl_entry) or (
|
||||
prev_gl_entry and prev_gl_entry[0].posting_date < prev_gl_via_je[0].posting_date
|
||||
):
|
||||
prev_gl_entry = prev_gl_via_je
|
||||
|
||||
if prev_gl_entry:
|
||||
start_date = getdate(add_days(prev_gl_entry[0].posting_date, 1))
|
||||
else:
|
||||
start_date = item.service_start_date
|
||||
if prev_gl_via_je:
|
||||
if (not prev_gl_entry) or (
|
||||
prev_gl_entry and prev_gl_entry[0].posting_date < prev_gl_via_je[0].posting_date
|
||||
):
|
||||
prev_gl_entry = prev_gl_via_je
|
||||
|
||||
if prev_gl_entry:
|
||||
start_date = getdate(add_days(prev_gl_entry[0].posting_date, 1))
|
||||
else:
|
||||
start_date = getdate(add_days(prev_posting_date, 1))
|
||||
start_date = item.service_start_date
|
||||
|
||||
end_date = get_last_day(start_date)
|
||||
if end_date >= item.service_end_date:
|
||||
end_date = item.service_end_date
|
||||
@@ -341,18 +338,12 @@ def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
|
||||
"enable_deferred_revenue" if doc.doctype == "Sales Invoice" else "enable_deferred_expense"
|
||||
)
|
||||
|
||||
accounts_frozen_upto = frappe.db.get_single_value("Accounts Settings", "acc_frozen_upto")
|
||||
accounts_frozen_upto = frappe.get_cached_value("Accounts Settings", "None", "acc_frozen_upto")
|
||||
|
||||
def _book_deferred_revenue_or_expense(
|
||||
item,
|
||||
via_journal_entry,
|
||||
submit_journal_entry,
|
||||
book_deferred_entries_based_on,
|
||||
prev_posting_date=None,
|
||||
item, via_journal_entry, submit_journal_entry, book_deferred_entries_based_on
|
||||
):
|
||||
start_date, end_date, last_gl_entry = get_booking_dates(
|
||||
doc, item, posting_date=posting_date, prev_posting_date=prev_posting_date
|
||||
)
|
||||
start_date, end_date, last_gl_entry = get_booking_dates(doc, item, posting_date=posting_date)
|
||||
if not (start_date and end_date):
|
||||
return
|
||||
|
||||
@@ -386,12 +377,9 @@ def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
|
||||
if not amount:
|
||||
return
|
||||
|
||||
gl_posting_date = end_date
|
||||
prev_posting_date = None
|
||||
# check if books nor frozen till endate:
|
||||
if accounts_frozen_upto and getdate(end_date) <= getdate(accounts_frozen_upto):
|
||||
gl_posting_date = get_last_day(add_days(accounts_frozen_upto, 1))
|
||||
prev_posting_date = end_date
|
||||
if accounts_frozen_upto and (end_date) <= getdate(accounts_frozen_upto):
|
||||
end_date = get_last_day(add_days(accounts_frozen_upto, 1))
|
||||
|
||||
if via_journal_entry:
|
||||
book_revenue_via_journal_entry(
|
||||
@@ -400,7 +388,7 @@ def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
|
||||
debit_account,
|
||||
amount,
|
||||
base_amount,
|
||||
gl_posting_date,
|
||||
end_date,
|
||||
project,
|
||||
account_currency,
|
||||
item.cost_center,
|
||||
@@ -416,7 +404,7 @@ def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
|
||||
against,
|
||||
amount,
|
||||
base_amount,
|
||||
gl_posting_date,
|
||||
end_date,
|
||||
project,
|
||||
account_currency,
|
||||
item.cost_center,
|
||||
@@ -430,11 +418,7 @@ def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
|
||||
|
||||
if getdate(end_date) < getdate(posting_date) and not last_gl_entry:
|
||||
_book_deferred_revenue_or_expense(
|
||||
item,
|
||||
via_journal_entry,
|
||||
submit_journal_entry,
|
||||
book_deferred_entries_based_on,
|
||||
prev_posting_date,
|
||||
item, via_journal_entry, submit_journal_entry, book_deferred_entries_based_on
|
||||
)
|
||||
|
||||
via_journal_entry = cint(
|
||||
|
||||
@@ -1,32 +1,33 @@
|
||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.ui.form.on("Account", {
|
||||
setup: function (frm) {
|
||||
frm.add_fetch("parent_account", "report_type", "report_type");
|
||||
frm.add_fetch("parent_account", "root_type", "root_type");
|
||||
frappe.ui.form.on('Account', {
|
||||
setup: function(frm) {
|
||||
frm.add_fetch('parent_account', 'report_type', 'report_type');
|
||||
frm.add_fetch('parent_account', 'root_type', 'root_type');
|
||||
},
|
||||
onload: function (frm) {
|
||||
frm.set_query("parent_account", function (doc) {
|
||||
onload: function(frm) {
|
||||
frm.set_query('parent_account', function(doc) {
|
||||
return {
|
||||
filters: {
|
||||
is_group: 1,
|
||||
company: doc.company,
|
||||
},
|
||||
"is_group": 1,
|
||||
"company": doc.company
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
refresh: function (frm) {
|
||||
frm.toggle_display("account_name", frm.is_new());
|
||||
refresh: function(frm) {
|
||||
frm.toggle_display('account_name', frm.is_new());
|
||||
|
||||
// hide fields if group
|
||||
frm.toggle_display(["tax_rate"], cint(frm.doc.is_group) == 0);
|
||||
frm.toggle_display(['account_type', 'tax_rate'], cint(frm.doc.is_group) == 0);
|
||||
|
||||
// disable fields
|
||||
frm.toggle_enable(["is_group", "company"], false);
|
||||
frm.toggle_enable(['is_group', 'company'], false);
|
||||
|
||||
if (cint(frm.doc.is_group) == 0) {
|
||||
frm.toggle_display("freeze_account", frm.doc.__onload && frm.doc.__onload.can_freeze_account);
|
||||
frm.toggle_display('freeze_account', frm.doc.__onload
|
||||
&& frm.doc.__onload.can_freeze_account);
|
||||
}
|
||||
|
||||
// read-only for root accounts
|
||||
@@ -37,147 +38,125 @@ frappe.ui.form.on("Account", {
|
||||
} else {
|
||||
// credit days and type if customer or supplier
|
||||
frm.set_intro(null);
|
||||
frm.trigger("account_type");
|
||||
frm.trigger('account_type');
|
||||
// show / hide convert buttons
|
||||
frm.trigger("add_toolbar_buttons");
|
||||
frm.trigger('add_toolbar_buttons');
|
||||
}
|
||||
if (frm.has_perm("write")) {
|
||||
frm.add_custom_button(
|
||||
__("Merge Account"),
|
||||
function () {
|
||||
frm.trigger("merge_account");
|
||||
},
|
||||
__("Actions")
|
||||
);
|
||||
frm.add_custom_button(
|
||||
__("Update Account Name / Number"),
|
||||
function () {
|
||||
frm.trigger("update_account_number");
|
||||
},
|
||||
__("Actions")
|
||||
);
|
||||
if (frm.has_perm('write')) {
|
||||
frm.add_custom_button(__('Merge Account'), function () {
|
||||
frm.trigger("merge_account");
|
||||
}, __('Actions'));
|
||||
frm.add_custom_button(__('Update Account Name / Number'), function () {
|
||||
frm.trigger("update_account_number");
|
||||
}, __('Actions'));
|
||||
}
|
||||
}
|
||||
},
|
||||
account_type: function (frm) {
|
||||
if (frm.doc.is_group == 0) {
|
||||
frm.toggle_display(["tax_rate"], frm.doc.account_type == "Tax");
|
||||
frm.toggle_display("warehouse", frm.doc.account_type == "Stock");
|
||||
frm.toggle_display(['tax_rate'], frm.doc.account_type == 'Tax');
|
||||
frm.toggle_display('warehouse', frm.doc.account_type == 'Stock');
|
||||
}
|
||||
},
|
||||
add_toolbar_buttons: function (frm) {
|
||||
frm.add_custom_button(
|
||||
__("Chart of Accounts"),
|
||||
() => {
|
||||
frappe.set_route("Tree", "Account");
|
||||
},
|
||||
__("View")
|
||||
);
|
||||
add_toolbar_buttons: function(frm) {
|
||||
frm.add_custom_button(__('Chart of Accounts'), () => {
|
||||
frappe.set_route("Tree", "Account");
|
||||
}, __('View'));
|
||||
|
||||
if (frm.doc.is_group == 1) {
|
||||
frm.add_custom_button(
|
||||
__("Convert to Non-Group"),
|
||||
function () {
|
||||
return frappe.call({
|
||||
doc: frm.doc,
|
||||
method: "convert_group_to_ledger",
|
||||
callback: function () {
|
||||
frm.refresh();
|
||||
},
|
||||
});
|
||||
},
|
||||
__("Actions")
|
||||
);
|
||||
} else if (cint(frm.doc.is_group) == 0 && frappe.boot.user.can_read.indexOf("GL Entry") !== -1) {
|
||||
frm.add_custom_button(
|
||||
__("General Ledger"),
|
||||
function () {
|
||||
frappe.route_options = {
|
||||
account: frm.doc.name,
|
||||
from_date: erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[1],
|
||||
to_date: erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[2],
|
||||
company: frm.doc.company,
|
||||
};
|
||||
frappe.set_route("query-report", "General Ledger");
|
||||
},
|
||||
__("View")
|
||||
);
|
||||
frm.add_custom_button(__('Convert to Non-Group'), function () {
|
||||
return frappe.call({
|
||||
doc: frm.doc,
|
||||
method: 'convert_group_to_ledger',
|
||||
callback: function() {
|
||||
frm.refresh();
|
||||
}
|
||||
});
|
||||
}, __('Actions'));
|
||||
|
||||
frm.add_custom_button(
|
||||
__("Convert to Group"),
|
||||
function () {
|
||||
return frappe.call({
|
||||
doc: frm.doc,
|
||||
method: "convert_ledger_to_group",
|
||||
callback: function () {
|
||||
frm.refresh();
|
||||
},
|
||||
});
|
||||
},
|
||||
__("Actions")
|
||||
);
|
||||
} else if (cint(frm.doc.is_group) == 0
|
||||
&& frappe.boot.user.can_read.indexOf("GL Entry") !== -1) {
|
||||
frm.add_custom_button(__('General Ledger'), function () {
|
||||
frappe.route_options = {
|
||||
"account": frm.doc.name,
|
||||
"from_date": frappe.sys_defaults.year_start_date,
|
||||
"to_date": frappe.sys_defaults.year_end_date,
|
||||
"company": frm.doc.company
|
||||
};
|
||||
frappe.set_route("query-report", "General Ledger");
|
||||
}, __('View'));
|
||||
|
||||
frm.add_custom_button(__('Convert to Group'), function () {
|
||||
return frappe.call({
|
||||
doc: frm.doc,
|
||||
method: 'convert_ledger_to_group',
|
||||
callback: function() {
|
||||
frm.refresh();
|
||||
}
|
||||
});
|
||||
}, __('Actions'));
|
||||
}
|
||||
},
|
||||
|
||||
merge_account: function (frm) {
|
||||
merge_account: function(frm) {
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __("Merge with Existing Account"),
|
||||
title: __('Merge with Existing Account'),
|
||||
fields: [
|
||||
{
|
||||
label: "Name",
|
||||
fieldname: "name",
|
||||
fieldtype: "Data",
|
||||
reqd: 1,
|
||||
default: frm.doc.name,
|
||||
},
|
||||
"label" : "Name",
|
||||
"fieldname": "name",
|
||||
"fieldtype": "Data",
|
||||
"reqd": 1,
|
||||
"default": frm.doc.name
|
||||
}
|
||||
],
|
||||
primary_action: function () {
|
||||
primary_action: function() {
|
||||
var data = d.get_values();
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.account.account.merge_account",
|
||||
args: {
|
||||
old: frm.doc.name,
|
||||
new: data.name,
|
||||
is_group: frm.doc.is_group,
|
||||
root_type: frm.doc.root_type,
|
||||
company: frm.doc.company
|
||||
},
|
||||
callback: function (r) {
|
||||
if (!r.exc) {
|
||||
if (r.message) {
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
if(r.message) {
|
||||
frappe.set_route("Form", "Account", r.message);
|
||||
}
|
||||
d.hide();
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
},
|
||||
primary_action_label: __("Merge"),
|
||||
primary_action_label: __('Merge')
|
||||
});
|
||||
d.show();
|
||||
},
|
||||
|
||||
update_account_number: function (frm) {
|
||||
update_account_number: function(frm) {
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __("Update Account Number / Name"),
|
||||
title: __('Update Account Number / Name'),
|
||||
fields: [
|
||||
{
|
||||
label: "Account Name",
|
||||
fieldname: "account_name",
|
||||
fieldtype: "Data",
|
||||
reqd: 1,
|
||||
default: frm.doc.account_name,
|
||||
"label": "Account Name",
|
||||
"fieldname": "account_name",
|
||||
"fieldtype": "Data",
|
||||
"reqd": 1,
|
||||
"default": frm.doc.account_name
|
||||
},
|
||||
{
|
||||
label: "Account Number",
|
||||
fieldname: "account_number",
|
||||
fieldtype: "Data",
|
||||
default: frm.doc.account_number,
|
||||
},
|
||||
"label": "Account Number",
|
||||
"fieldname": "account_number",
|
||||
"fieldtype": "Data",
|
||||
"default": frm.doc.account_number
|
||||
}
|
||||
],
|
||||
primary_action: function () {
|
||||
primary_action: function() {
|
||||
var data = d.get_values();
|
||||
if (
|
||||
data.account_number === frm.doc.account_number &&
|
||||
data.account_name === frm.doc.account_name
|
||||
) {
|
||||
if(data.account_number === frm.doc.account_number && data.account_name === frm.doc.account_name) {
|
||||
d.hide();
|
||||
return;
|
||||
}
|
||||
@@ -187,11 +166,11 @@ frappe.ui.form.on("Account", {
|
||||
args: {
|
||||
account_number: data.account_number,
|
||||
account_name: data.account_name,
|
||||
name: frm.doc.name,
|
||||
name: frm.doc.name
|
||||
},
|
||||
callback: function (r) {
|
||||
if (!r.exc) {
|
||||
if (r.message) {
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
if(r.message) {
|
||||
frappe.set_route("Form", "Account", r.message);
|
||||
} else {
|
||||
frm.set_value("account_number", data.account_number);
|
||||
@@ -199,11 +178,11 @@ frappe.ui.form.on("Account", {
|
||||
}
|
||||
d.hide();
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
},
|
||||
primary_action_label: __("Update"),
|
||||
primary_action_label: __('Update')
|
||||
});
|
||||
d.show();
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
"root_type",
|
||||
"report_type",
|
||||
"account_currency",
|
||||
"inter_company_account",
|
||||
"column_break1",
|
||||
"parent_account",
|
||||
"account_type",
|
||||
@@ -33,11 +34,15 @@
|
||||
{
|
||||
"fieldname": "properties",
|
||||
"fieldtype": "Section Break",
|
||||
"oldfieldtype": "Section Break"
|
||||
"oldfieldtype": "Section Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break0",
|
||||
"fieldtype": "Column Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
@@ -48,7 +53,9 @@
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "account_name",
|
||||
"oldfieldtype": "Data",
|
||||
"reqd": 1
|
||||
"reqd": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "account_number",
|
||||
@@ -56,13 +63,17 @@
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Account Number",
|
||||
"read_only": 1
|
||||
"read_only": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "is_group",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Group"
|
||||
"label": "Is Group",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
@@ -74,7 +85,9 @@
|
||||
"options": "Company",
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 1,
|
||||
"reqd": 1
|
||||
"reqd": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "root_type",
|
||||
@@ -82,7 +95,9 @@
|
||||
"in_standard_filter": 1,
|
||||
"label": "Root Type",
|
||||
"options": "\nAsset\nLiability\nIncome\nExpense\nEquity",
|
||||
"read_only": 1
|
||||
"read_only": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "report_type",
|
||||
@@ -90,18 +105,32 @@
|
||||
"in_standard_filter": 1,
|
||||
"label": "Report Type",
|
||||
"options": "\nBalance Sheet\nProfit and Loss",
|
||||
"read_only": 1
|
||||
"read_only": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_group==0",
|
||||
"fieldname": "account_currency",
|
||||
"fieldtype": "Link",
|
||||
"label": "Currency",
|
||||
"options": "Currency"
|
||||
"options": "Currency",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "inter_company_account",
|
||||
"fieldtype": "Check",
|
||||
"label": "Inter Company Account",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
@@ -113,7 +142,9 @@
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Account",
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
"search_index": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"description": "Setting Account Type helps in selecting this Account in transactions.",
|
||||
@@ -123,7 +154,9 @@
|
||||
"label": "Account Type",
|
||||
"oldfieldname": "account_type",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nAccumulated Depreciation\nAsset Received But Not Billed\nBank\nCash\nChargeable\nCapital Work in Progress\nCost of Goods Sold\nCurrent Asset\nCurrent Liability\nDepreciation\nDirect Expense\nDirect Income\nEquity\nExpense Account\nExpenses Included In Asset Valuation\nExpenses Included In Valuation\nFixed Asset\nIncome Account\nIndirect Expense\nIndirect Income\nLiability\nPayable\nReceivable\nRound Off\nStock\nStock Adjustment\nStock Received But Not Billed\nService Received But Not Billed\nTax\nTemporary"
|
||||
"options": "\nAccumulated Depreciation\nAsset Received But Not Billed\nBank\nCash\nChargeable\nCapital Work in Progress\nCost of Goods Sold\nDepreciation\nEquity\nExpense Account\nExpenses Included In Asset Valuation\nExpenses Included In Valuation\nFixed Asset\nIncome Account\nPayable\nReceivable\nRound Off\nStock\nStock Adjustment\nStock Received But Not Billed\nService Received But Not Billed\nTax\nTemporary",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"description": "Rate at which this tax is applied",
|
||||
@@ -131,7 +164,9 @@
|
||||
"fieldtype": "Float",
|
||||
"label": "Rate",
|
||||
"oldfieldname": "tax_rate",
|
||||
"oldfieldtype": "Currency"
|
||||
"oldfieldtype": "Currency",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"description": "If the account is frozen, entries are allowed to restricted users.",
|
||||
@@ -140,13 +175,17 @@
|
||||
"label": "Frozen",
|
||||
"oldfieldname": "freeze_account",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "No\nYes"
|
||||
"options": "No\nYes",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "balance_must_be",
|
||||
"fieldtype": "Select",
|
||||
"label": "Balance must be",
|
||||
"options": "\nDebit\nCredit"
|
||||
"options": "\nDebit\nCredit",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "lft",
|
||||
@@ -155,7 +194,9 @@
|
||||
"label": "Lft",
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
"search_index": 1
|
||||
"search_index": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "rgt",
|
||||
@@ -164,7 +205,9 @@
|
||||
"label": "Rgt",
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
"search_index": 1
|
||||
"search_index": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "old_parent",
|
||||
@@ -172,27 +215,33 @@
|
||||
"hidden": 1,
|
||||
"label": "Old Parent",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
"read_only": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "eval:(doc.report_type == 'Profit and Loss' && !doc.is_group)",
|
||||
"fieldname": "include_in_gross",
|
||||
"fieldtype": "Check",
|
||||
"label": "Include in gross"
|
||||
"label": "Include in gross",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "disabled",
|
||||
"fieldtype": "Check",
|
||||
"label": "Disable"
|
||||
"label": "Disable",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-money",
|
||||
"idx": 1,
|
||||
"is_tree": 1,
|
||||
"links": [],
|
||||
"modified": "2023-07-20 18:18:44.405723",
|
||||
"modified": "2020-06-11 15:15:54.338622",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Account",
|
||||
@@ -243,6 +292,7 @@
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"set_user_permissions": 1,
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
@@ -251,6 +301,5 @@
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "ASC",
|
||||
"states": [],
|
||||
"track_changes": 1
|
||||
}
|
||||
@@ -18,70 +18,7 @@ class BalanceMismatchError(frappe.ValidationError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidAccountMergeError(frappe.ValidationError):
|
||||
pass
|
||||
|
||||
|
||||
class Account(NestedSet):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
account_currency: DF.Link | None
|
||||
account_name: DF.Data
|
||||
account_number: DF.Data | None
|
||||
account_type: DF.Literal[
|
||||
"",
|
||||
"Accumulated Depreciation",
|
||||
"Asset Received But Not Billed",
|
||||
"Bank",
|
||||
"Cash",
|
||||
"Chargeable",
|
||||
"Capital Work in Progress",
|
||||
"Cost of Goods Sold",
|
||||
"Current Asset",
|
||||
"Current Liability",
|
||||
"Depreciation",
|
||||
"Direct Expense",
|
||||
"Direct Income",
|
||||
"Equity",
|
||||
"Expense Account",
|
||||
"Expenses Included In Asset Valuation",
|
||||
"Expenses Included In Valuation",
|
||||
"Fixed Asset",
|
||||
"Income Account",
|
||||
"Indirect Expense",
|
||||
"Indirect Income",
|
||||
"Liability",
|
||||
"Payable",
|
||||
"Receivable",
|
||||
"Round Off",
|
||||
"Stock",
|
||||
"Stock Adjustment",
|
||||
"Stock Received But Not Billed",
|
||||
"Service Received But Not Billed",
|
||||
"Tax",
|
||||
"Temporary",
|
||||
]
|
||||
balance_must_be: DF.Literal["", "Debit", "Credit"]
|
||||
company: DF.Link
|
||||
disabled: DF.Check
|
||||
freeze_account: DF.Literal["No", "Yes"]
|
||||
include_in_gross: DF.Check
|
||||
is_group: DF.Check
|
||||
lft: DF.Int
|
||||
old_parent: DF.Data | None
|
||||
parent_account: DF.Link
|
||||
report_type: DF.Literal["", "Balance Sheet", "Profit and Loss"]
|
||||
rgt: DF.Int
|
||||
root_type: DF.Literal["", "Asset", "Liability", "Income", "Expense", "Equity"]
|
||||
tax_rate: DF.Float
|
||||
# end: auto-generated types
|
||||
|
||||
nsm_parent_field = "parent_account"
|
||||
|
||||
def on_update(self):
|
||||
@@ -100,7 +37,7 @@ class Account(NestedSet):
|
||||
def autoname(self):
|
||||
from erpnext.accounts.utils import get_autoname_with_number
|
||||
|
||||
self.name = get_autoname_with_number(self.account_number, self.account_name, self.company)
|
||||
self.name = get_autoname_with_number(self.account_number, self.account_name, None, self.company)
|
||||
|
||||
def validate(self):
|
||||
from erpnext.accounts.utils import validate_field_number
|
||||
@@ -108,7 +45,6 @@ class Account(NestedSet):
|
||||
if frappe.local.flags.allow_unverified_charts:
|
||||
return
|
||||
self.validate_parent()
|
||||
self.validate_parent_child_account_type()
|
||||
self.validate_root_details()
|
||||
validate_field_number("Account", self.name, self.account_number, self.company, "account_number")
|
||||
self.validate_group_or_ledger()
|
||||
@@ -118,26 +54,11 @@ class Account(NestedSet):
|
||||
self.validate_balance_must_be_debit_or_credit()
|
||||
self.validate_account_currency()
|
||||
self.validate_root_company_and_sync_account_to_children()
|
||||
self.validate_receivable_payable_account_type()
|
||||
|
||||
def validate_parent_child_account_type(self):
|
||||
if self.parent_account:
|
||||
if self.account_type in [
|
||||
"Direct Income",
|
||||
"Indirect Income",
|
||||
"Current Asset",
|
||||
"Current Liability",
|
||||
"Direct Expense",
|
||||
"Indirect Expense",
|
||||
]:
|
||||
parent_account_type = frappe.db.get_value("Account", self.parent_account, ["account_type"])
|
||||
if parent_account_type == self.account_type:
|
||||
throw(_("Only Parent can be of type {0}").format(self.account_type))
|
||||
|
||||
def validate_parent(self):
|
||||
"""Fetch Parent Details and validate parent account"""
|
||||
if self.parent_account:
|
||||
par = frappe.get_cached_value(
|
||||
par = frappe.db.get_value(
|
||||
"Account", self.parent_account, ["name", "is_group", "company"], as_dict=1
|
||||
)
|
||||
if not par:
|
||||
@@ -161,7 +82,7 @@ class Account(NestedSet):
|
||||
|
||||
def set_root_and_report_type(self):
|
||||
if self.parent_account:
|
||||
par = frappe.get_cached_value(
|
||||
par = frappe.db.get_value(
|
||||
"Account", self.parent_account, ["report_type", "root_type"], as_dict=1
|
||||
)
|
||||
|
||||
@@ -171,7 +92,7 @@ class Account(NestedSet):
|
||||
self.root_type = par.root_type
|
||||
|
||||
if self.is_group:
|
||||
db_value = self.get_doc_before_save()
|
||||
db_value = frappe.db.get_value("Account", self.name, ["report_type", "root_type"], as_dict=1)
|
||||
if db_value:
|
||||
if self.report_type != db_value.report_type:
|
||||
frappe.db.sql(
|
||||
@@ -189,32 +110,14 @@ class Account(NestedSet):
|
||||
"Balance Sheet" if self.root_type in ("Asset", "Liability", "Equity") else "Profit and Loss"
|
||||
)
|
||||
|
||||
def validate_receivable_payable_account_type(self):
|
||||
doc_before_save = self.get_doc_before_save()
|
||||
receivable_payable_types = ["Receivable", "Payable"]
|
||||
if (
|
||||
doc_before_save
|
||||
and doc_before_save.account_type in receivable_payable_types
|
||||
and doc_before_save.account_type != self.account_type
|
||||
):
|
||||
# check for ledger entries
|
||||
if frappe.db.get_all("GL Entry", filters={"account": self.name, "is_cancelled": 0}, limit=1):
|
||||
msg = _(
|
||||
"There are ledger entries against this account. Changing {0} to non-{1} in live system will cause incorrect output in 'Accounts {2}' report"
|
||||
).format(
|
||||
frappe.bold("Account Type"), doc_before_save.account_type, doc_before_save.account_type
|
||||
)
|
||||
frappe.msgprint(msg)
|
||||
self.add_comment("Comment", msg)
|
||||
|
||||
def validate_root_details(self):
|
||||
doc_before_save = self.get_doc_before_save()
|
||||
|
||||
if doc_before_save and not doc_before_save.parent_account:
|
||||
throw(_("Root cannot be edited."), RootNotEditable)
|
||||
# does not exists parent
|
||||
if frappe.db.exists("Account", self.name):
|
||||
if not frappe.db.get_value("Account", self.name, "parent_account"):
|
||||
throw(_("Root cannot be edited."), RootNotEditable)
|
||||
|
||||
if not self.parent_account and not self.is_group:
|
||||
throw(_("The root account {0} must be a group").format(frappe.bold(self.name)))
|
||||
frappe.throw(_("The root account {0} must be a group").format(frappe.bold(self.name)))
|
||||
|
||||
def validate_root_company_and_sync_account_to_children(self):
|
||||
# ignore validation while creating new compnay or while syncing to child companies
|
||||
@@ -224,9 +127,7 @@ class Account(NestedSet):
|
||||
return
|
||||
ancestors = get_root_company(self.company)
|
||||
if ancestors:
|
||||
if frappe.get_cached_value(
|
||||
"Company", self.company, "allow_account_creation_against_child_company"
|
||||
):
|
||||
if frappe.get_value("Company", self.company, "allow_account_creation_against_child_company"):
|
||||
return
|
||||
if not frappe.db.get_value(
|
||||
"Account", {"account_name": self.account_name, "company": ancestors[0]}, "name"
|
||||
@@ -237,7 +138,7 @@ class Account(NestedSet):
|
||||
if not descendants:
|
||||
return
|
||||
parent_acc_name_map = {}
|
||||
parent_acc_name, parent_acc_number = frappe.get_cached_value(
|
||||
parent_acc_name, parent_acc_number = frappe.db.get_value(
|
||||
"Account", self.parent_account, ["account_name", "account_number"]
|
||||
)
|
||||
filters = {
|
||||
@@ -258,28 +159,27 @@ class Account(NestedSet):
|
||||
self.create_account_for_child_company(parent_acc_name_map, descendants, parent_acc_name)
|
||||
|
||||
def validate_group_or_ledger(self):
|
||||
doc_before_save = self.get_doc_before_save()
|
||||
if not doc_before_save or cint(doc_before_save.is_group) == cint(self.is_group):
|
||||
if self.get("__islocal"):
|
||||
return
|
||||
|
||||
if self.check_gle_exists():
|
||||
throw(_("Account with existing transaction cannot be converted to ledger"))
|
||||
elif self.is_group:
|
||||
if self.account_type and not self.flags.exclude_account_type_check:
|
||||
throw(_("Cannot covert to Group because Account Type is selected."))
|
||||
elif self.check_if_child_exists():
|
||||
throw(_("Account with child nodes cannot be set as ledger"))
|
||||
existing_is_group = frappe.db.get_value("Account", self.name, "is_group")
|
||||
if cint(self.is_group) != cint(existing_is_group):
|
||||
if self.check_gle_exists():
|
||||
throw(_("Account with existing transaction cannot be converted to ledger"))
|
||||
elif self.is_group:
|
||||
if self.account_type and not self.flags.exclude_account_type_check:
|
||||
throw(_("Cannot covert to Group because Account Type is selected."))
|
||||
elif self.check_if_child_exists():
|
||||
throw(_("Account with child nodes cannot be set as ledger"))
|
||||
|
||||
def validate_frozen_accounts_modifier(self):
|
||||
doc_before_save = self.get_doc_before_save()
|
||||
if not doc_before_save or doc_before_save.freeze_account == self.freeze_account:
|
||||
return
|
||||
|
||||
frozen_accounts_modifier = frappe.get_cached_value(
|
||||
"Accounts Settings", "Accounts Settings", "frozen_accounts_modifier"
|
||||
)
|
||||
if not frozen_accounts_modifier or frozen_accounts_modifier not in frappe.get_roles():
|
||||
throw(_("You are not authorized to set Frozen value"))
|
||||
old_value = frappe.db.get_value("Account", self.name, "freeze_account")
|
||||
if old_value and old_value != self.freeze_account:
|
||||
frozen_accounts_modifier = frappe.db.get_value(
|
||||
"Accounts Settings", None, "frozen_accounts_modifier"
|
||||
)
|
||||
if not frozen_accounts_modifier or frozen_accounts_modifier not in frappe.get_roles():
|
||||
throw(_("You are not authorized to set Frozen value"))
|
||||
|
||||
def validate_balance_must_be_debit_or_credit(self):
|
||||
from erpnext.accounts.utils import get_balance_on
|
||||
@@ -301,11 +201,8 @@ class Account(NestedSet):
|
||||
)
|
||||
|
||||
def validate_account_currency(self):
|
||||
self.currency_explicitly_specified = True
|
||||
|
||||
if not self.account_currency:
|
||||
self.account_currency = frappe.get_cached_value("Company", self.company, "default_currency")
|
||||
self.currency_explicitly_specified = False
|
||||
|
||||
gl_currency = frappe.db.get_value("GL Entry", {"account": self.name}, "account_currency")
|
||||
|
||||
@@ -326,9 +223,9 @@ class Account(NestedSet):
|
||||
)
|
||||
|
||||
# validate if parent of child company account to be added is a group
|
||||
if frappe.get_cached_value(
|
||||
"Account", self.parent_account, "is_group"
|
||||
) and not frappe.get_cached_value("Account", parent_acc_name_map[company], "is_group"):
|
||||
if frappe.db.get_value("Account", self.parent_account, "is_group") and not frappe.db.get_value(
|
||||
"Account", parent_acc_name_map[company], "is_group"
|
||||
):
|
||||
msg = _(
|
||||
"While creating account for Child Company {0}, parent account {1} found as a ledger account."
|
||||
).format(company_bold, parent_acc_name_bold)
|
||||
@@ -351,10 +248,8 @@ class Account(NestedSet):
|
||||
{
|
||||
"company": company,
|
||||
# parent account's currency should be passed down to child account's curreny
|
||||
# if currency explicitly specified by user, child will inherit. else, default currency will be used.
|
||||
"account_currency": self.account_currency
|
||||
if self.currency_explicitly_specified
|
||||
else erpnext.get_company_currency(company),
|
||||
# if it is None, it picks it up from default company currency, which might be unintended
|
||||
"account_currency": erpnext.get_company_currency(company),
|
||||
"parent_account": parent_acc_name_map[company],
|
||||
}
|
||||
)
|
||||
@@ -482,27 +377,23 @@ def validate_account_number(name, account_number, company):
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_account_number(name, account_name, account_number=None, from_descendant=False):
|
||||
account = frappe.get_cached_doc("Account", name)
|
||||
account = frappe.db.get_value("Account", name, "company", as_dict=True)
|
||||
if not account:
|
||||
return
|
||||
|
||||
old_acc_name, old_acc_number = account.account_name, account.account_number
|
||||
old_acc_name, old_acc_number = frappe.db.get_value(
|
||||
"Account", name, ["account_name", "account_number"]
|
||||
)
|
||||
|
||||
# check if account exists in parent company
|
||||
ancestors = get_ancestors_of("Company", account.company)
|
||||
allow_independent_account_creation = frappe.get_cached_value(
|
||||
allow_independent_account_creation = frappe.get_value(
|
||||
"Company", account.company, "allow_account_creation_against_child_company"
|
||||
)
|
||||
|
||||
if ancestors and not allow_independent_account_creation:
|
||||
for ancestor in ancestors:
|
||||
old_name = frappe.db.get_value(
|
||||
"Account",
|
||||
{"account_number": old_acc_number, "account_name": old_acc_name, "company": ancestor},
|
||||
"name",
|
||||
)
|
||||
|
||||
if old_name:
|
||||
if frappe.db.get_value("Account", {"account_name": old_acc_name, "company": ancestor}, "name"):
|
||||
# same account in parent company exists
|
||||
allow_child_account_creation = _("Allow Account Creation Against Child Company")
|
||||
|
||||
@@ -542,35 +433,24 @@ def update_account_number(name, account_name, account_number=None, from_descenda
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def merge_account(old, new):
|
||||
def merge_account(old, new, is_group, root_type, company):
|
||||
# Validate properties before merging
|
||||
new_account = frappe.get_cached_doc("Account", new)
|
||||
old_account = frappe.get_cached_doc("Account", old)
|
||||
|
||||
if not new_account:
|
||||
if not frappe.db.exists("Account", new):
|
||||
throw(_("Account {0} does not exist").format(new))
|
||||
|
||||
if (
|
||||
cint(new_account.is_group),
|
||||
new_account.root_type,
|
||||
new_account.company,
|
||||
cstr(new_account.account_currency),
|
||||
) != (
|
||||
cint(old_account.is_group),
|
||||
old_account.root_type,
|
||||
old_account.company,
|
||||
cstr(old_account.account_currency),
|
||||
):
|
||||
val = list(frappe.db.get_value("Account", new, ["is_group", "root_type", "company"]))
|
||||
|
||||
if val != [cint(is_group), root_type, company]:
|
||||
throw(
|
||||
msg=_(
|
||||
"""Merging is only possible if following properties are same in both records. Is Group, Root Type, Company and Account Currency"""
|
||||
),
|
||||
title=("Invalid Accounts"),
|
||||
exc=InvalidAccountMergeError,
|
||||
_(
|
||||
"""Merging is only possible if following properties are same in both records. Is Group, Root Type, Company"""
|
||||
)
|
||||
)
|
||||
|
||||
if old_account.is_group and new_account.parent_account == old:
|
||||
new_account.db_set("parent_account", frappe.get_cached_value("Account", old, "parent_account"))
|
||||
if is_group and frappe.db.get_value("Account", new, "parent_account") == old:
|
||||
frappe.db.set_value(
|
||||
"Account", new, "parent_account", frappe.db.get_value("Account", old, "parent_account")
|
||||
)
|
||||
|
||||
frappe.rename_doc("Account", old, new, merge=1, force=1)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
frappe.provide("frappe.treeview_settings");
|
||||
frappe.provide("frappe.treeview_settings")
|
||||
|
||||
frappe.treeview_settings["Account"] = {
|
||||
breadcrumb: "Accounts",
|
||||
@@ -7,12 +7,12 @@ frappe.treeview_settings["Account"] = {
|
||||
filters: [
|
||||
{
|
||||
fieldname: "company",
|
||||
fieldtype: "Select",
|
||||
fieldtype:"Select",
|
||||
options: erpnext.utils.get_tree_options("company"),
|
||||
label: __("Company"),
|
||||
default: erpnext.utils.get_tree_default("company"),
|
||||
on_change: function () {
|
||||
var me = frappe.treeview_settings["Account"].treeview;
|
||||
on_change: function() {
|
||||
var me = frappe.treeview_settings['Account'].treeview;
|
||||
var company = me.page.fields_dict.company.get_value();
|
||||
if (!company) {
|
||||
frappe.throw(__("Please set a Company"));
|
||||
@@ -22,36 +22,30 @@ frappe.treeview_settings["Account"] = {
|
||||
args: {
|
||||
company: company,
|
||||
},
|
||||
callback: function (r) {
|
||||
if (r.message) {
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
let root_company = r.message.length ? r.message[0] : "";
|
||||
me.page.fields_dict.root_company.set_value(root_company);
|
||||
|
||||
frappe.db.get_value(
|
||||
"Company",
|
||||
{ name: company },
|
||||
"allow_account_creation_against_child_company",
|
||||
(r) => {
|
||||
frappe.flags.ignore_root_company_validation =
|
||||
r.allow_account_creation_against_child_company;
|
||||
}
|
||||
);
|
||||
frappe.db.get_value("Company", {"name": company}, "allow_account_creation_against_child_company", (r) => {
|
||||
frappe.flags.ignore_root_company_validation = r.allow_account_creation_against_child_company;
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
fieldname: "root_company",
|
||||
fieldtype: "Data",
|
||||
fieldtype:"Data",
|
||||
label: __("Root Company"),
|
||||
hidden: true,
|
||||
disable_onchange: true,
|
||||
},
|
||||
disable_onchange: true
|
||||
}
|
||||
],
|
||||
root_label: "Accounts",
|
||||
get_tree_nodes: "erpnext.accounts.utils.get_children",
|
||||
on_get_node: function (nodes, deep = false) {
|
||||
get_tree_nodes: 'erpnext.accounts.utils.get_children',
|
||||
on_get_node: function(nodes, deep=false) {
|
||||
if (frappe.boot.user.can_read.indexOf("GL Entry") == -1) return;
|
||||
|
||||
let accounts = [];
|
||||
@@ -62,232 +56,147 @@ frappe.treeview_settings["Account"] = {
|
||||
accounts = nodes;
|
||||
}
|
||||
|
||||
frappe.db.get_single_value("Accounts Settings", "show_balance_in_coa").then((value) => {
|
||||
if (value) {
|
||||
const get_balances = frappe.call({
|
||||
method: "erpnext.accounts.utils.get_account_balances",
|
||||
args: {
|
||||
accounts: accounts,
|
||||
company: cur_tree.args.company,
|
||||
},
|
||||
});
|
||||
const get_balances = frappe.call({
|
||||
method: 'erpnext.accounts.utils.get_account_balances',
|
||||
args: {
|
||||
accounts: accounts,
|
||||
company: cur_tree.args.company
|
||||
},
|
||||
});
|
||||
|
||||
get_balances.then((r) => {
|
||||
if (!r.message || r.message.length == 0) return;
|
||||
get_balances.then(r => {
|
||||
if (!r.message || r.message.length == 0) return;
|
||||
|
||||
for (let account of r.message) {
|
||||
const node = cur_tree.nodes && cur_tree.nodes[account.value];
|
||||
if (!node || node.is_root) continue;
|
||||
for (let account of r.message) {
|
||||
|
||||
// show Dr if positive since balance is calculated as debit - credit else show Cr
|
||||
const balance = account.balance_in_account_currency || account.balance;
|
||||
const dr_or_cr = balance > 0 ? "Dr" : "Cr";
|
||||
const format = (value, currency) => format_currency(Math.abs(value), currency);
|
||||
const node = cur_tree.nodes && cur_tree.nodes[account.value];
|
||||
if (!node || node.is_root) continue;
|
||||
|
||||
if (account.balance !== undefined) {
|
||||
node.parent && node.parent.find(".balance-area").remove();
|
||||
$(
|
||||
'<span class="balance-area pull-right">' +
|
||||
(account.balance_in_account_currency
|
||||
? format(
|
||||
account.balance_in_account_currency,
|
||||
account.account_currency
|
||||
) + " / "
|
||||
: "") +
|
||||
format(account.balance, account.company_currency) +
|
||||
" " +
|
||||
dr_or_cr +
|
||||
"</span>"
|
||||
).insertBefore(node.$ul);
|
||||
}
|
||||
}
|
||||
});
|
||||
// show Dr if positive since balance is calculated as debit - credit else show Cr
|
||||
const balance = account.balance_in_account_currency || account.balance;
|
||||
const dr_or_cr = balance > 0 ? "Dr": "Cr";
|
||||
const format = (value, currency) => format_currency(Math.abs(value), currency);
|
||||
|
||||
if (account.balance!==undefined) {
|
||||
node.parent && node.parent.find('.balance-area').remove();
|
||||
$('<span class="balance-area pull-right">'
|
||||
+ (account.balance_in_account_currency ?
|
||||
(format(account.balance_in_account_currency, account.account_currency) + " / ") : "")
|
||||
+ format(account.balance, account.company_currency)
|
||||
+ " " + dr_or_cr
|
||||
+ '</span>').insertBefore(node.$ul);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
add_tree_node: "erpnext.accounts.utils.add_ac",
|
||||
menu_items: [
|
||||
add_tree_node: 'erpnext.accounts.utils.add_ac',
|
||||
menu_items:[
|
||||
{
|
||||
label: __("New Company"),
|
||||
action: function () {
|
||||
frappe.new_doc("Company", true);
|
||||
},
|
||||
condition: 'frappe.boot.user.can_create.indexOf("Company") !== -1',
|
||||
},
|
||||
label: __('New Company'),
|
||||
action: function() { frappe.new_doc("Company", true) },
|
||||
condition: 'frappe.boot.user.can_create.indexOf("Company") !== -1'
|
||||
}
|
||||
],
|
||||
fields: [
|
||||
{
|
||||
fieldtype: "Data",
|
||||
fieldname: "account_name",
|
||||
label: __("New Account Name"),
|
||||
reqd: true,
|
||||
description: __(
|
||||
"Name of new Account. Note: Please don't create accounts for Customers and Suppliers"
|
||||
),
|
||||
},
|
||||
{
|
||||
fieldtype: "Data",
|
||||
fieldname: "account_number",
|
||||
label: __("Account Number"),
|
||||
description: __("Number of new Account, it will be included in the account name as a prefix"),
|
||||
},
|
||||
{
|
||||
fieldtype: "Check",
|
||||
fieldname: "is_group",
|
||||
label: __("Is Group"),
|
||||
description: __(
|
||||
"Further accounts can be made under Groups, but entries can be made against non-Groups"
|
||||
),
|
||||
},
|
||||
{
|
||||
fieldtype: "Select",
|
||||
fieldname: "root_type",
|
||||
label: __("Root Type"),
|
||||
options: ["Asset", "Liability", "Equity", "Income", "Expense"].join("\n"),
|
||||
depends_on: "eval:doc.is_group && !doc.parent_account",
|
||||
},
|
||||
{
|
||||
fieldtype: "Select",
|
||||
fieldname: "account_type",
|
||||
label: __("Account Type"),
|
||||
options: frappe.get_meta("Account").fields.filter((d) => d.fieldname == "account_type")[0]
|
||||
.options,
|
||||
description: __("Optional. This setting will be used to filter in various transactions."),
|
||||
},
|
||||
{
|
||||
fieldtype: "Float",
|
||||
fieldname: "tax_rate",
|
||||
label: __("Tax Rate"),
|
||||
depends_on: 'eval:doc.is_group==0&&doc.account_type=="Tax"',
|
||||
},
|
||||
{
|
||||
fieldtype: "Link",
|
||||
fieldname: "account_currency",
|
||||
label: __("Currency"),
|
||||
options: "Currency",
|
||||
description: __("Optional. Sets company's default currency, if not specified."),
|
||||
{fieldtype:'Data', fieldname:'account_name', label:__('New Account Name'), reqd:true,
|
||||
description: __("Name of new Account. Note: Please don't create accounts for Customers and Suppliers")},
|
||||
{fieldtype:'Data', fieldname:'account_number', label:__('Account Number'),
|
||||
description: __("Number of new Account, it will be included in the account name as a prefix")},
|
||||
{fieldtype:'Check', fieldname:'is_group', label:__('Is Group'),
|
||||
description: __('Further accounts can be made under Groups, but entries can be made against non-Groups')},
|
||||
{fieldtype:'Select', fieldname:'root_type', label:__('Root Type'),
|
||||
options: ['Asset', 'Liability', 'Equity', 'Income', 'Expense'].join('\n'),
|
||||
depends_on: 'eval:doc.is_group && !doc.parent_account'},
|
||||
{fieldtype:'Select', fieldname:'account_type', label:__('Account Type'),
|
||||
options: frappe.get_meta("Account").fields.filter(d => d.fieldname=='account_type')[0].options,
|
||||
description: __("Optional. This setting will be used to filter in various transactions.")
|
||||
},
|
||||
{fieldtype:'Float', fieldname:'tax_rate', label:__('Tax Rate'),
|
||||
depends_on: 'eval:doc.is_group==0&&doc.account_type=="Tax"'},
|
||||
{fieldtype:'Link', fieldname:'account_currency', label:__('Currency'), options:"Currency",
|
||||
description: __("Optional. Sets company's default currency, if not specified.")}
|
||||
],
|
||||
ignore_fields: ["parent_account"],
|
||||
onload: function (treeview) {
|
||||
frappe.treeview_settings["Account"].treeview = {};
|
||||
$.extend(frappe.treeview_settings["Account"].treeview, treeview);
|
||||
ignore_fields:["parent_account"],
|
||||
onload: function(treeview) {
|
||||
frappe.treeview_settings['Account'].treeview = {};
|
||||
$.extend(frappe.treeview_settings['Account'].treeview, treeview);
|
||||
function get_company() {
|
||||
return treeview.page.fields_dict.company.get_value();
|
||||
}
|
||||
|
||||
// tools
|
||||
treeview.page.add_inner_button(
|
||||
__("Chart of Cost Centers"),
|
||||
function () {
|
||||
frappe.set_route("Tree", "Cost Center", { company: get_company() });
|
||||
},
|
||||
__("View")
|
||||
);
|
||||
treeview.page.add_inner_button(__("Chart of Cost Centers"), function() {
|
||||
frappe.set_route('Tree', 'Cost Center', {company: get_company()});
|
||||
}, __('View'));
|
||||
|
||||
treeview.page.add_inner_button(
|
||||
__("Opening Invoice Creation Tool"),
|
||||
function () {
|
||||
frappe.set_route("Form", "Opening Invoice Creation Tool", { company: get_company() });
|
||||
},
|
||||
__("View")
|
||||
);
|
||||
treeview.page.add_inner_button(__("Opening Invoice Creation Tool"), function() {
|
||||
frappe.set_route('Form', 'Opening Invoice Creation Tool', {company: get_company()});
|
||||
}, __('View'));
|
||||
|
||||
treeview.page.add_inner_button(
|
||||
__("Period Closing Voucher"),
|
||||
function () {
|
||||
frappe.set_route("List", "Period Closing Voucher", { company: get_company() });
|
||||
},
|
||||
__("View")
|
||||
);
|
||||
treeview.page.add_inner_button(__("Period Closing Voucher"), function() {
|
||||
frappe.set_route('List', 'Period Closing Voucher', {company: get_company()});
|
||||
}, __('View'));
|
||||
|
||||
treeview.page.add_inner_button(
|
||||
__("Journal Entry"),
|
||||
function () {
|
||||
frappe.new_doc("Journal Entry", { company: get_company() });
|
||||
},
|
||||
__("Create")
|
||||
);
|
||||
treeview.page.add_inner_button(
|
||||
__("Company"),
|
||||
function () {
|
||||
frappe.new_doc("Company");
|
||||
},
|
||||
__("Create")
|
||||
);
|
||||
|
||||
treeview.page.add_inner_button(__("Journal Entry"), function() {
|
||||
frappe.new_doc('Journal Entry', {company: get_company()});
|
||||
}, __('Create'));
|
||||
treeview.page.add_inner_button(__("Company"), function() {
|
||||
frappe.new_doc('Company');
|
||||
}, __('Create'));
|
||||
|
||||
// financial statements
|
||||
for (let report of [
|
||||
"Trial Balance",
|
||||
"General Ledger",
|
||||
"Balance Sheet",
|
||||
"Profit and Loss Statement",
|
||||
"Cash Flow Statement",
|
||||
"Accounts Payable",
|
||||
"Accounts Receivable",
|
||||
]) {
|
||||
treeview.page.add_inner_button(
|
||||
__(report),
|
||||
function () {
|
||||
frappe.set_route("query-report", report, { company: get_company() });
|
||||
},
|
||||
__("Financial Statements")
|
||||
);
|
||||
for (let report of ['Trial Balance', 'General Ledger', 'Balance Sheet',
|
||||
'Profit and Loss Statement', 'Cash Flow Statement', 'Accounts Payable', 'Accounts Receivable']) {
|
||||
treeview.page.add_inner_button(__(report), function() {
|
||||
frappe.set_route('query-report', report, {company: get_company()});
|
||||
}, __('Financial Statements'));
|
||||
}
|
||||
},
|
||||
post_render: function (treeview) {
|
||||
frappe.treeview_settings["Account"].treeview["tree"] = treeview.tree;
|
||||
treeview.page.set_primary_action(
|
||||
__("New"),
|
||||
function () {
|
||||
let root_company = treeview.page.fields_dict.root_company.get_value();
|
||||
|
||||
if (root_company) {
|
||||
frappe.throw(__("Please add the account to root level Company - {0}"), [root_company]);
|
||||
} else {
|
||||
treeview.new_node();
|
||||
}
|
||||
},
|
||||
"add"
|
||||
);
|
||||
},
|
||||
post_render: function(treeview) {
|
||||
frappe.treeview_settings['Account'].treeview["tree"] = treeview.tree;
|
||||
treeview.page.set_primary_action(__("New"), function() {
|
||||
let root_company = treeview.page.fields_dict.root_company.get_value();
|
||||
|
||||
if(root_company) {
|
||||
frappe.throw(__("Please add the account to root level Company - {0}"), [root_company]);
|
||||
} else {
|
||||
treeview.new_node();
|
||||
}
|
||||
}, "add");
|
||||
},
|
||||
toolbar: [
|
||||
{
|
||||
label: __("Add Child"),
|
||||
condition: function (node) {
|
||||
return (
|
||||
frappe.boot.user.can_create.indexOf("Account") !== -1 &&
|
||||
(!frappe.treeview_settings[
|
||||
"Account"
|
||||
].treeview.page.fields_dict.root_company.get_value() ||
|
||||
frappe.flags.ignore_root_company_validation) &&
|
||||
node.expandable &&
|
||||
!node.hide_add
|
||||
);
|
||||
label:__("Add Child"),
|
||||
condition: function(node) {
|
||||
return frappe.boot.user.can_create.indexOf("Account") !== -1
|
||||
&& (!frappe.treeview_settings['Account'].treeview.page.fields_dict.root_company.get_value()
|
||||
|| frappe.flags.ignore_root_company_validation)
|
||||
&& node.expandable && !node.hide_add;
|
||||
},
|
||||
click: function () {
|
||||
var me = frappe.views.trees["Account"];
|
||||
click: function() {
|
||||
var me = frappe.views.trees['Account'];
|
||||
me.new_node();
|
||||
},
|
||||
btnClass: "hidden-xs",
|
||||
btnClass: "hidden-xs"
|
||||
},
|
||||
{
|
||||
condition: function (node) {
|
||||
return !node.root && frappe.boot.user.can_read.indexOf("GL Entry") !== -1;
|
||||
condition: function(node) {
|
||||
return !node.root && frappe.boot.user.can_read.indexOf("GL Entry") !== -1
|
||||
},
|
||||
label: __("View Ledger"),
|
||||
click: function (node, btn) {
|
||||
click: function(node, btn) {
|
||||
frappe.route_options = {
|
||||
account: node.label,
|
||||
from_date: erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[1],
|
||||
to_date: erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[2],
|
||||
company:
|
||||
frappe.treeview_settings["Account"].treeview.page.fields_dict.company.get_value(),
|
||||
"account": node.label,
|
||||
"from_date": frappe.sys_defaults.year_start_date,
|
||||
"to_date": frappe.sys_defaults.year_end_date,
|
||||
"company": frappe.treeview_settings['Account'].treeview.page.fields_dict.company.get_value()
|
||||
};
|
||||
frappe.set_route("query-report", "General Ledger");
|
||||
},
|
||||
btnClass: "hidden-xs",
|
||||
},
|
||||
btnClass: "hidden-xs"
|
||||
}
|
||||
],
|
||||
extend_toolbar: true,
|
||||
};
|
||||
extend_toolbar: true
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ def create_charts(
|
||||
"root_type",
|
||||
"is_group",
|
||||
"tax_rate",
|
||||
"account_currency",
|
||||
]:
|
||||
|
||||
account_number = cstr(child.get("account_number")).strip()
|
||||
@@ -54,7 +53,7 @@ def create_charts(
|
||||
"account_number": account_number,
|
||||
"account_type": child.get("account_type"),
|
||||
"account_currency": child.get("account_currency")
|
||||
or frappe.get_cached_value("Company", company, "default_currency"),
|
||||
or frappe.db.get_value("Company", company, "default_currency"),
|
||||
"tax_rate": child.get("tax_rate"),
|
||||
}
|
||||
)
|
||||
@@ -96,17 +95,7 @@ def identify_is_group(child):
|
||||
is_group = child.get("is_group")
|
||||
elif len(
|
||||
set(child.keys())
|
||||
- set(
|
||||
[
|
||||
"account_name",
|
||||
"account_type",
|
||||
"root_type",
|
||||
"is_group",
|
||||
"tax_rate",
|
||||
"account_number",
|
||||
"account_currency",
|
||||
]
|
||||
)
|
||||
- set(["account_name", "account_type", "root_type", "is_group", "tax_rate", "account_number"])
|
||||
):
|
||||
is_group = 1
|
||||
else:
|
||||
@@ -159,7 +148,7 @@ def get_charts_for_country(country, with_standard=False):
|
||||
) or frappe.local.flags.allow_unverified_charts:
|
||||
charts.append(content["name"])
|
||||
|
||||
country_code = frappe.get_cached_value("Country", country, "code")
|
||||
country_code = frappe.db.get_value("Country", country, "code")
|
||||
if country_code:
|
||||
folders = ("verified",)
|
||||
if frappe.local.flags.allow_unverified_charts:
|
||||
@@ -196,7 +185,6 @@ def get_account_tree_from_existing_company(existing_company):
|
||||
"root_type",
|
||||
"tax_rate",
|
||||
"account_number",
|
||||
"account_currency",
|
||||
],
|
||||
order_by="lft, rgt",
|
||||
)
|
||||
@@ -279,7 +267,6 @@ def build_tree_from_json(chart_template, chart_data=None, from_coa_importer=Fals
|
||||
"root_type",
|
||||
"is_group",
|
||||
"tax_rate",
|
||||
"account_currency",
|
||||
]:
|
||||
continue
|
||||
|
||||
|
||||
@@ -0,0 +1,289 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
"""
|
||||
Import chart of accounts from OpenERP sources
|
||||
"""
|
||||
|
||||
import ast
|
||||
import json
|
||||
import os
|
||||
from xml.etree import ElementTree as ET
|
||||
|
||||
import frappe
|
||||
from frappe.utils.csvutils import read_csv_content
|
||||
|
||||
path = "/Users/nabinhait/projects/odoo/addons"
|
||||
|
||||
accounts = {}
|
||||
charts = {}
|
||||
all_account_types = []
|
||||
all_roots = {}
|
||||
|
||||
|
||||
def go():
|
||||
global accounts, charts
|
||||
default_account_types = get_default_account_types()
|
||||
|
||||
country_dirs = []
|
||||
for basepath, folders, files in os.walk(path):
|
||||
basename = os.path.basename(basepath)
|
||||
if basename.startswith("l10n_"):
|
||||
country_dirs.append(basename)
|
||||
|
||||
for country_dir in country_dirs:
|
||||
accounts, charts = {}, {}
|
||||
country_path = os.path.join(path, country_dir)
|
||||
manifest = ast.literal_eval(open(os.path.join(country_path, "__openerp__.py")).read())
|
||||
data_files = (
|
||||
manifest.get("data", []) + manifest.get("init_xml", []) + manifest.get("update_xml", [])
|
||||
)
|
||||
files_path = [os.path.join(country_path, d) for d in data_files]
|
||||
xml_roots = get_xml_roots(files_path)
|
||||
csv_content = get_csv_contents(files_path)
|
||||
prefix = country_dir if csv_content else None
|
||||
account_types = get_account_types(
|
||||
xml_roots.get("account.account.type", []), csv_content.get("account.account.type", []), prefix
|
||||
)
|
||||
account_types.update(default_account_types)
|
||||
|
||||
if xml_roots:
|
||||
make_maps_for_xml(xml_roots, account_types, country_dir)
|
||||
|
||||
if csv_content:
|
||||
make_maps_for_csv(csv_content, account_types, country_dir)
|
||||
make_account_trees()
|
||||
make_charts()
|
||||
|
||||
create_all_roots_file()
|
||||
|
||||
|
||||
def get_default_account_types():
|
||||
default_types_root = []
|
||||
default_types_root.append(
|
||||
ET.parse(os.path.join(path, "account", "data", "data_account_type.xml")).getroot()
|
||||
)
|
||||
return get_account_types(default_types_root, None, prefix="account")
|
||||
|
||||
|
||||
def get_xml_roots(files_path):
|
||||
xml_roots = frappe._dict()
|
||||
for filepath in files_path:
|
||||
fname = os.path.basename(filepath)
|
||||
if fname.endswith(".xml"):
|
||||
tree = ET.parse(filepath)
|
||||
root = tree.getroot()
|
||||
for node in root[0].findall("record"):
|
||||
if node.get("model") in [
|
||||
"account.account.template",
|
||||
"account.chart.template",
|
||||
"account.account.type",
|
||||
]:
|
||||
xml_roots.setdefault(node.get("model"), []).append(root)
|
||||
break
|
||||
return xml_roots
|
||||
|
||||
|
||||
def get_csv_contents(files_path):
|
||||
csv_content = {}
|
||||
for filepath in files_path:
|
||||
fname = os.path.basename(filepath)
|
||||
for file_type in ["account.account.template", "account.account.type", "account.chart.template"]:
|
||||
if fname.startswith(file_type) and fname.endswith(".csv"):
|
||||
with open(filepath, "r") as csvfile:
|
||||
try:
|
||||
csv_content.setdefault(file_type, []).append(read_csv_content(csvfile.read()))
|
||||
except Exception as e:
|
||||
continue
|
||||
return csv_content
|
||||
|
||||
|
||||
def get_account_types(root_list, csv_content, prefix=None):
|
||||
types = {}
|
||||
account_type_map = {
|
||||
"cash": "Cash",
|
||||
"bank": "Bank",
|
||||
"tr_cash": "Cash",
|
||||
"tr_bank": "Bank",
|
||||
"receivable": "Receivable",
|
||||
"tr_receivable": "Receivable",
|
||||
"account rec": "Receivable",
|
||||
"payable": "Payable",
|
||||
"tr_payable": "Payable",
|
||||
"equity": "Equity",
|
||||
"stocks": "Stock",
|
||||
"stock": "Stock",
|
||||
"tax": "Tax",
|
||||
"tr_tax": "Tax",
|
||||
"tax-out": "Tax",
|
||||
"tax-in": "Tax",
|
||||
"charges_personnel": "Chargeable",
|
||||
"fixed asset": "Fixed Asset",
|
||||
"cogs": "Cost of Goods Sold",
|
||||
}
|
||||
for root in root_list:
|
||||
for node in root[0].findall("record"):
|
||||
if node.get("model") == "account.account.type":
|
||||
data = {}
|
||||
for field in node.findall("field"):
|
||||
if (
|
||||
field.get("name") == "code"
|
||||
and field.text.lower() != "none"
|
||||
and account_type_map.get(field.text)
|
||||
):
|
||||
data["account_type"] = account_type_map[field.text]
|
||||
|
||||
node_id = prefix + "." + node.get("id") if prefix else node.get("id")
|
||||
types[node_id] = data
|
||||
|
||||
if csv_content and csv_content[0][0] == "id":
|
||||
for row in csv_content[1:]:
|
||||
row_dict = dict(zip(csv_content[0], row))
|
||||
data = {}
|
||||
if row_dict.get("code") and account_type_map.get(row_dict["code"]):
|
||||
data["account_type"] = account_type_map[row_dict["code"]]
|
||||
if data and data.get("id"):
|
||||
node_id = prefix + "." + data.get("id") if prefix else data.get("id")
|
||||
types[node_id] = data
|
||||
return types
|
||||
|
||||
|
||||
def make_maps_for_xml(xml_roots, account_types, country_dir):
|
||||
"""make maps for `charts` and `accounts`"""
|
||||
for model, root_list in xml_roots.items():
|
||||
for root in root_list:
|
||||
for node in root[0].findall("record"):
|
||||
if node.get("model") == "account.account.template":
|
||||
data = {}
|
||||
for field in node.findall("field"):
|
||||
if field.get("name") == "name":
|
||||
data["name"] = field.text
|
||||
if field.get("name") == "parent_id":
|
||||
parent_id = field.get("ref") or field.get("eval")
|
||||
data["parent_id"] = parent_id
|
||||
|
||||
if field.get("name") == "user_type":
|
||||
value = field.get("ref")
|
||||
if account_types.get(value, {}).get("account_type"):
|
||||
data["account_type"] = account_types[value]["account_type"]
|
||||
if data["account_type"] not in all_account_types:
|
||||
all_account_types.append(data["account_type"])
|
||||
|
||||
data["children"] = []
|
||||
accounts[node.get("id")] = data
|
||||
|
||||
if node.get("model") == "account.chart.template":
|
||||
data = {}
|
||||
for field in node.findall("field"):
|
||||
if field.get("name") == "name":
|
||||
data["name"] = field.text
|
||||
if field.get("name") == "account_root_id":
|
||||
data["account_root_id"] = field.get("ref")
|
||||
data["id"] = country_dir
|
||||
charts.setdefault(node.get("id"), {}).update(data)
|
||||
|
||||
|
||||
def make_maps_for_csv(csv_content, account_types, country_dir):
|
||||
for content in csv_content.get("account.account.template", []):
|
||||
for row in content[1:]:
|
||||
data = dict(zip(content[0], row))
|
||||
account = {
|
||||
"name": data.get("name"),
|
||||
"parent_id": data.get("parent_id:id") or data.get("parent_id/id"),
|
||||
"children": [],
|
||||
}
|
||||
user_type = data.get("user_type/id") or data.get("user_type:id")
|
||||
if account_types.get(user_type, {}).get("account_type"):
|
||||
account["account_type"] = account_types[user_type]["account_type"]
|
||||
if account["account_type"] not in all_account_types:
|
||||
all_account_types.append(account["account_type"])
|
||||
|
||||
accounts[data.get("id")] = account
|
||||
if not account.get("parent_id") and data.get("chart_template_id:id"):
|
||||
chart_id = data.get("chart_template_id:id")
|
||||
charts.setdefault(chart_id, {}).update({"account_root_id": data.get("id")})
|
||||
|
||||
for content in csv_content.get("account.chart.template", []):
|
||||
for row in content[1:]:
|
||||
if row:
|
||||
data = dict(zip(content[0], row))
|
||||
charts.setdefault(data.get("id"), {}).update(
|
||||
{
|
||||
"account_root_id": data.get("account_root_id:id") or data.get("account_root_id/id"),
|
||||
"name": data.get("name"),
|
||||
"id": country_dir,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def make_account_trees():
|
||||
"""build tree hierarchy"""
|
||||
for id in accounts.keys():
|
||||
account = accounts[id]
|
||||
|
||||
if account.get("parent_id"):
|
||||
if accounts.get(account["parent_id"]):
|
||||
# accounts[account["parent_id"]]["children"].append(account)
|
||||
accounts[account["parent_id"]][account["name"]] = account
|
||||
del account["parent_id"]
|
||||
del account["name"]
|
||||
|
||||
# remove empty children
|
||||
for id in accounts.keys():
|
||||
if "children" in accounts[id] and not accounts[id].get("children"):
|
||||
del accounts[id]["children"]
|
||||
|
||||
|
||||
def make_charts():
|
||||
"""write chart files in app/setup/doctype/company/charts"""
|
||||
for chart_id in charts:
|
||||
src = charts[chart_id]
|
||||
if not src.get("name") or not src.get("account_root_id"):
|
||||
continue
|
||||
|
||||
if not src["account_root_id"] in accounts:
|
||||
continue
|
||||
|
||||
filename = src["id"][5:] + "_" + chart_id
|
||||
|
||||
print("building " + filename)
|
||||
chart = {}
|
||||
chart["name"] = src["name"]
|
||||
chart["country_code"] = src["id"][5:]
|
||||
chart["tree"] = accounts[src["account_root_id"]]
|
||||
|
||||
for key, val in chart["tree"].items():
|
||||
if key in ["name", "parent_id"]:
|
||||
chart["tree"].pop(key)
|
||||
if type(val) == dict:
|
||||
val["root_type"] = ""
|
||||
if chart:
|
||||
fpath = os.path.join(
|
||||
"erpnext", "erpnext", "accounts", "doctype", "account", "chart_of_accounts", filename + ".json"
|
||||
)
|
||||
|
||||
with open(fpath, "r") as chartfile:
|
||||
old_content = chartfile.read()
|
||||
if not old_content or (
|
||||
json.loads(old_content).get("is_active", "No") == "No"
|
||||
and json.loads(old_content).get("disabled", "No") == "No"
|
||||
):
|
||||
with open(fpath, "w") as chartfile:
|
||||
chartfile.write(json.dumps(chart, indent=4, sort_keys=True))
|
||||
|
||||
all_roots.setdefault(filename, chart["tree"].keys())
|
||||
|
||||
|
||||
def create_all_roots_file():
|
||||
with open("all_roots.txt", "w") as f:
|
||||
for filename, roots in sorted(all_roots.items()):
|
||||
f.write(filename)
|
||||
f.write("\n----------------------\n")
|
||||
for r in sorted(roots):
|
||||
f.write(r.encode("utf-8"))
|
||||
f.write("\n")
|
||||
f.write("\n\n\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
go()
|
||||
@@ -2,437 +2,397 @@
|
||||
"country_code": "at",
|
||||
"name": "Austria - Chart of Accounts",
|
||||
"tree": {
|
||||
"Klasse 0 Aktiva: Anlageverm\u00f6gen": {
|
||||
"0100 Konzessionen ": {"account_type": "Fixed Asset"},
|
||||
"0110 Patentrechte und Lizenzen ": {"account_type": "Fixed Asset"},
|
||||
"0120 Datenverarbeitungsprogramme ": {"account_type": "Fixed Asset"},
|
||||
"0130 Marken, Warenzeichen und Musterschutzrechte, sonstige Urheberrechte ": {"account_type": "Fixed Asset"},
|
||||
"0140 Pacht- und Mietrechte ": {"account_type": "Fixed Asset"},
|
||||
"0150 Bezugs- und ähnliche Rechte ": {"account_type": "Fixed Asset"},
|
||||
"0160 Geschäfts-/Firmenwert ": {"account_type": "Fixed Asset"},
|
||||
"0170 Umgründungsmehrwert ": {"account_type": "Fixed Asset"},
|
||||
"0180 Geleistete Anzahlungen auf immaterielle Vermögensgegenstände": {"account_type": "Fixed Asset"},
|
||||
"0190 Kumulierte Abschreibungen zu immateriellen Vermögensgegenständen ": {"account_type": "Fixed Asset"},
|
||||
"0200 Unbebaute Grundstücke, soweit nicht landwirtschaftlich genutzt ": {"account_type": "Fixed Asset"},
|
||||
"0210 Bebaute Grundstücke (Grundwert) ": {"account_type": "Fixed Asset"},
|
||||
"0220 Landwirtschaftlich genutzte Grundstücke ": {"account_type": "Fixed Asset"},
|
||||
"0230 Grundstücksgleiche Rechte ": {"account_type": "Fixed Asset"},
|
||||
"0300 Betriebs- und Geschäftsgebäude auf eigenem Grund ": {"account_type": "Fixed Asset"},
|
||||
"0310 Wohn- und Sozialgebäude auf eigenem Grund ": {"account_type": "Fixed Asset"},
|
||||
"0320 Betriebs- und Geschäftsgebäude auf fremdem Grund ": {"account_type": "Fixed Asset"},
|
||||
"0330 Wohn- und Sozialgebäude auf fremdem Grund ": {"account_type": "Fixed Asset"},
|
||||
"0340 Grundstückseinrichtungen auf eigenem Grund ": {"account_type": "Fixed Asset"},
|
||||
"0350 Grundstückseinrichtungen auf fremdem Grund ": {"account_type": "Fixed Asset"},
|
||||
"0360 Bauliche Investitionen in fremden (gepachteten) Betriebs- und Geschäftsgebäuden": {"account_type": "Fixed Asset"},
|
||||
"0370 Bauliche Investitionen in fremden (gepachteten) Wohn- und Sozialgebäuden": {"account_type": "Fixed Asset"},
|
||||
"0390 Kumulierte Abschreibungen zu Grundstücken ": {"account_type": "Fixed Asset"},
|
||||
"0400 Maschinen und Geräte ": {"account_type": "Fixed Asset"},
|
||||
"0500 Maschinenwerkzeuge ": {"account_type": "Fixed Asset"},
|
||||
"0510 Allgemeine Werkzeuge und Handwerkzeuge ": {"account_type": "Fixed Asset"},
|
||||
"0520 Prototypen, Formen, Modelle ": {"account_type": "Fixed Asset"},
|
||||
"0530 Andere Erzeugungshilfsmittel (auch Softwarewerkzeuge)": {"account_type": "Fixed Asset"},
|
||||
"0540 Hebezeuge und Montageanlagen ": {"account_type": "Fixed Asset"},
|
||||
"0550 Geringwertige Vermögensgegenstände, soweit im Erzeugungsprozess ": {"account_type": "Fixed Asset"},
|
||||
"0560 Festwerte technische Anlagen und Maschinen ": {"account_type": "Fixed Asset"},
|
||||
"0590 Kumulierte Abschreibungen zu technischen Anlagen und Maschinen ": {"account_type": "Fixed Asset"},
|
||||
"0600 Betriebs- und Geschäftsausstattung, soweit nicht gesondert angeführt ": {"account_type": "Fixed Asset"},
|
||||
"0610 Andere Anlagen, soweit nicht gesondert angeführt ": {"account_type": "Fixed Asset"},
|
||||
"0620 Büromaschinen, EDV-Anlagen ": {"account_type": "Fixed Asset"},
|
||||
"0630 PKW und Kombis ": {"account_type": "Fixed Asset"},
|
||||
"0640 LKW ": {"account_type": "Fixed Asset"},
|
||||
"0650 Andere Beförderungsmittel ": {"account_type": "Fixed Asset"},
|
||||
"0660 Gebinde ": {"account_type": "Fixed Asset"},
|
||||
"0670 Geringwertige Vermögensgegenstände, soweit nicht im Erzeugungssprozess verwendet": {"account_type": "Fixed Asset"},
|
||||
"0680 Festwerte außer technische Anlagen und Maschinen ": {"account_type": "Fixed Asset"},
|
||||
"0690 Kumulierte Abschreibungen zu anderen Anlagen, Betriebs- und Geschäftsausstattung": {"account_type": "Fixed Asset"},
|
||||
"0700 Geleistete Anzahlungen auf Sachanlagen ": {"account_type": "Fixed Asset"},
|
||||
"0710 Anlagen in Bau ": {"account_type": "Fixed Asset"},
|
||||
"0790 Kumulierte Abschreibungen zu geleisteten Anzahlungen auf Sachanlagen ": {"account_type": "Fixed Asset"},
|
||||
"0800 Anteile an verbundenen Unternehmen ": {"account_type": "Fixed Asset"},
|
||||
"0810 Beteiligungen an Gemeinschaftsunternehmen ": {"account_type": "Fixed Asset"},
|
||||
"0820 Beteiligungen an angeschlossenen (assoziierten) Unternehmen ": {"account_type": "Fixed Asset"},
|
||||
"0830 Eigene Anteile, Anteile an herrschenden oder mit Mehrheit beteiligten ": {"account_type": "Fixed Asset"},
|
||||
"0840 Sonstige Beteiligungen ": {"account_type": "Fixed Asset"},
|
||||
"0850 Ausleihungen an verbundene Unternehmen ": {"account_type": "Fixed Asset"},
|
||||
"0860 Ausleihungen an Unternehmen mit Beteiligungsverhältnis": {"account_type": "Fixed Asset"},
|
||||
"0870 Ausleihungen an Gesellschafter ": {"account_type": "Fixed Asset"},
|
||||
"0880 Sonstige Ausleihungen ": {"account_type": "Fixed Asset"},
|
||||
"0890 Anteile an Kapitalgesellschaften ohne Beteiligungscharakter ": {"account_type": "Fixed Asset"},
|
||||
"0900 Anteile an Personengesellschaften ohne Beteiligungscharakter ": {"account_type": "Fixed Asset"},
|
||||
"0910 Genossenschaftsanteile ohne Beteiligungscharakter ": {"account_type": "Fixed Asset"},
|
||||
"0920 Anteile an Investmentfonds ": {"account_type": "Fixed Asset"},
|
||||
"0930 Festverzinsliche Wertpapiere des Anlagevermögens ": {"account_type": "Fixed Asset"},
|
||||
"0980 Geleistete Anzahlungen auf Finanzanlagen ": {"account_type": "Fixed Asset"},
|
||||
"0990 Kumulierte Abschreibungen zu Finanzanlagen ": {"account_type": "Fixed Asset"},
|
||||
"root_type": "Asset"
|
||||
"Summe Abschreibungen und Aufwendungen": {
|
||||
"7010 bis 7080 Abschreibungen auf das Anlageverm\u00f6gen (ausgenommen Finanzanlagen)": {},
|
||||
"7100 bis 7190 Sonstige Steuern": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"7200 bis 7290 Instandhaltung u. Reinigung durh Dritte, Entsorgung, Beleuchtung": {},
|
||||
"7300 bis 7310 Transporte durch Dritte": {},
|
||||
"7320 bis 7330 Kfz - Aufwand": {},
|
||||
"7340 bis 7350 Reise- und Fahraufwand": {},
|
||||
"7360 bis 7370 Tag- und N\u00e4chtigungsgelder": {},
|
||||
"7380 bis 7390 Nachrichtenaufwand": {},
|
||||
"7400 bis 7430 Miet- und Pachtaufwand": {},
|
||||
"7440 bis 7470 Leasingaufwand": {},
|
||||
"7480 bis 7490 Lizenzaufwand": {},
|
||||
"7500 bis 7530 Aufwand f\u00fcr beigestelltes Personal": {},
|
||||
"7540 bis 7570 Provisionen an Dritte": {},
|
||||
"7580 bis 7590 Aufsichtsratsverg\u00fctungen": {},
|
||||
"7610 bis 7620 Druckerzeugnisse und Vervielf\u00e4ltigungen": {},
|
||||
"7650 bis 7680 Werbung und Repr\u00e4sentationen": {},
|
||||
"7700 bis 7740 Versicherungen": {},
|
||||
"7750 bis 7760 Beratungs- und Pr\u00fcfungsaufwand": {},
|
||||
"7800 bis 7810 Schadensf\u00e4lle": {},
|
||||
"7840 bis 7880 Verschiedene betriebliche Aufwendungen": {},
|
||||
"7910 bis 7950 Aufwandsstellenrechung der Hersteller": {},
|
||||
"Abschreibungen auf aktivierte Aufwendungen f\u00fcr das Ingangs. u. Erweitern des Betriebes": {},
|
||||
"Abschreibungen vom Umlaufverm\u00f6gen, soweit diese die im Unternehmen \u00fcblichen Abschreibungen \u00fcbersteigen": {},
|
||||
"Aufwandsstellenrechnung": {},
|
||||
"Aus- und Fortbildung": {},
|
||||
"Buchwert abgegangener Anlagen, ausgenommen Finanzanlagen": {},
|
||||
"B\u00fcromaterial und Drucksorten": {},
|
||||
"Fachliteratur und Zeitungen ": {},
|
||||
"Herstellungskosten der zur Erzielung der Umsatzerl\u00f6se erbrachten Leistungen": {},
|
||||
"Mitgliedsbeitr\u00e4ge": {},
|
||||
"Skontoertr\u00e4ge auf sonstige betriebliche Aufwendungen": {},
|
||||
"Sonstige betrieblichen Aufwendungen": {},
|
||||
"Spenden und Trinkgelder": {},
|
||||
"Spesen des Geldverkehrs": {},
|
||||
"Verluste aus dem Abgang vom Anlageverm\u00f6gen, ausgenommen Finanzanlagen": {},
|
||||
"Vertriebskosten": {},
|
||||
"Verwaltungskosten": {},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"Klasse 1 Aktiva: Vorr\u00e4te": {
|
||||
"1000 Bezugsverrechnung": {"account_type": "Stock"},
|
||||
"1100 Rohstoffe": {"account_type": "Stock"},
|
||||
"1200 Bezogene Teile": {"account_type": "Stock"},
|
||||
"1300 Hilfsstoffe": {"account_type": "Stock"},
|
||||
"1350 Betriebsstoffe": {"account_type": "Stock"},
|
||||
"1360 Vorrat Energietraeger": {"account_type": "Stock"},
|
||||
"1400 Unfertige Erzeugnisse": {"account_type": "Stock"},
|
||||
"1500 Fertige Erzeugnisse": {"account_type": "Stock"},
|
||||
"1600 Handelswarenvorrat": {"account_type": "Stock Received But Not Billed"},
|
||||
"1700 Noch nicht abrechenbare Leistungen": {"account_type": "Stock"},
|
||||
"1800 Geleistete Anzahlungen": {"account_type": "Stock"},
|
||||
"1900 Wertberichtigungen": {"account_type": "Stock"},
|
||||
"root_type": "Asset"
|
||||
"Summe Betriebliche Ertr\u00e4ge": {
|
||||
"4400 bis 4490 Erl\u00f6sschm\u00e4lerungen": {},
|
||||
"4500 bis 4570 Ver\u00e4nderungen des Bestandes an fertigen und unfertigen Erzeugn. sowie an noch nicht abrechenbaren Leistungen": {},
|
||||
"4580 bis 4590 andere aktivierte Eigenleistungen": {},
|
||||
"4600 bis 4620 Erl\u00f6se aus dem Abgang vom Anlageverm\u00f6gen, ausgen. Finanzanlagen": {},
|
||||
"4630 bis 4650 Ertr\u00e4ge aus dem Abgang vom Anlageverm\u00f6gen, ausgen. Finanzanlagen": {},
|
||||
"4660 bis 4670 Ertr\u00e4ge aus der Zuschreibung zum Anlageverm\u00f6gen, ausgen. Finanzanlagen": {},
|
||||
"4700 bis 4790 Ertr\u00e4ge aus der Aufl\u00f6sung von R\u00fcckstellungen": {},
|
||||
"4800 bis 4990 \u00dcbrige betriebliche Ertr\u00e4ge": {},
|
||||
"Erl\u00f6se 0 % Ausfuhrlieferungen/Drittl\u00e4nder": {},
|
||||
"Erl\u00f6se 10 %": {},
|
||||
"Erl\u00f6se 20 %": {},
|
||||
"Erl\u00f6se aus im Inland stpfl. EG Lieferungen 10 % USt": {},
|
||||
"Erl\u00f6se aus im Inland stpfl. EG Lieferungen 20 % USt": {},
|
||||
"Erl\u00f6se i.g. Lieferungen (stfr)": {},
|
||||
"root_type": "Income"
|
||||
},
|
||||
"Klasse 3 Passiva: Verbindlichkeiten": {
|
||||
"3000 Allgemeine Verbindlichkeiten (Schuld)": {"account_type": "Payable"},
|
||||
"3010 R\u00fcckstellungen f\u00fcr Pensionen": {"account_type": "Payable"},
|
||||
"3020 Steuerr\u00fcckstellungen": {"account_type": "Tax"},
|
||||
"3041 Sonstige R\u00fcckstellungen": {"account_type": "Payable"},
|
||||
"3110 Verbindlichkeiten gegen\u00fcber Bank": {"account_type": "Payable"},
|
||||
"3150 Verbindlichkeiten Darlehen": {"account_type": "Payable"},
|
||||
"3185 Verbindlichkeiten Kreditkarte": {"account_type": "Payable"},
|
||||
"3380 Verbindlichkeiten aus der Annahme gezogener Wechsel u. d. Ausstellungen eigener Wechsel": {
|
||||
"Summe Eigenkapital R\u00fccklagen Abschlusskonten": {
|
||||
"9000 bis 9180 Gezeichnetes bzw. gewidmetes Kapital": {
|
||||
"account_type": "Equity"
|
||||
},
|
||||
"9200 bis 9290 Kapitalr\u00fccklagen": {
|
||||
"account_type": "Equity"
|
||||
},
|
||||
"9300 bis 9380 Gewinnr\u00fccklagen": {
|
||||
"account_type": "Equity"
|
||||
},
|
||||
"9400 bis 9590 Bewertungsreserven uns sonst. unversteuerte R\u00fccklagen": {
|
||||
"account_type": "Equity"
|
||||
},
|
||||
"9600 bis 9690 Privat und Verrechnungskonten bei Einzelunternehmen und Personengesellschaften": {},
|
||||
"9700 bis 9790 Einlagen stiller Gesellschafter ": {},
|
||||
"9900 bis 9999 Evidenzkonten": {},
|
||||
"Bilanzgewinn (-verlust )": {
|
||||
"account_type": "Equity"
|
||||
},
|
||||
"Er\u00f6ffnungsbilanz": {},
|
||||
"Gewinn- und Verlustrechnung": {},
|
||||
"Schlussbilanz": {},
|
||||
"nicht eingeforderte ausstehende Einlagen": {
|
||||
"account_type": "Equity"
|
||||
},
|
||||
"root_type": "Equity"
|
||||
},
|
||||
"Summe Finanzertr\u00e4ge und Aufwendungen": {
|
||||
"8000 bis 8040 Ertr\u00e4ge aus Beteiligungen": {},
|
||||
"8050 bis 8090 Ertr\u00e4ge aus anderen Wertpapieren und Ausleihungen des Finanzanlageverm\u00f6gens": {},
|
||||
"8100 bis 8130 Sonstige Zinsen und \u00e4hnliche Ertr\u00e4ge": {},
|
||||
"8220 bis 8250 Aufwendungen aus Beteiligungen": {},
|
||||
"8260 bis 8270 Aufwendungen aus sonst. Fiananzanlagen und aus Wertpapieren des Umlaufverm\u00f6gens": {},
|
||||
"8280 bis 8340 Zinsen und \u00e4hnliche Aufwendungem": {},
|
||||
"8400 bis 8440 Au\u00dferordentliche Ertr\u00e4ge": {},
|
||||
"8450 bis 8490 Au\u00dferordentliche Aufwendungen": {},
|
||||
"8500 bis 8590 Steuern vom Einkommen und vom Ertrag": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"8600 bis 8690 Aufl\u00f6sung unversteuerten R\u00fccklagen": {},
|
||||
"8700 bis 8740 Aufl\u00f6sung von Kapitalr\u00fccklagen": {},
|
||||
"8750 bis 8790 Aufl\u00f6sung von Gewinnr\u00fccklagen": {},
|
||||
"8800 bis 8890 Zuweisung von unversteuerten R\u00fccklagen": {},
|
||||
"Buchwert abgegangener Beteiligungen": {},
|
||||
"Buchwert abgegangener Wertpapiere des Umlaufverm\u00f6gens": {},
|
||||
"Buchwert abgegangener sonstiger Finanzanlagen": {},
|
||||
"Erl\u00f6se aus dem Abgang von Beteiligungen": {},
|
||||
"Erl\u00f6se aus dem Abgang von Wertpapieren des Umlaufverm\u00f6gens": {},
|
||||
"Erl\u00f6se aus dem Abgang von sonstigen Finanzanlagen": {},
|
||||
"Ertr\u00e4ge aus dem Abgang von und der Zuschreibung zu Finanzanlagen": {},
|
||||
"Ertr\u00e4ge aus dem Abgang von und der Zuschreibung zu Wertpapieren des Umlaufverm\u00f6gens": {},
|
||||
"Gewinabfuhr bzw. Verlust\u00fcberrechnung aus Ergebnisabf\u00fchrungsvertr\u00e4gen": {},
|
||||
"nicht ausgenutzte Lieferantenskonti": {},
|
||||
"root_type": "Income"
|
||||
},
|
||||
"Summe Fremdkapital": {
|
||||
"3020 bis 3030 Steuerr\u00fcckstellungen": {},
|
||||
"3040 bis 3090 Sonstige R\u00fcckstellungen": {},
|
||||
"3110 bis 3170 Verbindlichkeiten gegen\u00fcber Kredidinstituten": {},
|
||||
"3180 bis 3190 Verbindlichkeiten gegen\u00fcber Finanzinstituten": {},
|
||||
"3380 bis 3390 Verbindlichkeiten aus der Annahme gezogener Wechsel u. d. Ausstellungen eigener Wechsel": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"3400 Verbindlichkeiten gegen\u00fc. verb. Untern., Verbindl. gegen\u00fc. Untern., mit denen eine Beteiligungsverh\u00e4lnis besteht": {},
|
||||
"3460 Verbindlichkeiten gegenueber Gesellschaftern": {"account_type": "Payable"},
|
||||
"3470 Einlagen stiller Gesellschafter": {"account_type": "Payable"},
|
||||
"3585 Verbindlichkeiten Lohnsteuer": {"account_type": "Tax"},
|
||||
"3590 Verbindlichkeiten Kommunalabgaben": {"account_type": "Tax"},
|
||||
"3595 Verbindlichkeiten Dienstgeberbeitrag": {"account_type": "Tax"},
|
||||
"3600 Verbindlichkeiten Sozialversicherung": {"account_type": "Payable"},
|
||||
"3640 Verbindlichkeiten Loehne und Gehaelter": {"account_type": "Payable"},
|
||||
"3700 Sonstige Verbindlichkeiten": {"account_type": "Payable"},
|
||||
"3900 Passive Rechnungsabgrenzungsposten": {"account_type": "Payable"},
|
||||
"3100 Anleihen (einschlie\u00dflich konvertibler)": {"account_type": "Payable"},
|
||||
"3200 Erhaltene Anzahlungen auf Bestellungen": {"account_type": "Payable"},
|
||||
"3040 R\u00fcckstellungen f\u00fcr Abfertigung": {"account_type": "Payable"},
|
||||
|
||||
"3530 USt. \u00a719 (reverse charge)": {
|
||||
"3400 bis 3470 Verbindlichkeiten gegen\u00fc. verb. Untern., Verbindl. gegen\u00fc. Untern., mit denen eine Beteiligungsverh\u00e4lnis besteht": {},
|
||||
"3600 bis 3690 Verbindlichkeiten im Rahmen der sozialen Sicherheit": {},
|
||||
"3700 bis 3890 \u00dcbrige sonstige Verbindlichkeiten": {},
|
||||
"3900 bis 3990 Passive Rechnungsabgrenzungsposten": {},
|
||||
"Anleihen (einschlie\u00dflich konvertibler)": {},
|
||||
"Erhaltene Anzahlungenauf Bestellungen": {},
|
||||
"R\u00fcckstellungen f\u00fcr Abfertigung": {},
|
||||
"R\u00fcckstellungen f\u00fcr Pensionen": {},
|
||||
"USt. \u00a719 /art (reverse charge)": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"3500 Verbindlichkeiten aus Umsatzsteuer": {"account_type": "Tax"},
|
||||
"3580 Umsatzsteuer Zahllast": {
|
||||
"Umsatzsteuer": {},
|
||||
"Umsatzsteuer Zahllast": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"3510 Umsatzsteuer Inland 20%": {
|
||||
"Umsatzsteuer aus i.g. Erwerb 10%": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"3515 Umsatzsteuer Inland 10%": {
|
||||
"Umsatzsteuer aus i.g. Erwerb 20%": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"3520 Umsatzsteuer aus i.g. Erwerb 20%": {
|
||||
"Umsatzsteuer aus i.g. Lieferungen 10%": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"3525 Umsatzsteuer aus i.g. Erwerb 10%": {
|
||||
"Umsatzsteuer aus i.g. Lieferungen 20%": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"3560 Umsatzsteuer-Evidenzkonto f\u00fcr erhaltene Anzahlungen auf Bestellungen": {},
|
||||
"3360 Verbindlichkeiten aus Lieferungen u. Leistungen EU": {
|
||||
"Umsatzsteuer-Evidenzkonto f\u00fcr erhaltene Anzahlungen auf Bestellungen": {},
|
||||
"Verbindlichkeiten aus Lieferungen u. Leistungen EU": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"3000 Verbindlichkeiten aus Lieferungen u. Leistungen Inland": {
|
||||
"Verbindlichkeiten aus Lieferungen u. Leistungen Inland": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"3370 Verbindlichkeiten aus Lieferungen u. Leistungen sonst. Ausland": {
|
||||
"Verbindlichkeiten aus Lieferungen u. Leistungen sonst. Ausland": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"3400 Verbindlichkeiten gegen\u00fcber verbundenen Unternehmen": {},
|
||||
"3570 Verrechnung Finanzamt": {
|
||||
"Verbindlichkeiten gegen\u00fcber Gesellschaften": {},
|
||||
"Verrechnung Finanzamt": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"root_type": "Liability"
|
||||
},
|
||||
"Klasse 2 Aktiva: Umlaufverm\u00f6gen, Rechnungsabgrenzungen": {
|
||||
"2030 Forderungen aus Lieferungen und Leistungen Inland (0% USt, umsatzsteuerfrei)": {
|
||||
"Summe Kontoklasse 0 Anlageverm\u00f6gen": {
|
||||
"44 bis 49 Sonstige Maschinen und maschinelle Anlagen": {},
|
||||
"920 bis 930 Festverzinsliche Wertpapiere des Anlageverm\u00f6gens": {},
|
||||
"940 bis 970 Sonstige Finanzanlagen, Wertrechte": {},
|
||||
"Allgemeine Werkzeuge und Handwerkzeuge": {},
|
||||
"Andere Bef\u00f6rderungsmittel": {},
|
||||
"Andere Betriebs- und Gesch\u00e4ftsausstattung": {},
|
||||
"Andere Erzeugungshilfsmittel": {},
|
||||
"Anlagen im Bau": {},
|
||||
"Anteile an Investmentfonds": {},
|
||||
"Anteile an Kapitalgesellschaften ohne Beteiligungscharakter": {},
|
||||
"Anteile an Personengesellschaften ohne Beteiligungscharakter": {},
|
||||
"Anteile an verbundenen Unternehmen": {},
|
||||
"Antriebsmaschinen": {},
|
||||
"Aufwendungen f\u00fcs das Ingangssetzen u. Erweitern eines Betriebes": {},
|
||||
"Ausleihungen an verbundene Unternehmen": {},
|
||||
"Ausleihungen an verbundene Unternehmen, mit denen ein Beteiligungsverh\u00e4lnis besteht": {},
|
||||
"Bauliche Investitionen in fremden (gepachteten) Betriebs- und Gesch\u00e4ftsgeb\u00e4uden": {},
|
||||
"Bauliche Investitionen in fremden (gepachteten) Wohn- und Sozialgeb\u00e4uden": {},
|
||||
"Bebaute Grundst\u00fccke (Grundwert)": {},
|
||||
"Beheizungs- und Beleuchtungsanlagen": {},
|
||||
"Beteiligungen an Gemeinschaftunternehmen": {},
|
||||
"Beteiligungen an angeschlossenen (assoziierten) Unternehmen": {},
|
||||
"Betriebs- und Gesch\u00e4ftsgeb\u00e4ude auf eigenem Grund": {},
|
||||
"Betriebs- und Gesch\u00e4ftsgeb\u00e4ude auf fremdem Grund": {},
|
||||
"B\u00fcromaschinen, EDV - Anlagen": {},
|
||||
"Datenverarbeitungsprogramme": {},
|
||||
"Energieversorgungsanlagen": {},
|
||||
"Fertigungsmaschinen": {},
|
||||
"Gebinde": {},
|
||||
"Geleistete Anzahlungen": {},
|
||||
"Genossenschaften ohne Beteiligungscharakter": {},
|
||||
"Geringwertige Verm\u00f6gensgegenst\u00e4nde, soweit im Erzeugerprozess verwendet": {},
|
||||
"Geringwertige Verm\u00f6gensgegenst\u00e4nde, soweit nicht im Erzeugungsprozess verwendet": {},
|
||||
"Gesch\u00e4fts(Firmen)wert": {},
|
||||
"Grundst\u00fcckseinrichtunten auf eigenem Grund": {},
|
||||
"Grundst\u00fcckseinrichtunten auf fremdem Grund": {},
|
||||
"Grundst\u00fccksgleiche Rechte": {},
|
||||
"Hebezeuge und Montageanlagen": {},
|
||||
"Konzessionen": {},
|
||||
"Kumulierte Abschreibungen": {},
|
||||
"LKW": {},
|
||||
"Marken, Warenzeichen und Musterschutzrechte": {},
|
||||
"Maschinenwerkzeuge": {},
|
||||
"Nachrichten- und Kontrollanlagen": {},
|
||||
"PKW": {},
|
||||
"Pacht- und Mietrechte": {},
|
||||
"Patentrechte und Lizenzen": {},
|
||||
"Sonstige Ausleihungen": {},
|
||||
"Sonstige Beteiligungen": {},
|
||||
"Transportanlagen": {},
|
||||
"Unbebaute Grundst\u00fccke": {},
|
||||
"Vorrichtungen, Formen und Modelle": {},
|
||||
"Wohn- und Sozialgeb\u00e4ude auf eigenem Grund": {},
|
||||
"Wohn- und Sozialgeb\u00e4ude auf fremdem Grund": {},
|
||||
"root_type": "Asset"
|
||||
},
|
||||
"Summe Personalaufwand": {
|
||||
"6000 bis 6190 L\u00f6hne": {},
|
||||
"6200 bis 6390 Geh\u00e4lter": {},
|
||||
"6400 bis 6440 Aufwendungen f\u00fcr Abfertigungen": {},
|
||||
"6450 bis 6490 Aufwendungen f\u00fcr Altersversorgung": {},
|
||||
"6500 bis 6550 Gesetzlicher Sozialaufwand Arbeiter": {},
|
||||
"6560 bis 6590 Gesetzlicher Sozialaufwand Angestellte": {},
|
||||
"6600 bis 6650 Lohnabh\u00e4ngige Abgaben und Pflichtbeitr\u00e4gte": {},
|
||||
"6660 bis 6690 Gehaltsabh\u00e4ngige Abgaben und Pflichtbeitr\u00e4gte": {},
|
||||
"6700 bis 6890 Sonstige Sozialaufwendungen": {},
|
||||
"Aufwandsstellenrechnung": {},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"Summe Umlaufverm\u00f6gen": {
|
||||
"2000 bis 2007 Forderungen aus Lief. und Leist. Inland": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2010 Forderungen aus Lieferungen und Leistungen Inland (10% USt, umsatzsteuerfrei)": {
|
||||
"2100 bis 2120 Forderungen aus Lief. und Leist. EU": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2000 Forderungen aus Lieferungen und Leistungen Inland (20% USt, umsatzsteuerfrei)": {
|
||||
"2150 bis 2170 Forderungen aus Lief. und Leist. Ausland": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2040 Forderungen aus Lieferungen und Leistungen Inland (sonstiger USt-Satz)": {
|
||||
"2200 bis 2220 Forderungen gegen\u00fcber verbundenen Unternehmen": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2100 Forderungen aus Lieferungen und Leistungen EU": {
|
||||
"2250 bis 2270 Forderungen gegen\u00fcber Unternehmen, mit denen ein Beteiligungsverh\u00e4ltnis besteht": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2150 Forderungen aus Lieferungen und Leistungen Ausland (Nicht-EU)": {
|
||||
"2300 bis 2460 Sonstige Forderungen und Verm\u00f6gensgegenst\u00e4nde": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2200 Forderungen gegen\u00fcber verbundenen Unternehmen": {
|
||||
"2630 bis 2670 Sonstige Wertpapiere": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2250 Forderungen gegen\u00fcber Unternehmen, mit denen ein Beteiligungsverh\u00e4ltnis besteht": {
|
||||
"2750 bis 2770 Kassenbest\u00e4nde in Fremdw\u00e4hrung": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2300 Sonstige Forderungen und Verm\u00f6gensgegenst\u00e4nde": {
|
||||
"Aktive Rechnungsabrenzungsposten": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2630 Sonstige Wertpapiere": {
|
||||
"account_type": "Stock"
|
||||
},
|
||||
"2750 Kassenbest\u00e4nde in Fremdw\u00e4hrung": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"2900 Aktive Rechnungsabrenzungsposten": {
|
||||
"Anteile an verbundenen Unternehmen": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2600 Anteile an verbundenen Unternehmen": {
|
||||
"account_type": "Equity"
|
||||
},
|
||||
"2680 Besitzwechsel ohne Forderungen": {
|
||||
"Bank / Guthaben bei Kreditinstituten": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2950 Aktiviertes Disagio": {
|
||||
"Besitzwechsel ...": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2610 Eigene Anteile und Wertpapiere an mit Mehrheit beteiligten Unternehmen": {
|
||||
"Disagio": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2570 Einfuhrumsatzsteuer (bezahlt)": {"account_type": "Tax"},
|
||||
|
||||
"2460 Eingeforderte aber noch nicht eingezahlte Einlagen": {
|
||||
"Eigene Anteile (Wertpapiere)": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2180 Einzelwertberichtigungen zu Forderungen aus Lief. und Leist. Ausland": {
|
||||
"Einfuhrumsatzsteuer (bezahlt)": {},
|
||||
"Eingeforderte aber noch nicht eingezahlte Einlagen": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2130 Einzelwertberichtigungen zu Forderungen aus Lief. und Leist. EU": {
|
||||
"Einzelwertberichtigungen zu Forderungen aus Lief. und Leist. Ausland": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2080 Einzelwertberichtigungen zu Forderungen aus Lief. und Leist. Inland ": {
|
||||
"Einzelwertberichtigungen zu Forderungen aus Lief. und Leist. EU": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2270 Einzelwertberichtigungen zu Forderungen gegen\u00fcber Unternehmen mit denen ein Beteiligungsverh\u00e4ltnis besteht": {
|
||||
"Einzelwertberichtigungen zu Forderungen aus Lief. und Leist. Inland ": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2230 Einzelwertberichtigungen zu Forderungen gegen\u00fcber verbundenen Unternehmen": {
|
||||
"Einzelwertberichtigungen zu Forderungen gegen\u00fcber Unternehmen mit denen ein Beteiligungsverh\u00e4ltnis besteht": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2470 Einzelwertberichtigungen zu sonstigen Forderungen und Verm\u00f6gensgegenst\u00e4nden": {
|
||||
"Einzelwertberichtigungen zu Forderungen gegen\u00fcber verbundenen Unternehmen": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2700 Kassenbestand": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"2190 Pauschalwertberichtigungen zu Forderungen aus Lief. und Leist. sonstiges Ausland": {
|
||||
"Einzelwertberichtigungen zu sonstigen Forderungen und Verm\u00f6gensgegenst\u00e4nden": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2130 Pauschalwertberichtigungen zu Forderungen aus Lief. und Leist. EU": {
|
||||
"Kassenbestand": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2100 Pauschalwertberichtigungen zu Forderungen aus Lief. und Leist. Inland ": {
|
||||
"Pauschalwertberichtigungen zu Forderungen aus Lief. und Leist. Ausland": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2280 Pauschalwertberichtigungen zu Forderungen gegen\u00fcber Unternehmen mit denen ein Beteiligungsverh\u00e4ltnis besteht": {
|
||||
"Pauschalwertberichtigungen zu Forderungen aus Lief. und Leist. EU": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2240 Pauschalwertberichtigungen zu Forderungen gegen\u00fcber verbundenen Unternehmen": {
|
||||
"Pauschalwertberichtigungen zu Forderungen aus Lief. und Leist. Inland ": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2480 Pauschalwertberichtigungen zu sonstigen Forderungen und Verm\u00f6gensgegenst\u00e4nden": {
|
||||
"Pauschalwertberichtigungen zu Forderungen gegen\u00fcber Unternehmen mit denen ein Beteiligungsverh\u00e4ltnis besteht": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2740 Postwertzeichen": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"2780 Schecks in Euro": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"2800 Guthaben bei Bank": {
|
||||
"account_type": "Bank"
|
||||
},
|
||||
"2801 Guthaben bei Bank - Sparkonto": {
|
||||
"account_type": "Bank"
|
||||
},
|
||||
"2810 Guthaben bei Paypal": {
|
||||
"account_type": "Bank"
|
||||
},
|
||||
"2930 Mietvorauszahlungen": {
|
||||
"Pauschalwertberichtigungen zu Forderungen gegen\u00fcber verbundenen Unternehmen": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2980 Abgrenzung latenter Steuern": {
|
||||
"Pauschalwertberichtigungen zu sonstigen Forderungen und Verm\u00f6gensgegenst\u00e4nden": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2500 Vorsteuer": {
|
||||
"Postwertzeichen": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"2510 Vorsteuer Inland 10%": {
|
||||
"Schecks in Inlandsw\u00e4hrung": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"Sonstige Anteile": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"Stempelmarken": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"Steuerabgrenzung": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"Unterschiedsbetrag gem. Abschnitt XII Pensionskassengesetz": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"Unterschiedsbetrag zur gebotenen Pensionsr\u00fcckstellung": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"Vorsteuer": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"Vorsteuer aus ig. Erwerb 10%": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"2895 Schwebende Geldbewegugen": {
|
||||
"account_type": "Bank"
|
||||
},
|
||||
"2513 Vorsteuer Inland 5%": {
|
||||
"Vorsteuer aus ig. Erwerb 20%": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"2515 Vorsteuer Inland 20%": {
|
||||
"Vorsteuer \u00a719/Art 19 ( reverse charge ) ": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"2520 Vorsteuer aus innergemeinschaftlichem Erwerb 10%": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"2525 Vorsteuer aus innergemeinschaftlichem Erwerb 20%": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"2530 Vorsteuer \u00a719/Art 19 ( reverse charge ) ": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"2690 Wertberichtigungen zu Wertpapieren und Anteilen": {
|
||||
"Wertberichtigungen": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"root_type": "Asset"
|
||||
},
|
||||
"Klasse 4: Betriebliche Erträge": {
|
||||
"4000 Erlöse 20 %": {"account_type": "Income Account"},
|
||||
"4020 Erl\u00f6se 0 % steuerbefreit": {"account_type": "Income Account"},
|
||||
"4010 Erl\u00f6se 10 %": {"account_type": "Income Account"},
|
||||
"4030 Erl\u00f6se 13 %": {"account_type": "Income Account"},
|
||||
"4040 Erl\u00f6se 0 % innergemeinschaftliche Lieferungen": {"account_type": "Income Account"},
|
||||
"4400 Erl\u00f6sreduktion 0 % steuerbefreit": {"account_type": "Expense Account"},
|
||||
"4410 Erl\u00f6sreduktion 10 %": {"account_type": "Expense Account"},
|
||||
"4420 Erl\u00f6sreduktion 20 %": {"account_type": "Expense Account"},
|
||||
"4430 Erl\u00f6sreduktion 13 %": {"account_type": "Expense Account"},
|
||||
"4440 Erl\u00f6sreduktion 0 % innergemeinschaftliche Lieferungen": {"account_type": "Expense Account"},
|
||||
"4500 Ver\u00e4nderungen des Bestandes an fertigen und unfertigen Erzeugn. sowie an noch nicht abrechenbaren Leistungen": {"account_type": "Income Account"},
|
||||
"4580 Aktivierte Eigenleistungen": {"account_type": "Income Account"},
|
||||
"4600 Erl\u00f6se aus dem Abgang vom Anlageverm\u00f6gen, ausgen. Finanzanlagen": {"account_type": "Income Account"},
|
||||
"4630 Ertr\u00e4ge aus dem Abgang vom Anlageverm\u00f6gen, ausgen. Finanzanlagen": {"account_type": "Income Account"},
|
||||
"4660 Ertr\u00e4ge aus der Zuschreibung zum Anlageverm\u00f6gen, ausgen. Finanzanlagen": {"account_type": "Income Account"},
|
||||
"4700 Ertr\u00e4ge aus der Aufl\u00f6sung von R\u00fcckstellungen": {"account_type": "Income Account"},
|
||||
"4800 \u00dcbrige betriebliche Ertr\u00e4ge": {"account_type": "Income Account"},
|
||||
"root_type": "Income"
|
||||
"Summe Vorr\u00e4te": {
|
||||
"1000 bis 1090 Bezugsverrechnung": {},
|
||||
"1100 bis 1190 Rohstoffe": {},
|
||||
"1200 bis 1290 Bezogene Teile": {},
|
||||
"1300 bis 1340 Hilfsstoffe": {},
|
||||
"1350 bis 1390 Betriebsstoffe": {},
|
||||
"1400 bis 1490 Unfertige Erzeugniss": {},
|
||||
"1500 bis 1590 Fertige Erzeugniss": {},
|
||||
"1600 bis 1690 Waren": {},
|
||||
"1700 bis 1790 Noch nicht abgerechenbare Leistungen": {},
|
||||
"1900 bis 1990 Wertberichtigungen": {},
|
||||
"geleistete Anzahlungen": {},
|
||||
"root_type": "Asset"
|
||||
},
|
||||
"Klasse 5: Aufwand f\u00fcr Material und Leistungen": {
|
||||
"5000 Einkauf Partnerleistungen": {"account_type": "Cost of Goods Sold"},
|
||||
"5100 Verbrauch an Rohstoffen": {"account_type": "Cost of Goods Sold"},
|
||||
"5200 Verbrauch von bezogenen Fertig- und Einzelteilen": {"account_type": "Cost of Goods Sold"},
|
||||
"5300 Verbrauch von Hilfsstoffen": {"account_type": "Cost of Goods Sold"},
|
||||
"5340 Verbrauch Verpackungsmaterial": {"account_type": "Cost of Goods Sold"},
|
||||
"5470 Verbrauch von Kleinmaterial": {"account_type": "Cost of Goods Sold"},
|
||||
"5450 Verbrauch von Reinigungsmaterial": {"account_type": "Cost of Goods Sold"},
|
||||
"5400 Verbrauch von Betriebsstoffen": {"account_type": "Cost of Goods Sold"},
|
||||
"5500 Verbrauch von Werkzeugen und anderen Erzeugungshilfsmittel": {"account_type": "Cost of Goods Sold"},
|
||||
"5600 Verbrauch von Brenn- und Treibstoffen, Energie und Wasser": {"account_type": "Cost of Goods Sold"},
|
||||
"5700 Bearbeitung durch Dritte": {"account_type": "Cost of Goods Sold"},
|
||||
"5900 Aufwandsstellenrechnung Material": {"account_type": "Cost of Goods Sold"},
|
||||
"5820 Skontoertr\u00e4ge (20% USt.)": {"account_type": "Income Account"},
|
||||
"5810 Skontoertr\u00e4ge (10% USt.)": {"account_type": "Income Account"},
|
||||
"5010 Handelswareneinkauf 10 %": {"account_type": "Cost of Goods Sold"},
|
||||
"5020 Handelswareneinkauf 20 %": {"account_type": "Cost of Goods Sold"},
|
||||
"5040 Handelswareneinkauf innergemeinschaftlicher Erwerb 10 % VSt/10 % USt": {"account_type": "Cost of Goods Sold"},
|
||||
"5050 Handelswareneinkauf innergemeinschaftlicher Erwerb 20 % VSt/20 % USt": {"account_type": "Cost of Goods Sold"},
|
||||
"5070 Handelswareneinkauf innergemeinschaftlicher Erwerb ohne Vorsteuerabzug und 10 % USt": {"account_type": "Cost of Goods Sold"},
|
||||
"5080 Handelswareneinkauf innergemeinschaftlicher Erwerb ohne Vorsteuerabzug und 20 % USt": {"account_type": "Cost of Goods Sold"},
|
||||
"Summe Wareneinsatz": {
|
||||
"5100 bis 5190 Verbrauch an Rohstoffen": {},
|
||||
"5200 bis 5290 Verbrauch von bezogenen Fertig- und Einzelteilen": {},
|
||||
"5300 bis 5390 Verbrauch von Hilfsstoffen": {},
|
||||
"5400 bis 5490 Verbrauch von Betriebsstoffen": {},
|
||||
"5500 bis 5590 Verbrauch von Werkzeugen und anderen Erzeugungshilfsmittel": {},
|
||||
"5600 bis 5690 Verbrauch von Brenn- und Treibstoffen, Energie und Wasser": {},
|
||||
"5700 bis 5790 Sonstige bezogene Herstellungsleistungen": {},
|
||||
"Aufwandsstellenrechnung": {},
|
||||
"Skontoertr\u00e4ge auf Materialaufwand": {},
|
||||
"Skontoertr\u00e4ge auf sonstige bezogene Herstellungsleistungen": {},
|
||||
"Wareneinkauf 10 %": {},
|
||||
"Wareneinkauf 20 %": {},
|
||||
"Wareneinkauf igErwerb 10 % VSt/10 % USt": {},
|
||||
"Wareneinkauf igErwerb 20 % VSt/20 % USt": {},
|
||||
"Wareneinkauf igErwerb ohne Vorsteuerabzug und 10 % USt": {},
|
||||
"Wareneinkauf igErwerb ohne Vorsteuerabzug und 20 % USt": {},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"Klasse 6: Personalaufwand": {
|
||||
"6000 L\u00f6hne": {"account_type": "Payable"},
|
||||
"6200 Geh\u00e4lter": {"account_type": "Payable"},
|
||||
"6400 Aufwendungen f\u00fcr Abfertigungen": {"account_type": "Payable"},
|
||||
"6450 Aufwendungen f\u00fcr Altersversorgung": {"account_type": "Payable"},
|
||||
"6500 Gesetzlicher Sozialaufwand Arbeiter": {"account_type": "Payable"},
|
||||
"6560 Gesetzlicher Sozialaufwand Angestellte": {"account_type": "Payable"},
|
||||
"6600 Lohnabh\u00e4ngige Abgaben und Pflichtbeitr\u00e4gte": {"account_type": "Payable"},
|
||||
"6660 Gehaltsabh\u00e4ngige Abgaben und Pflichtbeitr\u00e4gte": {"account_type": "Payable"},
|
||||
"6700 Sonstige Sozialaufwendungen": {"account_type": "Payable"},
|
||||
"6900 Aufwandsstellenrechnung Personal": {"account_type": "Payable"},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"Klasse 7: Abschreibungen und sonstige betriebliche Aufwendungen": {
|
||||
"7010 Abschreibungen auf das Anlageverm\u00f6gen (ausgenommen Finanzanlagen)": {"account_type": "Depreciation"},
|
||||
"7100 Sonstige Steuern und Geb\u00fchren": {"account_type": "Tax"},
|
||||
"7200 Instandhaltung u. Reinigung durch Dritte, Entsorgung, Energie": {"account_type": "Expense Account"},
|
||||
"7300 Transporte durch Dritte": {"account_type": "Expense Account"},
|
||||
"7310 Fahrrad - Aufwand": {"account_type": "Expense Account"},
|
||||
"7320 Kfz - Aufwand": {"account_type": "Expense Account"},
|
||||
"7330 LKW - Aufwand": {"account_type": "Expense Account"},
|
||||
"7340 Lastenrad - Aufwand": {"account_type": "Expense Account"},
|
||||
"7350 Reise- und Fahraufwand": {"account_type": "Expense Account"},
|
||||
"7360 Tag- und N\u00e4chtigungsgelder": {"account_type": "Expense Account"},
|
||||
"7380 Nachrichtenaufwand": {"account_type": "Expense Account"},
|
||||
"7400 Miet- und Pachtaufwand": {"account_type": "Expense Account"},
|
||||
"7440 Leasingaufwand": {"account_type": "Expense Account"},
|
||||
"7480 Lizenzaufwand": {"account_type": "Expense Account"},
|
||||
"7500 Aufwand f\u00fcr beigestelltes Personal": {"account_type": "Expense Account"},
|
||||
"7540 Provisionen an Dritte": {"account_type": "Expense Account"},
|
||||
"7580 Aufsichtsratsverg\u00fctungen": {"account_type": "Expense Account"},
|
||||
"7610 Druckerzeugnisse und Vervielf\u00e4ltigungen": {"account_type": "Expense Account"},
|
||||
"7650 Werbung und Repr\u00e4sentationen": {"account_type": "Expense Account"},
|
||||
"7700 Versicherungen": {"account_type": "Expense Account"},
|
||||
"7750 Beratungs- und Pr\u00fcfungsaufwand": {"account_type": "Expense Account"},
|
||||
"7800 Forderungsverluste und Schadensf\u00e4lle": {"account_type": "Expense Account"},
|
||||
"7840 Verschiedene betriebliche Aufwendungen": {"account_type": "Expense Account"},
|
||||
"7910 Aufwandsstellenrechung der Hersteller": {"account_type": "Expense Account"},
|
||||
"7060 Sofortabschreibungen geringwertig": {"account_type": "Expense Account"},
|
||||
"7070 Abschreibungen vom Umlaufverm\u00f6gen, soweit diese die im Unternehmen \u00fcblichen Abschreibungen \u00fcbersteigen": {"account_type": "Depreciation"},
|
||||
"7900 Aufwandsstellenrechnung": {"account_type": "Expense Account"},
|
||||
"7770 Aus- und Fortbildung": {"account_type": "Expense Account"},
|
||||
"7820 Buchwert abgegangener Anlagen, ausgenommen Finanzanlagen": {"account_type": "Expense Account"},
|
||||
"7600 B\u00fcromaterial und Drucksorten": {"account_type": "Expense Account"},
|
||||
"7630 Fachliteratur und Zeitungen ": {"account_type": "Expense Account"},
|
||||
"7960 Herstellungskosten der zur Erzielung der Umsatzerl\u00f6se erbrachten Leistungen": {"account_type": "Expense Account"},
|
||||
"7780 Mitgliedsbeitr\u00e4ge": {"account_type": "Expense Account"},
|
||||
"7880 Skontoertr\u00e4ge auf sonstige betriebliche Aufwendungen": {"account_type": "Expense Account"},
|
||||
"7990 Sonstige betrieblichen Aufwendungen": {"account_type": "Expense Account"},
|
||||
"7680 Spenden und Trinkgelder": {"account_type": "Expense Account"},
|
||||
"7790 Spesen des Geldverkehrs": {"account_type": "Expense Account"},
|
||||
"7830 Verluste aus dem Abgang vom Anlageverm\u00f6gen, ausgenommen Finanzanlagen": {"account_type": "Expense Account"},
|
||||
"7970 Vertriebskosten": {"account_type": "Expense Account"},
|
||||
"7980 Verwaltungskosten": {"account_type": "Expense Account"},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"Klasse 8: Finanz- und ausserordentliche Ertr\u00e4ge und Aufwendungen": {
|
||||
"8000 Ertr\u00e4ge aus Beteiligungen": {"account_type": "Income Account"},
|
||||
"8050 Ertr\u00e4ge aus anderen Wertpapieren und Ausleihungen des Finanzanlageverm\u00f6gens": {"account_type": "Income Account"},
|
||||
"8100 Zinsen aus Bankguthaben": {"account_type": "Income Account"},
|
||||
"8110 Zinsen aus gewaehrten Darlehen": {"account_type": "Income Account"},
|
||||
"8130 Verzugszinsenertraege": {"account_type": "Income Account"},
|
||||
"8220 Aufwendungen aus Beteiligungen": {"account_type": "Expense Account"},
|
||||
"8260 Aufwendungen aus sonst. Fiananzanlagen und aus Wertpapieren des Umlaufverm\u00f6gens": {},
|
||||
"8280 Zinsen und \u00e4hnliche Aufwendungem": {"account_type": "Expense Account"},
|
||||
"8400 Au\u00dferordentliche Ertr\u00e4ge": {"account_type": "Income Account"},
|
||||
"8450 Au\u00dferordentliche Aufwendungen": {"account_type": "Expense Account"},
|
||||
"8500 Steuern vom Einkommen und vom Ertrag": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"8600 Aufl\u00f6sung unversteuerten R\u00fccklagen": {"account_type": "Income Account"},
|
||||
"8700 Aufl\u00f6sung von Kapitalr\u00fccklagen": {"account_type": "Income Account"},
|
||||
"8750 Aufl\u00f6sung von Gewinnr\u00fccklagen": {"account_type": "Income Account"},
|
||||
"8800 Zuweisung zu unversteuerten R\u00fccklagen": {"account_type": "Expense Account"},
|
||||
"8900 Zuweisung zu Gewinnr\u00fccklagen": {"account_type": "Expense Account"},
|
||||
"8100 Buchwert abgegangener Beteiligungen": {"account_type": "Expense Account"},
|
||||
"8130 Buchwert abgegangener Wertpapiere des Umlaufverm\u00f6gens": {"account_type": "Expense Account"},
|
||||
"8120 Buchwert abgegangener sonstiger Finanzanlagen": {"account_type": "Expense Account"},
|
||||
"8990 Gewinnabfuhr bzw. Verlust\u00fcberrechnung aus Ergebnisabf\u00fchrungsvertr\u00e4gen": {"account_type": "Expense Account"},
|
||||
"8350 nicht ausgenutzte Lieferantenskonti": {"account_type": "Expense Account"},
|
||||
"root_type": "Income"
|
||||
},
|
||||
"Klasse 9 Passiva: Eigenkapital, R\u00fccklagen, stille Einlagen, Abschlusskonten": {
|
||||
"9000 Gezeichnetes bzw. gewidmetes Kapital": {
|
||||
"account_type": "Equity"
|
||||
},
|
||||
"9200 Kapitalr\u00fccklagen": {
|
||||
"account_type": "Equity"
|
||||
},
|
||||
"9300 Gewinnr\u00fccklagen": {
|
||||
"account_type": "Equity"
|
||||
},
|
||||
"9400 Bewertungsreserven uns sonst. unversteuerte R\u00fccklagen": {
|
||||
"account_type": "Equity"
|
||||
},
|
||||
"9600 Private Entnahmen": {"account_type": "Equity"},
|
||||
"9610 Privatsteuern": {"account_type": "Equity"},
|
||||
"9700 Einlagen stiller Gesellschafter ": {"account_type": "Equity"},
|
||||
"9900 Evidenzkonto": {"account_type": "Equity"},
|
||||
"9800 Er\u00f6ffnungsbilanzkonto (EBK)": {"account_type": "Equity"},
|
||||
"9880 Jahresergebnis laut Gewinn- und Verlustrechnung (G+V)": {"account_type": "Equity"},
|
||||
"9850 Schlussbilanzkonto (SBK)": {"account_type": "Round Off"},
|
||||
"9190 nicht eingeforderte ausstehende Einlagen und berechtigte Entnahmen von Gesellschaftern": {
|
||||
"account_type": "Equity"
|
||||
},
|
||||
"root_type": "Equity"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -437,20 +437,12 @@
|
||||
},
|
||||
"Sales": {
|
||||
"Sales from Other Regions": {
|
||||
"Sales from Other Region": {
|
||||
"account_type": "Income Account"
|
||||
}
|
||||
"Sales from Other Region": {}
|
||||
},
|
||||
"Sales of same region": {
|
||||
"Management Consultancy Fees 1": {
|
||||
"account_type": "Income Account"
|
||||
},
|
||||
"Sales Account": {
|
||||
"account_type": "Income Account"
|
||||
},
|
||||
"Sales of I/C": {
|
||||
"account_type": "Income Account"
|
||||
}
|
||||
"Management Consultancy Fees 1": {},
|
||||
"Sales Account": {},
|
||||
"Sales of I/C": {}
|
||||
}
|
||||
},
|
||||
"root_type": "Income"
|
||||
|
||||
@@ -56,9 +56,7 @@
|
||||
"Constru\u00e7\u00f5es em Andamento de Im\u00f3veis Destinados \u00e0 Venda": {},
|
||||
"Estoques Destinados \u00e0 Doa\u00e7\u00e3o": {},
|
||||
"Im\u00f3veis Destinados \u00e0 Venda": {},
|
||||
"Insumos (materiais diretos)": {
|
||||
"account_type": "Stock"
|
||||
},
|
||||
"Insumos (materiais diretos)": {},
|
||||
"Insumos Agropecu\u00e1rios": {},
|
||||
"Mercadorias para Revenda": {},
|
||||
"Outras 11": {},
|
||||
@@ -148,65 +146,6 @@
|
||||
"root_type": "Asset"
|
||||
},
|
||||
"CUSTOS DE PRODU\u00c7\u00c3O": {
|
||||
"CUSTO DOS PRODUTOS E SERVI\u00c7OS VENDIDOS": {
|
||||
"CUSTO DOS PRODUTOS VENDIDOS": {
|
||||
"CUSTO DOS PRODUTOS VENDIDOS PARA AS DEMAIS ATIVIDADES": {
|
||||
"Custos dos Produtos Vendidos em Geral": {
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"Outros Custos 4": {},
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"CUSTO DOS PRODUTOS VENDIDOS PARA ASSIST\u00caNCIA SOCIAL": {
|
||||
"Custos dos Produtos para Assist\u00eancia Social - Gratuidades": {},
|
||||
"Custos dos Produtos para Assist\u00eancia Social - Vendidos": {},
|
||||
"Outras": {}
|
||||
},
|
||||
"CUSTO DOS PRODUTOS VENDIDOS PARA EDUCA\u00c7\u00c3O": {
|
||||
"Custos dos Produtos para Educa\u00e7\u00e3o - Gratuidades": {},
|
||||
"Custos dos Produtos para Educa\u00e7\u00e3o - Vendidos": {},
|
||||
"Outros Custos 6": {}
|
||||
},
|
||||
"CUSTO DOS PRODUTOS VENDIDOS PARA SA\u00daDE": {
|
||||
"Custos dos Produtos para Sa\u00fade - Gratuidades": {},
|
||||
"Custos dos Produtos para Sa\u00fade \u2013 Vendidos": {},
|
||||
"Outros Custos 5": {}
|
||||
},
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"CUSTO DOS SERVI\u00c7OS PRESTADOS": {
|
||||
"CUSTO DOS SERVI\u00c7OS PRESTADOS PARA AS DEMAIS ATIVIDADES": {
|
||||
"Custo dos Servi\u00e7os Prestados em Geral": {},
|
||||
"Outros Custos": {}
|
||||
},
|
||||
"CUSTO DOS SERVI\u00c7OS PRESTADOS PARA ASSIST\u00caNCIA SOCIAL": {
|
||||
"Custo dos Servi\u00e7os Prestados a Conv\u00eanios/Contratos/Parcerias": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es 1": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es/Subven\u00e7\u00f5es Vinculadas 1": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Gratuidade 1": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Pacientes Particulares": {},
|
||||
"Outros Custos 2": {}
|
||||
},
|
||||
"CUSTO DOS SERVI\u00c7OS PRESTADOS PARA EDUCA\u00c7\u00c3O": {
|
||||
"Custo dos Servi\u00e7os Prestados a Alunos N\u00e3o Bolsistas": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Conv\u00eanios/Contratos/Parcerias (Exceto PROUNI)": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es/Subven\u00e7\u00f5es Vinculadas": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Gratuidade": {},
|
||||
"Custo dos Servi\u00e7os Prestados ao PROUNI": {},
|
||||
"Outros Custos 1": {}
|
||||
},
|
||||
"CUSTO DOS SERVI\u00c7OS PRESTADOS PARA SA\u00daDE": {
|
||||
"Custo dos Servi\u00e7os Prestados a Conv\u00eanios SUS": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Conv\u00eanios/Contratos/Parcerias 1": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es 2": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es/Subven\u00e7\u00f5es Vinculadas 2": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Gratuidade 2": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Pacientes Particulares 1": {},
|
||||
"Outros Custos 3": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"CUSTO DOS BENS E SERVI\u00c7OS PRODUZIDOS": {
|
||||
"CUSTO DOS PRODUTOS DE FABRICA\u00c7\u00c3O PR\u00d3PRIA PRODUZIDOS": {
|
||||
"Alimenta\u00e7\u00e3o do Trabalhador": {},
|
||||
@@ -682,9 +621,7 @@
|
||||
"Receita das Unidades Imobili\u00e1rias Vendidas": {},
|
||||
"Receita de Exporta\u00e7\u00e3o Direta de Mercadorias e Produtos": {},
|
||||
"Receita de Exporta\u00e7\u00e3o de Servi\u00e7os": {},
|
||||
"Receita de Loca\u00e7\u00e3o de Bens M\u00f3veis e Im\u00f3veis": {
|
||||
"account_type": "Income Account"
|
||||
},
|
||||
"Receita de Loca\u00e7\u00e3o de Bens M\u00f3veis e Im\u00f3veis": {},
|
||||
"Receita de Vendas de Mercadorias e Produtos a Comercial Exportadora com Fim Espec\u00edfico de Exporta\u00e7\u00e3o": {}
|
||||
}
|
||||
}
|
||||
@@ -708,6 +645,65 @@
|
||||
}
|
||||
},
|
||||
"RESULTADO OPERACIONAL": {
|
||||
"CUSTO DOS PRODUTOS E SERVI\u00c7OS VENDIDOS": {
|
||||
"CUSTO DOS PRODUTOS VENDIDOS": {
|
||||
"CUSTO DOS PRODUTOS VENDIDOS PARA AS DEMAIS ATIVIDADES": {
|
||||
"Custos dos Produtos Vendidos em Geral": {
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"Outros Custos 4": {},
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"CUSTO DOS PRODUTOS VENDIDOS PARA ASSIST\u00caNCIA SOCIAL": {
|
||||
"Custos dos Produtos para Assist\u00eancia Social - Gratuidades": {},
|
||||
"Custos dos Produtos para Assist\u00eancia Social - Vendidos": {},
|
||||
"Outras": {}
|
||||
},
|
||||
"CUSTO DOS PRODUTOS VENDIDOS PARA EDUCA\u00c7\u00c3O": {
|
||||
"Custos dos Produtos para Educa\u00e7\u00e3o - Gratuidades": {},
|
||||
"Custos dos Produtos para Educa\u00e7\u00e3o - Vendidos": {},
|
||||
"Outros Custos 6": {}
|
||||
},
|
||||
"CUSTO DOS PRODUTOS VENDIDOS PARA SA\u00daDE": {
|
||||
"Custos dos Produtos para Sa\u00fade - Gratuidades": {},
|
||||
"Custos dos Produtos para Sa\u00fade \u2013 Vendidos": {},
|
||||
"Outros Custos 5": {}
|
||||
},
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"CUSTO DOS SERVI\u00c7OS PRESTADOS": {
|
||||
"CUSTO DOS SERVI\u00c7OS PRESTADOS PARA AS DEMAIS ATIVIDADES": {
|
||||
"Custo dos Servi\u00e7os Prestados em Geral": {},
|
||||
"Outros Custos": {}
|
||||
},
|
||||
"CUSTO DOS SERVI\u00c7OS PRESTADOS PARA ASSIST\u00caNCIA SOCIAL": {
|
||||
"Custo dos Servi\u00e7os Prestados a Conv\u00eanios/Contratos/Parcerias": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es 1": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es/Subven\u00e7\u00f5es Vinculadas 1": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Gratuidade 1": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Pacientes Particulares": {},
|
||||
"Outros Custos 2": {}
|
||||
},
|
||||
"CUSTO DOS SERVI\u00c7OS PRESTADOS PARA EDUCA\u00c7\u00c3O": {
|
||||
"Custo dos Servi\u00e7os Prestados a Alunos N\u00e3o Bolsistas": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Conv\u00eanios/Contratos/Parcerias (Exceto PROUNI)": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es/Subven\u00e7\u00f5es Vinculadas": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Gratuidade": {},
|
||||
"Custo dos Servi\u00e7os Prestados ao PROUNI": {},
|
||||
"Outros Custos 1": {}
|
||||
},
|
||||
"CUSTO DOS SERVI\u00c7OS PRESTADOS PARA SA\u00daDE": {
|
||||
"Custo dos Servi\u00e7os Prestados a Conv\u00eanios SUS": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Conv\u00eanios/Contratos/Parcerias 1": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es 2": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Doa\u00e7\u00f5es/Subven\u00e7\u00f5es Vinculadas 2": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Gratuidade 2": {},
|
||||
"Custo dos Servi\u00e7os Prestados a Pacientes Particulares 1": {},
|
||||
"Outros Custos 3": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"DESPESAS OPERACIONAIS": {
|
||||
"DESPESAS OPERACIONAIS 1": {
|
||||
"DESPESAS OPERACIONAIS 2": {
|
||||
|
||||
@@ -33,9 +33,7 @@
|
||||
},
|
||||
"Stocks": {
|
||||
"Mati\u00e8res premi\u00e8res": {},
|
||||
"Stock de produits fini": {
|
||||
"account_type": "Stock"
|
||||
},
|
||||
"Stock de produits fini": {},
|
||||
"Stock exp\u00e9di\u00e9 non-factur\u00e9": {},
|
||||
"Travaux en cours": {},
|
||||
"account_type": "Stock"
|
||||
@@ -397,11 +395,9 @@
|
||||
},
|
||||
"Produits": {
|
||||
"Revenus de ventes": {
|
||||
"Escomptes de volume sur ventes": {},
|
||||
" Escomptes de volume sur ventes": {},
|
||||
"Autres produits d'exploitation": {},
|
||||
"Ventes": {
|
||||
"account_type": "Income Account"
|
||||
},
|
||||
"Ventes": {},
|
||||
"Ventes avec des provinces harmonis\u00e9es": {},
|
||||
"Ventes avec des provinces non-harmonis\u00e9es": {},
|
||||
"Ventes \u00e0 l'\u00e9tranger": {}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,38 +1,38 @@
|
||||
{
|
||||
"country_code": "de",
|
||||
"name": "SKR03 mit Kontonummern",
|
||||
"tree": {
|
||||
"Aktiva": {
|
||||
"is_group": 1,
|
||||
"country_code": "de",
|
||||
"name": "SKR03 mit Kontonummern",
|
||||
"tree": {
|
||||
"Aktiva": {
|
||||
"is_group": 1,
|
||||
"root_type": "Asset",
|
||||
"A - Anlagevermögen": {
|
||||
"is_group": 1,
|
||||
"EDV-Software": {
|
||||
"account_number": "0027",
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"Geschäftsausstattung": {
|
||||
"account_number": "0410",
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"Büroeinrichtung": {
|
||||
"account_number": "0420",
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"Darlehen": {
|
||||
"account_number": "0565"
|
||||
},
|
||||
"Maschinen": {
|
||||
"account_number": "0210",
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"Betriebsausstattung": {
|
||||
"account_number": "0400",
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"Ladeneinrichtung": {
|
||||
"account_number": "0430",
|
||||
"account_type": "Fixed Asset"
|
||||
"A - Anlagevermögen": {
|
||||
"is_group": 1,
|
||||
"EDV-Software": {
|
||||
"account_number": "0027",
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"Gesch\u00e4ftsausstattung": {
|
||||
"account_number": "0410",
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"B\u00fcroeinrichtung": {
|
||||
"account_number": "0420",
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"Darlehen": {
|
||||
"account_number": "0565"
|
||||
},
|
||||
"Maschinen": {
|
||||
"account_number": "0210",
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"Betriebsausstattung": {
|
||||
"account_number": "0400",
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"Ladeneinrichtung": {
|
||||
"account_number": "0430",
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"Accumulated Depreciation": {
|
||||
"account_type": "Accumulated Depreciation"
|
||||
@@ -53,58 +53,43 @@
|
||||
},
|
||||
"II. Forderungen und sonstige Vermögensgegenstände": {
|
||||
"is_group": 1,
|
||||
"Forderungen aus Lieferungen und Leistungen mit Kontokorrent": {
|
||||
"Ford. a. Lieferungen und Leistungen": {
|
||||
"account_number": "1400",
|
||||
"account_type": "Receivable",
|
||||
"is_group": 1
|
||||
},
|
||||
"Forderungen aus Lieferungen und Leistungen ohne Kontokorrent": {
|
||||
"account_number": "1410",
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"Durchlaufende Posten": {
|
||||
"account_number": "1590"
|
||||
},
|
||||
"Verrechnungskonto Gewinnermittlung § 4 Abs. 3 EStG, nicht ergebniswirksam": {
|
||||
"Gewinnermittlung \u00a74/3 nicht Ergebniswirksam": {
|
||||
"account_number": "1371"
|
||||
},
|
||||
"Abziehbare Vorsteuer": {
|
||||
"account_type": "Tax",
|
||||
"is_group": 1,
|
||||
"Abziehbare Vorsteuer 7 %": {
|
||||
"account_number": "1571",
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 7.0
|
||||
"Abziehbare Vorsteuer 7%": {
|
||||
"account_number": "1571"
|
||||
},
|
||||
"Abziehbare Vorsteuer 19 %": {
|
||||
"account_number": "1576",
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 19.0
|
||||
"Abziehbare Vorsteuer 19%": {
|
||||
"account_number": "1576"
|
||||
},
|
||||
"Abziehbare Vorsteuer nach § 13b UStG 19 %": {
|
||||
"account_number": "1577",
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 19.0
|
||||
"Abziehbare Vorsteuer nach \u00a713b UStG 19%": {
|
||||
"account_number": "1577"
|
||||
},
|
||||
"Leistungen \u00a713b UStG 19% Vorsteuer, 19% Umsatzsteuer": {
|
||||
"account_number": "3120"
|
||||
}
|
||||
}
|
||||
},
|
||||
"III. Wertpapiere": {
|
||||
"is_group": 1,
|
||||
"Anteile an verbundenen Unternehmen (Umlaufvermögen)": {
|
||||
"account_number": "1340"
|
||||
},
|
||||
"Anteile an herrschender oder mit Mehrheit beteiligter Gesellschaft": {
|
||||
"account_number": "1344"
|
||||
},
|
||||
"Sonstige Wertpapiere": {
|
||||
"account_number": "1348"
|
||||
}
|
||||
"is_group": 1
|
||||
},
|
||||
"IV. Kassenbestand, Bundesbankguthaben, Guthaben bei Kreditinstituten und Schecks.": {
|
||||
"is_group": 1,
|
||||
"Kasse": {
|
||||
"is_group": 1,
|
||||
"account_type": "Cash",
|
||||
"is_group": 1,
|
||||
"Kasse": {
|
||||
"is_group": 1,
|
||||
"account_number": "1000",
|
||||
"account_type": "Cash"
|
||||
}
|
||||
@@ -126,21 +111,21 @@
|
||||
"C - Rechnungsabgrenzungsposten": {
|
||||
"is_group": 1,
|
||||
"Aktive Rechnungsabgrenzung": {
|
||||
"account_number": "0980"
|
||||
"account_number": "0980"
|
||||
}
|
||||
},
|
||||
"D - Aktive latente Steuern": {
|
||||
"is_group": 1,
|
||||
"Aktive latente Steuern": {
|
||||
"account_number": "0983"
|
||||
"account_number": "0983"
|
||||
}
|
||||
},
|
||||
"E - Aktiver Unterschiedsbetrag aus der Vermögensverrechnung": {
|
||||
"is_group": 1
|
||||
}
|
||||
},
|
||||
"Passiva": {
|
||||
"is_group": 1,
|
||||
},
|
||||
"Passiva": {
|
||||
"is_group": 1,
|
||||
"root_type": "Liability",
|
||||
"A. Eigenkapital": {
|
||||
"is_group": 1,
|
||||
@@ -185,13 +170,8 @@
|
||||
},
|
||||
"IV. Verbindlichkeiten aus Lieferungen und Leistungen": {
|
||||
"is_group": 1,
|
||||
"Verbindlichkeiten aus Lieferungen und Leistungen mit Kontokorrent": {
|
||||
"Verbindlichkeiten aus Lieferungen u. Leistungen": {
|
||||
"account_number": "1600",
|
||||
"account_type": "Payable",
|
||||
"is_group": 1
|
||||
},
|
||||
"Verbindlichkeiten aus Lieferungen und Leistungen ohne Kontokorrent": {
|
||||
"account_number": "1610",
|
||||
"account_type": "Payable"
|
||||
}
|
||||
},
|
||||
@@ -220,32 +200,26 @@
|
||||
},
|
||||
"Umsatzsteuer": {
|
||||
"is_group": 1,
|
||||
"Umsatzsteuer 7 %": {
|
||||
"account_number": "1771",
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 7.0
|
||||
"account_type": "Tax",
|
||||
"Umsatzsteuer 7%": {
|
||||
"account_number": "1771"
|
||||
},
|
||||
"Umsatzsteuer 19 %": {
|
||||
"account_number": "1776",
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 19.0
|
||||
"Umsatzsteuer 19%": {
|
||||
"account_number": "1776"
|
||||
},
|
||||
"Umsatzsteuer-Vorauszahlung": {
|
||||
"account_number": "1780",
|
||||
"account_type": "Tax"
|
||||
"account_number": "1780"
|
||||
},
|
||||
"Umsatzsteuer-Vorauszahlung 1/11": {
|
||||
"account_number": "1781"
|
||||
},
|
||||
"Umsatzsteuer nach § 13b UStG 19 %": {
|
||||
"account_number": "1787",
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 19.0
|
||||
"Umsatzsteuer \u00a7 13b UStG 19%": {
|
||||
"account_number": "1787"
|
||||
},
|
||||
"Umsatzsteuer Vorjahr": {
|
||||
"account_number": "1790"
|
||||
},
|
||||
"Umsatzsteuer frühere Jahre": {
|
||||
"Umsatzsteuer fr\u00fchere Jahre": {
|
||||
"account_number": "1791"
|
||||
}
|
||||
}
|
||||
@@ -260,56 +234,44 @@
|
||||
"E. Passive latente Steuern": {
|
||||
"is_group": 1
|
||||
}
|
||||
},
|
||||
"Erlöse u. Erträge 2/8": {
|
||||
"is_group": 1,
|
||||
"root_type": "Income",
|
||||
"Erlöskonten 8": {
|
||||
},
|
||||
"Erl\u00f6se u. Ertr\u00e4ge 2/8": {
|
||||
"is_group": 1,
|
||||
"root_type": "Income",
|
||||
"Erl\u00f6skonten 8": {
|
||||
"is_group": 1,
|
||||
"Erlöse": {
|
||||
"account_number": "8200",
|
||||
"account_type": "Income Account"
|
||||
},
|
||||
"Erlöse USt. 19 %": {
|
||||
"account_number": "8400",
|
||||
"account_type": "Income Account"
|
||||
},
|
||||
"Erlöse USt. 7 %": {
|
||||
"account_number": "8300",
|
||||
"account_type": "Income Account"
|
||||
}
|
||||
},
|
||||
"Ertragskonten 2": {
|
||||
"is_group": 1,
|
||||
"sonstige Zinsen und ähnliche Erträge": {
|
||||
"account_number": "2650",
|
||||
"account_type": "Income Account"
|
||||
},
|
||||
"Außerordentliche Erträge": {
|
||||
"account_number": "2500",
|
||||
"account_type": "Income Account"
|
||||
},
|
||||
"Sonstige Erträge": {
|
||||
"account_number": "2700",
|
||||
"account_type": "Income Account"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Aufwendungen 2/4": {
|
||||
"is_group": 1,
|
||||
"Erl\u00f6se": {
|
||||
"account_number": "8200",
|
||||
"account_type": "Income Account"
|
||||
},
|
||||
"Erl\u00f6se USt. 19%": {
|
||||
"account_number": "8400",
|
||||
"account_type": "Income Account"
|
||||
},
|
||||
"Erl\u00f6se USt. 7%": {
|
||||
"account_number": "8300",
|
||||
"account_type": "Income Account"
|
||||
}
|
||||
},
|
||||
"Ertragskonten 2": {
|
||||
"is_group": 1,
|
||||
"sonstige Zinsen und \u00e4hnliche Ertr\u00e4ge": {
|
||||
"account_number": "2650",
|
||||
"account_type": "Income Account"
|
||||
},
|
||||
"Au\u00dferordentliche Ertr\u00e4ge": {
|
||||
"account_number": "2500",
|
||||
"account_type": "Income Account"
|
||||
},
|
||||
"Sonstige Ertr\u00e4ge": {
|
||||
"account_number": "2700",
|
||||
"account_type": "Income Account"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Aufwendungen 2/4": {
|
||||
"is_group": 1,
|
||||
"root_type": "Expense",
|
||||
"Fremdleistungen": {
|
||||
"account_number": "3100",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Fremdleistungen ohne Vorsteuer": {
|
||||
"account_number": "3109",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Bauleistungen eines im Inland ansässigen Unternehmers 19 % Vorsteuer und 19 % Umsatzsteuer": {
|
||||
"account_number": "3120",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Wareneingang": {
|
||||
"account_number": "3200"
|
||||
},
|
||||
@@ -336,234 +298,234 @@
|
||||
"Gegenkonto 4996-4998": {
|
||||
"account_number": "4999"
|
||||
},
|
||||
"Abschreibungen": {
|
||||
"is_group": 1,
|
||||
"Abschreibungen": {
|
||||
"is_group": 1,
|
||||
"Abschreibungen auf Sachanlagen (ohne AfA auf Kfz und Gebäude)": {
|
||||
"account_number": "4830",
|
||||
"account_type": "Accumulated Depreciation"
|
||||
"account_number": "4830",
|
||||
"account_type": "Accumulated Depreciation"
|
||||
},
|
||||
"Abschreibungen auf Gebäude": {
|
||||
"account_number": "4831",
|
||||
"account_type": "Depreciation"
|
||||
"account_number": "4831",
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"Abschreibungen auf Kfz": {
|
||||
"account_number": "4832",
|
||||
"account_type": "Depreciation"
|
||||
"account_number": "4832",
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"Sofortabschreibung GWG": {
|
||||
"account_number": "4855",
|
||||
"account_type": "Expense Account"
|
||||
"account_number": "4855",
|
||||
"account_type": "Expense Account"
|
||||
}
|
||||
},
|
||||
"Kfz-Kosten": {
|
||||
"is_group": 1,
|
||||
"Kfz-Steuer": {
|
||||
"account_number": "4510",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Kfz-Versicherungen": {
|
||||
"account_number": "4520",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"laufende Kfz-Betriebskosten": {
|
||||
"account_number": "4530",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Kfz-Reparaturen": {
|
||||
"account_number": "4540",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Fremdfahrzeuge": {
|
||||
"account_number": "4570",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"sonstige Kfz-Kosten": {
|
||||
"account_number": "4580",
|
||||
"account_type": "Expense Account"
|
||||
}
|
||||
},
|
||||
"Personalkosten": {
|
||||
"is_group": 1,
|
||||
"Gehälter": {
|
||||
"account_number": "4120",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"gesetzliche soziale Aufwendungen": {
|
||||
"account_number": "4130",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Aufwendungen für Altersvorsorge": {
|
||||
"account_number": "4165",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Vermögenswirksame Leistungen": {
|
||||
"account_number": "4170",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Aushilfslöhne": {
|
||||
"account_number": "4190",
|
||||
"account_type": "Expense Account"
|
||||
}
|
||||
},
|
||||
"Raumkosten": {
|
||||
"is_group": 1,
|
||||
"Miete und Nebenkosten": {
|
||||
"account_number": "4210",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Gas, Wasser, Strom (Verwaltung, Vertrieb)": {
|
||||
"account_number": "4240",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Reinigung": {
|
||||
"account_number": "4250",
|
||||
"account_type": "Expense Account"
|
||||
}
|
||||
},
|
||||
"Reparatur/Instandhaltung": {
|
||||
"is_group": 1,
|
||||
"Reparaturen und Instandhaltungen von anderen Anlagen und Betriebs- und Geschäftsausstattung": {
|
||||
"account_number": "4805",
|
||||
"account_type": "Expense Account"
|
||||
}
|
||||
},
|
||||
"Versicherungsbeiträge": {
|
||||
"is_group": 1,
|
||||
"Versicherungen": {
|
||||
"account_number": "4360",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Beiträge": {
|
||||
"account_number": "4380",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"sonstige Ausgaben": {
|
||||
"account_number": "4390",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"steuerlich abzugsfähige Verspätungszuschläge und Zwangsgelder": {
|
||||
"account_number": "4396",
|
||||
"account_type": "Expense Account"
|
||||
}
|
||||
},
|
||||
"Werbe-/Reisekosten": {
|
||||
"is_group": 1,
|
||||
"Werbekosten": {
|
||||
"account_number": "4610",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Aufmerksamkeiten": {
|
||||
"account_number": "4653",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"nicht abzugsfähige Betriebsausg. aus Werbe-, Repräs.- u. Reisekosten": {
|
||||
"account_number": "4665",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Reisekosten Unternehmer": {
|
||||
"account_number": "4670",
|
||||
"account_type": "Expense Account"
|
||||
}
|
||||
},
|
||||
"verschiedene Kosten": {
|
||||
"is_group": 1,
|
||||
"Porto": {
|
||||
"account_number": "4910",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Telekom": {
|
||||
"account_number": "4920",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Mobilfunk D2": {
|
||||
"account_number": "4921",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Internet": {
|
||||
"account_number": "4922",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Bürobedarf": {
|
||||
"account_number": "4930",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Zeitschriften, Bücher": {
|
||||
"account_number": "4940",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Fortbildungskosten": {
|
||||
"account_number": "4945",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Buchführungskosten": {
|
||||
"account_number": "4955",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Abschluß- u. Prüfungskosten": {
|
||||
"account_number": "4957",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Nebenkosten des Geldverkehrs": {
|
||||
"account_number": "4970",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Werkzeuge und Kleingeräte": {
|
||||
"account_number": "4985",
|
||||
"account_type": "Expense Account"
|
||||
}
|
||||
},
|
||||
"Zinsaufwendungen": {
|
||||
"is_group": 1,
|
||||
"Zinsaufwendungen für kurzfristige Verbindlichkeiten": {
|
||||
"account_number": "2110",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Zinsaufwendungen für KFZ Finanzierung": {
|
||||
"account_number": "2121",
|
||||
"account_type": "Expense Account"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Anfangsbestand 9": {
|
||||
"is_group": 1,
|
||||
"root_type": "Equity",
|
||||
"Saldenvortragskonten": {
|
||||
"is_group": 1,
|
||||
"Saldenvortrag Sachkonten": {
|
||||
"account_number": "9000"
|
||||
},
|
||||
"Saldenvorträge Debitoren": {
|
||||
"account_number": "9008"
|
||||
},
|
||||
"Saldenvorträge Kreditoren": {
|
||||
"account_number": "9009"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Privatkonten 1": {
|
||||
"is_group": 1,
|
||||
"root_type": "Equity",
|
||||
"Privatentnahmen/-einlagen": {
|
||||
"is_group": 1,
|
||||
"Privatentnahme allgemein": {
|
||||
"account_number": "1800"
|
||||
},
|
||||
"Privatsteuern": {
|
||||
"account_number": "1810"
|
||||
},
|
||||
"Sonderausgaben beschränkt abzugsfähig": {
|
||||
"account_number": "1820"
|
||||
},
|
||||
"Sonderausgaben unbeschränkt abzugsfähig": {
|
||||
"account_number": "1830"
|
||||
},
|
||||
"Außergewöhnliche Belastungen": {
|
||||
"account_number": "1850"
|
||||
},
|
||||
"Privateinlagen": {
|
||||
"account_number": "1890"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Kfz-Kosten": {
|
||||
"is_group": 1,
|
||||
"Kfz-Steuer": {
|
||||
"account_number": "4510",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Kfz-Versicherungen": {
|
||||
"account_number": "4520",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"laufende Kfz-Betriebskosten": {
|
||||
"account_number": "4530",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Kfz-Reparaturen": {
|
||||
"account_number": "4540",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Fremdfahrzeuge": {
|
||||
"account_number": "4570",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"sonstige Kfz-Kosten": {
|
||||
"account_number": "4580",
|
||||
"account_type": "Expense Account"
|
||||
}
|
||||
},
|
||||
"Personalkosten": {
|
||||
"is_group": 1,
|
||||
"Geh\u00e4lter": {
|
||||
"account_number": "4120",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"gesetzliche soziale Aufwendungen": {
|
||||
"account_number": "4130",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Aufwendungen f\u00fcr Altersvorsorge": {
|
||||
"account_number": "4165",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Verm\u00f6genswirksame Leistungen": {
|
||||
"account_number": "4170",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Aushilfsl\u00f6hne": {
|
||||
"account_number": "4190",
|
||||
"account_type": "Expense Account"
|
||||
}
|
||||
},
|
||||
"Raumkosten": {
|
||||
"is_group": 1,
|
||||
"Miete und Nebenkosten": {
|
||||
"account_number": "4210",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Gas, Wasser, Strom (Verwaltung, Vertrieb)": {
|
||||
"account_number": "4240",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Reinigung": {
|
||||
"account_number": "4250",
|
||||
"account_type": "Expense Account"
|
||||
}
|
||||
},
|
||||
"Reparatur/Instandhaltung": {
|
||||
"is_group": 1,
|
||||
"Reparatur u. Instandh. von Anlagen/Maschinen u. Betriebs- u. Gesch\u00e4ftsausst.": {
|
||||
"account_number": "4805",
|
||||
"account_type": "Expense Account"
|
||||
}
|
||||
},
|
||||
"Versicherungsbeitr\u00e4ge": {
|
||||
"is_group": 1,
|
||||
"Versicherungen": {
|
||||
"account_number": "4360",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Beitr\u00e4ge": {
|
||||
"account_number": "4380",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"sonstige Ausgaben": {
|
||||
"account_number": "4390",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"steuerlich abzugsf\u00e4hige Versp\u00e4tungszuschl\u00e4ge und Zwangsgelder": {
|
||||
"account_number": "4396",
|
||||
"account_type": "Expense Account"
|
||||
}
|
||||
},
|
||||
"Werbe-/Reisekosten": {
|
||||
"is_group": 1,
|
||||
"Werbekosten": {
|
||||
"account_number": "4610",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Aufmerksamkeiten": {
|
||||
"account_number": "4653",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"nicht abzugsf\u00e4hige Betriebsausg. aus Werbe-, Repr\u00e4s.- u. Reisekosten": {
|
||||
"account_number": "4665",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Reisekosten Unternehmer": {
|
||||
"account_number": "4670",
|
||||
"account_type": "Expense Account"
|
||||
}
|
||||
},
|
||||
"verschiedene Kosten": {
|
||||
"is_group": 1,
|
||||
"Porto": {
|
||||
"account_number": "4910",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Telekom": {
|
||||
"account_number": "4920",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Mobilfunk D2": {
|
||||
"account_number": "4921",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Internet": {
|
||||
"account_number": "4922",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"B\u00fcrobedarf": {
|
||||
"account_number": "4930",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Zeitschriften, B\u00fccher": {
|
||||
"account_number": "4940",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Fortbildungskosten": {
|
||||
"account_number": "4945",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Buchf\u00fchrungskosten": {
|
||||
"account_number": "4955",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Abschlu\u00df- u. Pr\u00fcfungskosten": {
|
||||
"account_number": "4957",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Nebenkosten des Geldverkehrs": {
|
||||
"account_number": "4970",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Werkzeuge und Kleinger\u00e4te": {
|
||||
"account_number": "4985",
|
||||
"account_type": "Expense Account"
|
||||
}
|
||||
},
|
||||
"Zinsaufwendungen": {
|
||||
"is_group": 1,
|
||||
"Zinsaufwendungen f\u00fcr kurzfristige Verbindlichkeiten": {
|
||||
"account_number": "2110",
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
"Zinsaufwendungen f\u00fcr KFZ Finanzierung": {
|
||||
"account_number": "2121",
|
||||
"account_type": "Expense Account"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Anfangsbestand 9": {
|
||||
"is_group": 1,
|
||||
"root_type": "Equity",
|
||||
"Saldenvortragskonten": {
|
||||
"is_group": 1,
|
||||
"Saldenvortrag Sachkonten": {
|
||||
"account_number": "9000"
|
||||
},
|
||||
"Saldenvortr\u00e4ge Debitoren": {
|
||||
"account_number": "9008"
|
||||
},
|
||||
"Saldenvortr\u00e4ge Kreditoren": {
|
||||
"account_number": "9009"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Privatkonten 1": {
|
||||
"is_group": 1,
|
||||
"root_type": "Equity",
|
||||
"Privatentnahmen/-einlagen": {
|
||||
"is_group": 1,
|
||||
"Privatentnahme allgemein": {
|
||||
"account_number": "1800"
|
||||
},
|
||||
"Privatsteuern": {
|
||||
"account_number": "1810"
|
||||
},
|
||||
"Sonderausgaben beschr\u00e4nkt abzugsf\u00e4hig": {
|
||||
"account_number": "1820"
|
||||
},
|
||||
"Sonderausgaben unbeschr\u00e4nkt abzugsf\u00e4hig": {
|
||||
"account_number": "1830"
|
||||
},
|
||||
"Au\u00dfergew\u00f6hnliche Belastungen": {
|
||||
"account_number": "1850"
|
||||
},
|
||||
"Privateinlagen": {
|
||||
"account_number": "1890"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,10 +407,13 @@
|
||||
"Bewertungskorrektur zu Forderungen aus Lieferungen und Leistungen": {
|
||||
"account_number": "9960"
|
||||
},
|
||||
"Forderungen aus Lieferungen und Leistungen mit Kontokorrent": {
|
||||
"Debitoren": {
|
||||
"is_group": 1,
|
||||
"account_number": "10000"
|
||||
},
|
||||
"Forderungen aus Lieferungen und Leistungen": {
|
||||
"account_number": "1200",
|
||||
"account_type": "Receivable",
|
||||
"is_group": 1
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"Forderungen aus Lieferungen und Leistungen ohne Kontokorrent": {
|
||||
"account_number": "1210"
|
||||
@@ -1135,15 +1138,18 @@
|
||||
"Bewertungskorrektur zu Verb. aus Lieferungen und Leistungen": {
|
||||
"account_number": "9964"
|
||||
},
|
||||
"Verb. aus Lieferungen und Leistungen mit Kontokorrent": {
|
||||
"account_number": "3300",
|
||||
"account_type": "Payable",
|
||||
"Kreditoren": {
|
||||
"account_number": "70000",
|
||||
"is_group": 1,
|
||||
"Wareneingangs-Verrechnungskonto" : {
|
||||
"Wareneingangs-Verrechnungskonto" : {
|
||||
"account_number": "70001",
|
||||
"account_type": "Stock Received But Not Billed"
|
||||
}
|
||||
},
|
||||
"Verb. aus Lieferungen und Leistungen": {
|
||||
"account_number": "3300",
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"Verb. aus Lieferungen und Leistungen ohne Kontokorrent": {
|
||||
"account_number": "3310"
|
||||
},
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -69,7 +69,8 @@
|
||||
"Persediaan Barang": {
|
||||
"Persediaan Barang": {
|
||||
"account_number": "1141.000",
|
||||
"account_type": "Stock"
|
||||
"account_type": "Stock",
|
||||
"is_group": 1
|
||||
},
|
||||
"Uang Muka Pembelian": {
|
||||
"Uang Muka Pembelian": {
|
||||
@@ -669,8 +670,7 @@
|
||||
},
|
||||
"Penjualan Barang Dagangan": {
|
||||
"Penjualan": {
|
||||
"account_number": "4110.000",
|
||||
"account_type": "Income Account"
|
||||
"account_number": "4110.000"
|
||||
},
|
||||
"Potongan Penjualan": {
|
||||
"account_number": "4130.000"
|
||||
|
||||
@@ -109,7 +109,8 @@
|
||||
}
|
||||
},
|
||||
"INVENTARIOS": {
|
||||
"account_type": "Stock"
|
||||
"account_type": "Stock",
|
||||
"is_group": 1
|
||||
}
|
||||
},
|
||||
"ACTIVO LARGO PLAZO": {
|
||||
@@ -397,18 +398,10 @@
|
||||
"INGRESOS POR SERVICIOS 1": {}
|
||||
},
|
||||
"VENTAS": {
|
||||
"VENTAS EXPORTACION": {
|
||||
"account_type": "Income Account"
|
||||
},
|
||||
"VENTAS INMUEBLES": {
|
||||
"account_type": "Income Account"
|
||||
},
|
||||
"VENTAS NACIONALES": {
|
||||
"account_type": "Income Account"
|
||||
},
|
||||
"VENTAS NACIONALES AL DETAL": {
|
||||
"account_type": "Income Account"
|
||||
}
|
||||
"VENTAS EXPORTACION": {},
|
||||
"VENTAS INMUEBLES": {},
|
||||
"VENTAS NACIONALES": {},
|
||||
"VENTAS NACIONALES AL DETAL": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -2,13 +2,75 @@
|
||||
"country_code": "nl",
|
||||
"name": "Netherlands - Grootboekschema",
|
||||
"tree": {
|
||||
"FABRIKAGEREKENINGEN": {
|
||||
"is_group": 1,
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"FINANCIELE REKENINGEN, KORTLOPENDE VORDERINGEN EN SCHULDEN": {
|
||||
"Bank": {
|
||||
"RABO Bank": {
|
||||
"account_type": "Bank"
|
||||
},
|
||||
"account_type": "Bank"
|
||||
},
|
||||
},
|
||||
"KORTLOPENDE SCHULDEN": {
|
||||
"Af te dragen Btw-verlegd": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Afdracht loonheffing": {},
|
||||
"Btw af te dragen hoog": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Btw af te dragen laag": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Btw af te dragen overig": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Btw oude jaren": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Btw te vorderen hoog": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Btw te vorderen laag": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Btw te vorderen overig": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Btw-afdracht": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Crediteuren": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"Dividend": {},
|
||||
"Dividendbelasting": {},
|
||||
"Energiekosten 1": {},
|
||||
"Investeringsaftrek": {},
|
||||
"Loonheffing": {},
|
||||
"Overige te betalen posten": {},
|
||||
"Pensioenpremies 1": {},
|
||||
"Premie WIR": {},
|
||||
"Rekening-courant inkoopvereniging": {},
|
||||
"Rente": {},
|
||||
"Sociale lasten 1": {},
|
||||
"Stock Recieved niet gefactureerd": {
|
||||
"account_type": "Stock Received But Not Billed"
|
||||
},
|
||||
"Tanti\u00e8mes 1": {},
|
||||
"Te vorderen Btw-verlegd": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Telefoon/telefax 1": {},
|
||||
"Termijnen onderh. werk": {},
|
||||
"Vakantiedagen": {},
|
||||
"Vakantiegeld 1": {},
|
||||
"Vakantiezegels": {},
|
||||
"Vennootschapsbelasting": {},
|
||||
"Vooruit ontvangen bedr.": {}
|
||||
},
|
||||
"LIQUIDE MIDDELEN": {
|
||||
"ABN-AMRO bank": {},
|
||||
"Bankbetaalkaarten": {},
|
||||
@@ -29,110 +91,6 @@
|
||||
},
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"TUSSENREKENINGEN": {
|
||||
"Betaalwijze cadeaubonnen": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Betaalwijze chipknip": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Betaalwijze contant": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Betaalwijze pin": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen Nederland hoog": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen Nederland laag": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen Nederland onbelast": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen Nederland overig": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen Nederland verlegd": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen binnen EU hoog": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen binnen EU laag": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen binnen EU overig": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen buiten EU hoog": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen buiten EU laag": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen buiten EU overig": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Kassa 1": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Kassa 2": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Netto lonen": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Tegenrekening Inkopen": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Tussenrek. autom. betalingen": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Tussenrek. autom. loonbetalingen": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Tussenrek. cadeaubonbetalingen": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Tussenrekening balans": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Tussenrekening chipknip": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Tussenrekening correcties": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Tussenrekening pin": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Vraagposten": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"VOORRAAD GRONDSTOFFEN, HULPMATERIALEN EN HANDELSGOEDEREN": {
|
||||
"Emballage": {},
|
||||
"Gereed product 1": {},
|
||||
"Gereed product 2": {},
|
||||
"Goederen 1": {},
|
||||
"Goederen 2": {},
|
||||
"Goederen in consignatie": {},
|
||||
"Goederen onderweg": {},
|
||||
"Grondstoffen 1": {},
|
||||
"Grondstoffen 2": {},
|
||||
"Halffabrikaten 1": {},
|
||||
"Halffabrikaten 2": {},
|
||||
"Hulpstoffen 1": {},
|
||||
"Hulpstoffen 2": {},
|
||||
"Kantoorbenodigdheden": {},
|
||||
"Onderhanden werk": {},
|
||||
"Verpakkingsmateriaal": {},
|
||||
"Zegels": {},
|
||||
"root_type": "Asset"
|
||||
},
|
||||
"root_type": "Asset"
|
||||
},
|
||||
"VORDERINGEN": {
|
||||
"Debiteuren": {
|
||||
"account_type": "Receivable"
|
||||
@@ -146,299 +104,278 @@
|
||||
"Voorziening dubieuze debiteuren": {}
|
||||
},
|
||||
"root_type": "Asset"
|
||||
},
|
||||
"KORTLOPENDE SCHULDEN": {
|
||||
"Af te dragen Btw-verlegd": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Afdracht loonheffing": {},
|
||||
"Btw af te dragen hoog": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Btw af te dragen laag": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Btw af te dragen overig": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Btw oude jaren": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Btw te vorderen hoog": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Btw te vorderen laag": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Btw te vorderen overig": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Btw-afdracht": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Crediteuren": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"Dividend": {},
|
||||
"Dividendbelasting": {},
|
||||
"Energiekosten 1": {},
|
||||
"Investeringsaftrek": {},
|
||||
"Loonheffing": {},
|
||||
"Overige te betalen posten": {},
|
||||
"Pensioenpremies 1": {},
|
||||
"Premie WIR": {},
|
||||
"Rekening-courant inkoopvereniging": {},
|
||||
"Rente": {},
|
||||
"Sociale lasten 1": {},
|
||||
"Stock Recieved niet gefactureerd": {
|
||||
"account_type": "Stock Received But Not Billed"
|
||||
},
|
||||
"Tanti\u00e8mes 1": {},
|
||||
"Te vorderen Btw-verlegd": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Telefoon/telefax 1": {},
|
||||
"Termijnen onderh. werk": {},
|
||||
"Vakantiedagen": {},
|
||||
"Vakantiegeld 1": {},
|
||||
"Vakantiezegels": {},
|
||||
"Vennootschapsbelasting": {},
|
||||
"Vooruit ontvangen bedr.": {},
|
||||
"is_group": 1,
|
||||
"root_type": "Liability"
|
||||
},
|
||||
"FABRIKAGEREKENINGEN": {
|
||||
},
|
||||
"INDIRECTE KOSTEN": {
|
||||
"is_group": 1,
|
||||
"root_type": "Expense",
|
||||
"INDIRECTE KOSTEN": {
|
||||
"is_group": 1,
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"KOSTENREKENINGEN": {
|
||||
"AFSCHRIJVINGEN": {
|
||||
"Aanhangwagens": {},
|
||||
"Aankoopkosten": {},
|
||||
"Aanloopkosten": {},
|
||||
"Auteursrechten": {},
|
||||
"Bedrijfsgebouwen": {},
|
||||
"Bedrijfsinventaris": {
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"Drankvergunningen": {},
|
||||
"Fabrieksinventaris": {
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"Gebouwen": {},
|
||||
"Gereedschappen": {},
|
||||
"Goodwill": {},
|
||||
"Grondverbetering": {},
|
||||
"Heftrucks": {},
|
||||
"Kantine-inventaris": {},
|
||||
"Kantoorinventaris": {
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"Kantoormachines": {},
|
||||
"Licenties": {},
|
||||
"Machines 1": {},
|
||||
"Magazijninventaris": {},
|
||||
"Octrooien": {},
|
||||
"Ontwikkelingskosten": {},
|
||||
"Pachtersinvestering": {},
|
||||
"Parkeerplaats": {},
|
||||
"Personenauto's": {
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"Rijwielen en bromfietsen": {},
|
||||
"Tonnagevergunningen": {},
|
||||
"Verbouwingen": {},
|
||||
"Vergunningen": {},
|
||||
"Voorraadverschillen": {},
|
||||
"Vrachtauto's": {},
|
||||
"Winkels": {},
|
||||
"Woon-winkelhuis": {},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"KOSTENREKENINGEN": {
|
||||
"AFSCHRIJVINGEN": {
|
||||
"Aanhangwagens": {},
|
||||
"Aankoopkosten": {},
|
||||
"Aanloopkosten": {},
|
||||
"Auteursrechten": {},
|
||||
"Bedrijfsgebouwen": {},
|
||||
"Bedrijfsinventaris": {
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"ALGEMENE KOSTEN": {
|
||||
"Accountantskosten": {},
|
||||
"Advieskosten": {},
|
||||
"Assuranties 1": {},
|
||||
"Bankkosten": {},
|
||||
"Juridische kosten": {},
|
||||
"Overige algemene kosten": {},
|
||||
"Toev. Ass. eigen risico": {}
|
||||
"Drankvergunningen": {},
|
||||
"Fabrieksinventaris": {
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"BEDRIJFSKOSTEN": {
|
||||
"Assuranties 2": {},
|
||||
"Energie (krachtstroom)": {},
|
||||
"Gereedschappen 1": {},
|
||||
"Hulpmaterialen 1": {},
|
||||
"Huur inventaris": {},
|
||||
"Huur machines": {},
|
||||
"Leasing invent.operational": {},
|
||||
"Leasing mach. operational": {},
|
||||
"Onderhoud inventaris": {},
|
||||
"Onderhoud machines": {},
|
||||
"Ophalen/vervoer afval": {},
|
||||
"Overige bedrijfskosten": {}
|
||||
"Gebouwen": {},
|
||||
"Gereedschappen": {},
|
||||
"Goodwill": {},
|
||||
"Grondverbetering": {},
|
||||
"Heftrucks": {},
|
||||
"Kantine-inventaris": {},
|
||||
"Kantoorinventaris": {
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"FINANCIERINGSKOSTEN 1": {
|
||||
"Overige rentebaten": {},
|
||||
"Overige rentelasten": {},
|
||||
"Rente bankkrediet": {},
|
||||
"Rente huurkoopcontracten": {},
|
||||
"Rente hypotheek": {},
|
||||
"Rente leasecontracten": {},
|
||||
"Rente lening o/g": {},
|
||||
"Rente lening u/g": {}
|
||||
"Kantoormachines": {},
|
||||
"Licenties": {},
|
||||
"Machines 1": {},
|
||||
"Magazijninventaris": {},
|
||||
"Octrooien": {},
|
||||
"Ontwikkelingskosten": {},
|
||||
"Pachtersinvestering": {},
|
||||
"Parkeerplaats": {},
|
||||
"Personenauto's": {
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"HUISVESTINGSKOSTEN": {
|
||||
"Assurantie onroerend goed": {},
|
||||
"Belastingen onr. Goed": {},
|
||||
"Energiekosten": {},
|
||||
"Groot onderhoud onr. Goed": {},
|
||||
"Huur": {},
|
||||
"Huurwaarde woongedeelte": {},
|
||||
"Onderhoud onroerend goed": {},
|
||||
"Ontvangen huren": {},
|
||||
"Overige huisvestingskosten": {},
|
||||
"Pacht": {},
|
||||
"Schoonmaakkosten": {},
|
||||
"Toevoeging egalisatieres. Groot onderhoud": {}
|
||||
},
|
||||
"KANTOORKOSTEN": {
|
||||
"Administratiekosten": {},
|
||||
"Contributies/abonnementen": {},
|
||||
"Huur kantoorapparatuur": {},
|
||||
"Internetaansluiting": {},
|
||||
"Kantoorbenodigdh./drukw.": {},
|
||||
"Onderhoud kantoorinvent.": {},
|
||||
"Overige kantoorkosten": {},
|
||||
"Porti": {},
|
||||
"Telefoon/telefax": {}
|
||||
},
|
||||
"OVERIGE BATEN EN LASTEN": {
|
||||
"Betaalde schadevergoed.": {},
|
||||
"Boekverlies vaste activa": {},
|
||||
"Boekwinst van vaste activa": {},
|
||||
"K.O. regeling OB": {},
|
||||
"Kasverschillen": {},
|
||||
"Kosten loonbelasting": {},
|
||||
"Kosten omzetbelasting": {},
|
||||
"Nadelige koersverschillen": {},
|
||||
"Naheffing bedrijfsver.": {},
|
||||
"Ontvangen schadevergoed.": {},
|
||||
"Overige baten": {},
|
||||
"Overige lasten": {},
|
||||
"Voordelige koersverschil.": {}
|
||||
},
|
||||
"PERSONEELSKOSTEN": {
|
||||
"Autokostenvergoeding": {},
|
||||
"Bedrijfskleding": {},
|
||||
"Belastingvrije uitkeringen": {},
|
||||
"Bijzondere beloningen": {},
|
||||
"Congressen, seminars en symposia": {},
|
||||
"Gereedschapsgeld": {},
|
||||
"Geschenken personeel": {},
|
||||
"Gratificaties": {},
|
||||
"Inhouding pensioenpremies": {},
|
||||
"Inhouding sociale lasten": {},
|
||||
"Kantinekosten": {},
|
||||
"Lonen en salarissen": {},
|
||||
"Loonwerk": {},
|
||||
"Managementvergoedingen": {},
|
||||
"Opleidingskosten": {},
|
||||
"Oprenting stamrechtverpl.": {},
|
||||
"Overhevelingstoeslag": {},
|
||||
"Overige kostenverg.": {},
|
||||
"Overige personeelskosten": {},
|
||||
"Overige uitkeringen": {},
|
||||
"Pensioenpremies": {},
|
||||
"Provisie 1": {},
|
||||
"Reiskosten": {},
|
||||
"Rijwielvergoeding": {},
|
||||
"Sociale lasten": {},
|
||||
"Tanti\u00e8mes": {},
|
||||
"Thuiswerkers": {},
|
||||
"Toev. Backservice pens.verpl.": {},
|
||||
"Toevoeging pensioenverpl.": {},
|
||||
"Uitkering ziekengeld": {},
|
||||
"Uitzendkrachten": {},
|
||||
"Vakantiebonnen": {},
|
||||
"Vakantiegeld": {},
|
||||
"Vergoeding studiekosten": {},
|
||||
"Wervingskosten personeel": {}
|
||||
},
|
||||
"VERKOOPKOSTEN": {
|
||||
"Advertenties": {},
|
||||
"Afschrijving dubieuze deb.": {},
|
||||
"Beurskosten": {},
|
||||
"Etalagekosten": {},
|
||||
"Exportkosten": {},
|
||||
"Kascorrecties": {},
|
||||
"Overige verkoopkosten": {},
|
||||
"Provisie": {},
|
||||
"Reclame": {},
|
||||
"Reis en verblijfkosten": {},
|
||||
"Relatiegeschenken": {},
|
||||
"Representatiekosten": {},
|
||||
"Uitgaande vrachten": {},
|
||||
"Veilingkosten": {},
|
||||
"Verpakkingsmateriaal 1": {},
|
||||
"Websitekosten": {}
|
||||
},
|
||||
"VERVOERSKOSTEN": {
|
||||
"Assuranties auto's": {},
|
||||
"Brandstoffen": {},
|
||||
"Leasing auto's": {},
|
||||
"Onderhoud personenauto's": {},
|
||||
"Onderhoud vrachtauto's": {},
|
||||
"Overige vervoerskosten": {},
|
||||
"Priv\u00e9-gebruik auto's": {},
|
||||
"Wegenbelasting": {}
|
||||
},
|
||||
"VOORRAAD GEREED PRODUCT EN ONDERHANDEN WERK": {
|
||||
"Betalingskort. crediteuren": {},
|
||||
"Garantiekosten": {},
|
||||
"Hulpmaterialen": {},
|
||||
"Inkomende vrachten": {
|
||||
"account_type": "Expenses Included In Valuation"
|
||||
},
|
||||
"Inkoop import buiten EU hoog": {},
|
||||
"Inkoop import buiten EU laag": {},
|
||||
"Inkoop import buiten EU overig": {},
|
||||
"Inkoopbonussen": {},
|
||||
"Inkoopkosten": {},
|
||||
"Inkoopprovisie": {},
|
||||
"Inkopen BTW verlegd": {},
|
||||
"Inkopen EU hoog tarief": {},
|
||||
"Inkopen EU laag tarief": {},
|
||||
"Inkopen EU overig": {},
|
||||
"Inkopen hoog": {},
|
||||
"Inkopen laag": {},
|
||||
"Inkopen nul": {},
|
||||
"Inkopen overig": {},
|
||||
"Invoerkosten": {},
|
||||
"Kosten inkoopvereniging": {},
|
||||
"Kostprijs omzet grondstoffen": {
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"Kostprijs omzet handelsgoederen": {},
|
||||
"Onttrekking uitgev.garantie": {},
|
||||
"Priv\u00e9-gebruik goederen": {},
|
||||
"Stock aanpassing": {
|
||||
"account_type": "Stock Adjustment"
|
||||
},
|
||||
"Tegenrekening inkoop": {},
|
||||
"Toev. Voorz. incour. grondst.": {},
|
||||
"Toevoeging garantieverpl.": {},
|
||||
"Toevoeging voorz. incour. handelsgoed.": {},
|
||||
"Uitbesteed werk": {},
|
||||
"Voorz. Incourourant grondst.": {},
|
||||
"Voorz.incour. handelsgoed.": {},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"root_type": "Expense"
|
||||
}
|
||||
"Rijwielen en bromfietsen": {},
|
||||
"Tonnagevergunningen": {},
|
||||
"Verbouwingen": {},
|
||||
"Vergunningen": {},
|
||||
"Voorraadverschillen": {},
|
||||
"Vrachtauto's": {},
|
||||
"Winkels": {},
|
||||
"Woon-winkelhuis": {},
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"ALGEMENE KOSTEN": {
|
||||
"Accountantskosten": {},
|
||||
"Advieskosten": {},
|
||||
"Assuranties 1": {},
|
||||
"Bankkosten": {},
|
||||
"Juridische kosten": {},
|
||||
"Overige algemene kosten": {},
|
||||
"Toev. Ass. eigen risico": {}
|
||||
},
|
||||
"BEDRIJFSKOSTEN": {
|
||||
"Assuranties 2": {},
|
||||
"Energie (krachtstroom)": {},
|
||||
"Gereedschappen 1": {},
|
||||
"Hulpmaterialen 1": {},
|
||||
"Huur inventaris": {},
|
||||
"Huur machines": {},
|
||||
"Leasing invent.operational": {},
|
||||
"Leasing mach. operational": {},
|
||||
"Onderhoud inventaris": {},
|
||||
"Onderhoud machines": {},
|
||||
"Ophalen/vervoer afval": {},
|
||||
"Overige bedrijfskosten": {}
|
||||
},
|
||||
"FINANCIERINGSKOSTEN 1": {
|
||||
"Overige rentebaten": {},
|
||||
"Overige rentelasten": {},
|
||||
"Rente bankkrediet": {},
|
||||
"Rente huurkoopcontracten": {},
|
||||
"Rente hypotheek": {},
|
||||
"Rente leasecontracten": {},
|
||||
"Rente lening o/g": {},
|
||||
"Rente lening u/g": {}
|
||||
},
|
||||
"HUISVESTINGSKOSTEN": {
|
||||
"Assurantie onroerend goed": {},
|
||||
"Belastingen onr. Goed": {},
|
||||
"Energiekosten": {},
|
||||
"Groot onderhoud onr. Goed": {},
|
||||
"Huur": {},
|
||||
"Huurwaarde woongedeelte": {},
|
||||
"Onderhoud onroerend goed": {},
|
||||
"Ontvangen huren": {},
|
||||
"Overige huisvestingskosten": {},
|
||||
"Pacht": {},
|
||||
"Schoonmaakkosten": {},
|
||||
"Toevoeging egalisatieres. Groot onderhoud": {}
|
||||
},
|
||||
"KANTOORKOSTEN": {
|
||||
"Administratiekosten": {},
|
||||
"Contributies/abonnementen": {},
|
||||
"Huur kantoorapparatuur": {},
|
||||
"Internetaansluiting": {},
|
||||
"Kantoorbenodigdh./drukw.": {},
|
||||
"Onderhoud kantoorinvent.": {},
|
||||
"Overige kantoorkosten": {},
|
||||
"Porti": {},
|
||||
"Telefoon/telefax": {}
|
||||
},
|
||||
"OVERIGE BATEN EN LASTEN": {
|
||||
"Betaalde schadevergoed.": {},
|
||||
"Boekverlies vaste activa": {},
|
||||
"Boekwinst van vaste activa": {},
|
||||
"K.O. regeling OB": {},
|
||||
"Kasverschillen": {},
|
||||
"Kosten loonbelasting": {},
|
||||
"Kosten omzetbelasting": {},
|
||||
"Nadelige koersverschillen": {},
|
||||
"Naheffing bedrijfsver.": {},
|
||||
"Ontvangen schadevergoed.": {},
|
||||
"Overige baten": {},
|
||||
"Overige lasten": {},
|
||||
"Voordelige koersverschil.": {}
|
||||
},
|
||||
"PERSONEELSKOSTEN": {
|
||||
"Autokostenvergoeding": {},
|
||||
"Bedrijfskleding": {},
|
||||
"Belastingvrije uitkeringen": {},
|
||||
"Bijzondere beloningen": {},
|
||||
"Congressen, seminars en symposia": {},
|
||||
"Gereedschapsgeld": {},
|
||||
"Geschenken personeel": {},
|
||||
"Gratificaties": {},
|
||||
"Inhouding pensioenpremies": {},
|
||||
"Inhouding sociale lasten": {},
|
||||
"Kantinekosten": {},
|
||||
"Lonen en salarissen": {},
|
||||
"Loonwerk": {},
|
||||
"Managementvergoedingen": {},
|
||||
"Opleidingskosten": {},
|
||||
"Oprenting stamrechtverpl.": {},
|
||||
"Overhevelingstoeslag": {},
|
||||
"Overige kostenverg.": {},
|
||||
"Overige personeelskosten": {},
|
||||
"Overige uitkeringen": {},
|
||||
"Pensioenpremies": {},
|
||||
"Provisie 1": {},
|
||||
"Reiskosten": {},
|
||||
"Rijwielvergoeding": {},
|
||||
"Sociale lasten": {},
|
||||
"Tanti\u00e8mes": {},
|
||||
"Thuiswerkers": {},
|
||||
"Toev. Backservice pens.verpl.": {},
|
||||
"Toevoeging pensioenverpl.": {},
|
||||
"Uitkering ziekengeld": {},
|
||||
"Uitzendkrachten": {},
|
||||
"Vakantiebonnen": {},
|
||||
"Vakantiegeld": {},
|
||||
"Vergoeding studiekosten": {},
|
||||
"Wervingskosten personeel": {}
|
||||
},
|
||||
"VERKOOPKOSTEN": {
|
||||
"Advertenties": {},
|
||||
"Afschrijving dubieuze deb.": {},
|
||||
"Beurskosten": {},
|
||||
"Etalagekosten": {},
|
||||
"Exportkosten": {},
|
||||
"Kascorrecties": {},
|
||||
"Overige verkoopkosten": {},
|
||||
"Provisie": {},
|
||||
"Reclame": {},
|
||||
"Reis en verblijfkosten": {},
|
||||
"Relatiegeschenken": {},
|
||||
"Representatiekosten": {},
|
||||
"Uitgaande vrachten": {},
|
||||
"Veilingkosten": {},
|
||||
"Verpakkingsmateriaal 1": {},
|
||||
"Websitekosten": {}
|
||||
},
|
||||
"VERVOERSKOSTEN": {
|
||||
"Assuranties auto's": {},
|
||||
"Brandstoffen": {},
|
||||
"Leasing auto's": {},
|
||||
"Onderhoud personenauto's": {},
|
||||
"Onderhoud vrachtauto's": {},
|
||||
"Overige vervoerskosten": {},
|
||||
"Priv\u00e9-gebruik auto's": {},
|
||||
"Wegenbelasting": {}
|
||||
},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"TUSSENREKENINGEN": {
|
||||
"Betaalwijze cadeaubonnen": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Betaalwijze chipknip": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Betaalwijze contant": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Betaalwijze pin": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen Nederland hoog": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen Nederland laag": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen Nederland onbelast": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen Nederland overig": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen Nederland verlegd": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen binnen EU hoog": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen binnen EU laag": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen binnen EU overig": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen buiten EU hoog": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen buiten EU laag": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Inkopen buiten EU overig": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Kassa 1": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Kassa 2": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Netto lonen": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Tegenrekening Inkopen": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Tussenrek. autom. betalingen": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Tussenrek. autom. loonbetalingen": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Tussenrek. cadeaubonbetalingen": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Tussenrekening balans": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Tussenrekening chipknip": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Tussenrekening correcties": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Tussenrekening pin": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Vraagposten": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"root_type": "Asset"
|
||||
},
|
||||
"VASTE ACTIVA, EIGEN VERMOGEN, LANGLOPEND VREEMD VERMOGEN EN VOORZIENINGEN": {
|
||||
"EIGEN VERMOGEN": {
|
||||
@@ -665,7 +602,7 @@
|
||||
"account_type": "Equity"
|
||||
}
|
||||
},
|
||||
"root_type": "Equity"
|
||||
"root_type": "Asset"
|
||||
},
|
||||
"VERKOOPRESULTATEN": {
|
||||
"Diensten fabric. 0% niet-EU": {},
|
||||
@@ -690,6 +627,67 @@
|
||||
"Verleende Kredietbep. fabricage": {},
|
||||
"Verleende Kredietbep. handel": {},
|
||||
"root_type": "Income"
|
||||
},
|
||||
"VOORRAAD GEREED PRODUCT EN ONDERHANDEN WERK": {
|
||||
"Betalingskort. crediteuren": {},
|
||||
"Garantiekosten": {},
|
||||
"Hulpmaterialen": {},
|
||||
"Inkomende vrachten": {
|
||||
"account_type": "Expenses Included In Valuation"
|
||||
},
|
||||
"Inkoop import buiten EU hoog": {},
|
||||
"Inkoop import buiten EU laag": {},
|
||||
"Inkoop import buiten EU overig": {},
|
||||
"Inkoopbonussen": {},
|
||||
"Inkoopkosten": {},
|
||||
"Inkoopprovisie": {},
|
||||
"Inkopen BTW verlegd": {},
|
||||
"Inkopen EU hoog tarief": {},
|
||||
"Inkopen EU laag tarief": {},
|
||||
"Inkopen EU overig": {},
|
||||
"Inkopen hoog": {},
|
||||
"Inkopen laag": {},
|
||||
"Inkopen nul": {},
|
||||
"Inkopen overig": {},
|
||||
"Invoerkosten": {},
|
||||
"Kosten inkoopvereniging": {},
|
||||
"Kostprijs omzet grondstoffen": {
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"Kostprijs omzet handelsgoederen": {},
|
||||
"Onttrekking uitgev.garantie": {},
|
||||
"Priv\u00e9-gebruik goederen": {},
|
||||
"Stock aanpassing": {
|
||||
"account_type": "Stock Adjustment"
|
||||
},
|
||||
"Tegenrekening inkoop": {},
|
||||
"Toev. Voorz. incour. grondst.": {},
|
||||
"Toevoeging garantieverpl.": {},
|
||||
"Toevoeging voorz. incour. handelsgoed.": {},
|
||||
"Uitbesteed werk": {},
|
||||
"Voorz. Incourourant grondst.": {},
|
||||
"Voorz.incour. handelsgoed.": {},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"VOORRAAD GRONDSTOFFEN, HULPMATERIALEN EN HANDELSGOEDEREN": {
|
||||
"Emballage": {},
|
||||
"Gereed product 1": {},
|
||||
"Gereed product 2": {},
|
||||
"Goederen 1": {},
|
||||
"Goederen 2": {},
|
||||
"Goederen in consignatie": {},
|
||||
"Goederen onderweg": {},
|
||||
"Grondstoffen 1": {},
|
||||
"Grondstoffen 2": {},
|
||||
"Halffabrikaten 1": {},
|
||||
"Halffabrikaten 2": {},
|
||||
"Hulpstoffen 1": {},
|
||||
"Hulpstoffen 2": {},
|
||||
"Kantoorbenodigdheden": {},
|
||||
"Onderhanden werk": {},
|
||||
"Verpakkingsmateriaal": {},
|
||||
"Zegels": {},
|
||||
"root_type": "Asset"
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,18 +5,10 @@
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.test_runner import make_test_records
|
||||
from frappe.utils import nowdate
|
||||
|
||||
from erpnext.accounts.doctype.account.account import (
|
||||
InvalidAccountMergeError,
|
||||
merge_account,
|
||||
update_account_number,
|
||||
)
|
||||
from erpnext.accounts.doctype.account.account import merge_account, update_account_number
|
||||
from erpnext.stock import get_company_default_inventory_account, get_warehouse_account
|
||||
|
||||
test_dependencies = ["Company"]
|
||||
|
||||
|
||||
class TestAccount(unittest.TestCase):
|
||||
def test_rename_account(self):
|
||||
@@ -52,53 +44,49 @@ class TestAccount(unittest.TestCase):
|
||||
frappe.delete_doc("Account", "1211-11-4 - 6 - Debtors 1 - Test - - _TC")
|
||||
|
||||
def test_merge_account(self):
|
||||
create_account(
|
||||
account_name="Current Assets",
|
||||
is_group=1,
|
||||
parent_account="Application of Funds (Assets) - _TC",
|
||||
company="_Test Company",
|
||||
)
|
||||
|
||||
create_account(
|
||||
account_name="Securities and Deposits",
|
||||
is_group=1,
|
||||
parent_account="Current Assets - _TC",
|
||||
company="_Test Company",
|
||||
)
|
||||
|
||||
create_account(
|
||||
account_name="Earnest Money",
|
||||
parent_account="Securities and Deposits - _TC",
|
||||
company="_Test Company",
|
||||
)
|
||||
|
||||
create_account(
|
||||
account_name="Cash In Hand",
|
||||
is_group=1,
|
||||
parent_account="Current Assets - _TC",
|
||||
company="_Test Company",
|
||||
)
|
||||
|
||||
create_account(
|
||||
account_name="Receivable INR",
|
||||
parent_account="Current Assets - _TC",
|
||||
company="_Test Company",
|
||||
account_currency="INR",
|
||||
)
|
||||
|
||||
create_account(
|
||||
account_name="Receivable USD",
|
||||
parent_account="Current Assets - _TC",
|
||||
company="_Test Company",
|
||||
account_currency="USD",
|
||||
)
|
||||
if not frappe.db.exists("Account", "Current Assets - _TC"):
|
||||
acc = frappe.new_doc("Account")
|
||||
acc.account_name = "Current Assets"
|
||||
acc.is_group = 1
|
||||
acc.parent_account = "Application of Funds (Assets) - _TC"
|
||||
acc.company = "_Test Company"
|
||||
acc.insert()
|
||||
if not frappe.db.exists("Account", "Securities and Deposits - _TC"):
|
||||
acc = frappe.new_doc("Account")
|
||||
acc.account_name = "Securities and Deposits"
|
||||
acc.parent_account = "Current Assets - _TC"
|
||||
acc.is_group = 1
|
||||
acc.company = "_Test Company"
|
||||
acc.insert()
|
||||
if not frappe.db.exists("Account", "Earnest Money - _TC"):
|
||||
acc = frappe.new_doc("Account")
|
||||
acc.account_name = "Earnest Money"
|
||||
acc.parent_account = "Securities and Deposits - _TC"
|
||||
acc.company = "_Test Company"
|
||||
acc.insert()
|
||||
if not frappe.db.exists("Account", "Cash In Hand - _TC"):
|
||||
acc = frappe.new_doc("Account")
|
||||
acc.account_name = "Cash In Hand"
|
||||
acc.is_group = 1
|
||||
acc.parent_account = "Current Assets - _TC"
|
||||
acc.company = "_Test Company"
|
||||
acc.insert()
|
||||
if not frappe.db.exists("Account", "Accumulated Depreciation - _TC"):
|
||||
acc = frappe.new_doc("Account")
|
||||
acc.account_name = "Accumulated Depreciation"
|
||||
acc.parent_account = "Fixed Assets - _TC"
|
||||
acc.company = "_Test Company"
|
||||
acc.account_type = "Accumulated Depreciation"
|
||||
acc.insert()
|
||||
|
||||
doc = frappe.get_doc("Account", "Securities and Deposits - _TC")
|
||||
parent = frappe.db.get_value("Account", "Earnest Money - _TC", "parent_account")
|
||||
|
||||
self.assertEqual(parent, "Securities and Deposits - _TC")
|
||||
|
||||
merge_account("Securities and Deposits - _TC", "Cash In Hand - _TC")
|
||||
|
||||
merge_account(
|
||||
"Securities and Deposits - _TC", "Cash In Hand - _TC", doc.is_group, doc.root_type, doc.company
|
||||
)
|
||||
parent = frappe.db.get_value("Account", "Earnest Money - _TC", "parent_account")
|
||||
|
||||
# Parent account of the child account changes after merging
|
||||
@@ -107,28 +95,30 @@ class TestAccount(unittest.TestCase):
|
||||
# Old account doesn't exist after merging
|
||||
self.assertFalse(frappe.db.exists("Account", "Securities and Deposits - _TC"))
|
||||
|
||||
doc = frappe.get_doc("Account", "Current Assets - _TC")
|
||||
|
||||
# Raise error as is_group property doesn't match
|
||||
self.assertRaises(
|
||||
InvalidAccountMergeError,
|
||||
frappe.ValidationError,
|
||||
merge_account,
|
||||
"Current Assets - _TC",
|
||||
"Accumulated Depreciation - _TC",
|
||||
doc.is_group,
|
||||
doc.root_type,
|
||||
doc.company,
|
||||
)
|
||||
|
||||
doc = frappe.get_doc("Account", "Capital Stock - _TC")
|
||||
|
||||
# Raise error as root_type property doesn't match
|
||||
self.assertRaises(
|
||||
InvalidAccountMergeError,
|
||||
frappe.ValidationError,
|
||||
merge_account,
|
||||
"Capital Stock - _TC",
|
||||
"Softwares - _TC",
|
||||
)
|
||||
|
||||
# Raise error as currency doesn't match
|
||||
self.assertRaises(
|
||||
InvalidAccountMergeError,
|
||||
merge_account,
|
||||
"Receivable INR - _TC",
|
||||
"Receivable USD - _TC",
|
||||
doc.is_group,
|
||||
doc.root_type,
|
||||
doc.company,
|
||||
)
|
||||
|
||||
def test_account_sync(self):
|
||||
@@ -198,58 +188,6 @@ class TestAccount(unittest.TestCase):
|
||||
frappe.delete_doc("Account", "1234 - Test Rename Sync Account - _TC4")
|
||||
frappe.delete_doc("Account", "1234 - Test Rename Sync Account - _TC5")
|
||||
|
||||
def test_account_currency_sync(self):
|
||||
"""
|
||||
In a parent->child company setup, child should inherit parent account currency if explicitly specified.
|
||||
"""
|
||||
|
||||
make_test_records("Company")
|
||||
|
||||
frappe.local.flags.pop("ignore_root_company_validation", None)
|
||||
|
||||
def create_bank_account():
|
||||
acc = frappe.new_doc("Account")
|
||||
acc.account_name = "_Test Bank JPY"
|
||||
|
||||
acc.parent_account = "Temporary Accounts - _TC6"
|
||||
acc.company = "_Test Company 6"
|
||||
return acc
|
||||
|
||||
acc = create_bank_account()
|
||||
# Explicitly set currency
|
||||
acc.account_currency = "JPY"
|
||||
acc.insert()
|
||||
self.assertTrue(
|
||||
frappe.db.exists(
|
||||
{
|
||||
"doctype": "Account",
|
||||
"account_name": "_Test Bank JPY",
|
||||
"account_currency": "JPY",
|
||||
"company": "_Test Company 7",
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
frappe.delete_doc("Account", "_Test Bank JPY - _TC6")
|
||||
frappe.delete_doc("Account", "_Test Bank JPY - _TC7")
|
||||
|
||||
acc = create_bank_account()
|
||||
# default currency is used
|
||||
acc.insert()
|
||||
self.assertTrue(
|
||||
frappe.db.exists(
|
||||
{
|
||||
"doctype": "Account",
|
||||
"account_name": "_Test Bank JPY",
|
||||
"account_currency": "USD",
|
||||
"company": "_Test Company 7",
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
frappe.delete_doc("Account", "_Test Bank JPY - _TC6")
|
||||
frappe.delete_doc("Account", "_Test Bank JPY - _TC7")
|
||||
|
||||
def test_child_company_account_rename_sync(self):
|
||||
frappe.local.flags.pop("ignore_root_company_validation", None)
|
||||
|
||||
@@ -325,19 +263,6 @@ class TestAccount(unittest.TestCase):
|
||||
acc.account_currency = "USD"
|
||||
self.assertRaises(frappe.ValidationError, acc.save)
|
||||
|
||||
def test_account_balance(self):
|
||||
from erpnext.accounts.utils import get_balance_on
|
||||
|
||||
if not frappe.db.exists("Account", "Test Percent Account %5 - _TC"):
|
||||
acc = frappe.new_doc("Account")
|
||||
acc.account_name = "Test Percent Account %5"
|
||||
acc.parent_account = "Tax Assets - _TC"
|
||||
acc.company = "_Test Company"
|
||||
acc.insert()
|
||||
|
||||
balance = get_balance_on(account="Test Percent Account %5 - _TC", date=nowdate())
|
||||
self.assertEqual(balance, 0)
|
||||
|
||||
|
||||
def _make_test_records(verbose=None):
|
||||
from frappe.test_runner import make_test_objects
|
||||
@@ -372,7 +297,7 @@ def _make_test_records(verbose=None):
|
||||
# fixed asset depreciation
|
||||
["_Test Fixed Asset", "Current Assets", 0, "Fixed Asset", None],
|
||||
["_Test Accumulated Depreciations", "Current Assets", 0, "Accumulated Depreciation", None],
|
||||
["_Test Depreciations", "Expenses", 0, "Depreciation", None],
|
||||
["_Test Depreciations", "Expenses", 0, None, None],
|
||||
["_Test Gain/Loss on Asset Disposal", "Expenses", 0, None, None],
|
||||
# Receivable / Payable Account
|
||||
["_Test Receivable", "Current Assets", 0, "Receivable", None],
|
||||
@@ -420,20 +345,11 @@ def create_account(**kwargs):
|
||||
"Account", filters={"account_name": kwargs.get("account_name"), "company": kwargs.get("company")}
|
||||
)
|
||||
if account:
|
||||
account = frappe.get_doc("Account", account)
|
||||
account.update(
|
||||
dict(
|
||||
is_group=kwargs.get("is_group", 0),
|
||||
parent_account=kwargs.get("parent_account"),
|
||||
)
|
||||
)
|
||||
account.save()
|
||||
return account.name
|
||||
return account
|
||||
else:
|
||||
account = frappe.get_doc(
|
||||
dict(
|
||||
doctype="Account",
|
||||
is_group=kwargs.get("is_group", 0),
|
||||
account_name=kwargs.get("account_name"),
|
||||
account_type=kwargs.get("account_type"),
|
||||
parent_account=kwargs.get("parent_account"),
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
// frappe.ui.form.on("Account Closing Balance", {
|
||||
// refresh(frm) {
|
||||
|
||||
// },
|
||||
// });
|
||||
@@ -1,164 +0,0 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2023-02-21 15:20:59.586811",
|
||||
"default_view": "List",
|
||||
"doctype": "DocType",
|
||||
"document_type": "Document",
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"closing_date",
|
||||
"account",
|
||||
"cost_center",
|
||||
"debit",
|
||||
"credit",
|
||||
"account_currency",
|
||||
"debit_in_account_currency",
|
||||
"credit_in_account_currency",
|
||||
"project",
|
||||
"company",
|
||||
"finance_book",
|
||||
"period_closing_voucher",
|
||||
"is_period_closing_voucher_entry"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "closing_date",
|
||||
"fieldtype": "Date",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Closing Date",
|
||||
"oldfieldname": "posting_date",
|
||||
"oldfieldtype": "Date",
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "account",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Account",
|
||||
"oldfieldname": "account",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Account",
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Cost Center",
|
||||
"oldfieldname": "cost_center",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Cost Center"
|
||||
},
|
||||
{
|
||||
"fieldname": "debit",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Debit Amount",
|
||||
"oldfieldname": "debit",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "credit",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Credit Amount",
|
||||
"oldfieldname": "credit",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "account_currency",
|
||||
"fieldtype": "Link",
|
||||
"label": "Account Currency",
|
||||
"options": "Currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "debit_in_account_currency",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Debit Amount in Account Currency",
|
||||
"options": "account_currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "credit_in_account_currency",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Credit Amount in Account Currency",
|
||||
"options": "account_currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "project",
|
||||
"fieldtype": "Link",
|
||||
"label": "Project",
|
||||
"options": "Project"
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Company",
|
||||
"oldfieldname": "company",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Company",
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "finance_book",
|
||||
"fieldtype": "Link",
|
||||
"label": "Finance Book",
|
||||
"options": "Finance Book"
|
||||
},
|
||||
{
|
||||
"fieldname": "period_closing_voucher",
|
||||
"fieldtype": "Link",
|
||||
"in_standard_filter": 1,
|
||||
"label": "Period Closing Voucher",
|
||||
"options": "Period Closing Voucher",
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "is_period_closing_voucher_entry",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Period Closing Voucher Entry"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-list",
|
||||
"in_create": 1,
|
||||
"links": [],
|
||||
"modified": "2023-03-06 08:56:36.393237",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Account Closing Balance",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User"
|
||||
},
|
||||
{
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager"
|
||||
},
|
||||
{
|
||||
"export": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Auditor"
|
||||
}
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": []
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import cint, cstr
|
||||
|
||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
|
||||
get_accounting_dimensions,
|
||||
)
|
||||
|
||||
|
||||
class AccountClosingBalance(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
account: DF.Link | None
|
||||
account_currency: DF.Link | None
|
||||
closing_date: DF.Date | None
|
||||
company: DF.Link | None
|
||||
cost_center: DF.Link | None
|
||||
credit: DF.Currency
|
||||
credit_in_account_currency: DF.Currency
|
||||
debit: DF.Currency
|
||||
debit_in_account_currency: DF.Currency
|
||||
finance_book: DF.Link | None
|
||||
is_period_closing_voucher_entry: DF.Check
|
||||
period_closing_voucher: DF.Link | None
|
||||
project: DF.Link | None
|
||||
# end: auto-generated types
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def make_closing_entries(closing_entries, voucher_name, company, closing_date):
|
||||
accounting_dimensions = get_accounting_dimensions()
|
||||
|
||||
previous_closing_entries = get_previous_closing_entries(
|
||||
company, closing_date, accounting_dimensions
|
||||
)
|
||||
combined_entries = closing_entries + previous_closing_entries
|
||||
|
||||
merged_entries = aggregate_with_last_account_closing_balance(
|
||||
combined_entries, accounting_dimensions
|
||||
)
|
||||
|
||||
for key, value in merged_entries.items():
|
||||
cle = frappe.new_doc("Account Closing Balance")
|
||||
cle.update(value)
|
||||
cle.update(value["dimensions"])
|
||||
cle.update(
|
||||
{
|
||||
"period_closing_voucher": voucher_name,
|
||||
"closing_date": closing_date,
|
||||
}
|
||||
)
|
||||
cle.flags.ignore_permissions = True
|
||||
cle.flags.ignore_links = True
|
||||
cle.submit()
|
||||
|
||||
|
||||
def aggregate_with_last_account_closing_balance(entries, accounting_dimensions):
|
||||
merged_entries = {}
|
||||
for entry in entries:
|
||||
key, key_values = generate_key(entry, accounting_dimensions)
|
||||
merged_entries.setdefault(
|
||||
key,
|
||||
{
|
||||
"debit": 0,
|
||||
"credit": 0,
|
||||
"debit_in_account_currency": 0,
|
||||
"credit_in_account_currency": 0,
|
||||
},
|
||||
)
|
||||
|
||||
merged_entries[key]["dimensions"] = key_values
|
||||
merged_entries[key]["debit"] += entry.get("debit")
|
||||
merged_entries[key]["credit"] += entry.get("credit")
|
||||
merged_entries[key]["debit_in_account_currency"] += entry.get("debit_in_account_currency")
|
||||
merged_entries[key]["credit_in_account_currency"] += entry.get("credit_in_account_currency")
|
||||
|
||||
return merged_entries
|
||||
|
||||
|
||||
def generate_key(entry, accounting_dimensions):
|
||||
key = [
|
||||
cstr(entry.get("account")),
|
||||
cstr(entry.get("account_currency")),
|
||||
cstr(entry.get("cost_center")),
|
||||
cstr(entry.get("project")),
|
||||
cstr(entry.get("finance_book")),
|
||||
cint(entry.get("is_period_closing_voucher_entry")),
|
||||
]
|
||||
|
||||
key_values = {
|
||||
"company": cstr(entry.get("company")),
|
||||
"account": cstr(entry.get("account")),
|
||||
"account_currency": cstr(entry.get("account_currency")),
|
||||
"cost_center": cstr(entry.get("cost_center")),
|
||||
"project": cstr(entry.get("project")),
|
||||
"finance_book": cstr(entry.get("finance_book")),
|
||||
"is_period_closing_voucher_entry": cint(entry.get("is_period_closing_voucher_entry")),
|
||||
}
|
||||
for dimension in accounting_dimensions:
|
||||
key.append(cstr(entry.get(dimension)))
|
||||
key_values[dimension] = cstr(entry.get(dimension))
|
||||
|
||||
return tuple(key), key_values
|
||||
|
||||
|
||||
def get_previous_closing_entries(company, closing_date, accounting_dimensions):
|
||||
entries = []
|
||||
last_period_closing_voucher = frappe.db.get_all(
|
||||
"Period Closing Voucher",
|
||||
filters={"docstatus": 1, "company": company, "posting_date": ("<", closing_date)},
|
||||
fields=["name"],
|
||||
order_by="posting_date desc",
|
||||
limit=1,
|
||||
)
|
||||
|
||||
if last_period_closing_voucher:
|
||||
account_closing_balance = frappe.qb.DocType("Account Closing Balance")
|
||||
query = frappe.qb.from_(account_closing_balance).select(
|
||||
account_closing_balance.company,
|
||||
account_closing_balance.account,
|
||||
account_closing_balance.account_currency,
|
||||
account_closing_balance.debit,
|
||||
account_closing_balance.credit,
|
||||
account_closing_balance.debit_in_account_currency,
|
||||
account_closing_balance.credit_in_account_currency,
|
||||
account_closing_balance.cost_center,
|
||||
account_closing_balance.project,
|
||||
account_closing_balance.finance_book,
|
||||
account_closing_balance.is_period_closing_voucher_entry,
|
||||
)
|
||||
|
||||
for dimension in accounting_dimensions:
|
||||
query = query.select(account_closing_balance[dimension])
|
||||
|
||||
query = query.where(
|
||||
account_closing_balance.period_closing_voucher == last_period_closing_voucher[0].name
|
||||
)
|
||||
entries = query.run(as_dict=1)
|
||||
|
||||
return entries
|
||||
@@ -1,9 +0,0 @@
|
||||
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
# import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
|
||||
class TestAccountClosingBalance(FrappeTestCase):
|
||||
pass
|
||||
@@ -1,86 +1,63 @@
|
||||
// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on("Accounting Dimension", {
|
||||
refresh: function (frm) {
|
||||
frm.set_query("document_type", () => {
|
||||
frappe.ui.form.on('Accounting Dimension', {
|
||||
refresh: function(frm) {
|
||||
frm.set_query('document_type', () => {
|
||||
let invalid_doctypes = frappe.model.core_doctypes_list;
|
||||
invalid_doctypes.push(
|
||||
"Accounting Dimension",
|
||||
"Project",
|
||||
"Cost Center",
|
||||
"Accounting Dimension Detail",
|
||||
"Company"
|
||||
);
|
||||
invalid_doctypes.push('Accounting Dimension', 'Project',
|
||||
'Cost Center', 'Accounting Dimension Detail', 'Company');
|
||||
|
||||
return {
|
||||
filters: {
|
||||
name: ["not in", invalid_doctypes],
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("offsetting_account", "dimension_defaults", function (doc, cdt, cdn) {
|
||||
let d = locals[cdt][cdn];
|
||||
return {
|
||||
filters: {
|
||||
company: d.company,
|
||||
root_type: ["in", ["Asset", "Liability"]],
|
||||
is_group: 0,
|
||||
},
|
||||
name: ['not in', invalid_doctypes]
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
if (!frm.is_new()) {
|
||||
frm.add_custom_button(__("Show {0}", [frm.doc.document_type]), function () {
|
||||
frm.add_custom_button(__('Show {0}', [frm.doc.document_type]), function () {
|
||||
frappe.set_route("List", frm.doc.document_type);
|
||||
});
|
||||
|
||||
let button = frm.doc.disabled ? "Enable" : "Disable";
|
||||
|
||||
frm.add_custom_button(__(button), function () {
|
||||
frm.set_value("disabled", 1 - frm.doc.disabled);
|
||||
frm.add_custom_button(__(button), function() {
|
||||
|
||||
frm.set_value('disabled', 1 - frm.doc.disabled);
|
||||
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.disable_dimension",
|
||||
args: {
|
||||
doc: frm.doc,
|
||||
doc: frm.doc
|
||||
},
|
||||
freeze: true,
|
||||
callback: function (r) {
|
||||
callback: function(r) {
|
||||
let message = frm.doc.disabled ? "Dimension Disabled" : "Dimension Enabled";
|
||||
frm.save();
|
||||
frappe.show_alert({ message: __(message), indicator: "green" });
|
||||
},
|
||||
frappe.show_alert({message:__(message), indicator:'green'});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
document_type: function (frm) {
|
||||
frm.set_value("label", frm.doc.document_type);
|
||||
frm.set_value("fieldname", frappe.model.scrub(frm.doc.document_type));
|
||||
document_type: function(frm) {
|
||||
|
||||
frappe.db.get_value(
|
||||
"Accounting Dimension",
|
||||
{ document_type: frm.doc.document_type },
|
||||
"document_type",
|
||||
(r) => {
|
||||
if (r && r.document_type) {
|
||||
frm.set_df_property(
|
||||
"document_type",
|
||||
"description",
|
||||
"Document type is already set as dimension"
|
||||
);
|
||||
}
|
||||
frm.set_value('label', frm.doc.document_type);
|
||||
frm.set_value('fieldname', frappe.model.scrub(frm.doc.document_type));
|
||||
|
||||
frappe.db.get_value('Accounting Dimension', {'document_type': frm.doc.document_type}, 'document_type', (r) => {
|
||||
if (r && r.document_type) {
|
||||
frm.set_df_property('document_type', 'description', "Document type is already set as dimension");
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Accounting Dimension Detail", {
|
||||
dimension_defaults_add: function (frm, cdt, cdn) {
|
||||
frappe.ui.form.on('Accounting Dimension Detail', {
|
||||
dimension_defaults_add: function(frm, cdt, cdn) {
|
||||
let row = locals[cdt][cdn];
|
||||
row.reference_document = frm.doc.document_type;
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
@@ -11,31 +11,8 @@ from frappe.model import core_doctypes_list
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import cstr
|
||||
|
||||
from erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger import (
|
||||
get_allowed_types_from_settings,
|
||||
)
|
||||
|
||||
|
||||
class AccountingDimension(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
from erpnext.accounts.doctype.accounting_dimension_detail.accounting_dimension_detail import (
|
||||
AccountingDimensionDetail,
|
||||
)
|
||||
|
||||
dimension_defaults: DF.Table[AccountingDimensionDetail]
|
||||
disabled: DF.Check
|
||||
document_type: DF.Link
|
||||
fieldname: DF.Data | None
|
||||
label: DF.Data | None
|
||||
# end: auto-generated types
|
||||
|
||||
def before_insert(self):
|
||||
self.set_fieldname_and_label()
|
||||
|
||||
@@ -62,8 +39,6 @@ class AccountingDimension(Document):
|
||||
if not self.is_new():
|
||||
self.validate_document_type_change()
|
||||
|
||||
self.validate_dimension_defaults()
|
||||
|
||||
def validate_document_type_change(self):
|
||||
doctype_before_save = frappe.db.get_value("Accounting Dimension", self.name, "document_type")
|
||||
if doctype_before_save != self.document_type:
|
||||
@@ -71,27 +46,17 @@ class AccountingDimension(Document):
|
||||
message += _("Please create a new Accounting Dimension if required.")
|
||||
frappe.throw(message)
|
||||
|
||||
def validate_dimension_defaults(self):
|
||||
companies = []
|
||||
for default in self.get("dimension_defaults"):
|
||||
if default.company not in companies:
|
||||
companies.append(default.company)
|
||||
else:
|
||||
frappe.throw(_("Company {0} is added more than once").format(frappe.bold(default.company)))
|
||||
|
||||
def after_insert(self):
|
||||
if frappe.flags.in_test:
|
||||
make_dimension_in_accounting_doctypes(doc=self)
|
||||
else:
|
||||
frappe.enqueue(
|
||||
make_dimension_in_accounting_doctypes, doc=self, queue="long", enqueue_after_commit=True
|
||||
)
|
||||
frappe.enqueue(make_dimension_in_accounting_doctypes, doc=self, queue="long")
|
||||
|
||||
def on_trash(self):
|
||||
if frappe.flags.in_test:
|
||||
delete_accounting_dimension(doc=self)
|
||||
else:
|
||||
frappe.enqueue(delete_accounting_dimension, doc=self, queue="long", enqueue_after_commit=True)
|
||||
frappe.enqueue(delete_accounting_dimension, doc=self, queue="long")
|
||||
|
||||
def set_fieldname_and_label(self):
|
||||
if not self.label:
|
||||
@@ -110,7 +75,6 @@ def make_dimension_in_accounting_doctypes(doc, doclist=None):
|
||||
|
||||
doc_count = len(get_accounting_dimensions())
|
||||
count = 0
|
||||
repostable_doctypes = get_allowed_types_from_settings()
|
||||
|
||||
for doctype in doclist:
|
||||
|
||||
@@ -126,7 +90,6 @@ def make_dimension_in_accounting_doctypes(doc, doclist=None):
|
||||
"options": doc.document_type,
|
||||
"insert_after": insert_after_field,
|
||||
"owner": "Administrator",
|
||||
"allow_on_submit": 1 if doctype in repostable_doctypes else 0,
|
||||
}
|
||||
|
||||
meta = frappe.get_meta(doctype, cached=False)
|
||||
@@ -290,28 +253,21 @@ def get_dimension_with_children(doctype, dimensions):
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_dimensions(with_cost_center_and_project=False):
|
||||
|
||||
c = frappe.qb.DocType("Accounting Dimension Detail")
|
||||
p = frappe.qb.DocType("Accounting Dimension")
|
||||
dimension_filters = (
|
||||
frappe.qb.from_(p)
|
||||
.select(p.label, p.fieldname, p.document_type)
|
||||
.where(p.disabled == 0)
|
||||
.run(as_dict=1)
|
||||
)
|
||||
default_dimensions = (
|
||||
frappe.qb.from_(c)
|
||||
.inner_join(p)
|
||||
.on(c.parent == p.name)
|
||||
.select(p.fieldname, c.company, c.default_dimension)
|
||||
.run(as_dict=1)
|
||||
dimension_filters = frappe.db.sql(
|
||||
"""
|
||||
SELECT label, fieldname, document_type
|
||||
FROM `tabAccounting Dimension`
|
||||
WHERE disabled = 0
|
||||
""",
|
||||
as_dict=1,
|
||||
)
|
||||
|
||||
if isinstance(with_cost_center_and_project, str):
|
||||
if with_cost_center_and_project.lower().strip() == "true":
|
||||
with_cost_center_and_project = True
|
||||
else:
|
||||
with_cost_center_and_project = False
|
||||
default_dimensions = frappe.db.sql(
|
||||
"""SELECT p.fieldname, c.company, c.default_dimension
|
||||
FROM `tabAccounting Dimension Detail` c, `tabAccounting Dimension` p
|
||||
WHERE c.parent = p.name""",
|
||||
as_dict=1,
|
||||
)
|
||||
|
||||
if with_cost_center_and_project:
|
||||
dimension_filters.extend(
|
||||
@@ -327,30 +283,3 @@ def get_dimensions(with_cost_center_and_project=False):
|
||||
default_dimensions_map[dimension.company][dimension.fieldname] = dimension.default_dimension
|
||||
|
||||
return dimension_filters, default_dimensions_map
|
||||
|
||||
|
||||
def create_accounting_dimensions_for_doctype(doctype):
|
||||
accounting_dimensions = frappe.db.get_all(
|
||||
"Accounting Dimension", fields=["fieldname", "label", "document_type", "disabled"]
|
||||
)
|
||||
|
||||
if not accounting_dimensions:
|
||||
return
|
||||
|
||||
for d in accounting_dimensions:
|
||||
field = frappe.db.get_value("Custom Field", {"dt": doctype, "fieldname": d.fieldname})
|
||||
|
||||
if field:
|
||||
continue
|
||||
|
||||
df = {
|
||||
"fieldname": d.fieldname,
|
||||
"label": d.label,
|
||||
"fieldtype": "Link",
|
||||
"options": d.document_type,
|
||||
"insert_after": "accounting_dimensions_section",
|
||||
}
|
||||
|
||||
create_custom_field(doctype, df, ignore_validate=True)
|
||||
|
||||
frappe.clear_cache(doctype=doctype)
|
||||
|
||||
@@ -84,22 +84,12 @@ def create_dimension():
|
||||
frappe.set_user("Administrator")
|
||||
|
||||
if not frappe.db.exists("Accounting Dimension", {"document_type": "Department"}):
|
||||
dimension = frappe.get_doc(
|
||||
frappe.get_doc(
|
||||
{
|
||||
"doctype": "Accounting Dimension",
|
||||
"document_type": "Department",
|
||||
}
|
||||
)
|
||||
dimension.append(
|
||||
"dimension_defaults",
|
||||
{
|
||||
"company": "_Test Company",
|
||||
"reference_document": "Department",
|
||||
"default_dimension": "_Test Department - _TC",
|
||||
},
|
||||
)
|
||||
dimension.insert()
|
||||
dimension.save()
|
||||
).insert()
|
||||
else:
|
||||
dimension = frappe.get_doc("Accounting Dimension", "Department")
|
||||
dimension.disabled = 0
|
||||
|
||||
@@ -8,10 +8,7 @@
|
||||
"reference_document",
|
||||
"default_dimension",
|
||||
"mandatory_for_bs",
|
||||
"mandatory_for_pl",
|
||||
"column_break_lqns",
|
||||
"automatically_post_balancing_accounting_entry",
|
||||
"offsetting_account"
|
||||
"mandatory_for_pl"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -53,23 +50,6 @@
|
||||
"fieldtype": "Check",
|
||||
"in_list_view": 1,
|
||||
"label": "Mandatory For Profit and Loss Account"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "automatically_post_balancing_accounting_entry",
|
||||
"fieldtype": "Check",
|
||||
"label": "Automatically post balancing accounting entry"
|
||||
},
|
||||
{
|
||||
"fieldname": "offsetting_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Offsetting Account",
|
||||
"mandatory_depends_on": "eval: doc.automatically_post_balancing_accounting_entry",
|
||||
"options": "Account"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_lqns",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
|
||||
@@ -7,24 +7,4 @@ from frappe.model.document import Document
|
||||
|
||||
|
||||
class AccountingDimensionDetail(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
automatically_post_balancing_accounting_entry: DF.Check
|
||||
company: DF.Link | None
|
||||
default_dimension: DF.DynamicLink | None
|
||||
mandatory_for_bs: DF.Check
|
||||
mandatory_for_pl: DF.Check
|
||||
offsetting_account: DF.Link | None
|
||||
parent: DF.Data
|
||||
parentfield: DF.Data
|
||||
parenttype: DF.Data
|
||||
reference_document: DF.Link | None
|
||||
# end: auto-generated types
|
||||
|
||||
pass
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on("Accounting Dimension Filter", {
|
||||
refresh: function (frm, cdt, cdn) {
|
||||
let help_content = `<table class="table table-bordered" style="background-color: var(--scrollbar-track-color);">
|
||||
frappe.ui.form.on('Accounting Dimension Filter', {
|
||||
refresh: function(frm, cdt, cdn) {
|
||||
if (frm.doc.accounting_dimension) {
|
||||
frm.set_df_property('dimensions', 'label', frm.doc.accounting_dimension, cdn, 'dimension_value');
|
||||
}
|
||||
|
||||
let help_content =
|
||||
`<table class="table table-bordered" style="background-color: var(--scrollbar-track-color);">
|
||||
<tr><td>
|
||||
<p>
|
||||
<i class="fa fa-hand-right"></i>
|
||||
@@ -12,80 +17,66 @@ frappe.ui.form.on("Accounting Dimension Filter", {
|
||||
</td></tr>
|
||||
</table>`;
|
||||
|
||||
frm.set_df_property("dimension_filter_help", "options", help_content);
|
||||
frm.set_df_property('dimension_filter_help', 'options', help_content);
|
||||
},
|
||||
onload: function (frm) {
|
||||
frm.set_query("applicable_on_account", "accounts", function () {
|
||||
onload: function(frm) {
|
||||
frm.set_query('applicable_on_account', 'accounts', function() {
|
||||
return {
|
||||
filters: {
|
||||
company: frm.doc.company,
|
||||
},
|
||||
'company': frm.doc.company
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
frappe.db.get_list("Accounting Dimension", { fields: ["document_type"] }).then((res) => {
|
||||
let options = ["Cost Center", "Project"];
|
||||
frappe.db.get_list('Accounting Dimension',
|
||||
{fields: ['document_type']}).then((res) => {
|
||||
let options = ['Cost Center', 'Project'];
|
||||
|
||||
res.forEach((dimension) => {
|
||||
options.push(dimension.document_type);
|
||||
});
|
||||
|
||||
frm.set_df_property("accounting_dimension", "options", options);
|
||||
frm.set_df_property('accounting_dimension', 'options', options);
|
||||
});
|
||||
|
||||
frm.trigger("setup_filters");
|
||||
frm.trigger('setup_filters');
|
||||
},
|
||||
|
||||
setup_filters: function (frm) {
|
||||
setup_filters: function(frm) {
|
||||
let filters = {};
|
||||
|
||||
if (frm.doc.accounting_dimension) {
|
||||
frappe.model.with_doctype(frm.doc.accounting_dimension, function () {
|
||||
frappe.model.with_doctype(frm.doc.accounting_dimension, function() {
|
||||
if (frappe.model.is_tree(frm.doc.accounting_dimension)) {
|
||||
filters["is_group"] = 0;
|
||||
filters['is_group'] = 0;
|
||||
}
|
||||
|
||||
if (frappe.meta.has_field(frm.doc.accounting_dimension, "company")) {
|
||||
filters["company"] = frm.doc.company;
|
||||
if (frappe.meta.has_field(frm.doc.accounting_dimension, 'company')) {
|
||||
filters['company'] = frm.doc.company;
|
||||
}
|
||||
|
||||
frm.set_query("dimension_value", "dimensions", function () {
|
||||
frm.set_query('dimension_value', 'dimensions', function() {
|
||||
return {
|
||||
filters: filters,
|
||||
filters: filters
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
accounting_dimension: function (frm) {
|
||||
accounting_dimension: function(frm) {
|
||||
frm.clear_table("dimensions");
|
||||
let row = frm.add_child("dimensions");
|
||||
row.accounting_dimension = frm.doc.accounting_dimension;
|
||||
frm.fields_dict["dimensions"].grid.update_docfield_property(
|
||||
"dimension_value",
|
||||
"label",
|
||||
frm.doc.accounting_dimension
|
||||
);
|
||||
frm.refresh_field("dimensions");
|
||||
frm.trigger("setup_filters");
|
||||
},
|
||||
apply_restriction_on_values: function (frm) {
|
||||
/** If restriction on values is not applied, we should set "allow_or_restrict" to "Restrict" with an empty allowed dimension table.
|
||||
* Hence it's not "restricted" on any value.
|
||||
*/
|
||||
if (!frm.doc.apply_restriction_on_values) {
|
||||
frm.set_value("allow_or_restrict", "Restrict");
|
||||
frm.clear_table("dimensions");
|
||||
frm.refresh_field("dimensions");
|
||||
}
|
||||
frm.trigger('setup_filters');
|
||||
},
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Allowed Dimension", {
|
||||
dimensions_add: function (frm, cdt, cdn) {
|
||||
frappe.ui.form.on('Allowed Dimension', {
|
||||
dimensions_add: function(frm, cdt, cdn) {
|
||||
let row = locals[cdt][cdn];
|
||||
row.accounting_dimension = frm.doc.accounting_dimension;
|
||||
frm.refresh_field("dimensions");
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
"disabled",
|
||||
"column_break_2",
|
||||
"company",
|
||||
"apply_restriction_on_values",
|
||||
"allow_or_restrict",
|
||||
"section_break_4",
|
||||
"accounts",
|
||||
@@ -25,80 +24,94 @@
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Accounting Dimension",
|
||||
"reqd": 1
|
||||
"reqd": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_2",
|
||||
"fieldtype": "Column Break"
|
||||
"fieldtype": "Column Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_4",
|
||||
"fieldtype": "Section Break",
|
||||
"hide_border": 1
|
||||
"hide_border": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_6",
|
||||
"fieldtype": "Column Break"
|
||||
"fieldtype": "Column Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.apply_restriction_on_values == 1;",
|
||||
"fieldname": "allow_or_restrict",
|
||||
"fieldtype": "Select",
|
||||
"label": "Allow Or Restrict Dimension",
|
||||
"options": "Allow\nRestrict",
|
||||
"reqd": 1
|
||||
"reqd": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "accounts",
|
||||
"fieldtype": "Table",
|
||||
"label": "Applicable On Account",
|
||||
"options": "Applicable On Account",
|
||||
"reqd": 1
|
||||
"reqd": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.accounting_dimension && doc.apply_restriction_on_values",
|
||||
"depends_on": "eval:doc.accounting_dimension",
|
||||
"fieldname": "dimensions",
|
||||
"fieldtype": "Table",
|
||||
"label": "Applicable Dimension",
|
||||
"mandatory_depends_on": "eval:doc.apply_restriction_on_values == 1;",
|
||||
"options": "Allowed Dimension"
|
||||
"options": "Allowed Dimension",
|
||||
"reqd": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "disabled",
|
||||
"fieldtype": "Check",
|
||||
"label": "Disabled"
|
||||
"label": "Disabled",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"options": "Company",
|
||||
"reqd": 1
|
||||
"reqd": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "dimension_filter_help",
|
||||
"fieldtype": "HTML",
|
||||
"label": "Dimension Filter Help"
|
||||
"label": "Dimension Filter Help",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_10",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "apply_restriction_on_values",
|
||||
"fieldtype": "Check",
|
||||
"label": "Apply restriction on dimension values"
|
||||
"fieldtype": "Section Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2023-06-07 14:59:41.869117",
|
||||
"modified": "2021-02-03 12:04:58.678402",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Accounting Dimension Filter",
|
||||
"naming_rule": "Expression",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
@@ -141,6 +154,5 @@
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": [],
|
||||
"track_changes": 1
|
||||
}
|
||||
@@ -8,34 +8,6 @@ from frappe.model.document import Document
|
||||
|
||||
|
||||
class AccountingDimensionFilter(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
from erpnext.accounts.doctype.allowed_dimension.allowed_dimension import AllowedDimension
|
||||
from erpnext.accounts.doctype.applicable_on_account.applicable_on_account import (
|
||||
ApplicableOnAccount,
|
||||
)
|
||||
|
||||
accounting_dimension: DF.Literal
|
||||
accounts: DF.Table[ApplicableOnAccount]
|
||||
allow_or_restrict: DF.Literal["Allow", "Restrict"]
|
||||
apply_restriction_on_values: DF.Check
|
||||
company: DF.Link
|
||||
dimensions: DF.Table[AllowedDimension]
|
||||
disabled: DF.Check
|
||||
# end: auto-generated types
|
||||
|
||||
def before_save(self):
|
||||
# If restriction is not applied on values, then remove all the dimensions and set allow_or_restrict to Restrict
|
||||
if not self.apply_restriction_on_values:
|
||||
self.allow_or_restrict = "Restrict"
|
||||
self.set("dimensions", [])
|
||||
|
||||
def validate(self):
|
||||
self.validate_applicable_accounts()
|
||||
|
||||
@@ -72,12 +44,12 @@ def get_dimension_filter_map():
|
||||
a.applicable_on_account, d.dimension_value, p.accounting_dimension,
|
||||
p.allow_or_restrict, a.is_mandatory
|
||||
FROM
|
||||
`tabApplicable On Account` a,
|
||||
`tabApplicable On Account` a, `tabAllowed Dimension` d,
|
||||
`tabAccounting Dimension Filter` p
|
||||
LEFT JOIN `tabAllowed Dimension` d ON d.parent = p.name
|
||||
WHERE
|
||||
p.name = a.parent
|
||||
AND p.disabled = 0
|
||||
AND p.name = d.parent
|
||||
""",
|
||||
as_dict=1,
|
||||
)
|
||||
@@ -104,5 +76,4 @@ def build_map(map_object, dimension, account, filter_value, allow_or_restrict, i
|
||||
(dimension, account),
|
||||
{"allowed_dimensions": [], "is_mandatory": is_mandatory, "allow_or_restrict": allow_or_restrict},
|
||||
)
|
||||
if filter_value:
|
||||
map_object[(dimension, account)]["allowed_dimensions"].append(filter_value)
|
||||
map_object[(dimension, account)]["allowed_dimensions"].append(filter_value)
|
||||
|
||||
@@ -64,7 +64,6 @@ def create_accounting_dimension_filter():
|
||||
"accounting_dimension": "Cost Center",
|
||||
"allow_or_restrict": "Allow",
|
||||
"company": "_Test Company",
|
||||
"apply_restriction_on_values": 1,
|
||||
"accounts": [
|
||||
{
|
||||
"applicable_on_account": "Sales - _TC",
|
||||
@@ -86,7 +85,6 @@ def create_accounting_dimension_filter():
|
||||
"doctype": "Accounting Dimension Filter",
|
||||
"accounting_dimension": "Department",
|
||||
"allow_or_restrict": "Allow",
|
||||
"apply_restriction_on_values": 1,
|
||||
"company": "_Test Company",
|
||||
"accounts": [{"applicable_on_account": "Sales - _TC", "is_mandatory": 1}],
|
||||
"dimensions": [{"accounting_dimension": "Department", "dimension_value": "Accounts - _TC"}],
|
||||
|
||||
@@ -1,33 +1,24 @@
|
||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on("Accounting Period", {
|
||||
onload: function (frm) {
|
||||
if (
|
||||
frm.doc.closed_documents.length === 0 ||
|
||||
(frm.doc.closed_documents.length === 1 && frm.doc.closed_documents[0].document_type == undefined)
|
||||
) {
|
||||
frappe.ui.form.on('Accounting Period', {
|
||||
onload: function(frm) {
|
||||
if(frm.doc.closed_documents.length === 0 || (frm.doc.closed_documents.length === 1 && frm.doc.closed_documents[0].document_type == undefined)) {
|
||||
frappe.call({
|
||||
method: "get_doctypes_for_closing",
|
||||
doc: frm.doc,
|
||||
callback: function (r) {
|
||||
if (r.message) {
|
||||
doc:frm.doc,
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
cur_frm.clear_table("closed_documents");
|
||||
r.message.forEach(function (element) {
|
||||
r.message.forEach(function(element) {
|
||||
var c = frm.add_child("closed_documents");
|
||||
c.document_type = element.document_type;
|
||||
c.closed = element.closed;
|
||||
});
|
||||
refresh_field("closed_documents");
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
frm.set_query("document_type", "closed_documents", () => {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.get_doctypes_for_closing",
|
||||
};
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
@@ -11,28 +11,7 @@ class OverlapError(frappe.ValidationError):
|
||||
pass
|
||||
|
||||
|
||||
class ClosedAccountingPeriod(frappe.ValidationError):
|
||||
pass
|
||||
|
||||
|
||||
class AccountingPeriod(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
from erpnext.accounts.doctype.closed_document.closed_document import ClosedDocument
|
||||
|
||||
closed_documents: DF.Table[ClosedDocument]
|
||||
company: DF.Link
|
||||
end_date: DF.Date
|
||||
period_name: DF.Data
|
||||
start_date: DF.Date
|
||||
# end: auto-generated types
|
||||
|
||||
def validate(self):
|
||||
self.validate_overlap()
|
||||
|
||||
@@ -86,42 +65,3 @@ class AccountingPeriod(Document):
|
||||
"closed_documents",
|
||||
{"document_type": doctype_for_closing.document_type, "closed": doctype_for_closing.closed},
|
||||
)
|
||||
|
||||
|
||||
def validate_accounting_period_on_doc_save(doc, method=None):
|
||||
if doc.doctype == "Bank Clearance":
|
||||
return
|
||||
elif doc.doctype == "Asset":
|
||||
if doc.is_existing_asset:
|
||||
return
|
||||
else:
|
||||
date = doc.available_for_use_date
|
||||
elif doc.doctype == "Asset Repair":
|
||||
date = doc.completion_date
|
||||
else:
|
||||
date = doc.posting_date
|
||||
|
||||
ap = frappe.qb.DocType("Accounting Period")
|
||||
cd = frappe.qb.DocType("Closed Document")
|
||||
|
||||
accounting_period = (
|
||||
frappe.qb.from_(ap)
|
||||
.from_(cd)
|
||||
.select(ap.name)
|
||||
.where(
|
||||
(ap.name == cd.parent)
|
||||
& (ap.company == doc.company)
|
||||
& (cd.closed == 1)
|
||||
& (cd.document_type == doc.doctype)
|
||||
& (date >= ap.start_date)
|
||||
& (date <= ap.end_date)
|
||||
)
|
||||
).run(as_dict=1)
|
||||
|
||||
if accounting_period:
|
||||
frappe.throw(
|
||||
_("You cannot create a {0} within the closed Accounting Period {1}").format(
|
||||
doc.doctype, frappe.bold(accounting_period[0]["name"])
|
||||
),
|
||||
ClosedAccountingPeriod,
|
||||
)
|
||||
|
||||
@@ -6,11 +6,9 @@ import unittest
|
||||
import frappe
|
||||
from frappe.utils import add_months, nowdate
|
||||
|
||||
from erpnext.accounts.doctype.accounting_period.accounting_period import (
|
||||
ClosedAccountingPeriod,
|
||||
OverlapError,
|
||||
)
|
||||
from erpnext.accounts.doctype.accounting_period.accounting_period import OverlapError
|
||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||
from erpnext.accounts.general_ledger import ClosedAccountingPeriod
|
||||
|
||||
test_dependencies = ["Item"]
|
||||
|
||||
@@ -35,9 +33,9 @@ class TestAccountingPeriod(unittest.TestCase):
|
||||
ap1.save()
|
||||
|
||||
doc = create_sales_invoice(
|
||||
do_not_save=1, cost_center="_Test Company - _TC", warehouse="Stores - _TC"
|
||||
do_not_submit=1, cost_center="_Test Company - _TC", warehouse="Stores - _TC"
|
||||
)
|
||||
self.assertRaises(ClosedAccountingPeriod, doc.save)
|
||||
self.assertRaises(ClosedAccountingPeriod, doc.submit)
|
||||
|
||||
def tearDown(self):
|
||||
for d in frappe.get_all("Accounting Period"):
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on("Accounts Settings", {
|
||||
refresh: function (frm) {},
|
||||
frappe.ui.form.on('Accounts Settings', {
|
||||
refresh: function(frm) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2013-06-24 15:49:57",
|
||||
"description": "Settings for Accounts",
|
||||
"doctype": "DocType",
|
||||
"document_type": "Other",
|
||||
"editable_grid": 1,
|
||||
@@ -18,8 +19,8 @@
|
||||
"column_break_17",
|
||||
"enable_common_party_accounting",
|
||||
"allow_multi_currency_invoices_against_single_party_account",
|
||||
"journals_section",
|
||||
"merge_similar_account_heads",
|
||||
"report_setting_section",
|
||||
"use_custom_cash_flow",
|
||||
"deferred_accounting_settings_section",
|
||||
"book_deferred_entries_based_on",
|
||||
"column_break_18",
|
||||
@@ -30,17 +31,12 @@
|
||||
"determine_address_tax_category_from",
|
||||
"column_break_19",
|
||||
"add_taxes_from_item_tax_template",
|
||||
"book_tax_discount_loss",
|
||||
"round_row_wise_tax",
|
||||
"print_settings",
|
||||
"show_inclusive_tax_in_print",
|
||||
"show_taxes_as_table_in_print",
|
||||
"column_break_12",
|
||||
"show_payment_schedule_in_print",
|
||||
"currency_exchange_section",
|
||||
"allow_stale",
|
||||
"section_break_jpd0",
|
||||
"auto_reconcile_payments",
|
||||
"stale_days",
|
||||
"invoicing_settings_tab",
|
||||
"accounts_transactions_settings_section",
|
||||
@@ -58,19 +54,9 @@
|
||||
"closing_settings_tab",
|
||||
"period_closing_settings_section",
|
||||
"acc_frozen_upto",
|
||||
"ignore_account_closing_balance",
|
||||
"column_break_25",
|
||||
"frozen_accounts_modifier",
|
||||
"tab_break_dpet",
|
||||
"show_balance_in_coa",
|
||||
"banking_tab",
|
||||
"enable_party_matching",
|
||||
"enable_fuzzy_matching",
|
||||
"reports_tab",
|
||||
"remarks_section",
|
||||
"general_ledger_remarks_length",
|
||||
"column_break_lvjk",
|
||||
"receivable_payable_remarks_length"
|
||||
"report_settings_sb"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -105,7 +91,7 @@
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Enabling ensure each Purchase Invoice has a unique value in Supplier Invoice No. field",
|
||||
"description": "Enabling ensure each Sales Invoice has a unique value in Supplier Invoice No. field",
|
||||
"fieldname": "check_supplier_invoice_uniqueness",
|
||||
"fieldtype": "Check",
|
||||
"label": "Check Supplier Invoice Number Uniqueness"
|
||||
@@ -181,9 +167,20 @@
|
||||
"fieldtype": "Int",
|
||||
"label": "Stale Days"
|
||||
},
|
||||
{
|
||||
"fieldname": "report_settings_sb",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Report Settings"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Only select this if you have set up the Cash Flow Mapper documents",
|
||||
"fieldname": "use_custom_cash_flow",
|
||||
"fieldtype": "Check",
|
||||
"label": "Enable Custom Cash Flow Format"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Payment Terms from orders will be fetched into the invoices as is",
|
||||
"fieldname": "automatically_fetch_payment_terms",
|
||||
"fieldtype": "Check",
|
||||
"label": "Automatically Fetch Payment Terms from Order"
|
||||
@@ -339,121 +336,17 @@
|
||||
"fieldtype": "Tab Break",
|
||||
"label": "POS"
|
||||
},
|
||||
{
|
||||
"fieldname": "report_setting_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Report Setting"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Enabling this will allow creation of multi-currency invoices against single party account in company currency",
|
||||
"fieldname": "allow_multi_currency_invoices_against_single_party_account",
|
||||
"fieldtype": "Check",
|
||||
"label": "Allow multi-currency invoices against single party account "
|
||||
},
|
||||
{
|
||||
"fieldname": "tab_break_dpet",
|
||||
"fieldtype": "Tab Break",
|
||||
"label": "Chart Of Accounts"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "show_balance_in_coa",
|
||||
"fieldtype": "Check",
|
||||
"label": "Show Balances in Chart Of Accounts"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Split Early Payment Discount Loss into Income and Tax Loss",
|
||||
"fieldname": "book_tax_discount_loss",
|
||||
"fieldtype": "Check",
|
||||
"label": "Book Tax Loss on Early Payment Discount"
|
||||
},
|
||||
{
|
||||
"fieldname": "journals_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Journals"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Rows with Same Account heads will be merged on Ledger",
|
||||
"fieldname": "merge_similar_account_heads",
|
||||
"fieldtype": "Check",
|
||||
"label": "Merge Similar Account Heads"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_jpd0",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Payment Reconciliations"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "auto_reconcile_payments",
|
||||
"fieldtype": "Check",
|
||||
"label": "Auto Reconcile Payments"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "show_taxes_as_table_in_print",
|
||||
"fieldtype": "Check",
|
||||
"label": "Show Taxes as Table in Print"
|
||||
},
|
||||
{
|
||||
"fieldname": "banking_tab",
|
||||
"fieldtype": "Tab Break",
|
||||
"label": "Banking"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Auto match and set the Party in Bank Transactions",
|
||||
"fieldname": "enable_party_matching",
|
||||
"fieldtype": "Check",
|
||||
"label": "Enable Automatic Party Matching"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "enable_party_matching",
|
||||
"description": "Approximately match the description/party name against parties",
|
||||
"fieldname": "enable_fuzzy_matching",
|
||||
"fieldtype": "Check",
|
||||
"label": "Enable Fuzzy Matching"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Financial reports will be generated using GL Entry doctypes (should be enabled if Period Closing Voucher is not posted for all years sequentially or missing) ",
|
||||
"fieldname": "ignore_account_closing_balance",
|
||||
"fieldtype": "Check",
|
||||
"label": "Ignore Account Closing Balance"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Tax Amount will be rounded on a row(items) level",
|
||||
"fieldname": "round_row_wise_tax",
|
||||
"fieldtype": "Check",
|
||||
"label": "Round Tax Amount Row-wise"
|
||||
},
|
||||
{
|
||||
"fieldname": "reports_tab",
|
||||
"fieldtype": "Tab Break",
|
||||
"label": "Reports"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Truncates 'Remarks' column to set character length",
|
||||
"fieldname": "general_ledger_remarks_length",
|
||||
"fieldtype": "Int",
|
||||
"label": "General Ledger"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Truncates 'Remarks' column to set character length",
|
||||
"fieldname": "receivable_payable_remarks_length",
|
||||
"fieldtype": "Int",
|
||||
"label": "Accounts Receivable/Payable"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_lvjk",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "remarks_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Remarks Column Length"
|
||||
}
|
||||
],
|
||||
"icon": "icon-cog",
|
||||
@@ -461,7 +354,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2024-01-30 14:04:26.553554",
|
||||
"modified": "2022-07-11 13:37:50.605141",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Accounts Settings",
|
||||
|
||||
@@ -14,78 +14,21 @@ from erpnext.stock.utils import check_pending_reposting
|
||||
|
||||
|
||||
class AccountsSettings(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
acc_frozen_upto: DF.Date | None
|
||||
add_taxes_from_item_tax_template: DF.Check
|
||||
allow_multi_currency_invoices_against_single_party_account: DF.Check
|
||||
allow_stale: DF.Check
|
||||
auto_reconcile_payments: DF.Check
|
||||
automatically_fetch_payment_terms: DF.Check
|
||||
automatically_process_deferred_accounting_entry: DF.Check
|
||||
book_asset_depreciation_entry_automatically: DF.Check
|
||||
book_deferred_entries_based_on: DF.Literal["Days", "Months"]
|
||||
book_deferred_entries_via_journal_entry: DF.Check
|
||||
book_tax_discount_loss: DF.Check
|
||||
check_supplier_invoice_uniqueness: DF.Check
|
||||
credit_controller: DF.Link | None
|
||||
delete_linked_ledger_entries: DF.Check
|
||||
determine_address_tax_category_from: DF.Literal["Billing Address", "Shipping Address"]
|
||||
enable_common_party_accounting: DF.Check
|
||||
enable_fuzzy_matching: DF.Check
|
||||
enable_party_matching: DF.Check
|
||||
frozen_accounts_modifier: DF.Link | None
|
||||
general_ledger_remarks_length: DF.Int
|
||||
ignore_account_closing_balance: DF.Check
|
||||
make_payment_via_journal_entry: DF.Check
|
||||
merge_similar_account_heads: DF.Check
|
||||
over_billing_allowance: DF.Currency
|
||||
post_change_gl_entries: DF.Check
|
||||
receivable_payable_remarks_length: DF.Int
|
||||
role_allowed_to_over_bill: DF.Link | None
|
||||
round_row_wise_tax: DF.Check
|
||||
show_balance_in_coa: DF.Check
|
||||
show_inclusive_tax_in_print: DF.Check
|
||||
show_payment_schedule_in_print: DF.Check
|
||||
show_taxes_as_table_in_print: DF.Check
|
||||
stale_days: DF.Int
|
||||
submit_journal_entries: DF.Check
|
||||
unlink_advance_payment_on_cancelation_of_order: DF.Check
|
||||
unlink_payment_on_cancellation_of_invoice: DF.Check
|
||||
# end: auto-generated types
|
||||
def on_update(self):
|
||||
frappe.clear_cache()
|
||||
|
||||
def validate(self):
|
||||
old_doc = self.get_doc_before_save()
|
||||
clear_cache = False
|
||||
frappe.db.set_default(
|
||||
"add_taxes_from_item_tax_template", self.get("add_taxes_from_item_tax_template", 0)
|
||||
)
|
||||
|
||||
if old_doc.add_taxes_from_item_tax_template != self.add_taxes_from_item_tax_template:
|
||||
frappe.db.set_default(
|
||||
"add_taxes_from_item_tax_template", self.get("add_taxes_from_item_tax_template", 0)
|
||||
)
|
||||
clear_cache = True
|
||||
|
||||
if old_doc.enable_common_party_accounting != self.enable_common_party_accounting:
|
||||
frappe.db.set_default(
|
||||
"enable_common_party_accounting", self.get("enable_common_party_accounting", 0)
|
||||
)
|
||||
clear_cache = True
|
||||
frappe.db.set_default(
|
||||
"enable_common_party_accounting", self.get("enable_common_party_accounting", 0)
|
||||
)
|
||||
|
||||
self.validate_stale_days()
|
||||
|
||||
if old_doc.show_payment_schedule_in_print != self.show_payment_schedule_in_print:
|
||||
self.enable_payment_schedule_in_print()
|
||||
|
||||
if old_doc.acc_frozen_upto != self.acc_frozen_upto:
|
||||
self.validate_pending_reposts()
|
||||
|
||||
if clear_cache:
|
||||
frappe.clear_cache()
|
||||
self.enable_payment_schedule_in_print()
|
||||
self.validate_pending_reposts()
|
||||
|
||||
def validate_stale_days(self):
|
||||
if not self.allow_stale and cint(self.stale_days) <= 0:
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
frappe.ui.form.on("Accounts Settings", {
|
||||
refresh: function (frm) {
|
||||
|
||||
frappe.ui.form.on('Accounts Settings', {
|
||||
refresh: function(frm) {
|
||||
frm.set_df_property("acc_frozen_upto", "label", "Books Closed Through");
|
||||
frm.set_df_property(
|
||||
"frozen_accounts_modifier",
|
||||
"label",
|
||||
"Role Allowed to Close Books & Make Changes to Closed Periods"
|
||||
);
|
||||
frm.set_df_property("frozen_accounts_modifier", "label", "Role Allowed to Close Books & Make Changes to Closed Periods");
|
||||
frm.set_df_property("credit_controller", "label", "Credit Manager");
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
@@ -6,22 +6,4 @@ from frappe.model.document import Document
|
||||
|
||||
|
||||
class AdvanceTax(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
account_head: DF.Link | None
|
||||
allocated_amount: DF.Currency
|
||||
parent: DF.Data
|
||||
parentfield: DF.Data
|
||||
parenttype: DF.Data
|
||||
reference_detail: DF.Data | None
|
||||
reference_name: DF.DynamicLink | None
|
||||
reference_type: DF.Link | None
|
||||
# end: auto-generated types
|
||||
|
||||
pass
|
||||
|
||||
@@ -7,33 +7,4 @@ from frappe.model.document import Document
|
||||
|
||||
|
||||
class AdvanceTaxesandCharges(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
account_head: DF.Link
|
||||
add_deduct_tax: DF.Literal["Add", "Deduct"]
|
||||
allocated_amount: DF.Currency
|
||||
base_tax_amount: DF.Currency
|
||||
base_total: DF.Currency
|
||||
charge_type: DF.Literal[
|
||||
"", "Actual", "On Paid Amount", "On Previous Row Amount", "On Previous Row Total"
|
||||
]
|
||||
cost_center: DF.Link | None
|
||||
currency: DF.Link | None
|
||||
description: DF.SmallText
|
||||
included_in_paid_amount: DF.Check
|
||||
parent: DF.Data
|
||||
parentfield: DF.Data
|
||||
parenttype: DF.Data
|
||||
rate: DF.Float
|
||||
row_id: DF.Data | None
|
||||
tax_amount: DF.Currency
|
||||
total: DF.Currency
|
||||
# end: auto-generated types
|
||||
|
||||
pass
|
||||
|
||||
@@ -7,19 +7,4 @@ from frappe.model.document import Document
|
||||
|
||||
|
||||
class AllowedDimension(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
accounting_dimension: DF.Link | None
|
||||
dimension_value: DF.DynamicLink | None
|
||||
parent: DF.Data
|
||||
parentfield: DF.Data
|
||||
parenttype: DF.Data
|
||||
# end: auto-generated types
|
||||
|
||||
pass
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Company",
|
||||
"options": "Company",
|
||||
@@ -20,7 +19,7 @@
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2024-01-03 11:13:02.669632",
|
||||
"modified": "2020-05-01 12:32:34.044911",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Allowed To Transact With",
|
||||
@@ -29,6 +28,5 @@
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": [],
|
||||
"track_changes": 1
|
||||
}
|
||||
@@ -6,18 +6,4 @@ from frappe.model.document import Document
|
||||
|
||||
|
||||
class AllowedToTransactWith(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
company: DF.Link
|
||||
parent: DF.Data
|
||||
parentfield: DF.Data
|
||||
parenttype: DF.Data
|
||||
# end: auto-generated types
|
||||
|
||||
pass
|
||||
|
||||
@@ -7,19 +7,4 @@ from frappe.model.document import Document
|
||||
|
||||
|
||||
class ApplicableOnAccount(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
applicable_on_account: DF.Link
|
||||
is_mandatory: DF.Check
|
||||
parent: DF.Data
|
||||
parentfield: DF.Data
|
||||
parenttype: DF.Data
|
||||
# end: auto-generated types
|
||||
|
||||
pass
|
||||
|
||||
@@ -1,36 +1,41 @@
|
||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
frappe.provide("erpnext.integrations");
|
||||
frappe.provide('erpnext.integrations');
|
||||
|
||||
frappe.ui.form.on("Bank", {
|
||||
onload: function (frm) {
|
||||
frappe.ui.form.on('Bank', {
|
||||
onload: function(frm) {
|
||||
add_fields_to_mapping_table(frm);
|
||||
},
|
||||
refresh: function (frm) {
|
||||
refresh: function(frm) {
|
||||
add_fields_to_mapping_table(frm);
|
||||
frm.toggle_display(["address_html", "contact_html"], !frm.doc.__islocal);
|
||||
|
||||
frappe.dynamic_link = { doc: frm.doc, fieldname: 'name', doctype: 'Bank' };
|
||||
|
||||
frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
|
||||
|
||||
if (frm.doc.__islocal) {
|
||||
frm.set_df_property("address_and_contact", "hidden", 1);
|
||||
frm.set_df_property('address_and_contact', 'hidden', 1);
|
||||
frappe.contacts.clear_address_and_contact(frm);
|
||||
} else {
|
||||
frm.set_df_property("address_and_contact", "hidden", 0);
|
||||
}
|
||||
else {
|
||||
frm.set_df_property('address_and_contact', 'hidden', 0);
|
||||
frappe.contacts.render_address_and_contact(frm);
|
||||
}
|
||||
if (frm.doc.plaid_access_token) {
|
||||
frm.add_custom_button(__("Refresh Plaid Link"), () => {
|
||||
frm.add_custom_button(__('Refresh Plaid Link'), () => {
|
||||
new erpnext.integrations.refreshPlaidLink(frm.doc.plaid_access_token);
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
let add_fields_to_mapping_table = function (frm) {
|
||||
let options = [];
|
||||
|
||||
frappe.model.with_doctype("Bank Transaction", function () {
|
||||
frappe.model.with_doctype("Bank Transaction", function() {
|
||||
let meta = frappe.get_meta("Bank Transaction");
|
||||
meta.fields.forEach((value) => {
|
||||
meta.fields.forEach(value => {
|
||||
if (!["Section Break", "Column Break"].includes(value.fieldtype)) {
|
||||
options.push(value.fieldname);
|
||||
}
|
||||
@@ -38,32 +43,30 @@ let add_fields_to_mapping_table = function (frm) {
|
||||
});
|
||||
|
||||
frm.fields_dict.bank_transaction_mapping.grid.update_docfield_property(
|
||||
"bank_transaction_field",
|
||||
"options",
|
||||
options
|
||||
'bank_transaction_field', 'options', options
|
||||
);
|
||||
};
|
||||
|
||||
erpnext.integrations.refreshPlaidLink = class refreshPlaidLink {
|
||||
constructor(access_token) {
|
||||
this.access_token = access_token;
|
||||
this.plaidUrl = "https://cdn.plaid.com/link/v2/stable/link-initialize.js";
|
||||
this.plaidUrl = 'https://cdn.plaid.com/link/v2/stable/link-initialize.js';
|
||||
this.init_config();
|
||||
}
|
||||
|
||||
async init_config() {
|
||||
this.plaid_env = await frappe.db.get_single_value("Plaid Settings", "plaid_env");
|
||||
this.plaid_env = await frappe.db.get_single_value('Plaid Settings', 'plaid_env');
|
||||
this.token = await this.get_link_token_for_update();
|
||||
this.init_plaid();
|
||||
}
|
||||
|
||||
async get_link_token_for_update() {
|
||||
const token = frappe.xcall(
|
||||
"erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.get_link_token_for_update",
|
||||
'erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.get_link_token_for_update',
|
||||
{ access_token: this.access_token }
|
||||
);
|
||||
)
|
||||
if (!token) {
|
||||
frappe.throw(__("Cannot retrieve link token for update. Check Error Log for more information"));
|
||||
frappe.throw(__('Cannot retrieve link token for update. Check Error Log for more information'));
|
||||
}
|
||||
return token;
|
||||
}
|
||||
@@ -90,45 +93,31 @@ erpnext.integrations.refreshPlaidLink = class refreshPlaidLink {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
const el = document.createElement("script");
|
||||
el.type = "text/javascript";
|
||||
const el = document.createElement('script');
|
||||
el.type = 'text/javascript';
|
||||
el.async = true;
|
||||
el.src = src;
|
||||
el.addEventListener("load", resolve);
|
||||
el.addEventListener("error", reject);
|
||||
el.addEventListener("abort", reject);
|
||||
el.addEventListener('load', resolve);
|
||||
el.addEventListener('error', reject);
|
||||
el.addEventListener('abort', reject);
|
||||
document.head.appendChild(el);
|
||||
});
|
||||
}
|
||||
|
||||
onScriptLoaded(me) {
|
||||
me.linkHandler = Plaid.create({
|
||||
// eslint-disable-line no-undef
|
||||
env: me.plaid_env,
|
||||
token: me.token,
|
||||
onSuccess: me.plaid_success,
|
||||
onSuccess: me.plaid_success
|
||||
});
|
||||
}
|
||||
|
||||
onScriptError(error) {
|
||||
frappe.msgprint(
|
||||
__(
|
||||
"There was an issue connecting to Plaid's authentication server. Check browser console for more information"
|
||||
)
|
||||
);
|
||||
frappe.msgprint(__("There was an issue connecting to Plaid's authentication server. Check browser console for more information"));
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
plaid_success(token, response) {
|
||||
frappe
|
||||
.xcall(
|
||||
"erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.update_bank_account_ids",
|
||||
{
|
||||
response: response,
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
frappe.show_alert({ message: __("Plaid Link Updated"), indicator: "green" });
|
||||
});
|
||||
frappe.show_alert({ message: __('Plaid Link Updated'), indicator: 'green' });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -10,25 +10,6 @@ from frappe.model.document import Document
|
||||
|
||||
|
||||
class Bank(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
from erpnext.accounts.doctype.bank_transaction_mapping.bank_transaction_mapping import (
|
||||
BankTransactionMapping,
|
||||
)
|
||||
|
||||
bank_name: DF.Data
|
||||
bank_transaction_mapping: DF.Table[BankTransactionMapping]
|
||||
plaid_access_token: DF.Data | None
|
||||
swift_number: DF.Data | None
|
||||
website: DF.Data | None
|
||||
# end: auto-generated types
|
||||
|
||||
def onload(self):
|
||||
"""Load address and contacts in `__onload`"""
|
||||
load_address_and_contact(self)
|
||||
|
||||
@@ -1,49 +1,45 @@
|
||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on("Bank Account", {
|
||||
setup: function (frm) {
|
||||
frm.set_query("account", function () {
|
||||
frappe.ui.form.on('Bank Account', {
|
||||
setup: function(frm) {
|
||||
frm.set_query("account", function() {
|
||||
return {
|
||||
filters: {
|
||||
account_type: "Bank",
|
||||
company: frm.doc.company,
|
||||
is_group: 0,
|
||||
},
|
||||
'account_type': 'Bank',
|
||||
'company': frm.doc.company,
|
||||
'is_group': 0
|
||||
}
|
||||
};
|
||||
});
|
||||
frm.set_query("party_type", function () {
|
||||
frm.set_query("party_type", function() {
|
||||
return {
|
||||
query: "erpnext.setup.doctype.party_type.party_type.get_party_type",
|
||||
};
|
||||
});
|
||||
},
|
||||
refresh: function (frm) {
|
||||
frappe.dynamic_link = { doc: frm.doc, fieldname: "name", doctype: "Bank Account" };
|
||||
refresh: function(frm) {
|
||||
frappe.dynamic_link = { doc: frm.doc, fieldname: 'name', doctype: 'Bank Account' }
|
||||
|
||||
frm.toggle_display(["address_html", "contact_html"], !frm.doc.__islocal);
|
||||
frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
|
||||
|
||||
if (frm.doc.__islocal) {
|
||||
frappe.contacts.clear_address_and_contact(frm);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
frappe.contacts.render_address_and_contact(frm);
|
||||
}
|
||||
|
||||
if (frm.doc.integration_id) {
|
||||
frm.add_custom_button(__("Unlink external integrations"), function () {
|
||||
frappe.confirm(
|
||||
__(
|
||||
"This action will unlink this account from any external service integrating ERPNext with your bank accounts. It cannot be undone. Are you certain ?"
|
||||
),
|
||||
function () {
|
||||
frm.set_value("integration_id", "");
|
||||
}
|
||||
);
|
||||
frm.add_custom_button(__("Unlink external integrations"), function() {
|
||||
frappe.confirm(__("This action will unlink this account from any external service integrating ERPNext with your bank accounts. It cannot be undone. Are you certain ?"), function() {
|
||||
frm.set_value("integration_id", "");
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
is_company_account: function (frm) {
|
||||
frm.set_df_property("account", "reqd", frm.doc.is_company_account);
|
||||
},
|
||||
is_company_account: function(frm) {
|
||||
frm.set_df_property('account', 'reqd', frm.doc.is_company_account);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
"account_type",
|
||||
"account_subtype",
|
||||
"column_break_7",
|
||||
"disabled",
|
||||
"is_default",
|
||||
"is_company_account",
|
||||
"company",
|
||||
@@ -200,16 +199,10 @@
|
||||
"fieldtype": "Data",
|
||||
"in_global_search": 1,
|
||||
"label": "Branch Code"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "disabled",
|
||||
"fieldtype": "Check",
|
||||
"label": "Disabled"
|
||||
}
|
||||
],
|
||||
"links": [],
|
||||
"modified": "2023-09-22 21:31:34.763977",
|
||||
"modified": "2022-05-04 15:49:42.620630",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Account",
|
||||
|
||||
@@ -9,37 +9,9 @@ from frappe.contacts.address_and_contact import (
|
||||
load_address_and_contact,
|
||||
)
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import comma_and, get_link_to_form
|
||||
|
||||
|
||||
class BankAccount(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
account: DF.Link | None
|
||||
account_name: DF.Data
|
||||
account_subtype: DF.Link | None
|
||||
account_type: DF.Link | None
|
||||
bank: DF.Link
|
||||
bank_account_no: DF.Data | None
|
||||
branch_code: DF.Data | None
|
||||
company: DF.Link | None
|
||||
disabled: DF.Check
|
||||
iban: DF.Data | None
|
||||
integration_id: DF.Data | None
|
||||
is_company_account: DF.Check
|
||||
is_default: DF.Check
|
||||
last_integration_date: DF.Date | None
|
||||
mask: DF.Data | None
|
||||
party: DF.DynamicLink | None
|
||||
party_type: DF.Link | None
|
||||
# end: auto-generated types
|
||||
|
||||
def onload(self):
|
||||
"""Load address and contacts in `__onload`"""
|
||||
load_address_and_contact(self)
|
||||
@@ -53,19 +25,6 @@ class BankAccount(Document):
|
||||
def validate(self):
|
||||
self.validate_company()
|
||||
self.validate_iban()
|
||||
self.validate_account()
|
||||
|
||||
def validate_account(self):
|
||||
if self.account:
|
||||
if accounts := frappe.db.get_all(
|
||||
"Bank Account", filters={"account": self.account, "name": ["!=", self.name]}, as_list=1
|
||||
):
|
||||
frappe.throw(
|
||||
_("'{0}' account is already used by {1}. Use another account.").format(
|
||||
frappe.bold(self.account),
|
||||
frappe.bold(comma_and([get_link_to_form(self.doctype, x[0]) for x in accounts])),
|
||||
)
|
||||
)
|
||||
|
||||
def validate_company(self):
|
||||
if self.is_company_account and not self.company:
|
||||
@@ -111,12 +70,13 @@ def make_bank_account(doctype, docname):
|
||||
return doc
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_party_bank_account(party_type, party):
|
||||
return frappe.db.get_value(party_type, party, "default_bank_account")
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_bank_account_details(bank_account):
|
||||
return frappe.get_cached_value(
|
||||
return frappe.db.get_value(
|
||||
"Bank Account", bank_account, ["account", "bank", "bank_account_no"], as_dict=1
|
||||
)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on("Bank Account Subtype", {
|
||||
refresh: function () {},
|
||||
frappe.ui.form.on('Bank Account Subtype', {
|
||||
refresh: function() {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
@@ -6,15 +6,4 @@ from frappe.model.document import Document
|
||||
|
||||
|
||||
class BankAccountSubtype(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
account_subtype: DF.Data | None
|
||||
# end: auto-generated types
|
||||
|
||||
pass
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on("Bank Account Type", {
|
||||
frappe.ui.form.on('Bank Account Type', {
|
||||
// refresh: function(frm) {
|
||||
|
||||
// }
|
||||
});
|
||||
|
||||
@@ -7,15 +7,4 @@ from frappe.model.document import Document
|
||||
|
||||
|
||||
class BankAccountType(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
account_type: DF.Data | None
|
||||
# end: auto-generated types
|
||||
|
||||
pass
|
||||
|
||||
@@ -2,76 +2,57 @@
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.ui.form.on("Bank Clearance", {
|
||||
setup: function (frm) {
|
||||
setup: function(frm) {
|
||||
frm.add_fetch("account", "account_currency", "account_currency");
|
||||
|
||||
frm.set_query("account", function () {
|
||||
return {
|
||||
filters: {
|
||||
account_type: ["in", ["Bank", "Cash"]],
|
||||
is_group: 0,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("bank_account", function () {
|
||||
return {
|
||||
filters: {
|
||||
is_company_account: 1,
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
onload: function (frm) {
|
||||
let default_bank_account = frappe.defaults.get_user_default("Company")
|
||||
? locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"]
|
||||
: "";
|
||||
onload: function(frm) {
|
||||
|
||||
let default_bank_account = frappe.defaults.get_user_default("Company")?
|
||||
locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"]: "";
|
||||
frm.set_value("account", default_bank_account);
|
||||
|
||||
frm.set_query("account", function() {
|
||||
return {
|
||||
"filters": {
|
||||
"account_type": ["in",["Bank","Cash"]],
|
||||
"is_group": 0
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_value("from_date", frappe.datetime.month_start());
|
||||
frm.set_value("to_date", frappe.datetime.month_end());
|
||||
},
|
||||
|
||||
refresh: function (frm) {
|
||||
refresh: function(frm) {
|
||||
frm.disable_save();
|
||||
frm.add_custom_button(__("Get Payment Entries"), () => frm.trigger("get_payment_entries"));
|
||||
|
||||
frm.change_custom_button_type(__("Get Payment Entries"), null, "primary");
|
||||
},
|
||||
|
||||
update_clearance_date: function (frm) {
|
||||
update_clearance_date: function(frm) {
|
||||
return frappe.call({
|
||||
method: "update_clearance_date",
|
||||
doc: frm.doc,
|
||||
callback: function (r, rt) {
|
||||
callback: function(r, rt) {
|
||||
frm.refresh_field("payment_entries");
|
||||
frm.refresh_fields();
|
||||
|
||||
if (!frm.doc.payment_entries.length) {
|
||||
frm.change_custom_button_type(__("Get Payment Entries"), null, "primary");
|
||||
frm.change_custom_button_type(__("Update Clearance Date"), null, "default");
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
get_payment_entries: function (frm) {
|
||||
get_payment_entries: function(frm) {
|
||||
return frappe.call({
|
||||
method: "get_payment_entries",
|
||||
doc: frm.doc,
|
||||
callback: function (r, rt) {
|
||||
callback: function(r, rt) {
|
||||
frm.refresh_field("payment_entries");
|
||||
frm.refresh_fields();
|
||||
|
||||
if (frm.doc.payment_entries.length) {
|
||||
frm.add_custom_button(__("Update Clearance Date"), () =>
|
||||
frm.trigger("update_clearance_date")
|
||||
);
|
||||
|
||||
frm.change_custom_button_type(__("Get Payment Entries"), null, "default");
|
||||
frm.change_custom_button_type(__("Update Clearance Date"), null, "primary");
|
||||
}
|
||||
},
|
||||
$(frm.fields_dict.payment_entries.wrapper).find("[data-fieldname=amount]").each(function(i,v){
|
||||
if (i !=0){
|
||||
$(v).addClass("text-right")
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_copy": 1,
|
||||
"creation": "2013-01-10 16:34:05",
|
||||
"doctype": "DocType",
|
||||
@@ -14,8 +13,11 @@
|
||||
"bank_account",
|
||||
"include_reconciled_entries",
|
||||
"include_pos_transactions",
|
||||
"get_payment_entries",
|
||||
"section_break_10",
|
||||
"payment_entries"
|
||||
"payment_entries",
|
||||
"update_clearance_date",
|
||||
"total_amount"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -74,6 +76,11 @@
|
||||
"fieldtype": "Check",
|
||||
"label": "Include POS Transactions"
|
||||
},
|
||||
{
|
||||
"fieldname": "get_payment_entries",
|
||||
"fieldtype": "Button",
|
||||
"label": "Get Payment Entries"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_10",
|
||||
"fieldtype": "Section Break"
|
||||
@@ -84,14 +91,25 @@
|
||||
"fieldtype": "Table",
|
||||
"label": "Payment Entries",
|
||||
"options": "Bank Clearance Detail"
|
||||
},
|
||||
{
|
||||
"fieldname": "update_clearance_date",
|
||||
"fieldtype": "Button",
|
||||
"label": "Update Clearance Date"
|
||||
},
|
||||
{
|
||||
"fieldname": "total_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Amount",
|
||||
"options": "account_currency",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"hide_toolbar": 1,
|
||||
"icon": "fa fa-check",
|
||||
"idx": 1,
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2022-11-28 17:24:13.008692",
|
||||
"modified": "2020-04-06 16:12:06.628008",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Clearance",
|
||||
@@ -108,6 +126,5 @@
|
||||
"quick_entry": 1,
|
||||
"read_only": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "ASC",
|
||||
"states": []
|
||||
"sort_order": "ASC"
|
||||
}
|
||||
@@ -7,7 +7,6 @@ from frappe import _, msgprint
|
||||
from frappe.model.document import Document
|
||||
from frappe.query_builder.custom import ConstantColumn
|
||||
from frappe.utils import flt, fmt_money, getdate
|
||||
from pypika import Order
|
||||
|
||||
import erpnext
|
||||
|
||||
@@ -15,28 +14,6 @@ form_grid_templates = {"journal_entries": "templates/form_grid/bank_reconciliati
|
||||
|
||||
|
||||
class BankClearance(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
from erpnext.accounts.doctype.bank_clearance_detail.bank_clearance_detail import (
|
||||
BankClearanceDetail,
|
||||
)
|
||||
|
||||
account: DF.Link
|
||||
account_currency: DF.Link | None
|
||||
bank_account: DF.Link | None
|
||||
from_date: DF.Date
|
||||
include_pos_transactions: DF.Check
|
||||
include_reconciled_entries: DF.Check
|
||||
payment_entries: DF.Table[BankClearanceDetail]
|
||||
to_date: DF.Date
|
||||
# end: auto-generated types
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_payment_entries(self):
|
||||
if not (self.from_date and self.to_date):
|
||||
@@ -45,28 +22,162 @@ class BankClearance(Document):
|
||||
if not self.account:
|
||||
frappe.throw(_("Account is mandatory to get payment entries"))
|
||||
|
||||
entries = []
|
||||
condition = ""
|
||||
if not self.include_reconciled_entries:
|
||||
condition = "and (clearance_date IS NULL or clearance_date='0000-00-00')"
|
||||
|
||||
# get entries from all the apps
|
||||
for method_name in frappe.get_hooks("get_payment_entries_for_bank_clearance"):
|
||||
entries += (
|
||||
frappe.get_attr(method_name)(
|
||||
self.from_date,
|
||||
self.to_date,
|
||||
self.account,
|
||||
self.bank_account,
|
||||
self.include_reconciled_entries,
|
||||
self.include_pos_transactions,
|
||||
)
|
||||
or []
|
||||
journal_entries = frappe.db.sql(
|
||||
"""
|
||||
select
|
||||
"Journal Entry" as payment_document, t1.name as payment_entry,
|
||||
t1.cheque_no as cheque_number, t1.cheque_date,
|
||||
sum(t2.debit_in_account_currency) as debit, sum(t2.credit_in_account_currency) as credit,
|
||||
t1.posting_date, t2.against_account, t1.clearance_date, t2.account_currency
|
||||
from
|
||||
`tabJournal Entry` t1, `tabJournal Entry Account` t2
|
||||
where
|
||||
t2.parent = t1.name and t2.account = %(account)s and t1.docstatus=1
|
||||
and t1.posting_date >= %(from)s and t1.posting_date <= %(to)s
|
||||
and ifnull(t1.is_opening, 'No') = 'No' {condition}
|
||||
group by t2.account, t1.name
|
||||
order by t1.posting_date ASC, t1.name DESC
|
||||
""".format(
|
||||
condition=condition
|
||||
),
|
||||
{"account": self.account, "from": self.from_date, "to": self.to_date},
|
||||
as_dict=1,
|
||||
)
|
||||
|
||||
if self.bank_account:
|
||||
condition += "and bank_account = %(bank_account)s"
|
||||
|
||||
payment_entries = frappe.db.sql(
|
||||
"""
|
||||
select
|
||||
"Payment Entry" as payment_document, name as payment_entry,
|
||||
reference_no as cheque_number, reference_date as cheque_date,
|
||||
if(paid_from=%(account)s, paid_amount, 0) as credit,
|
||||
if(paid_from=%(account)s, 0, received_amount) as debit,
|
||||
posting_date, ifnull(party,if(paid_from=%(account)s,paid_to,paid_from)) as against_account, clearance_date,
|
||||
if(paid_to=%(account)s, paid_to_account_currency, paid_from_account_currency) as account_currency
|
||||
from `tabPayment Entry`
|
||||
where
|
||||
(paid_from=%(account)s or paid_to=%(account)s) and docstatus=1
|
||||
and posting_date >= %(from)s and posting_date <= %(to)s
|
||||
{condition}
|
||||
order by
|
||||
posting_date ASC, name DESC
|
||||
""".format(
|
||||
condition=condition
|
||||
),
|
||||
{
|
||||
"account": self.account,
|
||||
"from": self.from_date,
|
||||
"to": self.to_date,
|
||||
"bank_account": self.bank_account,
|
||||
},
|
||||
as_dict=1,
|
||||
)
|
||||
|
||||
loan_disbursement = frappe.qb.DocType("Loan Disbursement")
|
||||
|
||||
loan_disbursements = (
|
||||
frappe.qb.from_(loan_disbursement)
|
||||
.select(
|
||||
ConstantColumn("Loan Disbursement").as_("payment_document"),
|
||||
loan_disbursement.name.as_("payment_entry"),
|
||||
loan_disbursement.disbursed_amount.as_("credit"),
|
||||
ConstantColumn(0).as_("debit"),
|
||||
loan_disbursement.reference_number.as_("cheque_number"),
|
||||
loan_disbursement.reference_date.as_("cheque_date"),
|
||||
loan_disbursement.disbursement_date.as_("posting_date"),
|
||||
loan_disbursement.applicant.as_("against_account"),
|
||||
)
|
||||
.where(loan_disbursement.docstatus == 1)
|
||||
.where(loan_disbursement.disbursement_date >= self.from_date)
|
||||
.where(loan_disbursement.disbursement_date <= self.to_date)
|
||||
.where(loan_disbursement.clearance_date.isnull())
|
||||
.where(loan_disbursement.disbursement_account.isin([self.bank_account, self.account]))
|
||||
.orderby(loan_disbursement.disbursement_date)
|
||||
.orderby(loan_disbursement.name, frappe.qb.desc)
|
||||
).run(as_dict=1)
|
||||
|
||||
loan_repayment = frappe.qb.DocType("Loan Repayment")
|
||||
|
||||
query = (
|
||||
frappe.qb.from_(loan_repayment)
|
||||
.select(
|
||||
ConstantColumn("Loan Repayment").as_("payment_document"),
|
||||
loan_repayment.name.as_("payment_entry"),
|
||||
loan_repayment.amount_paid.as_("debit"),
|
||||
ConstantColumn(0).as_("credit"),
|
||||
loan_repayment.reference_number.as_("cheque_number"),
|
||||
loan_repayment.reference_date.as_("cheque_date"),
|
||||
loan_repayment.applicant.as_("against_account"),
|
||||
loan_repayment.posting_date,
|
||||
)
|
||||
.where(loan_repayment.docstatus == 1)
|
||||
.where(loan_repayment.clearance_date.isnull())
|
||||
.where(loan_repayment.posting_date >= self.from_date)
|
||||
.where(loan_repayment.posting_date <= self.to_date)
|
||||
.where(loan_repayment.payment_account.isin([self.bank_account, self.account]))
|
||||
)
|
||||
|
||||
if frappe.db.has_column("Loan Repayment", "repay_from_salary"):
|
||||
query = query.where((loan_repayment.repay_from_salary == 0))
|
||||
|
||||
query = query.orderby(loan_repayment.posting_date).orderby(loan_repayment.name, frappe.qb.desc)
|
||||
|
||||
loan_repayments = query.run(as_dict=True)
|
||||
|
||||
pos_sales_invoices, pos_purchase_invoices = [], []
|
||||
if self.include_pos_transactions:
|
||||
pos_sales_invoices = frappe.db.sql(
|
||||
"""
|
||||
select
|
||||
"Sales Invoice Payment" as payment_document, sip.name as payment_entry, sip.amount as debit,
|
||||
si.posting_date, si.customer as against_account, sip.clearance_date,
|
||||
account.account_currency, 0 as credit
|
||||
from `tabSales Invoice Payment` sip, `tabSales Invoice` si, `tabAccount` account
|
||||
where
|
||||
sip.account=%(account)s and si.docstatus=1 and sip.parent = si.name
|
||||
and account.name = sip.account and si.posting_date >= %(from)s and si.posting_date <= %(to)s
|
||||
order by
|
||||
si.posting_date ASC, si.name DESC
|
||||
""",
|
||||
{"account": self.account, "from": self.from_date, "to": self.to_date},
|
||||
as_dict=1,
|
||||
)
|
||||
|
||||
pos_purchase_invoices = frappe.db.sql(
|
||||
"""
|
||||
select
|
||||
"Purchase Invoice" as payment_document, pi.name as payment_entry, pi.paid_amount as credit,
|
||||
pi.posting_date, pi.supplier as against_account, pi.clearance_date,
|
||||
account.account_currency, 0 as debit
|
||||
from `tabPurchase Invoice` pi, `tabAccount` account
|
||||
where
|
||||
pi.cash_bank_account=%(account)s and pi.docstatus=1 and account.name = pi.cash_bank_account
|
||||
and pi.posting_date >= %(from)s and pi.posting_date <= %(to)s
|
||||
order by
|
||||
pi.posting_date ASC, pi.name DESC
|
||||
""",
|
||||
{"account": self.account, "from": self.from_date, "to": self.to_date},
|
||||
as_dict=1,
|
||||
)
|
||||
|
||||
entries = sorted(
|
||||
entries,
|
||||
list(payment_entries)
|
||||
+ list(journal_entries)
|
||||
+ list(pos_sales_invoices)
|
||||
+ list(pos_purchase_invoices)
|
||||
+ list(loan_disbursements)
|
||||
+ list(loan_repayments),
|
||||
key=lambda k: getdate(k["posting_date"]),
|
||||
)
|
||||
|
||||
self.set("payment_entries", [])
|
||||
self.total_amount = 0.0
|
||||
default_currency = erpnext.get_default_currency()
|
||||
|
||||
for d in entries:
|
||||
@@ -85,6 +196,7 @@ class BankClearance(Document):
|
||||
d.pop("debit")
|
||||
d.pop("account_currency")
|
||||
row.update(d)
|
||||
self.total_amount += flt(amount)
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_clearance_date(self):
|
||||
@@ -115,134 +227,3 @@ class BankClearance(Document):
|
||||
msgprint(_("Clearance Date updated"))
|
||||
else:
|
||||
msgprint(_("Clearance Date not mentioned"))
|
||||
|
||||
|
||||
def get_payment_entries_for_bank_clearance(
|
||||
from_date, to_date, account, bank_account, include_reconciled_entries, include_pos_transactions
|
||||
):
|
||||
entries = []
|
||||
|
||||
condition = ""
|
||||
if not include_reconciled_entries:
|
||||
condition = "and (clearance_date IS NULL or clearance_date='0000-00-00')"
|
||||
|
||||
journal_entries = frappe.db.sql(
|
||||
"""
|
||||
select
|
||||
"Journal Entry" as payment_document, t1.name as payment_entry,
|
||||
t1.cheque_no as cheque_number, t1.cheque_date,
|
||||
sum(t2.debit_in_account_currency) as debit, sum(t2.credit_in_account_currency) as credit,
|
||||
t1.posting_date, t2.against_account, t1.clearance_date, t2.account_currency
|
||||
from
|
||||
`tabJournal Entry` t1, `tabJournal Entry Account` t2
|
||||
where
|
||||
t2.parent = t1.name and t2.account = %(account)s and t1.docstatus=1
|
||||
and t1.posting_date >= %(from)s and t1.posting_date <= %(to)s
|
||||
and ifnull(t1.is_opening, 'No') = 'No' {condition}
|
||||
group by t2.account, t1.name
|
||||
order by t1.posting_date ASC, t1.name DESC
|
||||
""".format(
|
||||
condition=condition
|
||||
),
|
||||
{"account": account, "from": from_date, "to": to_date},
|
||||
as_dict=1,
|
||||
)
|
||||
|
||||
if bank_account:
|
||||
condition += "and bank_account = %(bank_account)s"
|
||||
|
||||
payment_entries = frappe.db.sql(
|
||||
"""
|
||||
select
|
||||
"Payment Entry" as payment_document, name as payment_entry,
|
||||
reference_no as cheque_number, reference_date as cheque_date,
|
||||
if(paid_from=%(account)s, paid_amount + total_taxes_and_charges, 0) as credit,
|
||||
if(paid_from=%(account)s, 0, received_amount) as debit,
|
||||
posting_date, ifnull(party,if(paid_from=%(account)s,paid_to,paid_from)) as against_account, clearance_date,
|
||||
if(paid_to=%(account)s, paid_to_account_currency, paid_from_account_currency) as account_currency
|
||||
from `tabPayment Entry`
|
||||
where
|
||||
(paid_from=%(account)s or paid_to=%(account)s) and docstatus=1
|
||||
and posting_date >= %(from)s and posting_date <= %(to)s
|
||||
{condition}
|
||||
order by
|
||||
posting_date ASC, name DESC
|
||||
""".format(
|
||||
condition=condition
|
||||
),
|
||||
{
|
||||
"account": account,
|
||||
"from": from_date,
|
||||
"to": to_date,
|
||||
"bank_account": bank_account,
|
||||
},
|
||||
as_dict=1,
|
||||
)
|
||||
|
||||
pos_sales_invoices, pos_purchase_invoices = [], []
|
||||
if include_pos_transactions:
|
||||
si_payment = frappe.qb.DocType("Sales Invoice Payment")
|
||||
si = frappe.qb.DocType("Sales Invoice")
|
||||
acc = frappe.qb.DocType("Account")
|
||||
|
||||
pos_sales_invoices = (
|
||||
frappe.qb.from_(si_payment)
|
||||
.inner_join(si)
|
||||
.on(si_payment.parent == si.name)
|
||||
.inner_join(acc)
|
||||
.on(si_payment.account == acc.name)
|
||||
.select(
|
||||
ConstantColumn("Sales Invoice").as_("payment_document"),
|
||||
si.name.as_("payment_entry"),
|
||||
si_payment.reference_no.as_("cheque_number"),
|
||||
si_payment.amount.as_("debit"),
|
||||
si.posting_date,
|
||||
si.customer.as_("against_account"),
|
||||
si_payment.clearance_date,
|
||||
acc.account_currency,
|
||||
ConstantColumn(0).as_("credit"),
|
||||
)
|
||||
.where(
|
||||
(si.docstatus == 1)
|
||||
& (si_payment.account == account)
|
||||
& (si.posting_date >= from_date)
|
||||
& (si.posting_date <= to_date)
|
||||
)
|
||||
.orderby(si.posting_date)
|
||||
.orderby(si.name, order=Order.desc)
|
||||
).run(as_dict=True)
|
||||
|
||||
pi = frappe.qb.DocType("Purchase Invoice")
|
||||
|
||||
pos_purchase_invoices = (
|
||||
frappe.qb.from_(pi)
|
||||
.inner_join(acc)
|
||||
.on(pi.cash_bank_account == acc.name)
|
||||
.select(
|
||||
ConstantColumn("Purchase Invoice").as_("payment_document"),
|
||||
pi.name.as_("payment_entry"),
|
||||
pi.paid_amount.as_("credit"),
|
||||
pi.posting_date,
|
||||
pi.supplier.as_("against_account"),
|
||||
pi.clearance_date,
|
||||
acc.account_currency,
|
||||
ConstantColumn(0).as_("debit"),
|
||||
)
|
||||
.where(
|
||||
(pi.docstatus == 1)
|
||||
& (pi.cash_bank_account == account)
|
||||
& (pi.posting_date >= from_date)
|
||||
& (pi.posting_date <= to_date)
|
||||
)
|
||||
.orderby(pi.posting_date)
|
||||
.orderby(pi.name, order=Order.desc)
|
||||
).run(as_dict=True)
|
||||
|
||||
entries = (
|
||||
list(payment_entries)
|
||||
+ list(journal_entries)
|
||||
+ list(pos_sales_invoices)
|
||||
+ list(pos_purchase_invoices)
|
||||
)
|
||||
|
||||
return entries
|
||||
|
||||
@@ -8,76 +8,26 @@ from frappe.utils import add_months, getdate
|
||||
|
||||
from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
|
||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
|
||||
from erpnext.tests.utils import if_lending_app_installed, if_lending_app_not_installed
|
||||
from erpnext.loan_management.doctype.loan.test_loan import (
|
||||
create_loan,
|
||||
create_loan_accounts,
|
||||
create_loan_type,
|
||||
create_repayment_entry,
|
||||
make_loan_disbursement_entry,
|
||||
)
|
||||
|
||||
|
||||
class TestBankClearance(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
clear_payment_entries()
|
||||
clear_loan_transactions()
|
||||
make_bank_account()
|
||||
create_loan_accounts()
|
||||
create_loan_masters()
|
||||
add_transactions()
|
||||
|
||||
# Basic test case to test if bank clearance tool doesn't break
|
||||
# Detailed test can be added later
|
||||
@if_lending_app_not_installed
|
||||
def test_bank_clearance(self):
|
||||
bank_clearance = frappe.get_doc("Bank Clearance")
|
||||
bank_clearance.account = "_Test Bank Clearance - _TC"
|
||||
bank_clearance.from_date = add_months(getdate(), -1)
|
||||
bank_clearance.to_date = getdate()
|
||||
bank_clearance.get_payment_entries()
|
||||
self.assertEqual(len(bank_clearance.payment_entries), 1)
|
||||
|
||||
@if_lending_app_installed
|
||||
def test_bank_clearance_with_loan(self):
|
||||
from lending.loan_management.doctype.loan.test_loan import (
|
||||
create_loan,
|
||||
create_loan_accounts,
|
||||
create_loan_product,
|
||||
create_repayment_entry,
|
||||
make_loan_disbursement_entry,
|
||||
)
|
||||
|
||||
def create_loan_masters():
|
||||
create_loan_product(
|
||||
"Clearance Loan",
|
||||
"Clearance Loan",
|
||||
2000000,
|
||||
13.5,
|
||||
25,
|
||||
0,
|
||||
5,
|
||||
"Cash",
|
||||
"_Test Bank Clearance - _TC",
|
||||
"_Test Bank Clearance - _TC",
|
||||
"Loan Account - _TC",
|
||||
"Interest Income Account - _TC",
|
||||
"Penalty Income Account - _TC",
|
||||
)
|
||||
|
||||
def make_loan():
|
||||
loan = create_loan(
|
||||
"_Test Customer",
|
||||
"Clearance Loan",
|
||||
280000,
|
||||
"Repay Over Number of Periods",
|
||||
20,
|
||||
applicant_type="Customer",
|
||||
)
|
||||
loan.submit()
|
||||
make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=getdate())
|
||||
repayment_entry = create_repayment_entry(
|
||||
loan.name, "_Test Customer", getdate(), loan.loan_amount
|
||||
)
|
||||
repayment_entry.save()
|
||||
repayment_entry.submit()
|
||||
|
||||
create_loan_accounts()
|
||||
create_loan_masters()
|
||||
make_loan()
|
||||
|
||||
bank_clearance = frappe.get_doc("Bank Clearance")
|
||||
bank_clearance.account = "_Test Bank Clearance - _TC"
|
||||
bank_clearance.from_date = add_months(getdate(), -1)
|
||||
@@ -86,19 +36,6 @@ class TestBankClearance(unittest.TestCase):
|
||||
self.assertEqual(len(bank_clearance.payment_entries), 3)
|
||||
|
||||
|
||||
def clear_payment_entries():
|
||||
frappe.db.delete("Payment Entry")
|
||||
|
||||
|
||||
@if_lending_app_installed
|
||||
def clear_loan_transactions():
|
||||
for dt in [
|
||||
"Loan Disbursement",
|
||||
"Loan Repayment",
|
||||
]:
|
||||
frappe.db.delete(dt)
|
||||
|
||||
|
||||
def make_bank_account():
|
||||
if not frappe.db.get_value("Account", "_Test Bank Clearance - _TC"):
|
||||
frappe.get_doc(
|
||||
@@ -112,8 +49,42 @@ def make_bank_account():
|
||||
).insert()
|
||||
|
||||
|
||||
def create_loan_masters():
|
||||
create_loan_type(
|
||||
"Clearance Loan",
|
||||
2000000,
|
||||
13.5,
|
||||
25,
|
||||
0,
|
||||
5,
|
||||
"Cash",
|
||||
"_Test Bank Clearance - _TC",
|
||||
"_Test Bank Clearance - _TC",
|
||||
"Loan Account - _TC",
|
||||
"Interest Income Account - _TC",
|
||||
"Penalty Income Account - _TC",
|
||||
)
|
||||
|
||||
|
||||
def add_transactions():
|
||||
make_payment_entry()
|
||||
make_loan()
|
||||
|
||||
|
||||
def make_loan():
|
||||
loan = create_loan(
|
||||
"_Test Customer",
|
||||
"Clearance Loan",
|
||||
280000,
|
||||
"Repay Over Number of Periods",
|
||||
20,
|
||||
applicant_type="Customer",
|
||||
)
|
||||
loan.submit()
|
||||
make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=getdate())
|
||||
repayment_entry = create_repayment_entry(loan.name, "_Test Customer", getdate(), loan.loan_amount)
|
||||
repayment_entry.save()
|
||||
repayment_entry.submit()
|
||||
|
||||
|
||||
def make_payment_entry():
|
||||
|
||||
@@ -6,25 +6,4 @@ from frappe.model.document import Document
|
||||
|
||||
|
||||
class BankClearanceDetail(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
against_account: DF.Data | None
|
||||
amount: DF.Data | None
|
||||
cheque_date: DF.Date | None
|
||||
cheque_number: DF.Data | None
|
||||
clearance_date: DF.Date | None
|
||||
parent: DF.Data
|
||||
parentfield: DF.Data
|
||||
parenttype: DF.Data
|
||||
payment_document: DF.Link | None
|
||||
payment_entry: DF.DynamicLink | None
|
||||
posting_date: DF.Date | None
|
||||
# end: auto-generated types
|
||||
|
||||
pass
|
||||
|
||||
@@ -1,39 +1,39 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
cur_frm.add_fetch("bank_account", "account", "account");
|
||||
cur_frm.add_fetch("bank_account", "bank_account_no", "bank_account_no");
|
||||
cur_frm.add_fetch("bank_account", "iban", "iban");
|
||||
cur_frm.add_fetch("bank_account", "branch_code", "branch_code");
|
||||
cur_frm.add_fetch("bank", "swift_number", "swift_number");
|
||||
cur_frm.add_fetch('bank_account','account','account');
|
||||
cur_frm.add_fetch('bank_account','bank_account_no','bank_account_no');
|
||||
cur_frm.add_fetch('bank_account','iban','iban');
|
||||
cur_frm.add_fetch('bank_account','branch_code','branch_code');
|
||||
cur_frm.add_fetch('bank','swift_number','swift_number');
|
||||
|
||||
frappe.ui.form.on("Bank Guarantee", {
|
||||
setup: function (frm) {
|
||||
frm.set_query("bank", function () {
|
||||
frappe.ui.form.on('Bank Guarantee', {
|
||||
setup: function(frm) {
|
||||
frm.set_query("bank", function() {
|
||||
return {
|
||||
filters: {
|
||||
company: frm.doc.company
|
||||
}
|
||||
};
|
||||
});
|
||||
frm.set_query("bank_account", function() {
|
||||
return {
|
||||
filters: {
|
||||
company: frm.doc.company,
|
||||
},
|
||||
};
|
||||
bank: frm.doc.bank
|
||||
}
|
||||
}
|
||||
});
|
||||
frm.set_query("bank_account", function () {
|
||||
frm.set_query("project", function() {
|
||||
return {
|
||||
filters: {
|
||||
company: frm.doc.company,
|
||||
bank: frm.doc.bank,
|
||||
},
|
||||
};
|
||||
});
|
||||
frm.set_query("project", function () {
|
||||
return {
|
||||
filters: {
|
||||
customer: frm.doc.customer,
|
||||
},
|
||||
customer: frm.doc.customer
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
bg_type: function (frm) {
|
||||
bg_type: function(frm) {
|
||||
if (frm.doc.bg_type == "Receiving") {
|
||||
frm.set_value("reference_doctype", "Sales Order");
|
||||
} else if (frm.doc.bg_type == "Providing") {
|
||||
@@ -41,33 +41,41 @@ frappe.ui.form.on("Bank Guarantee", {
|
||||
}
|
||||
},
|
||||
|
||||
reference_docname: function (frm) {
|
||||
reference_docname: function(frm) {
|
||||
if (frm.doc.reference_docname && frm.doc.reference_doctype) {
|
||||
let fields_to_fetch = ["grand_total"];
|
||||
let party_field = frm.doc.reference_doctype == "Sales Order" ? "customer" : "supplier";
|
||||
|
||||
if (frm.doc.reference_doctype == "Sales Order") {
|
||||
fields_to_fetch.push("project");
|
||||
}
|
||||
|
||||
fields_to_fetch.push(party_field);
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.bank_guarantee.bank_guarantee.get_voucher_details",
|
||||
method: "erpnext.accounts.doctype.bank_guarantee.bank_guarantee.get_vouchar_detials",
|
||||
args: {
|
||||
bank_guarantee_type: frm.doc.bg_type,
|
||||
reference_name: frm.doc.reference_docname,
|
||||
"column_list": fields_to_fetch,
|
||||
"doctype": frm.doc.reference_doctype,
|
||||
"docname": frm.doc.reference_docname
|
||||
},
|
||||
callback: function (r) {
|
||||
callback: function(r) {
|
||||
if (r.message) {
|
||||
if (r.message[party_field]) frm.set_value(party_field, r.message[party_field]);
|
||||
if (r.message.project) frm.set_value("project", r.message.project);
|
||||
if (r.message.grand_total) frm.set_value("amount", r.message.grand_total);
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
start_date: function (frm) {
|
||||
start_date: function(frm) {
|
||||
var end_date = frappe.datetime.add_days(cur_frm.doc.start_date, cur_frm.doc.validity - 1);
|
||||
cur_frm.set_value("end_date", end_date);
|
||||
},
|
||||
validity: function (frm) {
|
||||
validity: function(frm) {
|
||||
var end_date = frappe.datetime.add_days(cur_frm.doc.start_date, cur_frm.doc.validity - 1);
|
||||
cur_frm.set_value("end_date", end_date);
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2,46 +2,15 @@
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
import json
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.desk.search import sanitize_searchfield
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
||||
class BankGuarantee(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
account: DF.Link | None
|
||||
amended_from: DF.Link | None
|
||||
amount: DF.Currency
|
||||
bank: DF.Link | None
|
||||
bank_account: DF.Link | None
|
||||
bank_account_no: DF.Data | None
|
||||
bank_guarantee_number: DF.Data | None
|
||||
bg_type: DF.Literal["", "Receiving", "Providing"]
|
||||
branch_code: DF.Data | None
|
||||
charges: DF.Currency
|
||||
customer: DF.Link | None
|
||||
end_date: DF.Date | None
|
||||
fixed_deposit_number: DF.Data | None
|
||||
iban: DF.Data | None
|
||||
margin_money: DF.Currency
|
||||
more_information: DF.TextEditor | None
|
||||
name_of_beneficiary: DF.Data | None
|
||||
project: DF.Link | None
|
||||
reference_docname: DF.DynamicLink | None
|
||||
reference_doctype: DF.Link | None
|
||||
start_date: DF.Date
|
||||
supplier: DF.Link | None
|
||||
swift_number: DF.Data | None
|
||||
validity: DF.Int
|
||||
# end: auto-generated types
|
||||
|
||||
def validate(self):
|
||||
if not (self.customer or self.supplier):
|
||||
frappe.throw(_("Select the customer or supplier."))
|
||||
@@ -56,18 +25,14 @@ class BankGuarantee(Document):
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_voucher_details(bank_guarantee_type: str, reference_name: str):
|
||||
if not isinstance(reference_name, str):
|
||||
raise TypeError("reference_name must be a string")
|
||||
|
||||
fields_to_fetch = ["grand_total"]
|
||||
|
||||
if bank_guarantee_type == "Receiving":
|
||||
doctype = "Sales Order"
|
||||
fields_to_fetch.append("customer")
|
||||
fields_to_fetch.append("project")
|
||||
else:
|
||||
doctype = "Purchase Order"
|
||||
fields_to_fetch.append("supplier")
|
||||
|
||||
return frappe.db.get_value(doctype, reference_name, fields_to_fetch, as_dict=True)
|
||||
def get_vouchar_detials(column_list, doctype, docname):
|
||||
column_list = json.loads(column_list)
|
||||
for col in column_list:
|
||||
sanitize_searchfield(col)
|
||||
return frappe.db.sql(
|
||||
""" select {columns} from `tab{doctype}` where name=%s""".format(
|
||||
columns=", ".join(column_list), doctype=doctype
|
||||
),
|
||||
docname,
|
||||
as_dict=1,
|
||||
)[0]
|
||||
|
||||
@@ -8,83 +8,67 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
|
||||
return {
|
||||
filters: {
|
||||
company: frm.doc.company,
|
||||
is_company_account: 1,
|
||||
'is_company_account': 1
|
||||
},
|
||||
};
|
||||
});
|
||||
let no_bank_transactions_text = `<div class="text-muted text-center">${__(
|
||||
"No Matching Bank Transactions Found"
|
||||
)}</div>`;
|
||||
set_field_options("no_bank_transactions", no_bank_transactions_text);
|
||||
},
|
||||
|
||||
onload: function (frm) {
|
||||
// Set default filter dates
|
||||
let today = frappe.datetime.get_today();
|
||||
frm.doc.bank_statement_from_date = frappe.datetime.add_months(today, -1);
|
||||
frm.doc.bank_statement_to_date = today;
|
||||
frm.trigger("bank_account");
|
||||
},
|
||||
|
||||
filter_by_reference_date: function (frm) {
|
||||
if (frm.doc.filter_by_reference_date) {
|
||||
frm.set_value("bank_statement_from_date", "");
|
||||
frm.set_value("bank_statement_to_date", "");
|
||||
} else {
|
||||
frm.set_value("from_reference_date", "");
|
||||
frm.set_value("to_reference_date", "");
|
||||
}
|
||||
frm.trigger('bank_account');
|
||||
},
|
||||
|
||||
refresh: function (frm) {
|
||||
frm.disable_save();
|
||||
frappe.require("bank-reconciliation-tool.bundle.js", () => frm.trigger("make_reconciliation_tool"));
|
||||
|
||||
frm.add_custom_button(__("Upload Bank Statement"), () =>
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.bank_statement_import.bank_statement_import.upload_bank_statement",
|
||||
args: {
|
||||
dt: frm.doc.doctype,
|
||||
dn: frm.doc.name,
|
||||
company: frm.doc.company,
|
||||
bank_account: frm.doc.bank_account,
|
||||
},
|
||||
callback: function (r) {
|
||||
if (!r.exc) {
|
||||
var doc = frappe.model.sync(r.message);
|
||||
frappe.set_route("Form", doc[0].doctype, doc[0].name);
|
||||
}
|
||||
},
|
||||
})
|
||||
frappe.require("bank-reconciliation-tool.bundle.js", () =>
|
||||
frm.trigger("make_reconciliation_tool")
|
||||
);
|
||||
frm.upload_statement_button = frm.page.set_secondary_action(
|
||||
__("Upload Bank Statement"),
|
||||
() =>
|
||||
frappe.call({
|
||||
method:
|
||||
"erpnext.accounts.doctype.bank_statement_import.bank_statement_import.upload_bank_statement",
|
||||
args: {
|
||||
dt: frm.doc.doctype,
|
||||
dn: frm.doc.name,
|
||||
company: frm.doc.company,
|
||||
bank_account: frm.doc.bank_account,
|
||||
},
|
||||
callback: function (r) {
|
||||
if (!r.exc) {
|
||||
var doc = frappe.model.sync(r.message);
|
||||
frappe.set_route(
|
||||
"Form",
|
||||
doc[0].doctype,
|
||||
doc[0].name
|
||||
);
|
||||
}
|
||||
},
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
frm.add_custom_button(__("Auto Reconcile"), function () {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.auto_reconcile_vouchers",
|
||||
args: {
|
||||
bank_account: frm.doc.bank_account,
|
||||
from_date: frm.doc.bank_statement_from_date,
|
||||
to_date: frm.doc.bank_statement_to_date,
|
||||
filter_by_reference_date: frm.doc.filter_by_reference_date,
|
||||
from_reference_date: frm.doc.from_reference_date,
|
||||
to_reference_date: frm.doc.to_reference_date,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
frm.add_custom_button(__("Get Unreconciled Entries"), function () {
|
||||
frm.trigger("make_reconciliation_tool");
|
||||
});
|
||||
frm.change_custom_button_type(__("Get Unreconciled Entries"), null, "primary");
|
||||
after_save: function (frm) {
|
||||
frm.trigger("make_reconciliation_tool");
|
||||
},
|
||||
|
||||
bank_account: function (frm) {
|
||||
frappe.db.get_value("Bank Account", frm.doc.bank_account, "account", (r) => {
|
||||
frappe.db.get_value("Account", r.account, "account_currency", (r) => {
|
||||
frm.doc.account_currency = r.account_currency;
|
||||
frm.trigger("render_chart");
|
||||
});
|
||||
});
|
||||
frappe.db.get_value(
|
||||
"Bank Account",
|
||||
frm.doc.bank_account,
|
||||
"account",
|
||||
(r) => {
|
||||
frappe.db.get_value(
|
||||
"Account",
|
||||
r.account,
|
||||
"account_currency",
|
||||
(r) => {
|
||||
frm.currency = r.account_currency;
|
||||
frm.trigger("render_chart");
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
frm.trigger("get_account_opening_balance");
|
||||
},
|
||||
|
||||
@@ -103,7 +87,11 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
|
||||
) {
|
||||
frm.trigger("render_chart");
|
||||
frm.trigger("render");
|
||||
frappe.utils.scroll_to(frm.get_field("reconciliation_tool_cards").$wrapper, true, 30);
|
||||
frappe.utils.scroll_to(
|
||||
frm.get_field("reconciliation_tool_cards").$wrapper,
|
||||
true,
|
||||
30
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -112,10 +100,11 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
|
||||
get_account_opening_balance(frm) {
|
||||
if (frm.doc.bank_account && frm.doc.bank_statement_from_date) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_account_balance",
|
||||
method:
|
||||
"erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_account_balance",
|
||||
args: {
|
||||
bank_account: frm.doc.bank_account,
|
||||
till_date: frappe.datetime.add_days(frm.doc.bank_statement_from_date, -1),
|
||||
till_date: frm.doc.bank_statement_from_date,
|
||||
},
|
||||
callback: (response) => {
|
||||
frm.set_value("account_opening_balance", response.message);
|
||||
@@ -127,7 +116,8 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
|
||||
get_cleared_balance(frm) {
|
||||
if (frm.doc.bank_account && frm.doc.bank_statement_to_date) {
|
||||
return frappe.call({
|
||||
method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_account_balance",
|
||||
method:
|
||||
"erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_account_balance",
|
||||
args: {
|
||||
bank_account: frm.doc.bank_account,
|
||||
till_date: frm.doc.bank_statement_to_date,
|
||||
@@ -139,31 +129,39 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
|
||||
}
|
||||
},
|
||||
|
||||
render_chart(frm) {
|
||||
frm.cards_manager = new erpnext.accounts.bank_reconciliation.NumberCardManager({
|
||||
$reconciliation_tool_cards: frm.get_field("reconciliation_tool_cards").$wrapper,
|
||||
bank_statement_closing_balance: frm.doc.bank_statement_closing_balance,
|
||||
cleared_balance: frm.cleared_balance,
|
||||
currency: frm.doc.account_currency,
|
||||
});
|
||||
},
|
||||
render_chart: frappe.utils.debounce((frm) => {
|
||||
frm.cards_manager = new erpnext.accounts.bank_reconciliation.NumberCardManager(
|
||||
{
|
||||
$reconciliation_tool_cards: frm.get_field(
|
||||
"reconciliation_tool_cards"
|
||||
).$wrapper,
|
||||
bank_statement_closing_balance:
|
||||
frm.doc.bank_statement_closing_balance,
|
||||
cleared_balance: frm.cleared_balance,
|
||||
currency: frm.currency,
|
||||
}
|
||||
);
|
||||
}, 500),
|
||||
|
||||
render(frm) {
|
||||
if (frm.doc.bank_account) {
|
||||
frm.bank_reconciliation_data_table_manager =
|
||||
new erpnext.accounts.bank_reconciliation.DataTableManager({
|
||||
frm.bank_reconciliation_data_table_manager = new erpnext.accounts.bank_reconciliation.DataTableManager(
|
||||
{
|
||||
company: frm.doc.company,
|
||||
bank_account: frm.doc.bank_account,
|
||||
$reconciliation_tool_dt: frm.get_field("reconciliation_tool_dt").$wrapper,
|
||||
$no_bank_transactions: frm.get_field("no_bank_transactions").$wrapper,
|
||||
$reconciliation_tool_dt: frm.get_field(
|
||||
"reconciliation_tool_dt"
|
||||
).$wrapper,
|
||||
$no_bank_transactions: frm.get_field(
|
||||
"no_bank_transactions"
|
||||
).$wrapper,
|
||||
bank_statement_from_date: frm.doc.bank_statement_from_date,
|
||||
bank_statement_to_date: frm.doc.bank_statement_to_date,
|
||||
filter_by_reference_date: frm.doc.filter_by_reference_date,
|
||||
from_reference_date: frm.doc.from_reference_date,
|
||||
to_reference_date: frm.doc.to_reference_date,
|
||||
bank_statement_closing_balance: frm.doc.bank_statement_closing_balance,
|
||||
bank_statement_closing_balance:
|
||||
frm.doc.bank_statement_closing_balance,
|
||||
cards_manager: frm.cards_manager,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -10,11 +10,7 @@
|
||||
"column_break_1",
|
||||
"bank_statement_from_date",
|
||||
"bank_statement_to_date",
|
||||
"from_reference_date",
|
||||
"to_reference_date",
|
||||
"filter_by_reference_date",
|
||||
"column_break_2",
|
||||
"account_currency",
|
||||
"account_opening_balance",
|
||||
"bank_statement_closing_balance",
|
||||
"section_break_1",
|
||||
@@ -40,13 +36,13 @@
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.bank_account && !doc.filter_by_reference_date",
|
||||
"depends_on": "eval: doc.bank_account",
|
||||
"fieldname": "bank_statement_from_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "From Date"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.bank_account && !doc.filter_by_reference_date",
|
||||
"depends_on": "eval: doc.bank_statement_from_date",
|
||||
"fieldname": "bank_statement_to_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "To Date"
|
||||
@@ -60,7 +56,7 @@
|
||||
"fieldname": "account_opening_balance",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Account Opening Balance",
|
||||
"options": "account_currency",
|
||||
"options": "Currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
@@ -68,7 +64,7 @@
|
||||
"fieldname": "bank_statement_closing_balance",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Closing Balance",
|
||||
"options": "account_currency"
|
||||
"options": "Currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_1",
|
||||
@@ -87,38 +83,13 @@
|
||||
"fieldname": "no_bank_transactions",
|
||||
"fieldtype": "HTML",
|
||||
"options": "<div class=\"text-muted text-center\">No Matching Bank Transactions Found</div>"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.filter_by_reference_date",
|
||||
"fieldname": "from_reference_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "From Reference Date"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.filter_by_reference_date",
|
||||
"fieldname": "to_reference_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "To Reference Date"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "filter_by_reference_date",
|
||||
"fieldtype": "Check",
|
||||
"label": "Filter by Reference Date"
|
||||
},
|
||||
{
|
||||
"fieldname": "account_currency",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"label": "Account Currency",
|
||||
"options": "Currency"
|
||||
}
|
||||
],
|
||||
"hide_toolbar": 1,
|
||||
"index_web_pages_for_search": 1,
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2023-03-07 11:02:24.535714",
|
||||
"modified": "2021-04-21 11:13:49.831769",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Reconciliation Tool",
|
||||
@@ -137,6 +108,5 @@
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": []
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,101 +1,9 @@
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe import qb
|
||||
from frappe.tests.utils import FrappeTestCase, change_settings
|
||||
from frappe.utils import add_days, flt, getdate, today
|
||||
|
||||
from erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool import (
|
||||
auto_reconcile_vouchers,
|
||||
get_bank_transactions,
|
||||
)
|
||||
from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry
|
||||
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
|
||||
|
||||
|
||||
class TestBankReconciliationTool(AccountsTestMixin, FrappeTestCase):
|
||||
def setUp(self):
|
||||
self.create_company()
|
||||
self.create_customer()
|
||||
self.clear_old_entries()
|
||||
bank_dt = qb.DocType("Bank")
|
||||
q = qb.from_(bank_dt).delete().where(bank_dt.name == "HDFC").run()
|
||||
self.create_bank_account()
|
||||
|
||||
def tearDown(self):
|
||||
frappe.db.rollback()
|
||||
|
||||
def create_bank_account(self):
|
||||
bank = frappe.get_doc(
|
||||
{
|
||||
"doctype": "Bank",
|
||||
"bank_name": "HDFC",
|
||||
}
|
||||
).save()
|
||||
|
||||
self.bank_account = (
|
||||
frappe.get_doc(
|
||||
{
|
||||
"doctype": "Bank Account",
|
||||
"account_name": "HDFC _current_",
|
||||
"bank": bank,
|
||||
"is_company_account": True,
|
||||
"account": self.bank, # account from Chart of Accounts
|
||||
}
|
||||
)
|
||||
.insert()
|
||||
.name
|
||||
)
|
||||
|
||||
def test_auto_reconcile(self):
|
||||
# make payment
|
||||
from_date = add_days(today(), -1)
|
||||
to_date = today()
|
||||
payment = create_payment_entry(
|
||||
company=self.company,
|
||||
posting_date=from_date,
|
||||
payment_type="Receive",
|
||||
party_type="Customer",
|
||||
party=self.customer,
|
||||
paid_from=self.debit_to,
|
||||
paid_to=self.bank,
|
||||
paid_amount=100,
|
||||
).save()
|
||||
payment.reference_no = "123"
|
||||
payment = payment.save().submit()
|
||||
|
||||
# make bank transaction
|
||||
bank_transaction = (
|
||||
frappe.get_doc(
|
||||
{
|
||||
"doctype": "Bank Transaction",
|
||||
"date": to_date,
|
||||
"deposit": 100,
|
||||
"bank_account": self.bank_account,
|
||||
"reference_number": "123",
|
||||
"currency": "INR",
|
||||
}
|
||||
)
|
||||
.save()
|
||||
.submit()
|
||||
)
|
||||
|
||||
# assert API output pre reconciliation
|
||||
transactions = get_bank_transactions(self.bank_account, from_date, to_date)
|
||||
self.assertEqual(len(transactions), 1)
|
||||
self.assertEqual(transactions[0].name, bank_transaction.name)
|
||||
|
||||
# auto reconcile
|
||||
auto_reconcile_vouchers(
|
||||
bank_account=self.bank_account,
|
||||
from_date=from_date,
|
||||
to_date=to_date,
|
||||
filter_by_reference_date=False,
|
||||
)
|
||||
|
||||
# assert API output post reconciliation
|
||||
transactions = get_bank_transactions(self.bank_account, from_date, to_date)
|
||||
self.assertEqual(len(transactions), 0)
|
||||
class TestBankReconciliationTool(unittest.TestCase):
|
||||
pass
|
||||
|
||||
@@ -7,9 +7,11 @@ frappe.ui.form.on("Bank Statement Import", {
|
||||
frm.import_in_progress = false;
|
||||
if (data_import !== frm.doc.name) return;
|
||||
frappe.model.clear_doc("Bank Statement Import", frm.doc.name);
|
||||
frappe.model.with_doc("Bank Statement Import", frm.doc.name).then(() => {
|
||||
frm.refresh();
|
||||
});
|
||||
frappe.model
|
||||
.with_doc("Bank Statement Import", frm.doc.name)
|
||||
.then(() => {
|
||||
frm.refresh();
|
||||
});
|
||||
});
|
||||
frappe.realtime.on("data_import_progress", (data) => {
|
||||
frm.import_in_progress = true;
|
||||
@@ -36,9 +38,20 @@ frappe.ui.form.on("Bank Statement Import", {
|
||||
: __("Updating {0} of {1}, {2}", message_args);
|
||||
}
|
||||
if (data.skipping) {
|
||||
message = __("Skipping {0} of {1}, {2}", [data.current, data.total, eta_message]);
|
||||
message = __(
|
||||
"Skipping {0} of {1}, {2}",
|
||||
[
|
||||
data.current,
|
||||
data.total,
|
||||
eta_message,
|
||||
]
|
||||
);
|
||||
}
|
||||
frm.dashboard.show_progress(__("Import Progress"), percent, message);
|
||||
frm.dashboard.show_progress(
|
||||
__("Import Progress"),
|
||||
percent,
|
||||
message
|
||||
);
|
||||
frm.page.set_indicator(__("In Progress"), "orange");
|
||||
|
||||
// hide progress when complete
|
||||
@@ -80,12 +93,15 @@ frappe.ui.form.on("Bank Statement Import", {
|
||||
frm.trigger("show_report_error_button");
|
||||
|
||||
if (frm.doc.status === "Partial Success") {
|
||||
frm.add_custom_button(__("Export Errored Rows"), () => frm.trigger("export_errored_rows"));
|
||||
frm.add_custom_button(__("Export Errored Rows"), () =>
|
||||
frm.trigger("export_errored_rows")
|
||||
);
|
||||
}
|
||||
|
||||
if (frm.doc.status.includes("Success")) {
|
||||
frm.add_custom_button(__("Go to {0} List", [__(frm.doc.reference_doctype)]), () =>
|
||||
frappe.set_route("List", frm.doc.reference_doctype)
|
||||
frm.add_custom_button(
|
||||
__("Go to {0} List", [frm.doc.reference_doctype]),
|
||||
() => frappe.set_route("List", frm.doc.reference_doctype)
|
||||
);
|
||||
}
|
||||
},
|
||||
@@ -102,8 +118,13 @@ frappe.ui.form.on("Bank Statement Import", {
|
||||
frm.disable_save();
|
||||
if (frm.doc.status !== "Success") {
|
||||
if (!frm.is_new() && frm.has_import_file()) {
|
||||
let label = frm.doc.status === "Pending" ? __("Start Import") : __("Retry");
|
||||
frm.page.set_primary_action(label, () => frm.events.start_import(frm));
|
||||
let label =
|
||||
frm.doc.status === "Pending"
|
||||
? __("Start Import")
|
||||
: __("Retry");
|
||||
frm.page.set_primary_action(label, () =>
|
||||
frm.events.start_import(frm)
|
||||
);
|
||||
} else {
|
||||
frm.page.set_primary_action(__("Save"), () => frm.save());
|
||||
}
|
||||
@@ -120,7 +141,7 @@ frappe.ui.form.on("Bank Statement Import", {
|
||||
},
|
||||
|
||||
show_import_status(frm) {
|
||||
let import_log = JSON.parse(frm.doc.statement_import_log || "[]");
|
||||
let import_log = JSON.parse(frm.doc.import_log || "[]");
|
||||
let successful_records = import_log.filter((log) => log.success);
|
||||
let failed_records = import_log.filter((log) => !log.success);
|
||||
if (successful_records.length === 0) return;
|
||||
@@ -145,24 +166,24 @@ frappe.ui.form.on("Bank Statement Import", {
|
||||
message =
|
||||
successful_records.length > 1
|
||||
? __(
|
||||
"Successfully imported {0} records out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
||||
message_args
|
||||
)
|
||||
"Successfully imported {0} records out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
||||
message_args
|
||||
)
|
||||
: __(
|
||||
"Successfully imported {0} record out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
||||
message_args
|
||||
);
|
||||
"Successfully imported {0} record out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
||||
message_args
|
||||
);
|
||||
} else {
|
||||
message =
|
||||
successful_records.length > 1
|
||||
? __(
|
||||
"Successfully updated {0} records out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
||||
message_args
|
||||
)
|
||||
"Successfully updated {0} records out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
||||
message_args
|
||||
)
|
||||
: __(
|
||||
"Successfully updated {0} record out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
||||
message_args
|
||||
);
|
||||
"Successfully updated {0} record out of {1}. Click on Export Errored Rows, fix the errors and import again.",
|
||||
message_args
|
||||
);
|
||||
}
|
||||
}
|
||||
frm.dashboard.set_headline(message);
|
||||
@@ -205,7 +226,8 @@ frappe.ui.form.on("Bank Statement Import", {
|
||||
},
|
||||
|
||||
download_template() {
|
||||
let method = "/api/method/frappe.core.doctype.data_import.data_import.download_template";
|
||||
let method =
|
||||
"/api/method/frappe.core.doctype.data_import.data_import.download_template";
|
||||
|
||||
open_url_post(method, {
|
||||
doctype: "Bank Transaction",
|
||||
@@ -218,7 +240,7 @@ frappe.ui.form.on("Bank Statement Import", {
|
||||
"description",
|
||||
"reference_number",
|
||||
"bank_account",
|
||||
"currency",
|
||||
"currency"
|
||||
],
|
||||
},
|
||||
});
|
||||
@@ -287,9 +309,12 @@ frappe.ui.form.on("Bank Statement Import", {
|
||||
// method: 'frappe.core.doctype.data_import.data_import.get_preview_from_template',
|
||||
|
||||
show_import_preview(frm, preview_data) {
|
||||
let import_log = JSON.parse(frm.doc.statement_import_log || "[]");
|
||||
let import_log = JSON.parse(frm.doc.import_log || "[]");
|
||||
|
||||
if (frm.import_preview && frm.import_preview.doctype === frm.doc.reference_doctype) {
|
||||
if (
|
||||
frm.import_preview &&
|
||||
frm.import_preview.doctype === frm.doc.reference_doctype
|
||||
) {
|
||||
frm.import_preview.preview_data = preview_data;
|
||||
frm.import_preview.import_log = import_log;
|
||||
frm.import_preview.refresh();
|
||||
@@ -305,10 +330,19 @@ frappe.ui.form.on("Bank Statement Import", {
|
||||
frm,
|
||||
events: {
|
||||
remap_column(changed_map) {
|
||||
let template_options = JSON.parse(frm.doc.template_options || "{}");
|
||||
template_options.column_to_field_map = template_options.column_to_field_map || {};
|
||||
Object.assign(template_options.column_to_field_map, changed_map);
|
||||
frm.set_value("template_options", JSON.stringify(template_options));
|
||||
let template_options = JSON.parse(
|
||||
frm.doc.template_options || "{}"
|
||||
);
|
||||
template_options.column_to_field_map =
|
||||
template_options.column_to_field_map || {};
|
||||
Object.assign(
|
||||
template_options.column_to_field_map,
|
||||
changed_map
|
||||
);
|
||||
frm.set_value(
|
||||
"template_options",
|
||||
JSON.stringify(template_options)
|
||||
);
|
||||
frm.save().then(() => frm.trigger("import_file"));
|
||||
},
|
||||
},
|
||||
@@ -318,11 +352,10 @@ frappe.ui.form.on("Bank Statement Import", {
|
||||
|
||||
export_errored_rows(frm) {
|
||||
open_url_post(
|
||||
"/api/method/erpnext.accounts.doctype.bank_statement_import.bank_statement_import.download_errored_template",
|
||||
"/api/method/frappe.core.doctype.data_import.data_import.download_errored_template",
|
||||
{
|
||||
data_import_name: frm.doc.name,
|
||||
},
|
||||
true
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
@@ -342,7 +375,8 @@ frappe.ui.form.on("Bank Statement Import", {
|
||||
let other_warnings = [];
|
||||
for (let warning of warnings) {
|
||||
if (warning.row) {
|
||||
warnings_by_row[warning.row] = warnings_by_row[warning.row] || [];
|
||||
warnings_by_row[warning.row] =
|
||||
warnings_by_row[warning.row] || [];
|
||||
warnings_by_row[warning.row].push(warning);
|
||||
} else {
|
||||
other_warnings.push(warning);
|
||||
@@ -357,7 +391,9 @@ frappe.ui.form.on("Bank Statement Import", {
|
||||
if (w.field) {
|
||||
let label =
|
||||
w.field.label +
|
||||
(w.field.parent !== frm.doc.reference_doctype ? ` (${w.field.parent})` : "");
|
||||
(w.field.parent !== frm.doc.reference_doctype
|
||||
? ` (${w.field.parent})`
|
||||
: "");
|
||||
return `<li>${label}: ${w.message}</li>`;
|
||||
}
|
||||
return `<li>${w.message}</li>`;
|
||||
@@ -376,9 +412,10 @@ frappe.ui.form.on("Bank Statement Import", {
|
||||
.map((warning) => {
|
||||
let header = "";
|
||||
if (warning.col) {
|
||||
let column_number = `<span class="text-uppercase">${__("Column {0}", [
|
||||
warning.col,
|
||||
])}</span>`;
|
||||
let column_number = `<span class="text-uppercase">${__(
|
||||
"Column {0}",
|
||||
[warning.col]
|
||||
)}</span>`;
|
||||
let column_header = columns[warning.col].header_title;
|
||||
header = `${column_number} (${column_header})`;
|
||||
}
|
||||
@@ -402,7 +439,7 @@ frappe.ui.form.on("Bank Statement Import", {
|
||||
},
|
||||
|
||||
show_import_log(frm) {
|
||||
let import_log = JSON.parse(frm.doc.statement_import_log || "[]");
|
||||
let import_log = JSON.parse(frm.doc.import_log || "[]");
|
||||
let logs = import_log;
|
||||
frm.toggle_display("import_log", false);
|
||||
frm.toggle_display("import_log_section", logs.length > 0);
|
||||
@@ -417,28 +454,36 @@ frappe.ui.form.on("Bank Statement Import", {
|
||||
let html = "";
|
||||
if (log.success) {
|
||||
if (frm.doc.import_type === "Insert New Records") {
|
||||
html = __("Successfully imported {0}", [
|
||||
`<span class="underline">${frappe.utils.get_form_link(
|
||||
frm.doc.reference_doctype,
|
||||
log.docname,
|
||||
true
|
||||
)}<span>`,
|
||||
]);
|
||||
html = __(
|
||||
"Successfully imported {0}", [
|
||||
`<span class="underline">${frappe.utils.get_form_link(
|
||||
frm.doc.reference_doctype,
|
||||
log.docname,
|
||||
true
|
||||
)}<span>`,
|
||||
]
|
||||
);
|
||||
} else {
|
||||
html = __("Successfully updated {0}", [
|
||||
`<span class="underline">${frappe.utils.get_form_link(
|
||||
frm.doc.reference_doctype,
|
||||
log.docname,
|
||||
true
|
||||
)}<span>`,
|
||||
]);
|
||||
html = __(
|
||||
"Successfully updated {0}", [
|
||||
`<span class="underline">${frappe.utils.get_form_link(
|
||||
frm.doc.reference_doctype,
|
||||
log.docname,
|
||||
true
|
||||
)}<span>`,
|
||||
]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
let messages = log.messages
|
||||
.map(JSON.parse)
|
||||
.map((m) => {
|
||||
let title = m.title ? `<strong>${m.title}</strong>` : "";
|
||||
let message = m.message ? `<div>${m.message}</div>` : "";
|
||||
let title = m.title
|
||||
? `<strong>${m.title}</strong>`
|
||||
: "";
|
||||
let message = m.message
|
||||
? `<div>${m.message}</div>`
|
||||
: "";
|
||||
return title + message;
|
||||
})
|
||||
.join("");
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"section_import_preview",
|
||||
"import_preview",
|
||||
"import_log_section",
|
||||
"statement_import_log",
|
||||
"import_log",
|
||||
"show_failed_logs",
|
||||
"import_log_preview",
|
||||
"reference_doctype",
|
||||
@@ -90,6 +90,12 @@
|
||||
"options": "JSON",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "import_log",
|
||||
"fieldtype": "Code",
|
||||
"label": "Import Log",
|
||||
"options": "JSON"
|
||||
},
|
||||
{
|
||||
"fieldname": "import_log_section",
|
||||
"fieldtype": "Section Break",
|
||||
@@ -192,17 +198,11 @@
|
||||
{
|
||||
"fieldname": "column_break_4",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "statement_import_log",
|
||||
"fieldtype": "Code",
|
||||
"label": "Statement Import Log",
|
||||
"options": "JSON"
|
||||
}
|
||||
],
|
||||
"hide_toolbar": 1,
|
||||
"links": [],
|
||||
"modified": "2022-09-07 11:11:40.293317",
|
||||
"modified": "2021-05-12 14:17:37.777246",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Statement Import",
|
||||
|
||||
@@ -20,30 +20,6 @@ INVALID_VALUES = ("", None)
|
||||
|
||||
|
||||
class BankStatementImport(DataImport):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.types import DF
|
||||
|
||||
bank: DF.Link | None
|
||||
bank_account: DF.Link
|
||||
company: DF.Link
|
||||
google_sheets_url: DF.Data | None
|
||||
import_file: DF.Attach | None
|
||||
import_type: DF.Literal["", "Insert New Records", "Update Existing Records"]
|
||||
mute_emails: DF.Check
|
||||
reference_doctype: DF.Link
|
||||
show_failed_logs: DF.Check
|
||||
statement_import_log: DF.Code | None
|
||||
status: DF.Literal["Pending", "Success", "Partial Success", "Error"]
|
||||
submit_after_import: DF.Check
|
||||
template_options: DF.Code | None
|
||||
template_warnings: DF.Code | None
|
||||
# end: auto-generated types
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(BankStatementImport, self).__init__(*args, **kwargs)
|
||||
|
||||
@@ -77,20 +53,21 @@ class BankStatementImport(DataImport):
|
||||
if "Bank Account" not in json.dumps(preview["columns"]):
|
||||
frappe.throw(_("Please add the Bank Account column"))
|
||||
|
||||
from frappe.utils.background_jobs import is_job_enqueued
|
||||
from frappe.core.page.background_jobs.background_jobs import get_info
|
||||
from frappe.utils.scheduler import is_scheduler_inactive
|
||||
|
||||
if is_scheduler_inactive() and not frappe.flags.in_test:
|
||||
frappe.throw(_("Scheduler is inactive. Cannot import data."), title=_("Scheduler Inactive"))
|
||||
|
||||
job_id = f"bank_statement_import::{self.name}"
|
||||
if not is_job_enqueued(job_id):
|
||||
enqueued_jobs = [d.get("job_name") for d in get_info()]
|
||||
|
||||
if self.name not in enqueued_jobs:
|
||||
enqueue(
|
||||
start_import,
|
||||
queue="default",
|
||||
timeout=6000,
|
||||
event="data_import",
|
||||
job_id=job_id,
|
||||
job_name=self.name,
|
||||
data_import=self.name,
|
||||
bank_account=self.bank_account,
|
||||
import_file_path=self.import_file,
|
||||
|
||||
@@ -1,34 +1,36 @@
|
||||
let imports_in_progress = [];
|
||||
|
||||
frappe.listview_settings["Bank Statement Import"] = {
|
||||
frappe.listview_settings['Bank Statement Import'] = {
|
||||
onload(listview) {
|
||||
frappe.realtime.on("data_import_progress", (data) => {
|
||||
frappe.realtime.on('data_import_progress', data => {
|
||||
if (!imports_in_progress.includes(data.data_import)) {
|
||||
imports_in_progress.push(data.data_import);
|
||||
}
|
||||
});
|
||||
frappe.realtime.on("data_import_refresh", (data) => {
|
||||
imports_in_progress = imports_in_progress.filter((d) => d !== data.data_import);
|
||||
frappe.realtime.on('data_import_refresh', data => {
|
||||
imports_in_progress = imports_in_progress.filter(
|
||||
d => d !== data.data_import
|
||||
);
|
||||
listview.refresh();
|
||||
});
|
||||
},
|
||||
get_indicator: function (doc) {
|
||||
get_indicator: function(doc) {
|
||||
var colors = {
|
||||
Pending: "orange",
|
||||
"Not Started": "orange",
|
||||
"Partial Success": "orange",
|
||||
Success: "green",
|
||||
"In Progress": "orange",
|
||||
Error: "red",
|
||||
'Pending': 'orange',
|
||||
'Not Started': 'orange',
|
||||
'Partial Success': 'orange',
|
||||
'Success': 'green',
|
||||
'In Progress': 'orange',
|
||||
'Error': 'red'
|
||||
};
|
||||
let status = doc.status;
|
||||
if (imports_in_progress.includes(doc.name)) {
|
||||
status = "In Progress";
|
||||
status = 'In Progress';
|
||||
}
|
||||
if (status == "Pending") {
|
||||
status = "Not Started";
|
||||
if (status == 'Pending') {
|
||||
status = 'Not Started';
|
||||
}
|
||||
return [__(status), colors[status], "status,=," + doc.status];
|
||||
return [__(status), colors[status], 'status,=,' + doc.status];
|
||||
},
|
||||
hide_name_column: true,
|
||||
hide_name_column: true
|
||||
};
|
||||
|
||||
@@ -1,178 +0,0 @@
|
||||
from typing import Tuple, Union
|
||||
|
||||
import frappe
|
||||
from frappe.utils import flt
|
||||
from rapidfuzz import fuzz, process
|
||||
|
||||
|
||||
class AutoMatchParty:
|
||||
"""
|
||||
Matches by Account/IBAN and then by Party Name/Description sequentially.
|
||||
Returns when a result is obtained.
|
||||
|
||||
Result (if present) is of the form: (Party Type, Party,)
|
||||
"""
|
||||
|
||||
def __init__(self, **kwargs) -> None:
|
||||
self.__dict__.update(kwargs)
|
||||
|
||||
def get(self, key):
|
||||
return self.__dict__.get(key, None)
|
||||
|
||||
def match(self) -> Union[Tuple, None]:
|
||||
result = None
|
||||
result = AutoMatchbyAccountIBAN(
|
||||
bank_party_account_number=self.bank_party_account_number,
|
||||
bank_party_iban=self.bank_party_iban,
|
||||
deposit=self.deposit,
|
||||
).match()
|
||||
|
||||
fuzzy_matching_enabled = frappe.db.get_single_value("Accounts Settings", "enable_fuzzy_matching")
|
||||
if not result and fuzzy_matching_enabled:
|
||||
result = AutoMatchbyPartyNameDescription(
|
||||
bank_party_name=self.bank_party_name, description=self.description, deposit=self.deposit
|
||||
).match()
|
||||
|
||||
return result
|
||||
|
||||
|
||||
class AutoMatchbyAccountIBAN:
|
||||
def __init__(self, **kwargs) -> None:
|
||||
self.__dict__.update(kwargs)
|
||||
|
||||
def get(self, key):
|
||||
return self.__dict__.get(key, None)
|
||||
|
||||
def match(self):
|
||||
if not (self.bank_party_account_number or self.bank_party_iban):
|
||||
return None
|
||||
|
||||
result = self.match_account_in_party()
|
||||
return result
|
||||
|
||||
def match_account_in_party(self) -> Union[Tuple, None]:
|
||||
"""Check if there is a IBAN/Account No. match in Customer/Supplier/Employee"""
|
||||
result = None
|
||||
parties = get_parties_in_order(self.deposit)
|
||||
or_filters = self.get_or_filters()
|
||||
|
||||
for party in parties:
|
||||
party_result = frappe.db.get_all(
|
||||
"Bank Account", or_filters=or_filters, pluck="party", limit_page_length=1
|
||||
)
|
||||
|
||||
if party == "Employee" and not party_result:
|
||||
# Search in Bank Accounts first for Employee, and then Employee record
|
||||
if "bank_account_no" in or_filters:
|
||||
or_filters["bank_ac_no"] = or_filters.pop("bank_account_no")
|
||||
|
||||
party_result = frappe.db.get_all(
|
||||
party, or_filters=or_filters, pluck="name", limit_page_length=1
|
||||
)
|
||||
|
||||
if party_result:
|
||||
result = (
|
||||
party,
|
||||
party_result[0],
|
||||
)
|
||||
break
|
||||
|
||||
return result
|
||||
|
||||
def get_or_filters(self) -> dict:
|
||||
or_filters = {}
|
||||
if self.bank_party_account_number:
|
||||
or_filters["bank_account_no"] = self.bank_party_account_number
|
||||
|
||||
if self.bank_party_iban:
|
||||
or_filters["iban"] = self.bank_party_iban
|
||||
|
||||
return or_filters
|
||||
|
||||
|
||||
class AutoMatchbyPartyNameDescription:
|
||||
def __init__(self, **kwargs) -> None:
|
||||
self.__dict__.update(kwargs)
|
||||
|
||||
def get(self, key):
|
||||
return self.__dict__.get(key, None)
|
||||
|
||||
def match(self) -> Union[Tuple, None]:
|
||||
# fuzzy search by customer/supplier & employee
|
||||
if not (self.bank_party_name or self.description):
|
||||
return None
|
||||
|
||||
result = self.match_party_name_desc_in_party()
|
||||
return result
|
||||
|
||||
def match_party_name_desc_in_party(self) -> Union[Tuple, None]:
|
||||
"""Fuzzy search party name and/or description against parties in the system"""
|
||||
result = None
|
||||
parties = get_parties_in_order(self.deposit)
|
||||
|
||||
for party in parties:
|
||||
filters = {"status": "Active"} if party == "Employee" else {"disabled": 0}
|
||||
names = frappe.get_all(party, filters=filters, pluck=party.lower() + "_name")
|
||||
|
||||
for field in ["bank_party_name", "description"]:
|
||||
if not self.get(field):
|
||||
continue
|
||||
|
||||
result, skip = self.fuzzy_search_and_return_result(party, names, field)
|
||||
if result or skip:
|
||||
break
|
||||
|
||||
if result or skip:
|
||||
# Skip If: It was hard to distinguish between close matches and so match is None
|
||||
# OR if the right match was found
|
||||
break
|
||||
|
||||
return result
|
||||
|
||||
def fuzzy_search_and_return_result(self, party, names, field) -> Union[Tuple, None]:
|
||||
skip = False
|
||||
result = process.extract(query=self.get(field), choices=names, scorer=fuzz.token_set_ratio)
|
||||
party_name, skip = self.process_fuzzy_result(result)
|
||||
|
||||
if not party_name:
|
||||
return None, skip
|
||||
|
||||
return (
|
||||
party,
|
||||
party_name,
|
||||
), skip
|
||||
|
||||
def process_fuzzy_result(self, result: Union[list, None]):
|
||||
"""
|
||||
If there are multiple valid close matches return None as result may be faulty.
|
||||
Return the result only if one accurate match stands out.
|
||||
|
||||
Returns: Result, Skip (whether or not to discontinue matching)
|
||||
"""
|
||||
PARTY, SCORE, CUTOFF = 0, 1, 80
|
||||
|
||||
if not result or not len(result):
|
||||
return None, False
|
||||
|
||||
first_result = result[0]
|
||||
if len(result) == 1:
|
||||
return (first_result[PARTY] if first_result[SCORE] > CUTOFF else None), True
|
||||
|
||||
second_result = result[1]
|
||||
if first_result[SCORE] > CUTOFF:
|
||||
# If multiple matches with the same score, return None but discontinue matching
|
||||
# Matches were found but were too close to distinguish between
|
||||
if first_result[SCORE] == second_result[SCORE]:
|
||||
return None, True
|
||||
|
||||
return first_result[PARTY], True
|
||||
else:
|
||||
return None, False
|
||||
|
||||
|
||||
def get_parties_in_order(deposit: float) -> list:
|
||||
parties = ["Supplier", "Employee", "Customer"] # most -> least likely to receive
|
||||
if flt(deposit) > 0:
|
||||
parties = ["Customer", "Supplier", "Employee"] # most -> least likely to pay
|
||||
|
||||
return parties
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
frappe.ui.form.on("Bank Transaction", {
|
||||
onload(frm) {
|
||||
frm.set_query("payment_document", "payment_entries", function () {
|
||||
frm.set_query("payment_document", "payment_entries", function() {
|
||||
const payment_doctypes = frm.events.get_payment_doctypes(frm);
|
||||
return {
|
||||
filters: {
|
||||
@@ -12,18 +12,12 @@ frappe.ui.form.on("Bank Transaction", {
|
||||
};
|
||||
});
|
||||
},
|
||||
refresh(frm) {
|
||||
if (!frm.is_dirty() && frm.doc.payment_entries.length > 0) {
|
||||
frm.add_custom_button(__("Unreconcile Transaction"), () => {
|
||||
frm.call("remove_payment_entries").then(() => frm.refresh());
|
||||
});
|
||||
}
|
||||
},
|
||||
bank_account: function (frm) {
|
||||
|
||||
bank_account: function(frm) {
|
||||
set_bank_statement_filter(frm);
|
||||
},
|
||||
|
||||
setup: function (frm) {
|
||||
setup: function(frm) {
|
||||
frm.set_query("party_type", function () {
|
||||
return {
|
||||
filters: {
|
||||
@@ -33,10 +27,15 @@ frappe.ui.form.on("Bank Transaction", {
|
||||
});
|
||||
},
|
||||
|
||||
get_payment_doctypes: function () {
|
||||
get_payment_doctypes: function() {
|
||||
// get payment doctypes from all the apps
|
||||
return ["Payment Entry", "Journal Entry", "Sales Invoice", "Purchase Invoice", "Bank Transaction"];
|
||||
},
|
||||
return [
|
||||
"Payment Entry",
|
||||
"Journal Entry",
|
||||
"Sales Invoice",
|
||||
"Purchase Invoice",
|
||||
];
|
||||
}
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Bank Transaction Payments", {
|
||||
@@ -48,11 +47,10 @@ frappe.ui.form.on("Bank Transaction Payments", {
|
||||
const update_clearance_date = (frm, cdt, cdn) => {
|
||||
if (frm.doc.docstatus === 1) {
|
||||
frappe
|
||||
.xcall("erpnext.accounts.doctype.bank_transaction.bank_transaction.unclear_reference_payment", {
|
||||
doctype: cdt,
|
||||
docname: cdn,
|
||||
bt_name: frm.doc.name,
|
||||
})
|
||||
.xcall(
|
||||
"erpnext.accounts.doctype.bank_transaction.bank_transaction.unclear_reference_payment",
|
||||
{ doctype: cdt, docname: cdn }
|
||||
)
|
||||
.then((e) => {
|
||||
if (e == "success") {
|
||||
frappe.show_alert({
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user