Compare commits

..

1 Commits

Author SHA1 Message Date
Ankush Menat
d3117cca0c perf: add indexes on payment entry reference
Adds index on:
1. reference doctype
2. reference name

*Why not composite index?*

There are three type of queries on this doctype

- filtering ref_doctype - doctype index helps here
- filtering ref_name - name index helps here
- filtering both - name index helps here too. Since it has sufficiently
  high cardinality. Composite index wont help in case where ref_doctype
  isn't specfied.
2022-12-12 12:32:14 +05:30
3960 changed files with 791032 additions and 2448300 deletions

View File

@@ -1,12 +0,0 @@
reviews:
auto_review:
ignore_title_keywords:
- "sync translations"
- "update POT file"
- "style: "
review_status: false
poem: false
collapse_walkthrough: true
sequence_diagrams: false
changed_files_summary: false
high_level_summary: false

View File

@@ -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 = 1

View File

@@ -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
}
}

View File

@@ -28,26 +28,4 @@ b147b85e6ac19a9220cd1e2958a6ebd99373283a
494bd9ef78313436f0424b918f200dab8fc7c20b
# bulk format python code with black
baec607ff5905b1c67531096a9cf50ec7ff00a5d
# bulk refactor with sourcery
eb9ee3f79b94e594fc6dfa4f6514580e125eee8c
# js formatting
ec74a5e56617bbd76ac402451468fd4668af543d
# ruff formatting
a308792ee7fda18a681e9181f4fd00b36385bc23
# noisy typing refactoring of get_item_details
7b7211ac79c248a79ba8a999ff34e734d874c0ae
d827ed21adc7b36047e247cbb0dc6388d048a7f9
# `frappe.flags.in_test` => `frappe.in_test`
7a482a69985c952de0e8193c9d4e086aee65ee6d
# these commits actually changed something valuable
# but they have a lot of whitespace changes that make blame noisy
# PR: https://github.com/frappe/erpnext/pull/49816
3ffd50c772735877b330d010c1058f623da8721d
0e8f8677b8eb31e7834f72d1c6314d3c3f392ca6
baec607ff5905b1c67531096a9cf50ec7ff00a5d

View File

@@ -1,4 +1,4 @@
### Introduction (for first timers)
### Introduction (first timers)
Thank you for your interest in raising an Issue with ERPNext. An Issue could mean a bug report or a request for a missing feature. By raising a bug report, you are contributing to the development of ERPNext and this is the first step of participating in the community. Bug reports are very helpful for developers as they quickly fix the issue before other users start facing it.
@@ -6,31 +6,31 @@ Feature requests are also a great way to take the product forward. New ideas can
When you are raising an Issue, you should keep a few things in mind. Remember that the developer does not have access to your machine so you must give all the information you can while raising an Issue. If you are suggesting a feature, you should be very clear about what you want.
The Issue list is not the right place to ask a question or start a general discussion. If you want to do that, then the right place is the forum [https://discuss.frappe.io](https://discuss.frappe.io/c/erpnext/6).
The Issue list is not the right place to ask a question or start a general discussion. If you want to do that , then the right place is the forum [https://discuss.erpnext.com](https://discuss.erpnext.com).
### Reply and Closing Policy
If your issue is not clear or does not meet the guidelines, then it will be closed. If it is closed, please supply the requested information and re-open it.
If your issue is not clear or does not meet the guidelines, then it will be closed. If it is closed, please supply the information asked and re-open it.
### General Issue Guidelines
1. **Search existing Issues:** Before raising an Issue, search if it has been raised before. Maybe add a 👍 or give additional help by creating a mockup if it is not already created.
2. **Report each issue separately:** Don't club multiple, unrelated issues in one note.
3. **Brief:** Please don't include long explanations. Use screenshots and bullet points instead of descriptive paragraphs.
1. **Search existing Issues:** Before raising a Issue, search if it has been raised before. Maybe add a 👍 or give additional help by creating a mockup if it is not already created.
1. **Report each issue separately:** Don't club multiple, unreleated issues in one note.
1. **Brief:** Please don't include long explanations. Use screenshots and bullet points instead of descriptive paragraphs.
### Bug Report Guidelines
1. **Steps to Reproduce:** The bug report must have a list of steps needed to reproduce a bug. If we cannot reproduce it, then we cannot solve it.
2. **Version Number:** Please add the version number in your report. Often a bug is fixed in the latest version.
3. **Clear Title:** Add a clear subject to your bug report like "Unable to submit Purchase Order without Basic Rate" instead of just "Cannot Submit".
4. **Screenshots:** Screenshots are a great way of communicating issues. Try adding annotations or using LICEcap to take a screencast in `.gif` format.
1. **Version Number:** Please add the version number in your report. Often a bug is fixed in the latest version
1. **Clear Title:** Add a clear subject to your bug report like "Unable to submit Purchase Order without Basic Rate" instead of just "Cannot Submit"
1. **Screenshots:** Screenshots are a great way of communicating issues. Try adding annotations or using LiceCAP to take a screencast in `gif`.
### Feature Request Guidelines
1. **Clarity:** Clearly specify how you want the feature to behave. Don't just say "I would like multiple PDF formats", instead say "Ability to add multiple print formats for customers with different languages".
2. **Solution:** Try to identify what the feature should look like.
3. **Mockups:** Mockups are a great way to explain your requirement.
1. **Clarity:** Clearly specify how do you want the feature to behave. Don't just say "I would like multiple PDF formats", say that "Ability to add multiple print formats for customers with different languages".
1. **Solution:** Try and identify how the feature should look like.
1. **Mockups:** Mockups are a great way to explain your requirement.
### What if my issue is closed
### What if my Issue is closed
Don't worry, take the feedback, supply the correct information and re-open it!

View File

@@ -9,7 +9,7 @@ body:
Welcome to ERPNext issue tracker! Before creating an issue, please heed the following:
1. This tracker should only be used to report bugs and request features / enhancements to ERPNext
- For questions and general support, checkout the [user manual](https://docs.erpnext.com/) or use [forum](https://discuss.frappe.io/c/erpnext/6)
- For questions and general support, checkout the [user manual](https://docs.erpnext.com/) or use [forum](https://discuss.erpnext.com)
- For documentation issues, propose edit on [documentation site](https://docs.erpnext.com/) directly.
2. When making a bug report, make sure you provide all required information. The easier it is for
maintainers to reproduce, the faster it'll be fixed.
@@ -60,7 +60,7 @@ body:
description: Share exact version number of Frappe and ERPNext you are using.
placeholder: |
Frappe version -
ERPNext version -
ERPNext Verion -
validations:
required: true

View File

@@ -1,5 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Community Forum
url: https://discuss.frappe.io/c/erpnext/6
url: https://discuss.erpnext.com/
about: For general QnA, discussions and community help.

View File

@@ -1,6 +1,6 @@
---
name: Feature request
about: Suggest an idea or enhancement for ERPNext
about: Suggest an idea to improve ERPNext
title: ''
labels: feature-request
assignees: ''
@@ -11,27 +11,23 @@ assignees: ''
Welcome to ERPNext issue tracker! Before creating an issue, please heed the following:
1. This tracker should only be used to report bugs and request features / enhancements to ERPNext
- For questions and general support, checkout the manual https://docs.erpnext.com or use https://discuss.frappe.io/c/erpnext/6
- For questions and general support, checkout the manual https://erpnext.com/docs/user/manual/en or use https://discuss.erpnext.com
2. Use the search function before creating a new issue. Duplicates will be closed and directed to
the original discussion.
3. When making a feature request, make sure to be as verbose as possible. The better you convey your message, the greater the drive to make it happen.
Please keep in mind that we get many requests and we can't possibly work on all of them, we prioritize development based on the goals of the product and organization. Feature requests are still welcome as it helps us in research when we do decide to work on the requested feature.
Please keep in mind that we get many many requests and we can't possibly work on all of them, we prioritize development based on the goals of the product and organization. Feature requests are still welcome as it helps us in research when we do decide to work on the requested feature.
If you're in urgent need of a feature, please try the following channels to get paid developments done quickly:
If you're in urgent need to a feature, please try the following channels to get paid developments done quickly:
1. Certified ERPNext partners: https://erpnext.com/partners
2. Developer community on ERPNext forums: https://discuss.frappe.io/c/framework/5
2. Developer community on ERPNext forums: https://discuss.erpnext.com/c/developers/5
3. Telegram group for ERPNext/Frappe development work: https://t.me/erpnext_opps
-->
## Before Submitting
- [ ] I searched existing issues and confirmed this is not a duplicate
- [ ] This is a feature request, not a bug or support question
- [ ] For support: https://discuss.frappe.io/c/erpnext/6
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. As a [role], I have to [painful task] because [missing feature].
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
@@ -39,17 +35,5 @@ A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Impact**
<!-- Check one: -->
- [ ] Blocks critical workflow — no viable workaround
- [ ] Significant friction — workaround exists but is painful
- [ ] Nice to have — minor improvement
**Additional context**
Add any other context or screenshots about the feature request here.
**Environment**
- ERPNext Version: <!-- Find this in Help > About, e.g. v15.12.0 -->
- Frappe Version: <!-- Find this in Help > About, e.g. v15.10.0 -->
- Deployment: <!-- Frappe Cloud / Self-hosted / ERPNext Cloud -->

View File

@@ -66,8 +66,7 @@ ignore =
F841,
E713,
E712,
B023,
B028
B023
max-line-length = 200

View File

@@ -1,65 +1,54 @@
import sys
import requests
from urllib.parse import urlparse
import requests
WEBSITE_REPOS = [
docs_repos = [
"frappe_docs",
"erpnext_documentation",
"erpnext_com",
"frappe_io",
]
DOCUMENTATION_DOMAINS = [
"docs.erpnext.com",
"docs.frappe.io",
"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... 🏃")

View File

@@ -4,24 +4,14 @@ set -e
cd ~ || exit
sudo apt update
sudo apt remove mysql-server mysql-client
sudo apt install libcups2-dev redis-server mariadb-client libmariadb-dev
sudo apt update && sudo apt install redis-server libcups2-dev
pip install frappe-bench
githubbranch=${GITHUB_BASE_REF:-${GITHUB_REF##*/}}
frappeuser=${FRAPPE_USER:-"frappe"}
frappecommitish=${FRAPPE_BRANCH:-$githubbranch}
mkdir frappe
pushd frappe
git init
git remote add origin "https://github.com/${frappeuser}/frappe"
git fetch origin "${frappecommitish}" --depth 1
git checkout FETCH_HEAD
popd
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
mkdir ~/frappe-bench/sites/test_site
@@ -34,14 +24,14 @@ 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 -proot -e "SET GLOBAL character_set_server = 'utf8mb4'"
mysql --host 127.0.0.1 --port 3306 -u root -proot -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 -proot -e "CREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe'"
mysql --host 127.0.0.1 --port 3306 -u root -proot -e "CREATE DATABASE test_frappe"
mysql --host 127.0.0.1 --port 3306 -u root -proot -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 -proot -e "FLUSH PRIVILEGES"
fi
if [ "$DB" == "postgres" ];then
@@ -51,13 +41,12 @@ fi
install_whktml() {
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
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
@@ -66,13 +55,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 develop
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

View File

@@ -8,10 +8,9 @@
"mail_login": "test@example.com",
"mail_password": "test",
"admin_password": "admin",
"use_mysqlclient": 1,
"root_login": "root",
"root_password": "root",
"host_name": "http://test_site:8000",
"install_apps": ["payments", "erpnext"],
"install_apps": ["erpnext"],
"throttle_user_limit": 100
}

View File

@@ -2,9 +2,7 @@ import re
import sys
errors_encounter = 0
pattern = re.compile(
r"_\(([\"']{,3})(?P<message>((?!\1).)*)\1(\s*,\s*context\s*=\s*([\"'])(?P<py_context>((?!\5).)*)\5)*(\s*,(\s*?.*?\n*?)*(,\s*([\"'])(?P<js_context>((?!\11).)*)\11)*)*\)"
)
pattern = re.compile(r"_\(([\"']{,3})(?P<message>((?!\1).)*)\1(\s*,\s*context\s*=\s*([\"'])(?P<py_context>((?!\5).)*)\5)*(\s*,(\s*?.*?\n*?)*(,\s*([\"'])(?P<js_context>((?!\11).)*)\11)*)*\)")
words_pattern = re.compile(r"_{1,2}\([\"'`]{1,3}.*?[a-zA-Z]")
start_pattern = re.compile(r"_{1,2}\([f\"'`]{1,3}")
f_string_pattern = re.compile(r"_\(f[\"']")
@@ -12,14 +10,14 @@ 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"))]
files_to_scan = [_file for _file in files if _file.endswith(('.py', '.js'))]
for _file in files_to_scan:
with open(_file) as f:
print(f"Checking: {_file}")
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:
if 'frappe-lint: disable-translate' in line:
continue
start_matches = start_pattern.search(line)
@@ -30,9 +28,7 @@ for _file in files_to_scan:
has_f_string = f_string_pattern.search(line)
if has_f_string:
errors_encounter += 1
print(
f"\nF-strings are not supported for translations at line number {line_number}\n{line.strip()[:100]}"
)
print(f'\nF-strings are not supported for translations at line number {line_number}\n{line.strip()[:100]}')
continue
else:
continue
@@ -40,29 +36,25 @@ for _file in files_to_scan:
match = pattern.search(line)
error_found = False
if not match and line.endswith((",\n", "[\n")):
if not match and line.endswith((',\n', '[\n')):
# concat remaining text to validate multiline pattern
line = "".join(file_lines[line_number - 1 :])
line = line[start_matches.start() + 1 :]
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]}")
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]}"
)
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.'
)
print('\nVisit "https://frappeframework.com/docs/user/en/translations" to learn about valid translation strings.')
sys.exit(1)
else:
print("\nGood To Go!")
print('\nGood To Go!')

View File

@@ -1,40 +0,0 @@
#!/bin/bash
set -e
cd ~ || exit
echo "Setting Up Bench..."
pip install frappe-bench
bench -v init frappe-bench --skip-assets --skip-redis-config-generation --python "$(which python)"
cd ./frappe-bench || exit
echo "Get ERPNext..."
bench get-app --skip-assets erpnext "${GITHUB_WORKSPACE}"
echo "Generating POT file..."
bench generate-pot-file --app erpnext
cd ./apps/erpnext || exit
echo "Configuring git user..."
git config user.email "developers@erpnext.com"
git config user.name "frappe-pr-bot"
echo "Setting the correct git remote..."
# Here, the git remote is a local file path by default. Let's change it to the upstream repo.
git remote set-url upstream https://github.com/frappe/erpnext.git
echo "Creating a new branch..."
isodate=$(date -u +"%Y-%m-%d")
branch_name="pot_${BASE_BRANCH}_${isodate}"
git checkout -b "${branch_name}"
echo "Commiting changes..."
git add erpnext/locale/main.pot
git commit -m "chore: update POT file"
gh auth setup-git
git push -u upstream "${branch_name}"
echo "Creating a PR..."
gh pr create --fill --base "${BASE_BRANCH}" --head "${branch_name}" --reviewer ${PR_REVIEWER} -R frappe/erpnext

4
.github/release.yml vendored
View File

@@ -1,4 +0,0 @@
changelog:
exclude:
labels:
- skip-release-notes

8
.github/stale.yml vendored
View File

@@ -12,14 +12,6 @@ exemptProjects: true
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: true
# Skip the stale action for draft PRs
exemptDraftPr: true
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
- hotfix
- no-stale
pulls:
daysUntilStale: 15
daysUntilClose: 3

View File

@@ -5,16 +5,13 @@ on:
- closed
- labeled
permissions:
contents: read
jobs:
main:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Checkout Actions
uses: actions/checkout@v6
uses: actions/checkout@v2
with:
repository: "frappe/backport"
path: ./actions
@@ -24,6 +21,6 @@ jobs:
- name: Run backport
uses: ./actions/backport
with:
token: ${{secrets.RELEASE_TOKEN}}
token: ${{secrets.BACKPORT_BOT_TOKEN}}
labelsToAdd: "backport"
title: "{{originalTitle}}"

View File

@@ -2,10 +2,6 @@ name: Trigger Docker build on release
on:
release:
types: [released]
permissions:
contents: read
jobs:
curl:
runs-on: ubuntu-latest

View File

@@ -3,9 +3,6 @@ on:
pull_request:
types: [ opened, synchronize, reopened, edited ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
@@ -13,12 +10,12 @@ jobs:
steps:
- name: 'Setup Environment'
uses: actions/setup-python@v6
uses: actions/setup-python@v2
with:
python-version: '3.10'
- name: 'Clone repo'
uses: actions/checkout@v6
uses: actions/checkout@v2
- name: Validate Docs
env:

View File

@@ -1,44 +0,0 @@
# This workflow is agnostic to branches. Only maintain on develop branch.
# To add/remove branches just modify the matrix.
name: Regenerate POT file (translatable strings)
on:
schedule:
# 9:30 UTC => 3 PM IST Sunday
- cron: "30 9 * * 0"
workflow_dispatch:
jobs:
regenerate-pot-file:
name: Regenerate POT file
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
branch: ["develop", "version-16-hotfix"]
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v6
with:
ref: ${{ matrix.branch }}
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: "3.14"
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 24
- name: Run script to update POT file
run: |
bash ${GITHUB_WORKSPACE}/.github/helper/update_pot_file.sh
env:
GH_TOKEN: ${{ secrets.RELEASE_TOKEN }}
BASE_BRANCH: ${{ matrix.branch }}
PR_REVIEWER: barredterra # change to your GitHub username if you copied this file

View File

@@ -2,10 +2,6 @@
# To add/remove versions just modify the matrix.
name: Create weekly release pull requests
permissions:
contents: read
on:
schedule:
# 9:30 UTC => 3 PM IST Tuesday
@@ -13,13 +9,13 @@ on:
workflow_dispatch:
jobs:
stable-release:
release:
name: Release
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
version: ["15", "16"]
version: ["13", "14"]
steps:
- uses: octokit/request-action@v2.x

View File

@@ -1,30 +0,0 @@
name: "Auto-label PRs based on title"
on:
pull_request_target:
types: [opened, reopened]
jobs:
add-label-if-prefix-matches:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Check PR title and add label if it matches prefixes
uses: actions/github-script@v7
continue-on-error: true
with:
script: |
const title = context.payload.pull_request.title.toLowerCase();
const prefixes = ['chore', 'ci', 'style', 'test', 'refactor'];
// Check if the PR title starts with any of the prefixes
if (prefixes.some(prefix => title.startsWith(prefix))) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
labels: ['skip-release-notes']
});
}

View File

@@ -3,10 +3,6 @@ on:
pull_request_target:
types: [opened, reopened]
permissions:
issues: write
pull-requests: write
jobs:
triage:
runs-on: ubuntu-latest

View File

@@ -3,46 +3,27 @@ name: Linters
on:
pull_request: { }
permissions:
contents: read
jobs:
linters:
name: linters
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v2
- name: Set up Python 3.14
uses: actions/setup-python@v6
- name: Set up Python 3.10
uses: actions/setup-python@v2
with:
python-version: '3.14'
cache: pip
python-version: '3.10'
- name: Install and Run Pre-commit
uses: pre-commit/action@v3.0.0
semgrep:
name: semgrep
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Python 3.14
uses: actions/setup-python@v6
with:
python-version: '3.14'
cache: pip
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
- name: Semgrep for Test Correctness
run: semgrep ci --include=**/test_*.py --config ./semgrep/test-correctness.yml

View File

@@ -1,21 +0,0 @@
name: 'Lock threads'
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
permissions:
issues: write
pull-requests: write
jobs:
lock:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v5
with:
github-token: ${{ github.token }}
issue-inactive-days: 14
pr-inactive-days: 14

View File

@@ -8,14 +8,8 @@ on:
- '**.md'
- '**.html'
- '**.csv'
- 'crowdin.yml'
- '.coderabbit.yml'
- '.mergify.yml'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: patch-develop-${{ github.event_name }}-${{ github.event.number || github.event_name == 'workflow_dispatch' && github.run_id || '' }}
cancel-in-progress: true
@@ -29,44 +23,41 @@ jobs:
services:
mysql:
image: mariadb:11.8
image: mariadb:10.3
env:
MARIADB_ROOT_PASSWORD: 'root'
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
uses: actions/checkout@v6
uses: actions/checkout@v2
- name: Check for valid Python & Merge Conflicts
run: |
python -m compileall -fq "${GITHUB_WORKSPACE}"
python -m compileall -f "${GITHUB_WORKSPACE}"
if grep -lr --exclude-dir=node_modules "^<<<<<<< " "${GITHUB_WORKSPACE}"
then echo "Found merge conflicts"
exit 1
fi
- name: Setup Python
uses: actions/setup-python@v6
uses: "gabrielfalcao/pyenv-action@v9"
with:
python-version: |
3.11
3.13
3.14
versions: 3.10:latest, 3.7:latest
- name: Setup Node
uses: actions/setup-node@v6
uses: actions/setup-node@v2
with:
node-version: 24
node-version: 14
check-latest: true
- name: Add to Hosts
run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts
- name: Cache pip
uses: actions/cache@v4
uses: actions/cache@v2
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/*requirements.txt', '**/pyproject.toml') }}
@@ -75,7 +66,7 @@ jobs:
${{ runner.os }}-
- name: Cache node modules
uses: actions/cache@v4
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
@@ -88,9 +79,9 @@ jobs:
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v4
- uses: actions/cache@v2
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@@ -101,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
@@ -109,62 +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://frappe.io/files/erpnext-v14.sql.gz
bench --site test_site --force restore ~/frappe-bench/erpnext-v14.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 --python python$2
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 15 3.13
update_to_version 16 3.14
echo "Updating to latest version"
git -C "apps/frappe" fetch --depth 1 upstream "${GITHUB_BASE_REF:-${GITHUB_REF##*/}}"
git -C "apps/frappe" checkout -q -f FETCH_HEAD
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

View File

@@ -1,28 +0,0 @@
# Tests are skipped for these files but github doesn't allow "passing" hence this is required.
name: Skipped Patch Test
on:
pull_request:
paths:
- "**.js"
- "**.css"
- "**.md"
- "**.html"
- "**.csv"
- 'crowdin.yml'
- '.coderabbit.yml'
- '.mergify.yml'
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
name: Patch Test
steps:
- name: Pass skipped tests unconditionally
run: "echo Skipped"

View File

@@ -3,24 +3,20 @@ on:
push:
branches:
- version-13
permissions:
contents: read
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout Entire Repository
uses: actions/checkout@v6
uses: actions/checkout@v2
with:
fetch-depth: 0
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@v6
- name: Setup Node.js v14
uses: actions/setup-node@v2
with:
node-version: 20
node-version: 14
- name: Setup dependencies
run: |
npm install @semantic-release/git @semantic-release/exec --no-save
@@ -32,4 +28,4 @@ jobs:
GIT_AUTHOR_EMAIL: "developers@frappe.io"
GIT_COMMITTER_NAME: "Frappe PR Bot"
GIT_COMMITTER_EMAIL: "developers@frappe.io"
run: npx semantic-release
run: npx semantic-release

View File

@@ -1,42 +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' \
| sed -E 's/by @mergify //'
)
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 }}

View File

@@ -1,143 +0,0 @@
name: Individual
on:
workflow_dispatch:
concurrency:
group: server-individual-tests-lightmode-develop
cancel-in-progress: true
permissions:
contents: read
jobs:
discover:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Clone
uses: actions/checkout@v6
- id: set-matrix
run: |
# Use grep and find to get the list of test files
matrix=$(find . -path '*/test_*.py' | xargs grep -l 'def test_' | sort | awk '{
# Remove ./ prefix, file extension, and replace / with .
gsub(/^\.\//, "", $0)
gsub(/\.py$/, "", $0)
gsub(/\//, ".", $0)
# Add to array
tests[NR] = $0
}
END {
# Start JSON array
printf "{\n \"include\": [\n"
# Loop through array and create JSON objects
for (i=1; i<=NR; i++) {
printf " {\"test\": \"%s\"}", tests[i]
if (i < NR) printf ","
printf "\n"
}
# Close JSON array
printf " ]\n}"
}')
# Output the matrix
echo "matrix=$(echo "$matrix" | jq -c)" >> $GITHUB_OUTPUT
# For debugging (optional)
echo "Generated matrix:"
echo "$matrix"
test:
needs: discover
runs-on: ubuntu-latest
timeout-minutes: 60
env:
NODE_ENV: "production"
strategy:
fail-fast: false
matrix: ${{fromJson(needs.discover.outputs.matrix)}}
max-parallel: 14
name: Test
services:
mysql:
image: mariadb:10.6
env:
MARIADB_ROOT_PASSWORD: 'root'
ports:
- 3306:3306
options: --health-cmd="mariadb-admin ping" --health-interval=5s --health-timeout=2s --health-retries=3
steps:
- name: Clone
uses: actions/checkout@v6
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: '3.14'
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 24
check-latest: true
- name: Add to Hosts
run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts
- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/*requirements.txt', '**/pyproject.toml') }}
restore-keys: |
${{ runner.os }}-pip-
${{ runner.os }}-
- name: Cache node modules
uses: actions/cache@v4
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install
run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh
env:
DB: mariadb
TYPE: server
FRAPPE_USER: ${{ github.event.inputs.user }}
FRAPPE_BRANCH: ${{ github.event.inputs.branch }}
- name: Run Tests
run: |
site_name=$(echo "${{matrix.test}}" | sed -e 's/.*\.\(test_.*$\)/\1/')
echo "$site_name"
mkdir ~/frappe-bench/sites/$site_name
cp -r "${GITHUB_WORKSPACE}/.github/helper/site_config_mariadb.json" ~/frappe-bench/sites/$site_name/site_config.json
cd ~/frappe-bench/
bench --site $site_name reinstall --yes
bench --site $site_name set-config allow_tests true
bench --site $site_name run-tests --module ${{ matrix.test }} --lightmode

View File

@@ -15,13 +15,13 @@ jobs:
name: Check Commit Titles
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v3
with:
fetch-depth: 200
- uses: actions/setup-node@v6
- uses: actions/setup-node@v3
with:
node-version: 18
node-version: 14
check-latest: true
- name: Check commit titles

View File

@@ -1,31 +0,0 @@
# Tests are skipped for these files but github doesn't allow "passing" hence this is required.
name: Skipped Tests
on:
pull_request:
paths:
- "**.js"
- "**.css"
- "**.svg"
- "**.md"
- "**.html"
- 'crowdin.yml'
- '.coderabbit.yml'
- '.mergify.yml'
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
container: [1, 2, 3, 4]
name: Python Unit Tests
steps:
- name: Pass skipped tests unconditionally
run: "echo Skipped"

View File

@@ -1,37 +1,31 @@
name: Server (Mariadb)
on:
repository_dispatch:
types: [frappe-framework-change]
pull_request:
paths-ignore:
- '**.js'
- '**.css'
- '**.svg'
- '**.md'
- '**.html'
- 'crowdin.yml'
- '.coderabbit.yml'
- '.mergify.yml'
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
permissions:
contents: read
concurrency:
group: server-mariadb-develop-${{ github.event_name }}-${{ github.event.number || github.event_name == 'workflow_dispatch' && github.run_id || '' }}
cancel-in-progress: true
@@ -40,9 +34,6 @@ jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 60
env:
NODE_ENV: "production"
WITH_COVERAGE: ${{ github.event_name != 'pull_request' }}
strategy:
fail-fast: false
@@ -56,40 +47,39 @@ jobs:
mysql:
image: mariadb:10.6
env:
TZ: 'Asia/Kolkata'
MARIADB_ROOT_PASSWORD: 'root'
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
uses: actions/checkout@v6
uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v6
uses: actions/setup-python@v2
with:
python-version: '3.14'
python-version: '3.11'
- name: Check for valid Python & Merge Conflicts
run: |
python -m compileall -fq "${GITHUB_WORKSPACE}"
python -m compileall -f "${GITHUB_WORKSPACE}"
if grep -lr --exclude-dir=node_modules "^<<<<<<< " "${GITHUB_WORKSPACE}"
then echo "Found merge conflicts"
exit 1
fi
- name: Setup Node
uses: actions/setup-node@v6
uses: actions/setup-node@v2
with:
node-version: 24
node-version: 14
check-latest: true
- name: Add to Hosts
run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts
- name: Cache pip
uses: actions/cache@v4
uses: actions/cache@v2
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/*requirements.txt', '**/pyproject.toml') }}
@@ -98,7 +88,7 @@ jobs:
${{ runner.os }}-
- name: Cache node modules
uses: actions/cache@v4
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
@@ -111,9 +101,9 @@ jobs:
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v4
- uses: actions/cache@v2
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@@ -127,20 +117,17 @@ jobs:
DB: mariadb
TYPE: server
FRAPPE_USER: ${{ github.event.inputs.user }}
FRAPPE_BRANCH: ${{ github.event.client_payload.sha || github.event.inputs.branch }}
FRAPPE_BRANCH: ${{ github.event.inputs.branch }}
- name: Run Tests
run: 'cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --lightmode --app erpnext --total-builds ${{ strategy.job-total }} --build-number ${{ matrix.container }} --with-coverage'
run: 'cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --app erpnext --with-coverage --total-builds 4 --build-number ${{ matrix.container }}'
env:
TYPE: server
- name: Show bench output
if: ${{ always() }}
run: cat ~/frappe-bench/bench_start.log || true
CI_BUILD_ID: ${{ github.run_id }}
ORCHESTRATOR_URL: http://test-orchestrator.frappe.io
- name: Upload coverage data
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: coverage-${{ matrix.container }}
path: /home/runner/frappe-bench/sites/coverage.xml
@@ -151,15 +138,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Clone
uses: actions/checkout@v6
uses: actions/checkout@v2
- name: Download artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v3
- name: Upload coverage data
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@v2
with:
name: MariaDB
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
verbose: true

View File

@@ -6,18 +6,12 @@ on:
- '**.js'
- '**.md'
- '**.html'
- 'crowdin.yml'
- '.coderabbit.yml'
- '.mergify.yml'
types: [opened, labelled, synchronize, reopened]
concurrency:
group: server-postgres-develop-${{ github.event_name }}-${{ github.event.number || github.event_name == 'workflow_dispatch' && github.run_id || '' }}
cancel-in-progress: true
permissions:
contents: read
jobs:
test:
if: ${{ contains(github.event.pull_request.labels.*.name, 'postgres') }}
@@ -47,32 +41,32 @@ jobs:
steps:
- name: Clone
uses: actions/checkout@v6
uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v6
uses: actions/setup-python@v2
with:
python-version: '3.14'
python-version: '3.10'
- name: Check for valid Python & Merge Conflicts
run: |
python -m compileall -fq "${GITHUB_WORKSPACE}"
python -m compileall -f "${GITHUB_WORKSPACE}"
if grep -lr --exclude-dir=node_modules "^<<<<<<< " "${GITHUB_WORKSPACE}"
then echo "Found merge conflicts"
exit 1
fi
- name: Setup Node
uses: actions/setup-node@v6
uses: actions/setup-node@v2
with:
node-version: 24
node-version: 14
check-latest: true
- name: Add to Hosts
run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts
- name: Cache pip
uses: actions/cache@v4
uses: actions/cache@v2
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/*requirements.txt', '**/pyproject.toml') }}
@@ -81,7 +75,7 @@ jobs:
${{ runner.os }}-
- name: Cache node modules
uses: actions/cache@v4
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
@@ -94,9 +88,9 @@ jobs:
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v4
- uses: actions/cache@v2
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}

6
.gitignore vendored
View File

@@ -2,6 +2,7 @@
*.py~
.DS_Store
conf.py
locale
latest_updates.json
.wnf-lang-status
*.egg-info
@@ -14,8 +15,5 @@ __pycache__
*~
.idea/
.vscode/
.helix/
node_modules/
.backportrc.json
# Aider AI Chat
.aider*
.backportrc.json

View File

@@ -2,27 +2,36 @@ pull_request_rules:
- name: Auto-close PRs on stable branch
conditions:
- and:
- and:
- author!=surajshetty3416
- author!=gavindsouza
- author!=rohitwaghchaure
- 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
- base=version-16
- and:
- author!=surajshetty3416
- author!=gavindsouza
- author!=rohitwaghchaure
- author!=nabinhait
- author!=ankush
- author!=deepeshgarg007
- author!=frappe-pr-bot
- author!=mergify[bot]
- or:
- base=version-13
- base=version-12
actions:
close:
comment:
message: |
@{{author}}, thanks for the contribution, but we do not accept pull requests on a stable branch. Please raise PR on an appropriate hotfix branch.
https://github.com/frappe/erpnext/wiki/Pull-Request-Checklist#which-branch
message: |
@{{author}}, thanks for the contribution, but we do not accept pull requests on a stable branch. Please raise PR on an appropriate hotfix branch.
https://github.com/frappe/erpnext/wiki/Pull-Request-Checklist#which-branch
- name: Auto-close PRs on pre-release branch
conditions:
- base=version-13-pre-release
actions:
close:
comment:
message: |
@{{author}}, pre-release branch is not maintained anymore. Releases are directly done by merging hotfix branch to stable branches.
- name: backport to develop
conditions:
- label="backport develop"
@@ -32,6 +41,7 @@ pull_request_rules:
- develop
assignees:
- "{{ author }}"
- name: backport to version-14-hotfix
conditions:
- label="backport version-14-hotfix"
@@ -41,24 +51,57 @@ pull_request_rules:
- version-14-hotfix
assignees:
- "{{ author }}"
- name: backport to version-15-hotfix
- name: backport to version-14-pre-release
conditions:
- label="backport version-15-hotfix"
- label="backport version-14-pre-release"
actions:
backport:
branches:
- version-15-hotfix
- version-14-pre-release
assignees:
- "{{ author }}"
- name: backport to version-16-hotfix
- name: backport to version-13-hotfix
conditions:
- label="backport version-16-hotfix"
- label="backport version-13-hotfix"
actions:
backport:
branches:
- version-16-hotfix
- version-13-hotfix
assignees:
- "{{ author }}"
- name: backport to version-13-pre-release
conditions:
- label="backport version-13-pre-release"
actions:
backport:
branches:
- version-13-pre-release
assignees:
- "{{ author }}"
- name: backport to version-12-hotfix
conditions:
- label="backport version-12-hotfix"
actions:
backport:
branches:
- version-12-hotfix
assignees:
- "{{ author }}"
- name: backport to version-12-pre-release
conditions:
- label="backport version-12-pre-release"
actions:
backport:
branches:
- version-12-pre-release
assignees:
- "{{ author }}"
- name: Automatic merge on CI success and review
conditions:
- status-success=linters
@@ -89,6 +132,6 @@ pull_request_rules:
merge:
method: squash
commit_message_template: |
{{ title }} (#{{ number }})
{{ title }} (#{{ number }})
{{ body }}
{{ body }}

View File

@@ -1,11 +1,11 @@
exclude: 'node_modules|.git'
default_stages: [pre-commit]
default_stages: [commit]
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,56 +15,29 @@ 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
- repo: https://github.com/PyCQA/flake8
rev: 5.0.4
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/templates/includes/.*
)$
- id: flake8
additional_dependencies: [
'flake8-bugbear',
]
args: ['--config', '.github/helper/.flake8_strict']
exclude: ".*setup.py$"
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v8.44.0
- repo: https://github.com/adityahase/black
rev: 9cb0a69f4d0030cdf687eddf314468b39ed54119
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/.*
)$
- id: black
additional_dependencies: ['click==8.0.4']
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.2.0
- repo: https://github.com/timothycrosley/isort
rev: 5.9.1
hooks:
- id: ruff
name: "Run ruff import sorter"
args: ["--select=I", "--fix"]
- id: isort
exclude: ".*setup.py$"
- id: ruff
name: "Run ruff linter"
- id: ruff-format
name: "Run ruff formatter"
ci:
autoupdate_schedule: weekly

View File

@@ -3,21 +3,26 @@
# These owners will be the default owners for everything in
# the repo. Unless a later match takes precedence,
erpnext/accounts/ @ruthra-kumar
erpnext/assets/ @khushi8112
erpnext/regional @ruthra-kumar
erpnext/selling @ruthra-kumar
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 @mihir-kandoi
erpnext/maintenance/ @rohitwaghchaure @mihir-kandoi
erpnext/manufacturing/ @rohitwaghchaure @mihir-kandoi
erpnext/quality_management/ @rohitwaghchaure @mihir-kandoi
erpnext/stock/ @rohitwaghchaure @mihir-kandoi
erpnext/subcontracting/ @mihir-kandoi
erpnext/projects/ @nishkagosalia
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/controllers/ @ruthra-kumar @rohitwaghchaure @mihir-kandoi
erpnext/patches/ @ruthra-kumar @rohitwaghchaure @mihir-kandoi
erpnext/crm/ @NagariaHussain
erpnext/education/ @rutwikhdev
erpnext/projects/ @ruchamahabal
.github/ @ruthra-kumar @mihir-kandoi
pyproject.toml @ruthra-kumar
erpnext/controllers/ @deepeshgarg007 @nextchamp-saqib @rohitwaghchaure
erpnext/patches/ @deepeshgarg007 @nextchamp-saqib
.github/ @ankush
pyproject.toml @ankush

212
README.md
View File

@@ -1,185 +1,89 @@
<div align="center">
<a href="https://frappe.io/erpnext">
<img src="./erpnext/public/images/v16/erpnext.svg" alt="ERPNext Logo" height="80px" width="80px"/>
<a href="https://erpnext.com">
<img src="https://raw.githubusercontent.com/frappe/erpnext/develop/erpnext/public/images/erpnext-logo.png" height="128">
</a>
<h2>ERPNext</h2>
<div align="center">
<p>Powerful, Intuitive and Open-Source ERP</p>
</div>
<p align="center">
<p>ERP made simple</p>
</p>
[![Learn on Frappe School](https://img.shields.io/badge/Frappe%20School-Learn%20ERPNext-blue?style=flat-square)](https://frappe.school)<br><br>
[![CI](https://github.com/frappe/erpnext/actions/workflows/server-tests-mariadb.yml/badge.svg?event=schedule)](https://github.com/frappe/erpnext/actions/workflows/server-tests-mariadb.yml)
[![CI](https://github.com/frappe/erpnext/actions/workflows/server-tests.yml/badge.svg?branch=develop)](https://github.com/frappe/erpnext/actions/workflows/server-tests.yml)
[![UI](https://github.com/erpnext/erpnext_ui_tests/actions/workflows/ui-tests.yml/badge.svg?branch=develop&event=schedule)](https://github.com/erpnext/erpnext_ui_tests/actions/workflows/ui-tests.yml)
[![Open Source Helpers](https://www.codetriage.com/frappe/erpnext/badges/users.svg)](https://www.codetriage.com/frappe/erpnext)
[![codecov](https://codecov.io/gh/frappe/erpnext/branch/develop/graph/badge.svg?token=0TwvyUg3I5)](https://codecov.io/gh/frappe/erpnext)
[![docker pulls](https://img.shields.io/docker/pulls/frappe/erpnext-worker.svg)](https://hub.docker.com/r/frappe/erpnext-worker)
[https://erpnext.com](https://erpnext.com)
</div>
<div align="center">
<img src="./erpnext/public/images/v16/hero_image.png" alt="ERPNext Hero Image"/>
ERPNext as a monolith includes the following areas for managing businesses:
1. [Accounting](https://erpnext.com/open-source-accounting)
1. [Warehouse Management](https://erpnext.com/distribution/warehouse-management-system)
1. [CRM](https://erpnext.com/open-source-crm)
1. [Sales](https://erpnext.com/open-source-sales-purchase)
1. [Purchase](https://erpnext.com/open-source-sales-purchase)
1. [HRMS](https://erpnext.com/open-source-hrms)
1. [Project Management](https://erpnext.com/open-source-projects)
1. [Support](https://erpnext.com/open-source-help-desk-software)
1. [Asset Management](https://erpnext.com/open-source-asset-management-software)
1. [Quality Management](https://erpnext.com/docs/user/manual/en/quality-management)
1. [Manufacturing](https://erpnext.com/open-source-manufacturing-erp-software)
1. [Website Management](https://erpnext.com/open-source-website-builder-software)
1. [Customize ERPNext](https://erpnext.com/docs/user/manual/en/customize-erpnext)
1. [And More](https://erpnext.com/docs/user/manual/en/)
ERPNext is built on the [Frappe Framework](https://github.com/frappe/frappe), a full-stack web app framework built with Python & JavaScript.
## Installation
<div align="center" style="max-height: 40px;">
<a href="https://frappecloud.com/erpnext/signup">
<img src=".github/try-on-f-cloud-button.svg" height="40">
</a>
<a href="https://labs.play-with-docker.com/?stack=https://raw.githubusercontent.com/frappe/frappe_docker/main/pwd.yml">
<img src="https://raw.githubusercontent.com/play-with-docker/stacks/master/assets/images/button.png" alt="Try in PWD" height="37"/>
</a>
</div>
<div align="center">
<a href="https://erpnext-demo.frappe.cloud/api/method/erpnext_demo.erpnext_demo.auth.login_demo">Live Demo</a>
-
<a href="https://frappe.io/erpnext">Website</a>
-
<a href="https://docs.frappe.io/erpnext/">Documentation</a>
</div>
> Login for the PWD site: (username: Administrator, password: admin)
## ERPNext
### Containerized Installation
100% Open-Source ERP System to help you run your business.
Use docker to deploy ERPNext in production or for development of [Frappe](https://github.com/frappe/frappe) apps. See https://github.com/frappe/frappe_docker for more details.
### Motivation
Running a business is a complex task - handling invoices, tracking stock, managing personnel, and other daily operations. In a market where software is sold separately to manage each of these tasks, ERPNext does all of the above and more, for free.
### Key Features
- **Accounting**: All the tools you need to manage cash flow in one place, right from recording transactions to summarizing and analyzing financial reports.
- **Order Management**: Track inventory levels, replenish stock, and manage sales orders, customers, suppliers, shipments, deliverables, and order fulfillment.
- **Manufacturing**: Simplifies the production cycle, helps track material consumption, exhibits capacity planning, handles subcontracting, and more!
- **Asset Management**: From purchase to disposal, IT infrastructure to equipment. Covers every branch of your organization, all in one centralized system.
- **Projects**: Deliver both internal and external projects on time, budget and profitability. Track tasks, timesheets, and issues by project.
<details open>
<summary>More</summary>
<img src="https://erpnext.com/files/v16_bom.png"/>
<img src="https://erpnext.com/files/v16_stock_summary.png"/>
<img src="https://erpnext.com/files/v16_job_card.png"/>
<img src="https://erpnext.com/files/v16_tasks.png"/>
</details>
### Under the Hood
- [**Frappe Framework**](https://github.com/frappe/frappe): A full-stack web application framework written in Python and JavaScript. The framework provides a robust foundation for building web applications, including a database abstraction layer, user authentication, and a REST API.
- [**Frappe UI**](https://github.com/frappe/frappe-ui): A Vue-based UI library, to provide a modern user interface. The Frappe UI library provides a variety of components that can be used to build single-page applications on top of the Frappe Framework.
## Production Setup
### Managed Hosting
You can try [Frappe Cloud](https://frappecloud.com), a simple, user-friendly, and sophisticated [open-source](https://github.com/frappe/press) platform to host Frappe applications reliably and securely.
It handles installation, setup, upgrades, monitoring, maintenance, and support of your Frappe deployments. It is a fully featured developer platform with an ability to manage and control multiple Frappe deployments.
<div>
<a href="https://erpnext-demo.frappe.cloud/app/home" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://frappe.io/files/try-on-fc-white.png">
<img src="https://frappe.io/files/try-on-fc-black.png" alt="Try on Frappe Cloud" height="28" />
</picture>
</a>
</div>
### Self-Hosted
#### Docker
See [Frappe Docker Documentation](https://github.com/frappe/frappe_docker) for full documentation & FAQ on Docker setup
#### Prerequisites
- [Docker](https://docs.docker.com/get-docker/)
- [Docker Compose v2](https://docs.docker.com/compose/)
- [git](https://docs.github.com/en/get-started/getting-started-with-git/set-up-git)
> For Docker basics and best practices refer to Docker's [documentation](https://docs.docker.com)
#### Demo setup
The fastest way to try ERPNext is to play in a pre-configured sandbox, in your browser, click the button below:
<a href="https://labs.play-with-docker.com/?stack=https://raw.githubusercontent.com/frappe/frappe_docker/main/pwd.yml">
<img src="https://raw.githubusercontent.com/play-with-docker/stacks/master/assets/images/button.png" alt="Try in PWD"/>
</a>
### Try on your environment
> **⚠️ Disposable demo only**
>
> **This setup is intended for quick evaluation. Expect to throw the environment away.** You will not be able to install custom apps to this setup. For production deployments, custom configurations, and detailed explanations, see the full documentation.
First clone the repo:
```sh
git clone https://github.com/frappe/frappe_docker
cd frappe_docker
```
Then run:
```sh
docker compose -f pwd.yml up -d
```
Wait for a couple of minutes for ERPNext site to be created or check the `create-site` container logs before opening browser on port `8080`. (username: `Administrator`, password: `admin`)
See [Frappe Docker](https://github.com/frappe/frappe_docker/blob/main/docs/01-getting-started/03-arm64.md) for ARM based docker setup
## Development Setup
### Manual Install
The Easy Way: our install script for bench will install all dependencies (e.g. MariaDB). See https://github.com/frappe/bench for more details.
New passwords will be created for the ERPNext "Administrator" user, the MariaDB root user, and the Frappe user (the script displays the passwords and saves them to ~/frappe_passwords.txt).
New passwords will be created for the ERPNext "Administrator" user, the MariaDB root user, and the frappe user (the script displays the passwords and saves them to ~/frappe_passwords.txt).
### Local
## Learning and community
To setup the repository locally follow the steps mentioned below:
1. Setup bench by following the [Installation Steps](https://frappeframework.com/docs/user/en/installation) and start the server
```
bench start
```
2. In a separate terminal window, run the following commands:
```
# Create a new site
bench new-site erpnext.localhost
```
3. Get the ERPNext app and install it
```
# Get the ERPNext app
bench get-app https://github.com/frappe/erpnext
# Install the app
bench --site erpnext.localhost install-app erpnext
```
4. Open the URL `http://erpnext.localhost:8000/app` in your browser, you should see the app running
## Learning and Community
1. [Frappe School](https://school.frappe.io) - Learn Frappe Framework and ERPNext from the various courses by the maintainers or from the community.
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.frappe.io/c/erpnext/6) - Engage with the community of ERPNext users and service providers.
4. [Telegram Group](https://erpnext_public.t.me) - Get instant help from huge community of users.
3. [Discussion Forum](https://discuss.erpnext.com/) - Engage with community of ERPNext users and service providers.
4. [Telegram Group](https://t.me/erpnexthelp) - Get instant help from huge community of users.
## Contributing
1. [Issue Guidelines](https://github.com/frappe/erpnext/wiki/Issue-Guidelines)
2. [Report Security Vulnerabilities](https://erpnext.com/security)
3. [Pull Request Requirements](https://github.com/frappe/erpnext/wiki/Contribution-Guidelines)
4. [Translations](https://crowdin.com/project/frappe)
1. [Report Security Vulnerabilities](https://erpnext.com/security)
1. [Pull Request Requirements](https://github.com/frappe/erpnext/wiki/Contribution-Guidelines)
1. [Translations](https://translate.erpnext.com)
## License
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).
<br />
<br />
<div align="center" style="padding-top: 0.75rem;">
<a href="https://frappe.io" target="_blank">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://frappe.io/files/Frappe-white.png">
<img src="https://frappe.io/files/Frappe-black.png" alt="Frappe Technologies" height="28"/>
</picture>
</a>
</div>

View File

@@ -1,7 +1,7 @@
# Security Policy
The ERPNext team and community take security issues seriously. To report a security issue, please go through the information mentioned [here](https://frappe.io/security).
The ERPNext team and community take security issues seriously. To report a security issue, fill out the form at [https://erpnext.com/security/report](https://erpnext.com/security/report).
You can help us make ERPNext and all its users more secure by following the [Reporting guidelines](https://frappe.io/security).
You can help us make ERPNext and all it's users more secure by following the [Reporting guidelines](https://erpnext.com/security).
We appreciate your efforts to responsibly disclose your findings. We'll endeavor to respond quickly, and will keep you updated throughout the process.
We appreciate your efforts to responsibly disclose your findings. We'll endeavor to respond quickly, and will keep you updated throughout the process.

View File

@@ -18,9 +18,8 @@ We will grant permission to use the ERPNext name and logo for projects that meet
- The primary purpose of your project is to promote the spread and improvement of the ERPNext software.
- Your project is non-commercial in nature (it can make money to cover its costs or contribute to non-profit entities, but it cannot be run as a for-profit project or business).
- Your project neither promotes nor is associated with entities that currently fail to comply with the GPL license under which ERPNext is distributed.
If your project meets these criteria, you will be permitted to use the ERPNext name and logo to promote your project in any way you see fit with one exception: Please do not use ERPNext as part of a domain name.
Your project neither promotes nor is associated with entities that currently fail to comply with the GPL license under which ERPNext is distributed.
- If your project meets these criteria, you will be permitted to use the ERPNext name and logo to promote your project in any way you see fit with one exception: Please do not use ERPNext as part of a domain name.
Use of the ERPNext name and logo is additionally allowed in the following situations:

View File

@@ -1,3 +0,0 @@
**/setup/setup_wizard/data/uom_data.json,erpnext.gettext.extractors.uom_data.extract
**/setup/doctype/incoterm/incoterms.csv,erpnext.gettext.extractors.incoterms.extract
**/setup/setup_wizard/data/*.txt,erpnext.gettext.extractors.lines_from_txt_file.extract
1 **/setup/setup_wizard/data/uom_data.json erpnext.gettext.extractors.uom_data.extract
2 **/setup/doctype/incoterm/incoterms.csv erpnext.gettext.extractors.incoterms.extract
3 **/setup/setup_wizard/data/*.txt erpnext.gettext.extractors.lines_from_txt_file.extract

View File

@@ -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',
],
],
},
};

View File

@@ -1,14 +0,0 @@
files:
- source: /erpnext/locale/main.pot
translation: /erpnext/locale/%two_letters_code%.po
pull_request_title: "fix: sync translations from crowdin"
pull_request_labels:
- translation
- skip-release-notes
pull_request_reviewers:
- barredterra # change to your GitHub username if you copied this file
commit_message: "fix: %language% translations"
append_commit_message: false
languages_mapping:
two_letters_code:
pt-BR: pt_BR

View File

@@ -1,12 +1,8 @@
import functools
import inspect
from typing import TypeVar
import frappe
from frappe.model.document import Document
from frappe.utils.user import is_website_user
__version__ = "17.0.0-dev"
__version__ = "14.0.0-dev"
def get_default_company(user=None):
@@ -16,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:
@@ -39,8 +35,10 @@ def get_default_cost_center(company):
if not frappe.flags.company_cost_center:
frappe.flags.company_cost_center = {}
if company not in frappe.flags.company_cost_center:
frappe.flags.company_cost_center[company] = frappe.get_cached_value("Company", company, "cost_center")
if not company in frappe.flags.company_cost_center:
frappe.flags.company_cost_center[company] = frappe.get_cached_value(
"Company", company, "cost_center"
)
return frappe.flags.company_cost_center[company]
@@ -48,7 +46,7 @@ def get_company_currency(company):
"""Returns the default company currency"""
if not frappe.flags.company_currency:
frappe.flags.company_currency = {}
if company not in frappe.flags.company_currency:
if not company in frappe.flags.company_currency:
frappe.flags.company_currency[company] = frappe.db.get_value(
"Company", company, "default_currency", cache=True
)
@@ -57,7 +55,7 @@ def get_company_currency(company):
def set_perpetual_inventory(enable=1, company=None):
if not company:
company = "_Test Company" if frappe.in_test else get_default_company()
company = "_Test Company" if frappe.flags.in_test else get_default_company()
company = frappe.get_doc("Company", company)
company.enable_perpetual_inventory = enable
@@ -77,12 +75,12 @@ def encode_company_abbr(name, company=None, abbr=None):
def is_perpetual_inventory_enabled(company):
if not company:
company = "_Test Company" if frappe.in_test else get_default_company()
company = "_Test Company" if frappe.flags.in_test else get_default_company()
if not hasattr(frappe.local, "enable_perpetual_inventory"):
frappe.local.enable_perpetual_inventory = {}
if company not in frappe.local.enable_perpetual_inventory:
if not company in frappe.local.enable_perpetual_inventory:
frappe.local.enable_perpetual_inventory[company] = (
frappe.get_cached_value("Company", company, "enable_perpetual_inventory") or 0
)
@@ -97,7 +95,7 @@ def get_default_finance_book(company=None):
if not hasattr(frappe.local, "default_finance_book"):
frappe.local.default_finance_book = {}
if company not in frappe.local.default_finance_book:
if not company in frappe.local.default_finance_book:
frappe.local.default_finance_book[company] = frappe.get_cached_value(
"Company", company, "default_finance_book"
)
@@ -109,7 +107,7 @@ def get_party_account_type(party_type):
if not hasattr(frappe.local, "party_account_types"):
frappe.local.party_account_types = {}
if party_type not in frappe.local.party_account_types:
if not party_type in frappe.local.party_account_types:
frappe.local.party_account_types[party_type] = (
frappe.db.get_value("Party Type", party_type, "account_type") or ""
)
@@ -122,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):
@@ -140,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__}"
@@ -152,44 +147,3 @@ def allow_regional(fn):
return frappe.get_attr(overrides[function_path][-1])(*args, **kwargs)
return caller
def check_app_permission():
if frappe.session.user == "Administrator":
return True
if is_website_user():
return False
return True
T = TypeVar("T")
def normalize_ctx_input(T: type) -> callable:
"""
Normalizes the first argument (ctx) of the decorated function by:
- Converting Document objects to dictionaries
- Parsing JSON strings
- Casting the result to the specified type T
"""
def decorator(func: callable):
# conserve annotations for frappe.utils.typing_validations
@functools.wraps(func, assigned=(a for a in functools.WRAPPER_ASSIGNMENTS if a != "__annotations__"))
def wrapper(ctx: T | Document | dict | str, *args, **kwargs):
if isinstance(ctx, Document):
ctx = T(**ctx.as_dict())
elif isinstance(ctx, dict):
ctx = T(**ctx)
else:
ctx = T(**frappe.parse_json(ctx))
return func(ctx, *args, **kwargs)
# set annotations from function
wrapper.__annotations__.update({k: v for k, v in func.__annotations__.items() if k != "ctx"})
return wrapper
return decorator

View File

@@ -1,50 +0,0 @@
{
"cards": [
{
"card": "Total Outgoing Bills"
},
{
"card": "Total Incoming Bills"
},
{
"card": "Total Incoming Payment"
},
{
"card": "Total Outgoing Payment"
}
],
"charts": [
{
"chart": "Incoming Bills (Purchase Invoice)",
"width": "Half"
},
{
"chart": "Outgoing Bills (Sales Invoice)",
"width": "Half"
},
{
"chart": "Accounts Receivable Ageing",
"width": "Half"
},
{
"chart": "Accounts Payable Ageing",
"width": "Half"
},
{
"chart": "Bank Balance",
"width": "Full"
}
],
"creation": "2026-01-26 21:25:12.793893",
"dashboard_name": "Payments",
"docstatus": 0,
"doctype": "Dashboard",
"idx": 0,
"is_default": 0,
"is_standard": 1,
"modified": "2026-01-26 21:25:12.793893",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payments",
"owner": "Administrator"
}

View File

@@ -10,29 +10,27 @@ from frappe.contacts.doctype.address.address import (
class ERPNextAddress(Address):
def validate(self):
self.validate_reference()
self.update_company_address()
if hasattr(super(), "validate"):
super().validate()
self.update_compnay_address()
super(ERPNextAddress, self).validate()
def link_address(self):
"""Link address based on owner"""
if self.is_your_company_address:
return
return super().link_address()
return super(ERPNextAddress, self).link_address()
def update_company_address(self):
def update_compnay_address(self):
for link in self.get("links"):
if link.link_doctype == "Company":
self.is_your_company_address = 1
def validate_reference(self):
if self.is_your_company_address and not [row for row in self.links if row.link_doctype == "Company"]:
if self.is_your_company_address and not [
row for row in self.links if row.link_doctype == "Company"
]:
frappe.throw(
_(
"Address needs to be linked to a Company. Please add a row for Company in the Links table."
),
_("Address needs to be linked to a Company. Please add a row for Company in the Links table."),
title=_("Company Not Linked"),
)
@@ -40,10 +38,6 @@ class ERPNextAddress(Address):
"""
After Address is updated, update the related 'Primary Address' on Customer.
"""
if hasattr(super(), "on_update"):
super().on_update()
address_display = get_address_display(self.as_dict())
filters = {"customer_primary_address": self.name}
customers = frappe.db.get_all("Customer", filters=filters, as_list=True)
@@ -52,7 +46,7 @@ class ERPNextAddress(Address):
@frappe.whitelist()
def get_shipping_address(company: str, address: str | None = None):
def get_shipping_address(company, address=None):
filters = [
["Dynamic Link", "link_doctype", "=", "Company"],
["Dynamic Link", "link_name", "=", company],

View File

@@ -9,20 +9,18 @@
"idx": 0,
"is_public": 1,
"is_standard": 1,
"last_synced_on": "2026-01-02 13:01:24.037552",
"modified": "2026-01-02 13:04:57.850305",
"last_synced_on": "2020-07-22 12:19:59.879476",
"modified": "2020-07-22 12:21:48.780513",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Balance",
"number_of_groups": 0,
"owner": "Administrator",
"roles": [],
"show_values_over_chart": 1,
"source": "Account Balance Timeline",
"time_interval": "Monthly",
"timeseries": 1,
"time_interval": "Quarterly",
"timeseries": 0,
"timespan": "Last Year",
"type": "Line",
"use_report_chart": 0,
"y_axis": []
}
}

View File

@@ -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,

View File

@@ -1,25 +1,23 @@
{
"chart_name": "Profit and Loss",
"chart_type": "Report",
"creation": "2025-04-01 20:38:16.986176",
"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": "2025-12-19 12:37:31.673782",
"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": [],
"show_values_over_chart": 1,
"timeseries": 0,
"type": "Line",
"type": "Bar",
"use_report_chart": 1,
"y_axis": []
}
}

View File

@@ -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,23 +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,
default: locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"],
get_query: () => {
return {
filters: {
account_type: "Bank",
is_group: 0,
},
};
},
reqd: 1
},
],
]
};

View File

@@ -4,7 +4,7 @@
import frappe
from frappe import _
from frappe.utils import add_to_date, formatdate, getdate, nowdate
from frappe.utils import add_to_date, formatdate, get_link_to_form, getdate, nowdate
from frappe.utils.dashboard import cache_source
from frappe.utils.dateutils import get_from_date_from_timespan, get_period_ending
from frappe.utils.nestedset import get_descendants_of
@@ -13,15 +13,15 @@ from frappe.utils.nestedset import get_descendants_of
@frappe.whitelist()
@cache_source
def get(
chart_name: str | None = None,
chart: str | dict | None = None,
no_cache: bool | None = None,
filters: str | dict | None = None,
from_date: str | None = None,
to_date: str | None = None,
timespan: str | None = None,
time_interval: str | None = None,
heatmap_year: str | None = None,
chart_name=None,
chart=None,
no_cache=None,
filters=None,
from_date=None,
to_date=None,
timespan=None,
time_interval=None,
heatmap_year=None,
):
if chart_name:
chart = frappe.get_doc("Dashboard Chart", chart_name)
@@ -39,12 +39,19 @@ def get(
account = filters.get("account")
company = filters.get("company")
if not company and not account:
frappe.throw(_("Company and account filters not set!"))
if not company:
frappe.throw(_("Company filter not set!"))
if not account:
frappe.throw(_("Account filter not set!"))
if not account and chart_name:
frappe.throw(
_("Account is not set for the dashboard chart {0}").format(
get_link_to_form("Dashboard Chart", chart_name)
)
)
if not frappe.db.exists("Account", account) and chart_name:
frappe.throw(
_("Account {0} does not exists in the dashboard chart {1}").format(
account, get_link_to_form("Dashboard Chart", chart_name)
)
)
if not to_date:
to_date = nowdate()
@@ -76,6 +83,7 @@ def build_result(account, dates, gl_entries):
# get balances in debit
for entry in gl_entries:
# entry date is after the current pointer, so move the pointer forward
while getdate(entry.posting_date) > result[date_index][0]:
date_index += 1
@@ -125,6 +133,8 @@ def get_dates_from_timegrain(from_date, to_date, timegrain):
dates = [get_period_ending(from_date, timegrain)]
while getdate(dates[-1]) < getdate(to_date):
date = get_period_ending(add_to_date(dates[-1], years=years, months=months, days=days), timegrain)
date = get_period_ending(
add_to_date(dates[-1], years=years, months=months, days=days), timegrain
)
dates.append(date)
return dates

View File

@@ -24,10 +24,14 @@ from erpnext.accounts.utils import get_account_currency
def validate_service_stop_date(doc):
"""Validates service_stop_date for Purchase Invoice and Sales Invoice"""
enable_check = "enable_deferred_revenue" if doc.doctype == "Sales Invoice" else "enable_deferred_expense"
enable_check = (
"enable_deferred_revenue" if doc.doctype == "Sales Invoice" else "enable_deferred_expense"
)
old_stop_dates = {}
old_doc = frappe.db.get_all(f"{doc.doctype} Item", {"parent": doc.name}, ["name", "service_stop_date"])
old_doc = frappe.db.get_all(
"{0} Item".format(doc.doctype), {"parent": doc.name}, ["name", "service_stop_date"]
)
for d in old_doc:
old_stop_dates[d.name] = d.service_stop_date or ""
@@ -46,8 +50,7 @@ def validate_service_stop_date(doc):
if (
old_stop_dates
and old_stop_dates.get(item.name)
and item.service_stop_date
and getdate(item.service_stop_date) != getdate(old_stop_dates.get(item.name))
and item.service_stop_date != old_stop_dates.get(item.name)
):
frappe.throw(_("Cannot change Service Stop Date for item in row {0}").format(item.idx))
@@ -59,14 +62,16 @@ def build_conditions(process_type, account, company):
)
if account:
conditions += f"AND {deferred_account}={frappe.db.escape(account)}"
conditions += "AND %s='%s'" % (deferred_account, account)
elif company:
conditions += f"AND p.company = {frappe.db.escape(company)}"
return conditions
def convert_deferred_expense_to_expense(deferred_process, start_date=None, end_date=None, conditions=""):
def convert_deferred_expense_to_expense(
deferred_process, start_date=None, end_date=None, conditions=""
):
# book the expense/income on the last day, but it will be trigger on the 1st of month at 12:00 AM
if not start_date:
@@ -76,14 +81,16 @@ def convert_deferred_expense_to_expense(deferred_process, start_date=None, end_d
# check for the purchase invoice for which GL entries has to be done
invoices = frappe.db.sql_list(
f"""
"""
select distinct item.parent
from `tabPurchase Invoice Item` item, `tabPurchase Invoice` p
where item.service_start_date<=%s and item.service_end_date>=%s
and item.enable_deferred_expense = 1 and item.parent=p.name
and item.docstatus = 1 and ifnull(item.amount, 0) > 0
{conditions}
""",
{0}
""".format(
conditions
),
(end_date, start_date),
) # nosec
@@ -96,7 +103,9 @@ def convert_deferred_expense_to_expense(deferred_process, start_date=None, end_d
send_mail(deferred_process)
def convert_deferred_revenue_to_income(deferred_process, start_date=None, end_date=None, conditions=""):
def convert_deferred_revenue_to_income(
deferred_process, start_date=None, end_date=None, conditions=""
):
# book the expense/income on the last day, but it will be trigger on the 1st of month at 12:00 AM
if not start_date:
@@ -106,14 +115,16 @@ def convert_deferred_revenue_to_income(deferred_process, start_date=None, end_da
# check for the sales invoice for which GL entries has to be done
invoices = frappe.db.sql_list(
f"""
"""
select distinct item.parent
from `tabSales Invoice Item` item, `tabSales Invoice` p
where item.service_start_date<=%s and item.service_end_date>=%s
and item.enable_deferred_revenue = 1 and item.parent=p.name
and item.docstatus = 1 and ifnull(item.amount, 0) > 0
{conditions}
""",
{0}
""".format(
conditions
),
(end_date, start_date),
) # nosec
@@ -125,7 +136,7 @@ def convert_deferred_revenue_to_income(deferred_process, start_date=None, end_da
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)
@@ -135,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
@@ -221,7 +229,7 @@ def calculate_monthly_amount(
if amount + already_booked_amount_in_account_currency > item.net_amount:
amount = item.net_amount - already_booked_amount_in_account_currency
if get_first_day(start_date) != start_date or get_last_day(end_date) != end_date:
if not (get_first_day(start_date) == start_date and get_last_day(end_date) == end_date):
partial_month = flt(date_diff(end_date, start_date)) / flt(
date_diff(get_last_day(end_date), get_first_day(start_date))
)
@@ -232,7 +240,9 @@ def calculate_monthly_amount(
already_booked_amount, already_booked_amount_in_account_currency = get_already_booked_amount(
doc, item
)
base_amount = flt(item.base_net_amount - already_booked_amount, item.precision("base_net_amount"))
base_amount = flt(
item.base_net_amount - already_booked_amount, item.precision("base_net_amount")
)
if account_currency == doc.company_currency:
amount = base_amount
else:
@@ -252,13 +262,17 @@ def calculate_amount(doc, item, last_gl_entry, total_days, total_booking_days, a
if account_currency == doc.company_currency:
amount = base_amount
else:
amount = flt(item.net_amount * total_booking_days / flt(total_days), item.precision("net_amount"))
amount = flt(
item.net_amount * total_booking_days / flt(total_days), item.precision("net_amount")
)
else:
already_booked_amount, already_booked_amount_in_account_currency = get_already_booked_amount(
doc, item
)
base_amount = flt(item.base_net_amount - already_booked_amount, item.precision("base_net_amount"))
base_amount = flt(
item.base_net_amount - already_booked_amount, item.precision("base_net_amount")
)
if account_currency == doc.company_currency:
amount = base_amount
else:
@@ -279,22 +293,26 @@ def get_already_booked_amount(doc, item):
gl_entries_details = frappe.db.sql(
"""
select sum({}) as total_credit, sum({}) as total_credit_in_account_currency, voucher_detail_no
select sum({0}) as total_credit, sum({1}) as total_credit_in_account_currency, voucher_detail_no
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
group by voucher_detail_no
""".format(total_credit_debit, total_credit_debit_currency),
""".format(
total_credit_debit, total_credit_debit_currency
),
(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name),
as_dict=True,
)
journal_entry_details = frappe.db.sql(
"""
SELECT sum(c.{}) as total_credit, sum(c.{}) as total_credit_in_account_currency, reference_detail_no
SELECT sum(c.{0}) as total_credit, sum(c.{1}) as total_credit_in_account_currency, reference_detail_no
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 p.docstatus < 2 group by reference_detail_no
""".format(total_credit_debit, total_credit_debit_currency),
""".format(
total_credit_debit, total_credit_debit_currency
),
(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name),
as_dict=True,
)
@@ -316,20 +334,16 @@ def get_already_booked_amount(doc, item):
def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
enable_check = "enable_deferred_revenue" if doc.doctype == "Sales Invoice" else "enable_deferred_expense"
enable_check = (
"enable_deferred_revenue" if doc.doctype == "Sales Invoice" else "enable_deferred_expense"
)
accounts_frozen_upto = frappe.db.get_value("Company", doc.company, "accounts_frozen_till_date")
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
@@ -361,45 +375,42 @@ def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
)
if not amount:
prev_posting_date = end_date
else:
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
return
if via_journal_entry:
book_revenue_via_journal_entry(
doc,
credit_account,
debit_account,
amount,
base_amount,
gl_posting_date,
project,
account_currency,
item.cost_center,
item,
deferred_process,
submit_journal_entry,
)
else:
make_gl_entries(
doc,
credit_account,
debit_account,
against,
amount,
base_amount,
gl_posting_date,
project,
account_currency,
item.cost_center,
item,
deferred_process,
)
# check if books nor frozen till endate:
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(
doc,
credit_account,
debit_account,
amount,
base_amount,
end_date,
project,
account_currency,
item.cost_center,
item,
deferred_process,
submit_journal_entry,
)
else:
make_gl_entries(
doc,
credit_account,
debit_account,
against,
amount,
base_amount,
end_date,
project,
account_currency,
item.cost_center,
item,
deferred_process,
)
# Returned in case of any errors because it tries to submit the same record again and again in case of errors
if frappe.flags.deferred_accounting_error:
@@ -407,17 +418,15 @@ 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(
frappe.db.get_singles_value("Accounts Settings", "book_deferred_entries_via_journal_entry")
)
submit_journal_entry = cint(frappe.db.get_singles_value("Accounts Settings", "submit_journal_entries"))
submit_journal_entry = cint(
frappe.db.get_singles_value("Accounts Settings", "submit_journal_entries")
)
book_deferred_entries_based_on = frappe.db.get_singles_value(
"Accounts Settings", "book_deferred_entries_based_on"
)
@@ -437,7 +446,9 @@ def process_deferred_accounting(posting_date=None):
posting_date = today()
if not cint(
frappe.db.get_singles_value("Accounts Settings", "automatically_process_deferred_accounting_entry")
frappe.db.get_singles_value(
"Accounts Settings", "automatically_process_deferred_accounting_entry"
)
):
return
@@ -449,12 +460,14 @@ def process_deferred_accounting(posting_date=None):
for company in companies:
for record_type in ("Income", "Expense"):
doc = frappe.get_doc(
doctype="Process Deferred Accounting",
company=company.name,
posting_date=posting_date,
start_date=start_date,
end_date=end_date,
type=record_type,
dict(
doctype="Process Deferred Accounting",
company=company.name,
posting_date=posting_date,
start_date=start_date,
end_date=end_date,
type=record_type,
)
)
doc.insert()
@@ -523,10 +536,9 @@ def make_gl_entries(
if gl_entries:
try:
make_gl_entries(gl_entries, cancel=(doc.docstatus == 2), merge_entries=True)
if not frappe.in_test:
frappe.db.commit()
frappe.db.commit()
except Exception as e:
if frappe.in_test:
if frappe.flags.in_test:
doc.log_error(f"Error while processing deferred accounting for Invoice {doc.name}")
raise e
else:
@@ -559,13 +571,16 @@ def book_revenue_via_journal_entry(
deferred_process=None,
submit="No",
):
if amount == 0:
return
journal_entry = frappe.new_doc("Journal Entry")
journal_entry.posting_date = posting_date
journal_entry.company = doc.company
journal_entry.voucher_type = "Deferred Revenue" if doc.doctype == "Sales Invoice" else "Deferred Expense"
journal_entry.voucher_type = (
"Deferred Revenue" if doc.doctype == "Sales Invoice" else "Deferred Expense"
)
journal_entry.process_deferred_accounting = deferred_process
debit_entry = {
@@ -606,8 +621,7 @@ def book_revenue_via_journal_entry(
if submit:
journal_entry.submit()
if not frappe.in_test:
frappe.db.commit()
frappe.db.commit()
except Exception:
frappe.db.rollback()
doc.log_error(f"Error while processing deferred accounting for Invoice {doc.name}")
@@ -615,6 +629,7 @@ def book_revenue_via_journal_entry(
def get_deferred_booking_accounts(doctype, voucher_detail_no, dr_or_cr):
if doctype == "Sales Invoice":
credit_account, debit_account = frappe.db.get_value(
"Sales Invoice Item",

View File

@@ -1,31 +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);
frm.toggle_enable(["is_group", "company", "account_number"], frm.is_new());
// disable fields
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
@@ -36,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;
}
@@ -186,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);
@@ -198,11 +178,11 @@ frappe.ui.form.on("Account", {
}
d.hide();
}
},
}
});
},
primary_action_label: __("Update"),
primary_action_label: __('Update')
});
d.show();
},
}
});

View File

@@ -3,7 +3,6 @@
"allow_copy": 1,
"allow_import": 1,
"creation": "2013-01-30 12:49:46",
"default_view": "Tree",
"description": "Heads (or groups) against which Accounting Entries are made and balances are maintained.",
"doctype": "DocType",
"document_type": "Setup",
@@ -19,9 +18,9 @@
"root_type",
"report_type",
"account_currency",
"inter_company_account",
"column_break1",
"parent_account",
"account_category",
"account_type",
"tax_rate",
"freeze_account",
@@ -35,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%"
},
{
@@ -50,24 +53,29 @@
"no_copy": 1,
"oldfieldname": "account_name",
"oldfieldtype": "Data",
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "account_number",
"fieldtype": "Data",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Account Number"
"label": "Account Number",
"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
},
{
"fetch_from": "parent_account.company",
"fetch_if_empty": 1,
"fieldname": "company",
"fieldtype": "Link",
"in_standard_filter": 1,
@@ -75,8 +83,11 @@
"oldfieldname": "company",
"oldfieldtype": "Link",
"options": "Company",
"read_only": 1,
"remember_last_selected_value": 1,
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "root_type",
@@ -84,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",
@@ -92,31 +105,46 @@
"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%"
},
{
"fieldname": "parent_account",
"fieldtype": "Link",
"ignore_user_permissions": 1,
"in_preview": 1,
"label": "Parent Account",
"oldfieldname": "parent_account",
"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.",
@@ -126,16 +154,19 @@
"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\nRound Off for Opening\nStock\nStock Adjustment\nStock Received But Not Billed\nService Received But Not Billed\nTax\nTemporary",
"search_index": 1
"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",
"fieldname": "tax_rate",
"fieldtype": "Float",
"label": "Tax Rate",
"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.",
@@ -144,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",
@@ -159,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",
@@ -168,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",
@@ -176,34 +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"
},
{
"description": "Used with Financial Report Template",
"fieldname": "account_category",
"fieldtype": "Link",
"label": "Account Category",
"options": "Account Category"
"label": "Disable",
"show_days": 1,
"show_seconds": 1
}
],
"icon": "fa fa-money",
"idx": 1,
"is_tree": 1,
"links": [],
"modified": "2026-04-14 18:14:42.202065",
"modified": "2020-06-11 15:15:54.338622",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Account",
@@ -254,24 +292,14 @@
"read": 1,
"report": 1,
"role": "Accounts Manager",
"set_user_permissions": 1,
"share": 1,
"write": 1
},
{
"role": "HR User",
"select": 1
},
{
"role": "HR Manager",
"select": 1
}
],
"row_format": "Dynamic",
"search_fields": "account_number",
"show_name_in_global_search": 1,
"show_preview_popup": 1,
"sort_field": "creation",
"sort_field": "modified",
"sort_order": "ASC",
"states": [],
"track_changes": 1
}
}

View File

@@ -4,7 +4,7 @@
import frappe
from frappe import _, throw
from frappe.utils import add_to_date, cint, cstr, pretty_date
from frappe.utils import cint, cstr
from frappe.utils.nestedset import NestedSet, get_ancestors_of, get_descendants_of
import erpnext
@@ -18,85 +18,20 @@ 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_category: DF.Link | None
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",
"Round Off for Opening",
"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):
if frappe.local.flags.ignore_update_nsm:
return
else:
super().on_update()
super(Account, self).on_update()
def onload(self):
role_allowed_for_frozen_entries = frappe.db.get_value(
"Company", self.company, "role_allowed_for_frozen_entries"
frozen_accounts_modifier = frappe.db.get_value(
"Accounts Settings", "Accounts Settings", "frozen_accounts_modifier"
)
if not role_allowed_for_frozen_entries or role_allowed_for_frozen_entries in frappe.get_roles():
if not frozen_accounts_modifier or frozen_accounts_modifier in frappe.get_roles():
self.set_onload("can_freeze_account", True)
def autoname(self):
@@ -105,13 +40,13 @@ class Account(NestedSet):
self.name = get_autoname_with_number(self.account_number, self.account_name, self.company)
def validate(self):
from erpnext.accounts.utils import validate_field_number
if frappe.local.flags.allow_unverified_charts:
return
self.validate_parent()
self.validate_parent_child_account_type()
self.validate_root_details()
self.validate_account_number()
self.validate_disabled()
validate_field_number("Account", self.name, self.account_number, self.company, "account_number")
self.validate_group_or_ledger()
self.set_root_and_report_type()
self.validate_mandatory()
@@ -119,21 +54,6 @@ 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"""
@@ -171,7 +91,7 @@ class Account(NestedSet):
if par.root_type:
self.root_type = par.root_type
if cint(self.is_group):
if self.is_group:
db_value = self.get_doc_before_save()
if db_value:
if self.report_type != db_value.report_type:
@@ -190,36 +110,20 @@ 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)
if not self.parent_account and not cint(self.is_group):
if not self.parent_account and not self.is_group:
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
if frappe.local.flags.ignore_root_company_validation or self.flags.ignore_root_company_validation:
if (
frappe.local.flags.ignore_root_company_validation or self.flags.ignore_root_company_validation
):
return
ancestors = get_root_company(self.company)
if ancestors:
@@ -256,14 +160,6 @@ class Account(NestedSet):
self.create_account_for_child_company(parent_acc_name_map, descendants, parent_acc_name)
def validate_disabled(self):
doc_before_save = self.get_doc_before_save()
if not doc_before_save or cint(doc_before_save.disabled) == cint(self.disabled):
return
if cint(self.disabled):
self.validate_default_accounts_in_company()
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):
@@ -271,44 +167,21 @@ class Account(NestedSet):
if self.check_gle_exists():
throw(_("Account with existing transaction cannot be converted to ledger"))
elif cint(self.is_group):
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."))
self.validate_default_accounts_in_company()
elif self.check_if_child_exists():
throw(_("Account with child nodes cannot be set as ledger"))
def validate_default_accounts_in_company(self):
default_account_fields = get_company_default_account_fields()
company_default_accounts = frappe.db.get_value(
"Company", self.company, list(default_account_fields.keys()), as_dict=1
)
msg = _("Account {0} cannot be disabled as it is already set as {1} for {2}.")
if not self.disabled:
msg = _("Account {0} cannot be converted to Group as it is already set as {1} for {2}.")
for d in default_account_fields:
if company_default_accounts.get(d) == self.name:
throw(
msg.format(
frappe.bold(self.name),
frappe.bold(default_account_fields.get(d)),
frappe.bold(self.company),
)
)
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
role_allowed_for_frozen_entries = frappe.get_cached_value(
"Company", self.company, "role_allowed_for_frozen_entries"
frozen_accounts_modifier = frappe.get_cached_value(
"Accounts Settings", "Accounts Settings", "frozen_accounts_modifier"
)
if not role_allowed_for_frozen_entries or role_allowed_for_frozen_entries not in frappe.get_roles():
if not frozen_accounts_modifier or frozen_accounts_modifier not in frappe.get_roles():
throw(_("You are not authorized to set Frozen value"))
def validate_balance_must_be_debit_or_credit(self):
@@ -331,36 +204,15 @@ 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, "is_cancelled": 0}, "account_currency"
)
gl_currency = frappe.db.get_value("GL Entry", {"account": self.name}, "account_currency")
if gl_currency and self.account_currency != gl_currency:
if frappe.db.get_value("GL Entry", {"account": self.name}):
frappe.throw(_("Currency can not be changed after making entries using some other currency"))
def validate_account_number(self, account_number=None):
if not account_number:
account_number = self.account_number
if account_number:
account_with_same_number = frappe.db.get_value(
"Account",
{"account_number": account_number, "company": self.company, "name": ["!=", self.name]},
)
if account_with_same_number:
frappe.throw(
_("Account Number {0} already used in account {1}").format(
account_number, account_with_same_number
)
)
def create_account_for_child_company(self, parent_acc_name_map, descendants, parent_acc_name):
for company in descendants:
company_bold = frappe.bold(company)
@@ -399,10 +251,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],
}
)
@@ -466,16 +316,17 @@ class Account(NestedSet):
if self.check_gle_exists():
throw(_("Account with existing transaction can not be deleted"))
super().on_trash(True)
super(Account, self).on_trash(True)
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_parent_account(doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict):
def get_parent_account(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql(
"""select name from tabAccount
where is_group = 1 and docstatus != 2 and company = {}
and {} like {} order by name limit {} offset {}""".format("%s", searchfield, "%s", "%s", "%s"),
where is_group = 1 and docstatus != 2 and company = %s
and %s like %s order by name limit %s offset %s"""
% ("%s", searchfield, "%s", "%s", "%s"),
(filters["company"], "%%%s%%" % txt, page_len, start),
as_list=1,
)
@@ -514,11 +365,21 @@ def get_account_autoname(account_number, account_name, company):
return " - ".join(parts)
def validate_account_number(name, account_number, company):
if account_number:
account_with_same_number = frappe.db.get_value(
"Account", {"account_number": account_number, "company": company, "name": ["!=", name]}
)
if account_with_same_number:
frappe.throw(
_("Account Number {0} already used in account {1}").format(
account_number, account_with_same_number
)
)
@frappe.whitelist()
def update_account_number(
name: str, account_name: str, account_number: str | None = None, from_descendant: bool = False
):
_ensure_idle_system()
def update_account_number(name, account_name, account_number=None, from_descendant=False):
account = frappe.get_cached_doc("Account", name)
if not account:
return
@@ -533,13 +394,7 @@ def update_account_number(
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 and not from_descendant:
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")
@@ -557,7 +412,7 @@ def update_account_number(
frappe.throw(message, title=_("Rename Not Allowed"))
account.validate_account_number(account_number)
validate_account_number(name, account_number, account.company)
if account_number:
frappe.db.set_value("Account", name, "account_number", account_number.strip())
else:
@@ -579,35 +434,25 @@ def update_account_number(
@frappe.whitelist()
def merge_account(old: str, new: str):
_ensure_idle_system()
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:
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),
if (new_account.is_group, new_account.root_type, new_account.company) != (
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:
if is_group and new_account.parent_account == old:
new_account.db_set("parent_account", frappe.get_cached_value("Account", old, "parent_account"))
frappe.rename_doc("Account", old, new, merge=1, force=1)
@@ -616,7 +461,7 @@ def merge_account(old: str, new: str):
@frappe.whitelist()
def get_root_company(company: str):
def get_root_company(company):
# return the topmost company in the hierarchy
ancestors = get_ancestors_of("Company", company, "lft asc")
return [ancestors[0]] if ancestors else []
@@ -632,57 +477,7 @@ def sync_update_account_number_in_child(
if old_acc_number:
filters["account_number"] = old_acc_number
for d in frappe.db.get_values("Account", filters=filters, fieldname=["company", "name"], as_dict=True):
for d in frappe.db.get_values(
"Account", filters=filters, fieldname=["company", "name"], as_dict=True
):
update_account_number(d["name"], account_name, account_number, from_descendant=True)
def _ensure_idle_system():
# Don't allow renaming if accounting entries are actively being updated, there are two main reasons:
# 1. Correctness: It's next to impossible to ensure that renamed account is not being used *right now*.
# 2. Performance: Renaming requires locking out many tables entirely and severely degrades performance.
if frappe.in_test:
return
last_gl_update = None
try:
# We also lock inserts to GL entry table with for_update here.
last_gl_update = frappe.db.get_value("GL Entry", {}, "modified", for_update=True, wait=False)
except frappe.QueryTimeoutError:
# wait=False fails immediately if there's an active transaction.
last_gl_update = add_to_date(None, seconds=-1)
if not last_gl_update:
return
if last_gl_update > add_to_date(None, minutes=-5):
frappe.throw(
_(
"Last GL Entry update was done {}. This operation is not allowed while system is actively being used. Please wait for 5 minutes before retrying."
).format(pretty_date(last_gl_update)),
title=_("System In Use"),
)
def get_company_default_account_fields():
return {
"default_bank_account": "Default Bank Account",
"default_cash_account": "Default Cash Account",
"default_receivable_account": "Default Receivable Account",
"default_payable_account": "Default Payable Account",
"default_expense_account": "Default Expense Account",
"default_income_account": "Default Income Account",
"stock_received_but_not_billed": "Stock Received But Not Billed Account",
"stock_adjustment_account": "Stock Adjustment Account",
"write_off_account": "Write Off Account",
"default_discount_account": "Default Payment Discount Account",
"unrealized_profit_loss_account": "Unrealized Profit / Loss Account",
"exchange_gain_loss_account": "Exchange Gain / Loss Account",
"unrealized_exchange_gain_loss_account": "Unrealized Exchange Gain / Loss Account",
"round_off_account": "Round Off Account",
"default_deferred_revenue_account": "Default Deferred Revenue Account",
"default_deferred_expense_account": "Default Deferred Expense Account",
"accumulated_depreciation_account": "Accumulated Depreciation Account",
"depreciation_expense_account": "Depreciation Expense Account",
"disposal_account": "Gain/Loss Account on Asset Disposal",
}

View File

@@ -1,4 +1,4 @@
frappe.provide("frappe.treeview_settings");
frappe.provide("frappe.treeview_settings")
frappe.treeview_settings["Account"] = {
breadcrumb: "Accounts",
@@ -7,13 +7,12 @@ frappe.treeview_settings["Account"] = {
filters: [
{
fieldname: "company",
fieldtype: "Select",
fieldtype:"Select",
options: erpnext.utils.get_tree_options("company"),
label: __("Company"),
render_on_toolbar: true,
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"));
@@ -23,269 +22,181 @@ 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_node_render: function (node, deep) {
const render_balances = () => {
for (let account of cur_tree.account_balance_data) {
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 = [];
if (deep) {
// in case of `get_all_nodes`
accounts = nodes.reduce((acc, node) => [...acc, ...node.data], []);
} else {
accounts = nodes;
}
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;
for (let account of r.message) {
const node = cur_tree.nodes && cur_tree.nodes[account.value];
if (!node || node.is_root) continue;
// 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 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.account_currency != account.company_currency
? format(account.balance_in_account_currency, account.account_currency) +
" / "
: "") +
format(account.balance, account.company_currency) +
" " +
dr_or_cr +
"</span>"
).insertBefore(node.$ul);
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);
}
}
};
if (frappe.boot.user.can_read.indexOf("GL Entry") == -1) return;
if (!cur_tree.account_balance_data) {
frappe.db.get_single_value("Accounts Settings", "show_balance_in_coa").then((value) => {
if (value) {
frappe.call({
method: "erpnext.accounts.utils.get_account_balances_coa",
args: {
company: cur_tree.args.company,
include_default_fb_balances: true,
},
callback: function (r) {
if (!r.message || r.message.length === 0) return;
cur_tree.account_balance_data = r.message || [];
render_balances();
},
});
}
});
} else {
render_balances();
}
});
},
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"
),
onchange: function () {
if (!this.value) {
this.layout.set_value("root_type", "");
}
},
},
{
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: "Link",
fieldname: "account_category",
label: __("Account Category"),
options: frappe.get_meta("Account").fields.filter((d) => d.fieldname == "account_category")[0]
.options,
description: __("Optional. Used with Financial Report Template"),
},
{
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"),
"default",
true
);
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"),
"default",
true
);
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_divider_to_button_group(__("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'));
// financial statements
for (let report of [
"Trial Balance",
"General Ledger",
"Balance Sheet",
"Profit and Loss Statement",
"Cash Flow",
"Accounts Payable",
"Accounts Receivable",
]) {
treeview.page.add_inner_button(
__(report),
function () {
frappe.set_route("query-report", report, { company: get_company() });
},
__("View")
);
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;
if (treeview.can_create) {
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 = {
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()
};
if (node.parent_label) {
frappe.route_options["account"] = node.label;
}
frappe.set_route("query-report", "General Ledger");
},
btnClass: "hidden-xs",
},
btnClass: "hidden-xs"
}
],
extend_toolbar: true,
};
extend_toolbar: true
}

View File

@@ -18,12 +18,19 @@ def create_charts(
accounts = []
def _import_accounts(children, parent, root_type, root_account=False):
nonlocal custom_chart
for account_name, child in children.items():
if root_account:
root_type = child.get("root_type")
if account_name not in get_chart_metadata_fields():
if account_name not in [
"account_name",
"account_number",
"account_type",
"root_type",
"is_group",
"tax_rate",
]:
account_number = cstr(child.get("account_number")).strip()
account_name, account_name_in_db = add_suffix_if_duplicate(
account_name, account_number, accounts
@@ -31,9 +38,7 @@ def create_charts(
is_group = identify_is_group(child)
report_type = (
"Balance Sheet"
if root_type in ["Asset", "Liability", "Equity"]
else "Profit and Loss"
"Balance Sheet" if root_type in ["Asset", "Liability", "Equity"] else "Profit and Loss"
)
account = frappe.get_doc(
@@ -47,10 +52,8 @@ def create_charts(
"report_type": report_type,
"account_number": account_number,
"account_type": child.get("account_type"),
"account_category": child.get("account_category"),
"account_currency": child.get("account_currency")
if custom_chart
else frappe.get_cached_value("Company", company, "default_currency"),
or frappe.get_cached_value("Company", company, "default_currency"),
"tax_rate": child.get("tax_rate"),
}
)
@@ -70,7 +73,7 @@ def create_charts(
# after all accounts are already inserted.
frappe.local.flags.ignore_update_nsm = True
_import_accounts(chart, None, None, root_account=True)
rebuild_tree("Account")
rebuild_tree("Account", "parent_account")
frappe.local.flags.ignore_update_nsm = False
@@ -90,7 +93,10 @@ def add_suffix_if_duplicate(account_name, account_number, accounts):
def identify_is_group(child):
if child.get("is_group"):
is_group = child.get("is_group")
elif len(set(child.keys()) - set(get_chart_metadata_fields())):
elif len(
set(child.keys())
- set(["account_name", "account_type", "root_type", "is_group", "tax_rate", "account_number"])
):
is_group = 1
else:
is_group = 0
@@ -98,8 +104,7 @@ def identify_is_group(child):
return is_group
@frappe.whitelist()
def get_chart(chart_template: str | None, existing_company: str | None = None):
def get_chart(chart_template, existing_company=None):
chart = {}
if existing_company:
return get_account_tree_from_existing_company(existing_company)
@@ -125,14 +130,14 @@ def get_chart(chart_template: str | None, existing_company: str | None = None):
for fname in os.listdir(path):
fname = frappe.as_unicode(fname)
if fname.endswith(".json"):
with open(os.path.join(path, fname)) as f:
with open(os.path.join(path, fname), "r") as f:
chart = f.read()
if chart and json.loads(chart).get("name") == chart_template:
return json.loads(chart).get("tree")
@frappe.whitelist()
def get_charts_for_country(country: str, with_standard: bool = False):
def get_charts_for_country(country, with_standard=False):
charts = []
def _get_chart_name(content):
@@ -157,7 +162,7 @@ def get_charts_for_country(country: str, with_standard: bool = False):
for fname in os.listdir(path):
fname = frappe.as_unicode(fname)
if (fname.startswith(country_code) or fname.startswith(country)) and fname.endswith(".json"):
with open(os.path.join(path, fname)) as f:
with open(os.path.join(path, fname), "r") as f:
_get_chart_name(f.read())
# if more than one charts, returned then add the standard
@@ -180,7 +185,6 @@ def get_account_tree_from_existing_company(existing_company):
"root_type",
"tax_rate",
"account_number",
"account_currency",
],
order_by="lft, rgt",
)
@@ -215,8 +219,6 @@ def build_account_tree(tree, parent, all_accounts):
tree[child.account_name]["account_type"] = child.account_type
if child.tax_rate:
tree[child.account_name]["tax_rate"] = child.tax_rate
if child.account_currency:
tree[child.account_name]["account_currency"] = child.account_currency
if not parent:
tree[child.account_name]["root_type"] = child.root_type
@@ -225,7 +227,7 @@ def build_account_tree(tree, parent, all_accounts):
@frappe.whitelist()
def validate_bank_account(coa: str, bank_account: str):
def validate_bank_account(coa, bank_account):
accounts = []
chart = get_chart(coa)
@@ -233,7 +235,7 @@ def validate_bank_account(coa: str, bank_account: str):
def _get_account_names(account_master):
for account_name, child in account_master.items():
if account_name not in get_chart_metadata_fields():
if account_name not in ["account_number", "account_type", "root_type", "is_group", "tax_rate"]:
accounts.append(account_name)
_get_account_names(child)
@@ -244,9 +246,7 @@ def validate_bank_account(coa: str, bank_account: str):
@frappe.whitelist()
def build_tree_from_json(
chart_template: str, chart_data: dict | None = None, from_coa_importer: bool = False
):
def build_tree_from_json(chart_template, chart_data=None, from_coa_importer=False):
"""get chart template from its folder and parse the json to be rendered as tree"""
chart = chart_data or get_chart(chart_template)
@@ -260,7 +260,14 @@ def build_tree_from_json(
"""recursively called to form a parent-child based list of dict from chart template"""
for account_name, child in children.items():
account = {}
if account_name in get_chart_metadata_fields():
if account_name in [
"account_name",
"account_number",
"account_type",
"root_type",
"is_group",
"tax_rate",
]:
continue
if from_coa_importer:
@@ -278,16 +285,3 @@ def build_tree_from_json(
_import_accounts(chart, None)
return accounts
def get_chart_metadata_fields():
return [
"account_name",
"account_number",
"account_type",
"account_category",
"root_type",
"is_group",
"tax_rate",
"account_currency",
]

View File

@@ -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()

View File

@@ -26,7 +26,7 @@
"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"},
"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"},
@@ -65,41 +65,42 @@
"0980 Geleistete Anzahlungen auf Finanzanlagen ": {"account_type": "Fixed Asset"},
"0990 Kumulierte Abschreibungen zu Finanzanlagen ": {"account_type": "Fixed Asset"},
"root_type": "Asset"
},
},
"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"},
"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"},
"1900 Wertberichtigungen": {"account_type": "Stock"},
"1800 Geleistete Anzahlungen": {"account_type": "Stock"},
"1900 Wertberichtigungen": {"account_type": "Stock"},
"root_type": "Asset"
},
},
"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"},
"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"},
"3185 Verbindlichkeiten Kreditkarte": {"account_type": "Payable"},
"3380 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"},
"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"},
"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"},
@@ -118,13 +119,13 @@
},
"3515 Umsatzsteuer Inland 10%": {
"account_type": "Tax"
},
},
"3520 Umsatzsteuer aus i.g. Erwerb 20%": {
"account_type": "Tax"
},
"3525 Umsatzsteuer aus i.g. Erwerb 10%": {
"account_type": "Tax"
},
},
"3560 Umsatzsteuer-Evidenzkonto f\u00fcr erhaltene Anzahlungen auf Bestellungen": {},
"3360 Verbindlichkeiten aus Lieferungen u. Leistungen EU": {
"account_type": "Payable"
@@ -140,7 +141,7 @@
"account_type": "Tax"
},
"root_type": "Liability"
},
},
"Klasse 2 Aktiva: Umlaufverm\u00f6gen, Rechnungsabgrenzungen": {
"2030 Forderungen aus Lieferungen und Leistungen Inland (0% USt, umsatzsteuerfrei)": {
"account_type": "Receivable"
@@ -153,7 +154,7 @@
},
"2040 Forderungen aus Lieferungen und Leistungen Inland (sonstiger USt-Satz)": {
"account_type": "Receivable"
},
},
"2100 Forderungen aus Lieferungen und Leistungen EU": {
"account_type": "Receivable"
},
@@ -191,7 +192,7 @@
"account_type": "Receivable"
},
"2570 Einfuhrumsatzsteuer (bezahlt)": {"account_type": "Tax"},
"2460 Eingeforderte aber noch nicht eingezahlte Einlagen": {
"account_type": "Receivable"
},
@@ -242,10 +243,10 @@
},
"2800 Guthaben bei Bank": {
"account_type": "Bank"
},
},
"2801 Guthaben bei Bank - Sparkonto": {
"account_type": "Bank"
},
},
"2810 Guthaben bei Paypal": {
"account_type": "Bank"
},
@@ -263,19 +264,19 @@
},
"2895 Schwebende Geldbewegugen": {
"account_type": "Bank"
},
},
"2513 Vorsteuer Inland 5%": {
"account_type": "Tax"
},
"2515 Vorsteuer Inland 20%": {
"account_type": "Tax"
},
},
"2520 Vorsteuer aus innergemeinschaftlichem Erwerb 10%": {
"account_type": "Tax"
},
"2525 Vorsteuer aus innergemeinschaftlichem Erwerb 20%": {
"account_type": "Tax"
},
},
"2530 Vorsteuer \u00a719/Art 19 ( reverse charge ) ": {
"account_type": "Tax"
},
@@ -285,16 +286,16 @@
"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"},
"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"},
"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"},
"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"},
@@ -303,15 +304,15 @@
"4700 Ertr\u00e4ge aus der Aufl\u00f6sung von R\u00fcckstellungen": {"account_type": "Income Account"},
"4800 \u00dcbrige betriebliche Ertr\u00e4ge": {"account_type": "Income Account"},
"root_type": "Income"
},
},
"Klasse 5: Aufwand f\u00fcr Material und Leistungen": {
"5000 Einkauf Partnerleistungen": {"account_type": "Cost of Goods Sold"},
"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"},
"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"},
@@ -339,7 +340,7 @@
"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"},
@@ -348,7 +349,7 @@
"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"},
"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"},
@@ -408,7 +409,7 @@
"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"
@@ -434,5 +435,5 @@
},
"root_type": "Equity"
}
}
}
}

View File

@@ -0,0 +1,531 @@
{
"country_code": "tr",
"name": "Turkey - Tek D\u00fczen Hesap Plan\u0131",
"tree": {
"Duran Varl\u0131klar": {
"Di\u011fer Alacaklar": {
"Ba\u011fl\u0131 Ortakl\u0131klardan Alacaklar": {},
"Di\u011fer Alacak Senetleri Reeskontu(-)": {},
"Di\u011fer \u00c7e\u015fitli Alacaklar": {},
"Ortaklardan Alacaklar": {},
"Personelden Alacaklar": {},
"\u0130\u015ftiraklerden Alacaklar": {},
"\u015e\u00fcpheli Di\u011fer Alacaklar Kar\u015f\u0131l\u0131\u011f\u0131(-)": {}
},
"Di\u011fer Duran Varl\u0131klar": {
"Birikmi\u015f Amortismanlar(-)": {},
"Di\u011fer KDV": {},
"Di\u011fer \u00c7e\u015fitli Duran Varl\u0131klar": {},
"Elden \u00c7\u0131kar\u0131lacak Stoklar Ve Maddi Duran Varl\u0131klar": {},
"Gelecek Y\u0131llar \u0130htiyac\u0131 Stoklar": {},
"Gelecek Y\u0131llarda \u0130ndirilecek KDV": {},
"Pe\u015fin \u00d6denen Vergi Ve Fonlar": {},
"Stok De\u011fer D\u00fc\u015f\u00fckl\u00fc\u011f\u00fc Kar\u015f\u0131l\u0131\u011f\u0131(-)": {}
},
"Gelecek Y\u0131llara Ait Giderler ve Gelir Tahakkuklar\u0131": {
"Gelecek Y\u0131llara Ait Giderler": {},
"Gelir Tahakkuklar\u0131": {}
},
"Maddi Duran Varl\u0131klar": {
"Arazi Ve Arsalar": {},
"Binalar": {},
"Birikmi\u015f Amortismanlar(-)": {},
"Demirba\u015flar": {},
"Di\u011fer Maddi Duran Varl\u0131klar": {},
"Ta\u015f\u0131tlar": {},
"Tesis, Makine Ve Cihazlar": {},
"Verilen Avanslar": {},
"Yap\u0131lmakta Olan Yat\u0131r\u0131mlar": {},
"Yer Alt\u0131 Ve Yer \u00dcst\u00fc D\u00fczenleri": {}
},
"Maddi Olmayan Duran Varl\u0131klar": {
"Ara\u015ft\u0131rma Ve Geli\u015ftirme Giderleri": {},
"Birikmi\u015f Amortismanlar(-)": {},
"Di\u011fer Maddi Olmayan Duran Varl\u0131klar": {},
"Haklar": {},
"Kurulu\u015f Ve \u00d6rg\u00fctlenme Giderleri": {},
"Verilen Avanslar": {},
"\u00d6zel Maliyetler": {},
"\u015eerefiye": {}
},
"Mali Duran Varl\u0131klar": {
"Ba\u011fl\u0131 Menkul K\u0131ymetler": {},
"Ba\u011fl\u0131 Menkul K\u0131ymetler De\u011fer D\u00fc\u015f\u00fckl\u00fc\u011f\u00fc Kar\u015f\u0131l\u0131\u011f\u0131(-)": {},
"Ba\u011fl\u0131 Ortakl\u0131klar": {},
"Ba\u011fl\u0131 Ortakl\u0131klar Sermaye Paylar\u0131 De\u011fer D\u00fc\u015f\u00fckl\u00fc\u011f\u00fc Kar\u015f\u0131l\u0131\u011f\u0131(-)": {},
"Ba\u011fl\u0131 Ortakl\u0131klara Sermaye Taahh\u00fctleri(-)": {},
"Di\u011fer Mali Duran Varl\u0131klar": {},
"Di\u011fer Mali Duran Varl\u0131klar Kar\u015f\u0131l\u0131\u011f\u0131(-)": {},
"\u0130\u015ftirakler": {},
"\u0130\u015ftirakler Sermaye Paylar\u0131 De\u011fer D\u00fc\u015f\u00fckl\u00fc\u011f\u00fc Kar\u015f\u0131l\u0131\u011f\u0131(-)": {},
"\u0130\u015ftiraklere Sermaye Taahh\u00fctleri(-)": {}
},
"Ticari Alacaklar": {
"Alacak Senetleri": {},
"Alacak Senetleri Reeskontu(-)": {},
"Al\u0131c\u0131lar": {},
"Kazaqn\u0131lmam\u0131\u015f Finansal Kiralama Faiz Gelirleri(-)": {},
"Verilen Depozito Ve Teminatlar": {},
"\u015e\u00fcpheli Ticari Alacaklar Kar\u015f\u0131l\u0131\u011f\u0131(-)": {}
},
"root_type": "",
"\u00d6zel T\u00fckenmeye Tabi Varl\u0131klar": {
"Arama Giderleri": {},
"Birikmi\u015f T\u00fckenme Paylar\u0131(-)": {},
"Di\u011fer \u00d6zel T\u00fckenmeye Tabi Varl\u0131klar": {},
"Haz\u0131rl\u0131k Ve Geli\u015ftirme Giderleri": {},
"Verilen Avanslar": {}
}
},
"D\u00f6nen Varl\u0131klar": {
"Di\u011fer Alacaklar": {
"Ba\u011fl\u0131 Ortakl\u0131klardan Alacaklar": {},
"Di\u011fer Alacak Senetleri Reeskontu(-)": {},
"Di\u011fer \u00c7e\u015fitli Alacaklar": {},
"Ortaklardan Alacaklar": {},
"Personelden Alacaklar": {},
"\u0130\u015ftiraklerden Alacaklar": {},
"\u015e\u00fcpheli Di\u011fer Alacaklar": {},
"\u015e\u00fcpheli Di\u011fer Alacaklar Kar\u015f\u0131l\u0131\u011f\u0131(-)": {}
},
"Di\u011fer D\u00f6nen Varl\u0131klar": {
"Devreden KDV": {},
"Di\u011fer D\u00f6nen Varl\u0131klar Kar\u015f\u0131l\u0131\u011f\u0131(-)": {},
"Di\u011fer KDV": {},
"Di\u011fer \u00c7e\u015fitli D\u00f6nen Varl\u0131klar": {},
"Personel Avanslar\u0131": {},
"Pe\u015fin \u00d6denen Vergiler Ve Fonlar": {},
"Say\u0131m Ve Tesell\u00fcm Noksanlar\u0131": {},
"\u0130ndirilecek KDV": {},
"\u0130\u015f Avanslar\u0131": {}
},
"Gelecek Aylara Ait Giderler ve Gelir Tahakkuklar\u0131": {
"Gelecek Aylara Ait Giderler": {},
"Gelir Tahakkuklar\u0131": {}
},
"Haz\u0131r De\u011ferler": {
"Al\u0131nan \u00c7ekler": {},
"Bankalar": {
"account_type": "Bank"
},
"Di\u011fer Haz\u0131r De\u011ferler": {},
"Kasa": {
"account_type": "Cash"
},
"Verilen \u00c7ekler ve \u00d6deme Emirleri(-)": {}
},
"Menkul K\u0131ymetler": {
"Di\u011fer Menkul K\u0131ymetler": {},
"Hisse Senetleri": {},
"Kamu Kesimi Tahvil, Senet ve Bonolar\u0131": {},
"Menkul K\u0131ymetler De\u011fer D\u00fc\u015f\u00fckl\u00fc\u011f\u00fc Kar\u015f\u0131l\u0131\u011f\u0131(-)": {},
"\u00d6zel Kesim Tahvil Senet Ve Bonolar\u0131": {}
},
"Stoklar": {
"Mamuller": {},
"Stok De\u011fer D\u00fc\u015f\u00fckl\u00fc\u011f\u00fc Kar\u015f\u0131l\u0131\u011f\u0131(-)": {},
"Ticari Mallar": {},
"Verilen Sipari\u015f Avanslar\u0131": {},
"Yar\u0131 Mamuller": {},
"\u0130lk Madde Malzeme": {}
},
"Ticari Alacaklar": {
"Alacak Senetleri": {},
"Alacak Senetleri Reeskontu(-)": {},
"Al\u0131c\u0131lar": {},
"Di\u011fer Ticari Alacaklar": {},
"Kazan\u0131lmam\u0131\u015f Finansal Kiralama Faiz Gelirleri(-)": {},
"Verilen Depozito ve Teminatlar": {},
"\u015e\u00fcpheli Ticari Alacaklar": {},
"\u015e\u00fcpheli Ticari Alacaklar Kar\u015f\u0131l\u0131\u011f\u0131": {}
},
"Y\u0131llara Yayg\u0131n \u0130n\u015faat ve Onar\u0131m Maliyetleri": {
"Ta\u015feronlara Verilen Avanslar": {},
"Y\u0131llara Yayg\u0131n \u0130n\u015faat Ve Onar\u0131m Maliyetleri": {}
},
"root_type": ""
},
"Gelir Tablosu Hesaplar\u0131": {
"Br\u00fct Sat\u0131\u015flar": {
"Di\u011fer Gelirler": {},
"Yurt D\u0131\u015f\u0131 Sat\u0131\u015flar": {},
"Yurt \u0130\u00e7i Sat\u0131\u015flar": {}
},
"Di\u011fer Faaliyetlerden Olu\u015fan Gelir ve K\u00e2rlar": {
"Ba\u011fl\u0131 Ortakl\u0131klardan Temett\u00fc Gelirleri": {},
"Di\u011fer Ola\u011fan Gelir Ve K\u00e2rlar": {},
"Enflasyon D\u00fczeltme K\u00e2rlar\u0131": {},
"Faiz Gelirleri": {},
"Kambiyo K\u00e2rlar\u0131": {},
"Komisyon Gelirleri": {},
"Konusu Kalmayan Kar\u015f\u0131l\u0131klar": {},
"Menkul K\u0131ymet Sat\u0131\u015f K\u00e2rlar\u0131": {},
"Reeskont Faiz Gelirleri": {},
"\u0130\u015ftiraklerden Temett\u00fc Gelirleri": {}
},
"Di\u011fer Faaliyetlerden Olu\u015fan Gider ve Zararlar (-)": {
"Di\u011fer Ola\u011fan Gider Ve Zararlar(-)": {},
"Enflasyon D\u00fczeltmesi Zararlar\u0131(-)": {},
"Kambiyo Zararlar\u0131(-)": {},
"Kar\u015f\u0131l\u0131k Giderleri(-)": {},
"Komisyon Giderleri(-)": {},
"Menkul K\u0131ymet Sat\u0131\u015f Zararlar\u0131(-)": {},
"Reeskont Faiz Giderleri(-)": {}
},
"D\u00f6nem Net K\u00e2r\u0131 Ve Zarar\u0131": {
"D\u00f6nem K\u00e2r\u0131 Vergi Ve Di\u011fer Yasal Y\u00fck\u00fcml\u00fcl\u00fck Kar\u015f\u0131l\u0131klar\u0131(-)": {},
"D\u00f6nem K\u00e2r\u0131 Veya Zarar\u0131": {},
"D\u00f6nem Net K\u00e2r\u0131 Veya Zarar\u0131": {},
"Enflasyon D\u00fczeltme Hesab\u0131": {},
"Y\u0131llara Yayg\u0131n \u0130n\u015faat Ve Enflasyon D\u00fczeltme Hesab\u0131": {}
},
"Faaliyet Giderleri(-)": {
"Ara\u015ft\u0131rma Ve Geli\u015ftirme Giderleri(-)": {},
"Genel Y\u00f6netim Giderleri(-)": {},
"Pazarlama Sat\u0131\u015f Ve Da\u011f\u0131t\u0131m Giderleri(-)": {}
},
"Finansman Giderleri": {
"K\u0131sa Vadeli Bor\u00e7lanma Giderleri(-)": {},
"Uzun Vadeli Bor\u00e7lanma Giderleri(-)": {}
},
"Ola\u011fan D\u0131\u015f\u0131 Gelir Ve K\u00e2rlar": {
"Di\u011fer Ola\u011fan D\u0131\u015f\u0131 Gelir Ve K\u00e2rlar": {},
"\u00d6nceki D\u00f6nem Gelir Ve K\u00e2rlar\u0131": {}
},
"Ola\u011fan D\u0131\u015f\u0131 Gider Ve Zaralar(-)": {
"Di\u011fer Ola\u011fan D\u0131\u015f\u0131 Gider Ve Zararlar(-)": {},
"\u00c7al\u0131\u015fmayan K\u0131s\u0131m Gider Ve Zararlar\u0131(-)": {},
"\u00d6nceki D\u00f6nem Gider Ve Zararlar\u0131(-)": {}
},
"Sat\u0131\u015f \u0130ndirimleri (-)": {
"Di\u011fer \u0130ndirimler": {},
"Sat\u0131\u015f \u0130ndirimleri(-)": {},
"Sat\u0131\u015ftan \u0130adeler(-)": {}
},
"Sat\u0131\u015flar\u0131n Maliyeti(-)": {
"Di\u011fer Sat\u0131\u015flar\u0131n Maliyeti(-)": {},
"Sat\u0131lan Hizmet Maliyeti(-)": {},
"Sat\u0131lan Mamuller Maliyeti(-)": {},
"Sat\u0131lan Ticari Mallar Maliyeti(-)": {}
},
"root_type": ""
},
"K\u0131sa Vadeli Yabanc\u0131 Kaynaklar": {
"Al\u0131nan Avanslar": {
"Al\u0131nan Di\u011fer Avanslar": {
"account_type": "Payable"
},
"Al\u0131nan Sipari\u015f Avanslar\u0131": {
"account_type": "Payable"
},
"account_type": "Payable"
},
"Bor\u00e7 ve Gider Kar\u015f\u0131l\u0131klar\u0131": {
"Di\u011fer Bor\u00e7 Ve Gider Kar\u015f\u0131l\u0131klar\u0131": {
"account_type": "Payable"
},
"D\u00f6nem K\u00e2r\u0131 Vergi Ve Di\u011fer Yasal Y\u00fck\u00fcml\u00fcl\u00fck Kar\u015f\u0131l\u0131klar\u0131": {
"account_type": "Tax"
},
"D\u00f6nem K\u00e2r\u0131n\u0131n Pe\u015fin \u00d6denen Vergi Ve Di\u011fer Y\u00fck\u00fcml\u00fcl\u00fckler(-)": {
"account_type": "Tax"
},
"K\u0131dem Tazminat\u0131 Kar\u015f\u0131l\u0131\u011f\u0131": {},
"Maliyet Giderleri Kar\u015f\u0131l\u0131\u011f\u0131": {},
"account_type": "Payable"
},
"Di\u011fer Bor\u00e7lar": {
"Ba\u011fl\u0131 Ortakl\u0131klara Bor\u00e7lar": {
"account_type": "Payable"
},
"Di\u011fer Bor\u00e7 Senetleri Reeskontu(-)": {
"account_type": "Payable"
},
"Di\u011fer \u00c7e\u015fitli Bor\u00e7lar": {
"account_type": "Payable"
},
"Ortaklara Bor\u00e7lar": {
"account_type": "Payable"
},
"Personele Bor\u00e7lar": {
"account_type": "Payable"
},
"account_type": "Payable",
"\u0130\u015ftiraklere Bor\u00e7lar": {
"account_type": "Payable"
}
},
"Di\u011fer K\u0131sa Vadeli Yabanc\u0131 Kaynaklar": {
"Di\u011fer KDV": {
"account_type": "Tax"
},
"Di\u011fer \u00c7e\u015fitli Yabanc\u0131 Kaynaklar": {},
"Hesaplanan KDV": {
"account_type": "Tax"
},
"Merkez Ve \u015eubeler Cari Hesab\u0131": {},
"Say\u0131m Ve Tesell\u00fcm Fazlalar\u0131": {},
"account_type": "Payable"
},
"Gelecek Aylara Ait Gelirler Ve Gider Tahakkuklar\u0131": {
"Gelecek Aylara Ait Gelirler": {},
"Gider Tahakkuklar\u0131": {}
},
"Mali Bor\u00e7lar": {
"Banka Kredileri": {
"account_type": "Payable"
},
"Di\u011fer Mali Bor\u00e7lar": {
"account_type": "Payable"
},
"Ertelenmi\u015f Finansal Kiralama Bor\u00e7lanma Maliyetleri(-)": {
"account_type": "Payable"
},
"Finansal Kiralama \u0130\u015flemlerinden Bor\u00e7lar": {
"account_type": "Payable"
},
"Menkul K\u0131ymetler \u0130hra\u00e7 Fark\u0131(-)": {
"account_type": "Payable"
},
"Tahvil Anapara Bor\u00e7, Taksit Ve Faizleri": {
"account_type": "Payable"
},
"Uzun Vadeli Kredilerin Anapara Taksitleri Ve Faizleri": {
"account_type": "Payable"
},
"account_type": "Payable",
"\u00c7\u0131kar\u0131lan Bonolar Ve Senetler": {
"account_type": "Payable"
},
"\u00c7\u0131kar\u0131lm\u0131\u015f Di\u011fer Menkul K\u0131ymetler": {
"account_type": "Payable"
}
},
"Ticari Bor\u00e7lar": {
"Al\u0131nan Depozito Ve Teminatlar": {
"account_type": "Payable"
},
"Bor\u00e7 Senetleri": {
"account_type": "Payable"
},
"Bor\u00e7 Senetleri Reeskontu(-)": {
"account_type": "Payable"
},
"Di\u011fer Ticari Bor\u00e7lar": {
"account_type": "Payable"
},
"Sat\u0131c\u0131lar": {
"account_type": "Payable"
},
"account_type": "Payable"
},
"Y\u0131llara Yayg\u0131n \u0130n\u015faat Ve Onar\u0131m Hakedi\u015fleri": {
"350 Y\u0131llara Yayg\u0131n \u0130n\u015faat Ve Onar\u0131m Hakedi\u015fleri Bedelleri": {
"account_type": "Payable"
},
"account_type": "Payable"
},
"root_type": "",
"\u00d6denecek Vergi ve Di\u011fer Y\u00fck\u00fcml\u00fcl\u00fckler": {
"Vadesi Ge\u00e7mi\u015f, Ertelenmi\u015f Veya Taksitlendirilmi\u015f Vergi Ve Di\u011fer Y\u00fck\u00fcml\u00fcl\u00fckler": {
"account_type": "Tax"
},
"account_type": "Tax",
"\u00d6denecek Di\u011fer Y\u00fck\u00fcml\u00fcl\u00fckler": {
"account_type": "Tax"
},
"\u00d6denecek Sosyal G\u00fcvenl\u00fck Kesintileri": {
"account_type": "Tax"
},
"\u00d6denecek Vergi Ve Fonlar": {
"account_type": "Tax"
}
}
},
"Maliyet Hesaplar\u0131": {
"Ara\u015ft\u0131rma Ve Geli\u015ftirme Giderleri": {},
"Direkt \u0130lk Madde Ve Malzeme Giderleri": {
"Direk \u0130lk Madde Ve Malzeme Giderleri Hesab\u0131": {},
"Direkt \u0130lk Madde Ve Malzeme Fiyat Fark\u0131": {},
"Direkt \u0130lk Madde Ve Malzeme Miktar Fark\u0131": {},
"Direkt \u0130lk Madde Ve Malzeme Yans\u0131tma Hesab\u0131": {}
},
"Direkt \u0130\u015f\u00e7ilik Giderleri": {
"Direkt \u0130\u015f\u00e7ilik Giderleri": {},
"Direkt \u0130\u015f\u00e7ilik Giderleri Yans\u0131tma Hesab\u0131": {},
"Direkt \u0130\u015f\u00e7ilik S\u00fcre Farklar\u0131": {},
"Direkt \u0130\u015f\u00e7ilik \u00dccret Farklar\u0131": {}
},
"Finansman Giderleri": {
"Finansman Giderleri": {},
"Finansman Giderleri Fark Hesab\u0131": {},
"Finansman Giderleri Yans\u0131tma Hesab\u0131": {}
},
"Genel Y\u00f6netim Giderleri": {
"Genel Y\u00f6netim Gider Farklar\u0131 Hesab\u0131": {},
"Genel Y\u00f6netim Giderleri": {},
"Genel Y\u00f6netim Giderleri Yans\u0131tma Hesab\u0131": {}
},
"Genel \u00dcretim Giderleri": {
"Genel \u00dcretim Giderleri": {},
"Genel \u00dcretim Giderleri B\u00fct\u00e7e Farklar\u0131": {},
"Genel \u00dcretim Giderleri Kapasite Farklar\u0131": {},
"Genel \u00dcretim Giderleri Verimlilik Giderleri": {},
"Genel \u00dcretim Giderleri Yans\u0131tma Hesab\u0131": {}
},
"Hizmet \u00dcretim Maliyeti": {
"Hizmet \u00dcretim Maliyeti": {},
"Hizmet \u00dcretim Maliyeti Fark Hesaplar\u0131": {},
"Hizmet \u00dcretim Maliyeti Yans\u0131tma Hesab\u0131": {}
},
"Maliyet Muhasebesi Ba\u011flant\u0131 Hesaplar\u0131": {
"Maliyet Muhasebesi Ba\u011flant\u0131 Hesab\u0131": {},
"Maliyet Muhasebesi Yans\u0131tma Hesab\u0131": {}
},
"Pazarlama, Sat\u0131\u015f Ve Da\u011f\u0131t\u0131m Giderleri": {
"Atra\u015ft\u0131rma Ve Geli\u015ftirme Giderleri": {},
"Pazarlama Sat\u0131\u015f Ve Dag\u0131t\u0131m Giderleri Yans\u0131tma Hesab\u0131": {},
"Pazarlama Sat\u0131\u015f Ve Da\u011f\u0131t\u0131m Giderleri Fark Hesab\u0131": {}
},
"root_type": ""
},
"Naz\u0131m Hesaplar": {
"root_type": ""
},
"Serbest Hesaplar": {
"root_type": ""
},
"Uzun Vadeli Yabanc\u0131 Kaynaklar": {
"Al\u0131nan Avanslar": {
"Al\u0131nan Di\u011fer Avanslar": {
"account_type": "Payable"
},
"Al\u0131nan Sipari\u015f Avanslar\u0131": {
"account_type": "Payable"
},
"account_type": "Payable"
},
"Bor\u00e7 Ve Gider Kar\u015f\u0131l\u0131klar\u0131": {
"Di\u011fer Bor\u00e7 Ve Gider Kar\u015f\u0131l\u0131klar\u0131": {
"account_type": "Payable"
},
"K\u0131dem Tazminat\u0131 Kar\u015f\u0131l\u0131\u011f\u0131": {},
"account_type": "Payable"
},
"Di\u011fer Bor\u00e7lar": {
"Ba\u011fl\u0131 Ortakl\u0131klara Bor\u00e7lar": {
"account_type": "Payable"
},
"Di\u011fer Bor\u00e7 Senetleri Reeskontu(-)": {
"account_type": "Payable"
},
"Di\u011fer \u00c7e\u015fitli Bor\u00e7lar": {
"account_type": "Payable"
},
"Kamuya Olan Ertelenmi\u015f Veya Taksitlendirilmi\u015f Bor\u00e7lar": {
"account_type": "Payable"
},
"Ortaklara Bor\u00e7lar": {
"account_type": "Payable"
},
"account_type": "Payable",
"\u0130\u015ftiraklere Bor\u00e7lar": {
"account_type": "Payable"
}
},
"Di\u011fer Uzun Vadeli Yabanc\u0131 Kaynaklar": {
"Di\u011fer \u00c7e\u015fitli Uzun Vadeli Yabanc\u0131 Kaynaklar": {
"account_type": "Payable"
},
"Gelecek Y\u0131llara Ertelenmi\u015f Veya Terkin Edilecek KDV": {
"account_type": "Payable"
},
"Tesise Kat\u0131lma Paylar\u0131": {
"account_type": "Payable"
},
"account_type": "Payable"
},
"Gelecek Y\u0131llara Ait Gelirler Ve Gider Tahakkuklar\u0131": {
"Gelecek Y\u0131llara Ait Gelirler": {},
"Gider Tahakkuklar\u0131": {}
},
"Mali Bor\u00e7lar": {
"Banka Kredileri": {
"account_type": "Payable"
},
"Di\u011fer Mali Bor\u00e7lar": {
"account_type": "Payable"
},
"Ertelenmi\u015f Finansal Kiralama Bor\u00e7lanma Maliyetleri(-)": {
"account_type": "Payable"
},
"Finansal Kiralama \u0130\u015flemlerinden Bor\u00e7lar": {
"account_type": "Payable"
},
"Menkul K\u0131ymetler \u0130hra\u00e7 Fark\u0131(-)": {
"account_type": "Payable"
},
"account_type": "Payable",
"\u00c7\u0131kar\u0131lm\u0131\u015f Di\u011fer Menkul K\u0131ymetler": {
"account_type": "Payable"
},
"\u00c7\u0131kar\u0131lm\u0131\u015f Tahviller": {
"account_type": "Payable"
}
},
"Ticari Bor\u00e7lar": {
"Al\u0131nan Depozito Ve Teminatlar": {
"account_type": "Payable"
},
"Bor\u00e7 Senetleri": {
"account_type": "Payable"
},
"Bor\u00e7 Senetleri Reeskontu(-)": {
"account_type": "Payable"
},
"Di\u011fer Ticari Bor\u00e7lar": {
"account_type": "Payable"
},
"Sat\u0131c\u0131lar": {
"account_type": "Payable"
},
"account_type": "Payable"
},
"root_type": ""
},
"\u00d6z Kaynaklar": {
"D\u00f6nem Net K\u00e2r\u0131 (Zarar\u0131)": {
"D\u00f6nem Net K\u00e2r\u0131": {},
"D\u00f6nem Net Zarar\u0131(-)": {}
},
"Ge\u00e7mi\u015f Y\u0131llar K\u00e2rlar\u0131": {
"Ge\u00e7mi\u015f Y\u0131llar K\u00e2rlar\u0131": {}
},
"Ge\u00e7mi\u015f Y\u0131llar Zararlar\u0131(-)": {
"Ge\u00e7mi\u015f Y\u0131llar Zararlar\u0131(-)": {}
},
"K\u00e2r Yedekleri": {
"Di\u011fer K\u00e2r Yedekleri": {},
"Ola\u011fan\u00fcst\u00fc Yedekler": {},
"Stat\u00fc Yedekleri": {},
"Yasal Yedekler": {},
"\u00d6zel Fonlar": {}
},
"Sermaye Yedekleri": {
"Di\u011fer Sermaye Yedekleri": {},
"Hisse Senedi \u0130ptal K\u00e2rlar\u0131": {},
"Hisse Senetleri \u0130hra\u00e7 Primleri": {},
"Maddi Duran Varl\u0131k Yeniden De\u011ferlenme Art\u0131\u015flar\u0131": {},
"Maliyet Art\u0131\u015flar\u0131 Fonu": {},
"\u0130\u015ftirakler Yeniden De\u011ferleme Art\u0131\u015flar\u0131": {}
},
"root_type": "",
"\u00d6denmi\u015f Sermaye": {
"Sermaye": {},
"\u00d6denmi\u015f Sermaye(-)": {
"account_type": "Payable"
}
}
}
}
}

View File

@@ -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"

View File

@@ -1,817 +0,0 @@
{
"country_code": "au",
"name": "Australia - Chart of Accounts with Account Numbers",
"tree": {
"Assets": {
"Current Assets": {
"Cash On Hand": {
"Cash On Hand": {
"account_number": "11010",
"account_type": "Cash"
},
"account_number": "110",
"is_group": 1
},
"Cash at Bank": {
"Every Day Bank Account": {
"account_number": "11510",
"account_type": "Bank"
},
"Business Savings Account": {
"account_number": "11520"
},
"Business Term Deposit": {
"account_number": "11530"
},
"account_number": "115",
"is_group": 1
},
"Trade Receivables": {
"Trade Debtors": {
"account_number": "12010",
"account_type": "Receivable"
},
"Provision for Doubtful Debts": {
"account_number": "12020"
},
"Sundry Debtors": {
"account_number": "12030"
},
"Debtor Refund": {
"account_number": "12040"
},
"account_number": "120",
"is_group": 1
},
"Inventory": {
"Stock On Hand": {
"account_number": "13010",
"account_type": "Stock"
},
"WIP - Work In Progress - Manufacturing": {
"account_number": "13020"
},
"account_number": "130",
"is_group": 1
},
"Prepayments": {
"Prepayments": {
"account_number": "14010"
},
"Provisional Tax Paid": {
"account_number": "14020"
},
"account_number": "140",
"is_group": 1
},
"account_number": "11",
"is_group": 1
},
"Non Current Assets": {
"Plant & Equipment": {
"Plant & Equipment": {
"account_number": "16010",
"account_type": "Fixed Asset"
},
"Accumulated Depreciation Plant & Equipment": {
"account_number": "16020",
"account_type": "Accumulated Depreciation"
},
"account_number": "160",
"is_group": 1
},
"Motor Vehicle": {
"Motor Vehicle": {
"account_number": "16110",
"account_type": "Fixed Asset"
},
"Accumulated Depreciation Motor Vehicle": {
"account_number": "16120",
"account_type": "Accumulated Depreciation"
},
"account_number": "161",
"is_group": 1
},
"Office Equipment": {
"Office Furniture & Equipment": {
"account_number": "16210",
"account_type": "Fixed Asset"
},
"Accumulated Depreciation Office Furniture & Equipment": {
"account_number": "16220",
"account_type": "Accumulated Depreciation"
},
"account_number": "162",
"is_group": 1
},
"Computer Equipment": {
"Computer Equipment": {
"account_number": "16310",
"account_type": "Fixed Asset"
},
"Accumulated Depreciation Computer Equipment": {
"account_number": "16320",
"account_type": "Accumulated Depreciation"
},
"account_number": "163",
"is_group": 1
},
"Building": {
"Buildings": {
"account_number": "16410",
"account_type": "Fixed Asset"
},
"Accumulated Depreciation Buildings": {
"account_number": "16420",
"account_type": "Accumulated Depreciation"
},
"CWIP - Construction Work In Progress": {
"account_number": "16430",
"account_type": "Capital Work in Progress"
},
"Accumulated Depreciation - Others": {
"account_number": "16440",
"account_type": "Accumulated Depreciation"
},
"account_number": "164",
"is_group": 1
},
"Related Party": {
"Loan to Party 1": {
"account_number": "17010"
},
"account_number": "170",
"is_group": 1
},
"Investments & Unlisted Entities": {
"Investment - Entity 1": {
"account_number": "17510"
},
"account_number": "175",
"is_group": 1
},
"Intagible Assets": {
"Goodwill": {
"account_number": "18010"
},
"Opening Balance Temporary ": {
"account_number": "18090",
"account_type": "Temporary"
},
"account_number": "180",
"is_group": 1
},
"account_number": "16",
"is_group": 1
},
"account_number": "1",
"root_type": "Asset"
},
"Liabilities": {
"Current Liabilities": {
"Trade Payables - Current": {
"Trade Creditors": {
"account_number": "21010",
"account_type": "Payable"
},
"Goods Received Not Invoiced": {
"account_number": "21050",
"account_type": "Stock Received But Not Billed"
},
"Service Received Not Invoiced": {
"account_number": "21060"
},
"Asset Received Not Invoiced": {
"account_number": "21070",
"account_type": "Asset Received But Not Billed"
},
"account_number": "210",
"is_group": 1
},
"Other Payables - Current": {
"Accrued Expenses": {
"account_number": "21510"
},
"Payroll - Wages Clearing": {
"account_number": "21550"
},
"Payroll - Superannuation Deductions": {
"account_number": "21555"
},
"Payroll - Misc Deductions": {
"account_number": "21560"
},
"Payroll - Withholding Tax Payable": {
"account_number": "21565"
},
"account_number": "215",
"is_group": 1
},
"GST": {
"GST Payments to ATO": {
"account_number": "22030"
},
"Provision for PAYG Tax": {
"account_number": "22040"
},
"account_number": "220",
"account_type": "Tax",
"is_group": 1
},
"Interest & Non Bearing Liabilities - Current": {
"Credit Card - VISA": {
"account_number": "22510"
},
"account_number": "225",
"is_group": 1
},
"Bank Overdraft": {
"Bank Overdraft Cash at Bank": {
"account_number": "23010"
},
"account_number": "230",
"is_group": 1
},
"Trade Finance": {
"Trade Finance": {
"account_number": "23510"
},
"account_number": "235",
"is_group": 1
},
"Lease Liabilities": {
"Finance Lease - Current": {
"account_number": "24010"
},
"account_number": "240",
"is_group": 1
},
"Provisions": {
"Provision for Long Service Leave": {
"account_number": "24510"
},
"Provision for Holiday Pay": {
"account_number": "24520"
},
"account_number": "245",
"is_group": 1
},
"account_number": "21",
"is_group": 1
},
"Non Current Liabilities": {
"Trade & Other Payables - Non Current": {
"Loan Account - Party 1": {
"account_number": "25010"
},
"account_number": "250",
"is_group": 1
},
"Interest & Non Bearing Liabilities - Non Current": {
"Non Current Liability - Director Loan": {
"account_number": "25510"
},
"account_number": "255",
"is_group": 1
},
"Bank Loans - Non Current": {
"Bank Loan 1 - Non Current": {
"account_number": "26010"
},
"account_number": "260",
"is_group": 1
},
"Lease Liabilities - Non Current": {
"Finance Lease - Non Current": {
"account_number": "27010"
},
"account_number": "270",
"is_group": 1
},
"Provisions - Non Current": {
"Provision for Long Service Leave": {
"account_number": "27510"
},
"Provision for Holiday Pay": {
"account_number": "27520"
},
"account_number": "275",
"is_group": 1
},
"account_number": "25",
"is_group": 1
},
"account_number": "2",
"root_type": "Liability"
},
"Equity": {
"Equity": {
"Owner's/Shareholder's Equity": {
"Owner's/Shareholders Capital": {
"account_number": "31010",
"account_type": "Equity"
},
"Owner's/Shareholders Drawings": {
"account_number": "31020",
"account_type": "Equity"
},
"account_number": "310",
"is_group": 1
},
"Earnings": {
"Current Year Earnings": {
"account_number": "35010",
"account_type": "Equity"
},
"Retained Earnings": {
"account_number": "35020",
"account_type": "Equity"
},
"account_number": "350",
"is_group": 1
},
"account_number": "31",
"is_group": 1
},
"account_number": "3",
"root_type": "Equity"
},
"Revenue": {
"Revenue": {
"Sales Revenue": {
"Sales Income": {
"account_number": "41010",
"account_type": "Income Account"
},
"Freight Income": {
"account_number": "41020",
"account_type": "Income Account"
},
"Other Income": {
"account_number": "41030",
"account_type": "Income Account"
},
"Service Income": {
"account_number": "41040",
"account_type": "Income Account"
},
"account_number": "410",
"is_group": 1
},
"Other Revenue": {
"Commission Received": {
"account_number": "42010"
},
"Discounts Received": {
"account_number": "42020"
},
"Interest received": {
"account_number": "42030"
},
"Profit/Loss on Sales of Assets": {
"account_number": "42040"
},
"Rent Received": {
"account_number": "42050"
},
"Sundry Income": {
"account_number": "42060"
},
"account_number": "420",
"is_group": 1
},
"account_number": "41",
"is_group": 1
},
"account_number": "4",
"root_type": "Income"
},
"Cost of Goods": {
"Cost of Goods": {
"Cost of Goods Sold": {
"Cost of Goods Sold": {
"account_number": "51010",
"account_type": "Cost of Goods Sold"
},
"Freight Expenses (sales related)": {
"account_number": "51020"
},
"Discounts Given": {
"account_number": "51030"
},
"Subcontracting Charges": {
"account_number": "51040"
},
"account_number": "510",
"is_group": 1
},
"Other COGS": {
"Purchases - Miscellaneous": {
"account_number": "52010"
},
"Duty & Customs Fees": {
"account_number": "52020",
"account_type": "Tax"
},
"Freight Inwards": {
"account_number": "52030",
"account_type": "Chargeable"
},
"Stock Adjustment": {
"account_number": "52040",
"account_type": "Stock Adjustment"
},
"Stock Wirte Off": {
"account_number": "52050",
"account_type": "Stock Adjustment"
},
"Stock Valuation Expenses": {
"account_number": "52060",
"account_type": "Expenses Included In Valuation"
},
"Asset Valuation Expenses": {
"account_number": "52070",
"account_type": "Expenses Included In Asset Valuation"
},
"account_number": "520",
"is_group": 1
},
"account_number": "51",
"is_group": 1
},
"account_number": "5",
"root_type": "Expense"
},
"Expenses": {
"Fixed Expenses": {
"Payroll & Related Expenses": {
"Salaries & Wages": {
"account_number": "61010"
},
"Superannuation": {
"account_number": "61015"
},
"Staff Amenities - GST Paid": {
"account_number": "61020"
},
"Staff Amenities - GST Free": {
"account_number": "61025"
},
"Staff Recruitment": {
"account_number": "61030"
},
"Staff Training": {
"account_number": "61035"
},
"Fringe Benefits Tax": {
"account_number": "61040"
},
"Payroll Tax": {
"account_number": "61045"
},
"Workers Compensation": {
"account_number": "61050"
},
"Long Service Leave": {
"account_number": "61060"
},
"Mileage Reimbursement": {
"account_number": "61070"
},
"Overtime": {
"account_number": "61080"
},
"Worksafe Insurance": {
"account_number": "61090"
},
"account_number": "610",
"is_group": 1
},
"Depreciation Expenses": {
"Depreciation - Plant & Equipment": {
"account_number": "62010",
"account_type": "Depreciation"
},
"Depreciation - Motor Vehicle": {
"account_number": "62020",
"account_type": "Depreciation"
},
"Depreciation - Office Equipment": {
"account_number": "62030",
"account_type": "Depreciation"
},
"Depreciation - Computer Equipment": {
"account_number": "62040",
"account_type": "Depreciation"
},
"Depreciation - Building": {
"account_number": "62050",
"account_type": "Depreciation"
},
"Depreciation - Others": {
"account_number": "62510",
"account_type": "Depreciation"
},
"account_number": "620",
"is_group": 1
},
"account_number": "61",
"is_group": 1
},
"Accrued Expenses": {
"Accrued Expenses": {
"Accrued Expenses - Salaries & Wages": {
"account_number": "63010"
},
"Accrued Expenses - Interest": {
"account_number": "63020"
},
"account_number": "630",
"is_group": 1
},
"account_number": "63",
"is_group": 1
},
"Operating Expenses": {
"General and Administrative Expenses": {
"Low Value Assets less than $300": {
"account_number": "64010"
},
"Office Supplies": {
"account_number": "64020"
},
"Postage & Courier": {
"account_number": "64025"
},
"Printing & Stationery": {
"account_number": "64030"
},
"Registration Fees / Filing Fees": {
"account_number": "64040"
},
"Travel & Accommodation - Local": {
"account_number": "64050"
},
"Travel & Accommodation - Overseas": {
"account_number": "64060"
},
"Relocation Costs": {
"account_number": "64070"
},
"Hire Charges": {
"account_number": "64080"
},
"Repairs & Maintenance": {
"account_number": "64210"
},
"Cleaning Expenses": {
"account_number": "64215"
},
"Uniforms": {
"account_number": "64220"
},
"Security": {
"account_number": "64225"
},
"Subscriptions & Licences": {
"account_number": "64510"
},
"Software Expenses": {
"account_number": "64515"
},
"Marketing Expenses": {
"account_number": "64520"
},
"Advertising Expenses": {
"account_number": "64525"
},
"Website Hosting & Domain Expenses": {
"account_number": "64530"
},
"Computer Repairs / Supplies": {
"account_number": "64540"
},
"Conferences": {
"account_number": "64550"
},
"Consultancy /Contract Services": {
"account_number": "64560"
},
"Training Services": {
"account_number": "64570"
},
"Workshop Supplies": {
"account_number": "64580"
},
"Consumables": {
"account_number": "64585"
},
"Entertainment Expenses - Deductible": {
"account_number": "64810"
},
"Entertainment Expenses - Non Deductible": {
"account_number": "64820"
},
"Amortisation Of Goodwill": {
"account_number": "64910"
},
"General / Miscellaneous Expenses": {
"account_number": "64915",
"account_type": "Chargeable"
},
"Donations": {
"account_number": "64920"
},
"Client Gifts": {
"account_number": "64930"
},
"Employee Gifts": {
"account_number": "64935"
},
"account_number": "640",
"is_group": 1
},
"Occupancy Expenses": {
"Rental Expenses": {
"account_number": "65010"
},
"Property Insurance": {
"account_number": "65020"
},
"Electricity Expenses": {
"account_number": "65030"
},
"Water Rates": {
"account_number": "65040"
},
"Gas Expenses": {
"account_number": "65050"
},
"Property Taxes": {
"account_number": "65060"
},
"Rates": {
"account_number": "65070"
},
"account_number": "650",
"is_group": 1
},
"Communication & Vehicle Expenses": {
"Internet Expenses": {
"account_number": "66010"
},
"Mobile Telephone": {
"account_number": "66020"
},
"Telephone Expenses": {
"account_number": "66030"
},
"Motor Vehicle - Fuel Expenses": {
"account_number": "66040"
},
"Motor Vehicle - Parking & Tolls": {
"account_number": "66050"
},
"Motor Vehicle - Registration & Insurance": {
"account_number": "66060"
},
"Motor Vehicle - Service & Repairs": {
"account_number": "66070"
},
"Taxi": {
"account_number": "66080"
},
"account_number": "660",
"is_group": 1
},
"account_number": "64",
"is_group": 1
},
"Non-Operating Expenses": {
"Finance Costs": {
"Interest - Bank Loans": {
"account_number": "67010"
},
"Interest - Finance Leases": {
"account_number": "67020"
},
"Interest - Other Loans": {
"account_number": "67025"
},
"Insurance": {
"account_number": "67030"
},
"Bank Charges": {
"account_number": "67050"
},
"Rounding off": {
"account_number": "67055",
"account_type": "Round Off"
},
"Audit Fees": {
"account_number": "67060"
},
"Accounting Fees": {
"account_number": "67070"
},
"Legal Fees": {
"account_number": "67080"
},
"Management Fees": {
"account_number": "67090"
},
"account_number": "670",
"is_group": 1
},
"Other Costs": {
"Doubtful Debts": {
"account_number": "67510"
},
"Fines": {
"account_number": "67520"
},
"Debt Collection": {
"account_number": "67530"
},
"Bad Debts": {
"account_number": "67540"
},
"account_number": "675",
"is_group": 1
},
"account_number": "67",
"is_group": 1
},
"Variable Expenses": {
"Variable Expenses": {
"Bonus & Commissions Paid": {
"account_number": "68010"
},
"Bonus & Commissions To be Paid": {
"account_number": "68020"
},
"Warranty Claims": {
"account_number": "68030"
},
"account_number": "680",
"is_group": 1
},
"account_number": "68",
"is_group": 1
},
"account_number": "6",
"root_type": "Expense"
},
"Other Income": {
"Other Income": {
"Interest Income": {
"Interest Income": {
"account_number": "71010"
},
"account_number": "710",
"is_group": 1
},
"Asset Disposal Income": {
"Gain on Asset Disposal": {
"account_number": "73010"
},
"account_number": "730",
"is_group": 1
},
"account_number": "71",
"is_group": 1
},
"account_number": "7",
"root_type": "Income"
},
"Other Expenses": {
"Other Expenses": {
"Income Tax Expenses": {
"Income Tax Expenses": {
"account_number": "81010"
},
"account_number": "810",
"is_group": 1
},
"Foreign Exchange Gain/Loss": {
"Exchange Loss/Gain - Realized": {
"account_number": "82010"
},
"account_number": "820",
"is_group": 1
},
"Asset Disposal Expenses": {
"Loss on Asset Disposal": {
"account_number": "83010"
},
"account_number": "830",
"is_group": 1
},
"account_number": "81",
"is_group": 1
},
"account_number": "8",
"root_type": "Expense"
}
}
}

View File

@@ -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": {

View File

@@ -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": {}

View File

@@ -1,532 +0,0 @@
{
"country_code": "ch",
"name": "240812 Schulkontenrahmen VEB - DE",
"tree": {
"Aktiven": {
"account_number": "1",
"is_group": 1,
"root_type": "Asset",
"Umlaufvermögen": {
"account_number": "10",
"is_group": 1,
"Flüssige Mittel": {
"account_number": "100",
"is_group": 1,
"Kasse": {
"account_number": "1000",
"account_type": "Cash"
},
"Bankguthaben": {
"account_number": "1020",
"account_type": "Bank"
}
},
"Kurzfristig gehaltene Aktiven mit Börsenkurs": {
"account_number": "106",
"is_group": 1,
"Wertschriften": {
"account_number": "1060"
},
"Wertberichtigungen Wertschriften": {
"account_number": "1069"
}
},
"Forderungen aus Lieferungen und Leistungen": {
"account_number": "110",
"is_group": 1,
"Forderungen aus Lieferungen und Leistungen (Debitoren)": {
"account_number": "1100"
},
"Delkredere": {
"account_number": "1109"
}
},
"Übrige kurzfristige Forderungen": {
"account_number": "114",
"is_group": 1,
"Vorschüsse und Darlehen": {
"account_number": "1140"
},
"Wertberichtigungen Vorschüsse und Darlehen": {
"account_number": "1149"
},
"Vorsteuer MWST Material, Waren, Dienstleistungen, Energie": {
"account_number": "1170"
},
"Vorsteuer MWST Investitionen, übriger Betriebsaufwand": {
"account_number": "1171"
},
"Verrechnungssteuer": {
"account_number": "1176"
},
"Forderungen gegenüber Sozialversicherungen und Vorsorgeeinrichtungen": {
"account_number": "1180"
},
"Quellensteuer": {
"account_number": "1189"
},
"Sonstige kurzfristige Forderungen": {
"account_number": "1190"
},
"Wertberichtigungen sonstige kurzfristige Forderungen": {
"account_number": "1199"
}
},
"Vorräte und nicht fakturierte Dienstleistungen": {
"account_number": "120",
"is_group": 1,
"Handelswaren": {
"account_number": "1200"
},
"Rohstoffe": {
"account_number": "1210"
},
"Werkstoffe": {
"account_number": "1220"
},
"Hilfs- und Verbrauchsmaterial": {
"account_number": "1230"
},
"Handelswaren in Konsignation": {
"account_number": "1250"
},
"Fertige Erzeugnisse": {
"account_number": "1260"
},
"Unfertige Erzeugnisse": {
"account_number": "1270"
},
"Nicht fakturierte Dienstleistungen": {
"account_number": "1280"
}
},
"Aktive Rechnungsabgrenzungen": {
"account_number": "130",
"is_group": 1,
"Bezahlter Aufwand des Folgejahres": {
"account_number": "1300"
},
"Noch nicht erhaltener Ertrag": {
"account_number": "1301"
}
}
},
"Anlagevermögen": {
"account_number": "14",
"is_group": 1,
"Finanzanlagen": {
"account_number": "140",
"is_group": 1,
"Wertschriften": {
"account_number": "1400"
},
"Wertberichtigungen Wertschriften": {
"account_number": "1409"
},
"Darlehen": {
"account_number": "1440"
},
"Hypotheken": {
"account_number": "1441"
},
"Wertberichtigungen langfristige Forderungen": {
"account_number": "1449"
}
},
"Beteiligungen": {
"account_number": "148",
"is_group": 1,
"Beteiligungen": {
"account_number": "1480"
},
"Wertberichtigungen Beteiligungen": {
"account_number": "1489"
}
},
"Mobile Sachanlagen": {
"account_number": "150",
"is_group": 1,
"Maschinen und Apparate": {
"account_number": "1500"
},
"Wertberichtigungen Maschinen und Apparate": {
"account_number": "1509"
},
"Mobiliar und Einrichtungen": {
"account_number": "1510"
},
"Wertberichtigungen Mobiliar und Einrichtungen": {
"account_number": "1519"
},
"Büromaschinen, Informatik, Kommunikationstechnologie": {
"account_number": "1520"
},
"Wertberichtigungen Büromaschinen, Informatik, Kommunikationstechnologie": {
"account_number": "1529"
},
"Fahrzeuge": {
"account_number": "1530"
},
"Wertberichtigungen Fahrzeuge": {
"account_number": "1539"
},
"Werkzeuge und Geräte": {
"account_number": "1540"
},
"Wertberichtigungen Werkzeuge und Geräte": {
"account_number": "1549"
}
},
"Immobile Sachanlagen": {
"account_number": "160",
"is_group": 1,
"Geschäftsliegenschaften": {
"account_number": "1600"
},
"Wertberichtigungen Geschäftsliegenschaften": {
"account_number": "1609"
}
},
"Immaterielle Werte": {
"account_number": "170",
"is_group": 1,
"Patente, Know-how, Lizenzen, Rechte, Entwicklungen": {
"account_number": "1700"
},
"Wertberichtigungen Patente, Know-how, Lizenzen, Rechte, Entwicklungen": {
"account_number": "1709"
},
"Goodwill": {
"account_number": "1770"
},
"Wertberichtigungen Goodwill": {
"account_number": "1779"
}
},
"Nicht einbezahltes Grund-, Gesellschafter- oder Stiftungskapital": {
"account_number": "180",
"is_group": 1,
"Nicht einbezahltes Aktien-, Stamm-, Anteilschein- oder Stiftungskapital": {
"account_number": "1850"
}
}
}
},
"Passiven": {
"account_number": "2",
"is_group": 1,
"root_type": "Liability",
"Kurzfristiges Fremdkapital": {
"account_number": "20",
"is_group": 1,
"Verbindlichkeiten aus Lieferungen und Leistungen": {
"account_number": "200",
"is_group": 1,
"Verbindlichkeiten aus Lieferungen und Leistungen (Kreditoren)": {
"account_number": "2000"
},
"Erhaltene Anzahlungen": {
"account_number": "2030"
}
},
"Kurzfristige verzinsliche Verbindlichkeiten": {
"account_number": "210",
"is_group": 1,
"Bankverbindlichkeiten": {
"account_number": "2100"
},
"Verbindlichkeiten aus Finanzierungsleasing": {
"account_number": "2120"
},
"Übrige verzinsliche Verbindlichkeiten": {
"account_number": "2140"
}
},
"Übrige kurzfristige Verbindlichkeiten": {
"account_number": "220",
"is_group": 1,
"Geschuldete MWST (Umsatzsteuer)": {
"account_number": "2200"
},
"Abrechnungskonto MWST": {
"account_number": "2201"
},
"Verrechnungssteuer": {
"account_number": "2206"
},
"Direkte Steuern": {
"account_number": "2208"
},
"Sonstige kurzfristige Verbindlichkeiten": {
"account_number": "2210"
},
"Beschlossene Ausschüttungen": {
"account_number": "2261"
},
"Sozialversicherungen und Vorsorgeeinrichtungen": {
"account_number": "2270"
},
"Quellensteuer": {
"account_number": "2279"
}
},
"Passive Rechnungsabgrenzungen und kurzfristige Rückstellungen": {
"account_number": "230",
"is_group": 1,
"Noch nicht bezahlter Aufwand": {
"account_number": "2300"
},
"Erhaltener Ertrag des Folgejahres": {
"account_number": "2301"
},
"Kurzfristige Rückstellungen": {
"account_number": "2330"
}
}
},
"Langfristiges Fremdkapital": {
"account_number": "24",
"is_group": 1,
"Langfristige verzinsliche Verbindlichkeiten": {
"account_number": "240",
"is_group": 1,
"Bankverbindlichkeiten": {
"account_number": "2400"
},
"Verbindlichkeiten aus Finanzierungsleasing": {
"account_number": "2420"
},
"Obligationenanleihen": {
"account_number": "2430"
},
"Darlehen": {
"account_number": "2450"
},
"Hypotheken": {
"account_number": "2451"
}
},
"Übrige langfristige Verbindlichkeiten": {
"account_number": "250",
"is_group": 1,
"Übrige langfristige Verbindlichkeiten (unverzinslich)": {
"account_number": "2500"
}
},
"Rückstellungen sowie vom Gesetz vorgesehene ähnliche Positionen": {
"account_number": "260",
"is_group": 1,
"Rückstellungen": {
"account_number": "2600"
}
}
},
"Eigenkapital (juristische Personen)": {
"account_number": "28",
"is_group": 1,
"Grund-, Gesellschafter- oder Stiftungskapital": {
"account_number": "280",
"is_group": 1,
"Aktien-, Stamm-, Anteilschein- oder Stiftungskapital": {
"account_number": "2800"
}
},
"Reserven und Jahresgewinn oder Jahresverlust": {
"account_number": "290",
"is_group": 1,
"Gesetzliche Kapitalreserve": {
"account_number": "2900"
},
"Reserve für eigene Kapitalanteile": {
"account_number": "2930"
},
"Aufwertungsreserve": {
"account_number": "2940"
},
"Gesetzliche Gewinnreserve": {
"account_number": "2950"
},
"Freiwillige Gewinnreserven": {
"account_number": "2960"
},
"Gewinnvortrag oder Verlustvortrag": {
"account_number": "2970"
},
"Jahresgewinn oder Jahresverlust": {
"account_number": "2979"
},
"Eigene Aktien, Stammanteile oder Anteilscheine (Minusposten)": {
"account_number": "2980"
}
}
}
},
"Betrieblicher Ertrag aus Lieferungen und Leistungen": {
"account_number": "3",
"is_group": 1,
"root_type": "Income",
"Produktionserlöse": {
"account_number": "3000"
},
"Handelserlöse": {
"account_number": "3200"
},
"Dienstleistungserlöse": {
"account_number": "3400"
},
"Übrige Erlöse aus Lieferungen und Leistungen": {
"account_number": "3600"
},
"Eigenleistungen": {
"account_number": "3700"
},
"Eigenverbrauch": {
"account_number": "3710"
},
"Erlösminderungen": {
"account_number": "3800"
},
"Verluste Forderungen (Debitoren), Veränderung Delkredere": {
"account_number": "3805"
},
"Bestandesänderungen unfertige Erzeugnisse": {
"account_number": "3900"
},
"Bestandesänderungen fertige Erzeugnisse": {
"account_number": "3901"
},
"Bestandesänderungen nicht fakturierte Dienstleistungen": {
"account_number": "3940"
}
},
"Aufwand für Material, Handelswaren, Dienstleistungen und Energie": {
"account_number": "4",
"is_group": 1,
"root_type": "Expense",
"Materialaufwand Produktion": {
"account_number": "4000"
},
"Handelswarenaufwand": {
"account_number": "4200"
},
"Aufwand für bezogene Dienstleistungen": {
"account_number": "4400"
},
"Energieaufwand zur Leistungserstellung": {
"account_number": "4500"
},
"Aufwandminderungen": {
"account_number": "4900"
}
},
"Personalaufwand": {
"account_number": "5",
"is_group": 1,
"root_type": "Expense",
"Lohnaufwand": {
"account_number": "5000"
},
"Sozialversicherungsaufwand": {
"account_number": "5700"
},
"Übriger Personalaufwand": {
"account_number": "5800"
},
"Leistungen Dritter": {
"account_number": "5900"
}
},
"Übriger betrieblicher Aufwand, Abschreibungen und Wertberichtigungen sowie Finanzergebnis": {
"account_number": "6",
"is_group": 1,
"root_type": "Expense",
"Raumaufwand": {
"account_number": "6000"
},
"Unterhalt, Reparaturen, Ersatz mobile Sachanlagen": {
"account_number": "6100"
},
"Leasingaufwand mobile Sachanlagen": {
"account_number": "6105"
},
"Fahrzeug- und Transportaufwand": {
"account_number": "6200"
},
"Fahrzeugleasing und -mieten": {
"account_number": "6260"
},
"Sachversicherungen, Abgaben, Gebühren, Bewilligungen": {
"account_number": "6300"
},
"Energie- und Entsorgungsaufwand": {
"account_number": "6400"
},
"Verwaltungsaufwand": {
"account_number": "6500"
},
"Informatikaufwand inkl. Leasing": {
"account_number": "6570"
},
"Werbeaufwand": {
"account_number": "6600"
},
"Sonstiger betrieblicher Aufwand": {
"account_number": "6700"
},
"Abschreibungen und Wertberichtigungen auf Positionen des Anlagevermögens": {
"account_number": "6800"
},
"Finanzaufwand": {
"account_number": "6900"
},
"Finanzertrag": {
"account_number": "6950"
}
},
"Betrieblicher Nebenerfolg": {
"account_number": "7",
"is_group": 1,
"root_type": "Income",
"Ertrag Nebenbetrieb": {
"account_number": "7000"
},
"Aufwand Nebenbetrieb": {
"account_number": "7010"
},
"Ertrag betriebliche Liegenschaft": {
"account_number": "7500"
},
"Aufwand betriebliche Liegenschaft": {
"account_number": "7510"
}
},
"Betriebsfremder, ausserordentlicher, einmaliger oder periodenfremder Aufwand und Ertrag": {
"account_number": "8",
"is_group": 1,
"root_type": "Expense",
"Betriebsfremder Aufwand": {
"account_number": "8000"
},
"Betriebsfremder Ertrag": {
"account_number": "8100"
},
"Ausserordentlicher, einmaliger oder periodenfremder Aufwand": {
"account_number": "8500"
},
"Ausserordentlicher, einmaliger oder periodenfremder Ertrag": {
"account_number": "8510"
},
"Direkte Steuern": {
"account_number": "8900"
}
},
"Abschluss": {
"account_number": "9",
"is_group": 1,
"root_type": "Equity",
"Jahresgewinn oder Jahresverlust": {
"account_number": "9200"
}
}
}
}

View File

@@ -1,569 +0,0 @@
{
"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"
},
"Accumulated Depreciation": {
"account_type": "Accumulated Depreciation"
}
},
"B - Umlaufvermögen": {
"is_group": 1,
"I. Vorräte": {
"is_group": 1,
"Roh-, Hilfs- und Betriebsstoffe (Bestand)": {
"account_number": "3970",
"account_type": "Stock"
},
"Waren (Bestand)": {
"account_number": "3980",
"account_type": "Stock"
}
},
"II. Forderungen und sonstige Vermögensgegenstände": {
"is_group": 1,
"Forderungen aus Lieferungen und Leistungen mit Kontokorrent": {
"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": {
"account_number": "1371"
},
"Abziehbare Vorsteuer": {
"is_group": 1,
"Abziehbare Vorsteuer 7 %": {
"account_number": "1571",
"account_type": "Tax",
"tax_rate": 7.0
},
"Abziehbare Vorsteuer 19 %": {
"account_number": "1576",
"account_type": "Tax",
"tax_rate": 19.0
},
"Abziehbare Vorsteuer nach § 13b UStG 19 %": {
"account_number": "1577",
"account_type": "Tax",
"tax_rate": 19.0
}
}
},
"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"
}
},
"IV. Kassenbestand, Bundesbankguthaben, Guthaben bei Kreditinstituten und Schecks.": {
"is_group": 1,
"Kasse": {
"is_group": 1,
"account_type": "Cash",
"Kasse": {
"account_number": "1000",
"account_type": "Cash"
}
},
"Bank": {
"is_group": 1,
"account_type": "Bank",
"Postbank": {
"account_number": "1100",
"account_type": "Bank"
},
"Bankkonto": {
"account_number": "1200",
"account_type": "Bank"
}
}
}
},
"C - Rechnungsabgrenzungsposten": {
"is_group": 1,
"Aktive Rechnungsabgrenzung": {
"account_number": "0980"
}
},
"D - Aktive latente Steuern": {
"is_group": 1,
"Aktive latente Steuern": {
"account_number": "0983"
}
},
"E - Aktiver Unterschiedsbetrag aus der Vermögensverrechnung": {
"is_group": 1
}
},
"Passiva": {
"is_group": 1,
"root_type": "Liability",
"A. Eigenkapital": {
"is_group": 1,
"I. Gezeichnetes Kapital": {
"is_group": 1
},
"II. Kapitalrücklage": {
"is_group": 1
},
"III. Gewinnrücklagen": {
"is_group": 1
},
"IV. Gewinnvortrag/Verlustvortrag": {
"is_group": 1
},
"V. Jahresüberschuß/Jahresfehlbetrag": {
"is_group": 1
}
},
"B. Rückstellungen": {
"is_group": 1,
"I. Rückstellungen für Pensionen und ähnliche Verpflichtungen": {
"is_group": 1
},
"II. Steuerrückstellungen": {
"is_group": 1
},
"III. sonstige Rückstellungen": {
"is_group": 1
}
},
"C. Verbindlichkeiten": {
"is_group": 1,
"I. Anleihen": {
"is_group": 1
},
"II. Verbindlichkeiten gegenüber Kreditinstituten": {
"is_group": 1
},
"III. Erhaltene Anzahlungen auf Bestellungen": {
"is_group": 1
},
"IV. Verbindlichkeiten aus Lieferungen und Leistungen": {
"is_group": 1,
"Verbindlichkeiten aus Lieferungen und Leistungen mit Kontokorrent": {
"account_number": "1600",
"account_type": "Payable",
"is_group": 1
},
"Verbindlichkeiten aus Lieferungen und Leistungen ohne Kontokorrent": {
"account_number": "1610",
"account_type": "Payable"
}
},
"V. Verbindlichkeiten aus der Annahme gezogener Wechsel und der Ausstellung eigener Wechsel": {
"is_group": 1
},
"VI. Verbindlichkeiten gegenüber verbundenen Unternehmen": {
"is_group": 1
},
"VII. Verbindlichkeiten gegenüber Unternehmen, mit denen ein Beteiligungsverhältnis besteht": {
"is_group": 1
},
"VIII. sonstige Verbindlichkeiten": {
"is_group": 1,
"Sonstige Verbindlichkeiten": {
"account_number": "1700",
"account_type": "Asset Received But Not Billed"
},
"Sonstige Verbindlichkeiten (1 bis 5 Jahre)": {
"account_number": "1702",
"account_type": "Stock Received But Not Billed"
},
"Verbindlichkeiten aus Lohn und Gehalt": {
"account_number": "1740",
"account_type": "Payable"
},
"Umsatzsteuer": {
"is_group": 1,
"Umsatzsteuer 7 %": {
"account_number": "1771",
"account_type": "Tax",
"tax_rate": 7.0
},
"Umsatzsteuer 19 %": {
"account_number": "1776",
"account_type": "Tax",
"tax_rate": 19.0
},
"Umsatzsteuer-Vorauszahlung": {
"account_number": "1780",
"account_type": "Tax"
},
"Umsatzsteuer-Vorauszahlung 1/11": {
"account_number": "1781"
},
"Umsatzsteuer nach § 13b UStG 19 %": {
"account_number": "1787",
"account_type": "Tax",
"tax_rate": 19.0
},
"Umsatzsteuer Vorjahr": {
"account_number": "1790"
},
"Umsatzsteuer frühere Jahre": {
"account_number": "1791"
}
}
}
},
"D. Rechnungsabgrenzungsposten": {
"is_group": 1,
"Passive Rechnungsabgrenzung": {
"account_number": "0990"
}
},
"E. Passive latente Steuern": {
"is_group": 1
}
},
"Erlöse u. Erträge 2/8": {
"is_group": 1,
"root_type": "Income",
"Erlöskonten 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,
"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"
},
"Bezugsnebenkosten": {
"account_number": "3800",
"account_type": "Expenses Included In Asset Valuation"
},
"Herstellungskosten": {
"account_number": "4996",
"account_type": "Cost of Goods Sold"
},
"Verluste aus dem Abgang von Gegenständen des Anlagevermögens": {
"account_number": "2320",
"account_type": "Stock Adjustment"
},
"Verwaltungskosten": {
"account_number": "4997",
"account_type": "Expenses Included In Valuation"
},
"Vertriebskosten": {
"account_number": "4998",
"account_type": "Expenses Included In Valuation"
},
"Gegenkonto 4996-4998": {
"account_number": "4999"
},
"Abschreibungen": {
"is_group": 1,
"Abschreibungen auf Sachanlagen (ohne AfA auf Kfz und Gebäude)": {
"account_number": "4830",
"account_type": "Accumulated Depreciation"
},
"Abschreibungen auf Gebäude": {
"account_number": "4831",
"account_type": "Depreciation"
},
"Abschreibungen auf Kfz": {
"account_number": "4832",
"account_type": "Depreciation"
},
"Sofortabschreibung GWG": {
"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"
}
}
}
}
}

View File

@@ -0,0 +1,531 @@
{
"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\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"
}
},
"B - Umlaufvermögen": {
"is_group": 1,
"I. Vorräte": {
"is_group": 1,
"Roh-, Hilfs- und Betriebsstoffe (Bestand)": {
"account_number": "3970",
"account_type": "Stock"
},
"Waren (Bestand)": {
"account_number": "3980",
"account_type": "Stock"
}
},
"II. Forderungen und sonstige Vermögensgegenstände": {
"is_group": 1,
"Ford. a. Lieferungen und Leistungen": {
"account_number": "1400",
"account_type": "Receivable"
},
"Durchlaufende Posten": {
"account_number": "1590"
},
"Gewinnermittlung \u00a74/3 nicht Ergebniswirksam": {
"account_number": "1371"
},
"Abziehbare Vorsteuer": {
"account_type": "Tax",
"is_group": 1,
"Abziehbare Vorsteuer 7%": {
"account_number": "1571"
},
"Abziehbare Vorsteuer 19%": {
"account_number": "1576"
},
"Abziehbare Vorsteuer nach \u00a713b UStG 19%": {
"account_number": "1577"
},
"Leistungen \u00a713b UStG 19% Vorsteuer, 19% Umsatzsteuer": {
"account_number": "3120"
}
}
},
"III. Wertpapiere": {
"is_group": 1
},
"IV. Kassenbestand, Bundesbankguthaben, Guthaben bei Kreditinstituten und Schecks.": {
"is_group": 1,
"Kasse": {
"account_type": "Cash",
"is_group": 1,
"Kasse": {
"is_group": 1,
"account_number": "1000",
"account_type": "Cash"
}
},
"Bank": {
"is_group": 1,
"account_type": "Bank",
"Postbank": {
"account_number": "1100",
"account_type": "Bank"
},
"Bankkonto": {
"account_number": "1200",
"account_type": "Bank"
}
}
}
},
"C - Rechnungsabgrenzungsposten": {
"is_group": 1,
"Aktive Rechnungsabgrenzung": {
"account_number": "0980"
}
},
"D - Aktive latente Steuern": {
"is_group": 1,
"Aktive latente Steuern": {
"account_number": "0983"
}
},
"E - Aktiver Unterschiedsbetrag aus der Vermögensverrechnung": {
"is_group": 1
}
},
"Passiva": {
"is_group": 1,
"root_type": "Liability",
"A. Eigenkapital": {
"is_group": 1,
"I. Gezeichnetes Kapital": {
"is_group": 1
},
"II. Kapitalrücklage": {
"is_group": 1
},
"III. Gewinnrücklagen": {
"is_group": 1
},
"IV. Gewinnvortrag/Verlustvortrag": {
"is_group": 1
},
"V. Jahresüberschuß/Jahresfehlbetrag": {
"is_group": 1
}
},
"B. Rückstellungen": {
"is_group": 1,
"I. Rückstellungen für Pensionen und ähnliche Verpflichtungen": {
"is_group": 1
},
"II. Steuerrückstellungen": {
"is_group": 1
},
"III. sonstige Rückstellungen": {
"is_group": 1
}
},
"C. Verbindlichkeiten": {
"is_group": 1,
"I. Anleihen": {
"is_group": 1
},
"II. Verbindlichkeiten gegenüber Kreditinstituten": {
"is_group": 1
},
"III. Erhaltene Anzahlungen auf Bestellungen": {
"is_group": 1
},
"IV. Verbindlichkeiten aus Lieferungen und Leistungen": {
"is_group": 1,
"Verbindlichkeiten aus Lieferungen u. Leistungen": {
"account_number": "1600",
"account_type": "Payable"
}
},
"V. Verbindlichkeiten aus der Annahme gezogener Wechsel und der Ausstellung eigener Wechsel": {
"is_group": 1
},
"VI. Verbindlichkeiten gegenüber verbundenen Unternehmen": {
"is_group": 1
},
"VII. Verbindlichkeiten gegenüber Unternehmen, mit denen ein Beteiligungsverhältnis besteht": {
"is_group": 1
},
"VIII. sonstige Verbindlichkeiten": {
"is_group": 1,
"Sonstige Verbindlichkeiten": {
"account_number": "1700",
"account_type": "Asset Received But Not Billed"
},
"Sonstige Verbindlichkeiten (1 bis 5 Jahre)": {
"account_number": "1702",
"account_type": "Stock Received But Not Billed"
},
"Verbindlichkeiten aus Lohn und Gehalt": {
"account_number": "1740",
"account_type": "Payable"
},
"Umsatzsteuer": {
"is_group": 1,
"account_type": "Tax",
"Umsatzsteuer 7%": {
"account_number": "1771"
},
"Umsatzsteuer 19%": {
"account_number": "1776"
},
"Umsatzsteuer-Vorauszahlung": {
"account_number": "1780"
},
"Umsatzsteuer-Vorauszahlung 1/11": {
"account_number": "1781"
},
"Umsatzsteuer \u00a7 13b UStG 19%": {
"account_number": "1787"
},
"Umsatzsteuer Vorjahr": {
"account_number": "1790"
},
"Umsatzsteuer fr\u00fchere Jahre": {
"account_number": "1791"
}
}
}
},
"D. Rechnungsabgrenzungsposten": {
"is_group": 1,
"Passive Rechnungsabgrenzung": {
"account_number": "0990"
}
},
"E. Passive latente Steuern": {
"is_group": 1
}
},
"Erl\u00f6se u. Ertr\u00e4ge 2/8": {
"is_group": 1,
"root_type": "Income",
"Erl\u00f6skonten 8": {
"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",
"Wareneingang": {
"account_number": "3200"
},
"Bezugsnebenkosten": {
"account_number": "3800",
"account_type": "Expenses Included In Asset Valuation"
},
"Herstellungskosten": {
"account_number": "4996",
"account_type": "Cost of Goods Sold"
},
"Verluste aus dem Abgang von Gegenständen des Anlagevermögens": {
"account_number": "2320",
"account_type": "Stock Adjustment"
},
"Verwaltungskosten": {
"account_number": "4997",
"account_type": "Expenses Included In Valuation"
},
"Vertriebskosten": {
"account_number": "4998",
"account_type": "Expenses Included In Valuation"
},
"Gegenkonto 4996-4998": {
"account_number": "4999"
},
"Abschreibungen": {
"is_group": 1,
"Abschreibungen auf Sachanlagen (ohne AfA auf Kfz und Gebäude)": {
"account_number": "4830",
"account_type": "Accumulated Depreciation"
},
"Abschreibungen auf Gebäude": {
"account_number": "4831",
"account_type": "Depreciation"
},
"Abschreibungen auf Kfz": {
"account_number": "4832",
"account_type": "Depreciation"
},
"Sofortabschreibung GWG": {
"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\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"
}
}
}
}
}

View File

@@ -1525,8 +1525,7 @@
"41-Clients et comptes rattach\u00e9s (PASSIF)": {
"Clients cr\u00e9diteurs": {
"Clients - Avances et acomptes re\u00e7us sur commandes": {
"account_number": "4191",
"account_type": "Income Account"
"account_number": "4191"
},
"Clients - Dettes pour emballages et mat\u00e9riels consign\u00e9s": {
"account_number": "4196"
@@ -3142,4 +3141,4 @@
"account_number": "7"
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More