Compare commits
2 Commits
v15.8.2
...
fix_pos_er
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8571bac00 | ||
|
|
40cdde8820 |
60
.github/helper/translation.py
vendored
Normal file
60
.github/helper/translation.py
vendored
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
errors_encounter = 0
|
||||||
|
pattern = re.compile(r"_\(([\"']{,3})(?P<message>((?!\1).)*)\1(\s*,\s*context\s*=\s*([\"'])(?P<py_context>((?!\5).)*)\5)*(\s*,(\s*?.*?\n*?)*(,\s*([\"'])(?P<js_context>((?!\11).)*)\11)*)*\)")
|
||||||
|
words_pattern = re.compile(r"_{1,2}\([\"'`]{1,3}.*?[a-zA-Z]")
|
||||||
|
start_pattern = re.compile(r"_{1,2}\([f\"'`]{1,3}")
|
||||||
|
f_string_pattern = re.compile(r"_\(f[\"']")
|
||||||
|
starts_with_f_pattern = re.compile(r"_\(f")
|
||||||
|
|
||||||
|
# skip first argument
|
||||||
|
files = sys.argv[1:]
|
||||||
|
files_to_scan = [_file for _file in files if _file.endswith(('.py', '.js'))]
|
||||||
|
|
||||||
|
for _file in files_to_scan:
|
||||||
|
with open(_file, 'r') as f:
|
||||||
|
print(f'Checking: {_file}')
|
||||||
|
file_lines = f.readlines()
|
||||||
|
for line_number, line in enumerate(file_lines, 1):
|
||||||
|
if 'frappe-lint: disable-translate' in line:
|
||||||
|
continue
|
||||||
|
|
||||||
|
start_matches = start_pattern.search(line)
|
||||||
|
if start_matches:
|
||||||
|
starts_with_f = starts_with_f_pattern.search(line)
|
||||||
|
|
||||||
|
if starts_with_f:
|
||||||
|
has_f_string = f_string_pattern.search(line)
|
||||||
|
if has_f_string:
|
||||||
|
errors_encounter += 1
|
||||||
|
print(f'\nF-strings are not supported for translations at line number {line_number}\n{line.strip()[:100]}')
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
|
match = pattern.search(line)
|
||||||
|
error_found = False
|
||||||
|
|
||||||
|
if not match and line.endswith((',\n', '[\n')):
|
||||||
|
# concat remaining text to validate multiline pattern
|
||||||
|
line = "".join(file_lines[line_number - 1:])
|
||||||
|
line = line[start_matches.start() + 1:]
|
||||||
|
match = pattern.match(line)
|
||||||
|
|
||||||
|
if not match:
|
||||||
|
error_found = True
|
||||||
|
print(f'\nTranslation syntax error at line number {line_number}\n{line.strip()[:100]}')
|
||||||
|
|
||||||
|
if not error_found and not words_pattern.search(line):
|
||||||
|
error_found = True
|
||||||
|
print(f'\nTranslation is useless because it has no words at line number {line_number}\n{line.strip()[:100]}')
|
||||||
|
|
||||||
|
if error_found:
|
||||||
|
errors_encounter += 1
|
||||||
|
|
||||||
|
if errors_encounter > 0:
|
||||||
|
print('\nVisit "https://frappeframework.com/docs/user/en/translations" to learn about valid translation strings.')
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print('\nGood To Go!')
|
||||||
26
.github/workflows/backport.yml
vendored
Normal file
26
.github/workflows/backport.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
name: Backport
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
types:
|
||||||
|
- closed
|
||||||
|
- labeled
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
main:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 60
|
||||||
|
steps:
|
||||||
|
- name: Checkout Actions
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
repository: "frappe/backport"
|
||||||
|
path: ./actions
|
||||||
|
ref: develop
|
||||||
|
- name: Install Actions
|
||||||
|
run: npm install --production --prefix ./actions
|
||||||
|
- name: Run backport
|
||||||
|
uses: ./actions/backport
|
||||||
|
with:
|
||||||
|
token: ${{secrets.BACKPORT_BOT_TOKEN}}
|
||||||
|
labelsToAdd: "backport"
|
||||||
|
title: "{{originalTitle}}"
|
||||||
32
.github/workflows/initiate_release.yml
vendored
Normal file
32
.github/workflows/initiate_release.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# This workflow is agnostic to branches. Only maintain on develop branch.
|
||||||
|
# To add/remove versions just modify the matrix.
|
||||||
|
|
||||||
|
name: Create weekly release pull requests
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
# 9:30 UTC => 3 PM IST Tuesday
|
||||||
|
- cron: "30 9 * * 2"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
stable-release:
|
||||||
|
name: Release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
version: ["13", "14"]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: octokit/request-action@v2.x
|
||||||
|
with:
|
||||||
|
route: POST /repos/{owner}/{repo}/pulls
|
||||||
|
owner: frappe
|
||||||
|
repo: erpnext
|
||||||
|
title: |-
|
||||||
|
"chore: release v${{ matrix.version }}"
|
||||||
|
body: "Automated weekly release."
|
||||||
|
base: version-${{ matrix.version }}
|
||||||
|
head: version-${{ matrix.version }}-hotfix
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||||
1
.github/workflows/patch.yml
vendored
1
.github/workflows/patch.yml
vendored
@@ -134,6 +134,7 @@ jobs:
|
|||||||
}
|
}
|
||||||
|
|
||||||
update_to_version 14
|
update_to_version 14
|
||||||
|
update_to_version 15
|
||||||
|
|
||||||
echo "Updating to latest version"
|
echo "Updating to latest version"
|
||||||
git -C "apps/frappe" checkout -q -f "${GITHUB_BASE_REF:-${GITHUB_REF##*/}}"
|
git -C "apps/frappe" checkout -q -f "${GITHUB_BASE_REF:-${GITHUB_REF##*/}}"
|
||||||
|
|||||||
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -2,23 +2,21 @@ name: Generate Semantic Release
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- version-15
|
- version-13
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
name: Release
|
name: Release
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Entire Repository
|
- name: Checkout Entire Repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v2
|
uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 18
|
||||||
|
|
||||||
- name: Setup dependencies
|
- name: Setup dependencies
|
||||||
run: |
|
run: |
|
||||||
npm install @semantic-release/git @semantic-release/exec --no-save
|
npm install @semantic-release/git @semantic-release/exec --no-save
|
||||||
|
|||||||
26
.github/workflows/server-tests-mariadb.yml
vendored
26
.github/workflows/server-tests-mariadb.yml
vendored
@@ -117,7 +117,7 @@ jobs:
|
|||||||
FRAPPE_BRANCH: ${{ github.event.inputs.branch }}
|
FRAPPE_BRANCH: ${{ github.event.inputs.branch }}
|
||||||
|
|
||||||
- name: Run Tests
|
- name: Run Tests
|
||||||
run: 'cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --app erpnext --total-builds 4 --build-number ${{ matrix.container }}'
|
run: 'cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --app erpnext --with-coverage --total-builds 4 --build-number ${{ matrix.container }}'
|
||||||
env:
|
env:
|
||||||
TYPE: server
|
TYPE: server
|
||||||
CI_BUILD_ID: ${{ github.run_id }}
|
CI_BUILD_ID: ${{ github.run_id }}
|
||||||
@@ -126,3 +126,27 @@ jobs:
|
|||||||
- name: Show bench output
|
- name: Show bench output
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
run: cat ~/frappe-bench/bench_start.log || true
|
run: cat ~/frappe-bench/bench_start.log || true
|
||||||
|
|
||||||
|
- name: Upload coverage data
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: coverage-${{ matrix.container }}
|
||||||
|
path: /home/runner/frappe-bench/sites/coverage.xml
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
name: Coverage Wrap Up
|
||||||
|
needs: test
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Clone
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Download artifacts
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
|
||||||
|
- name: Upload coverage data
|
||||||
|
uses: codecov/codecov-action@v2
|
||||||
|
with:
|
||||||
|
name: MariaDB
|
||||||
|
fail_ci_if_error: true
|
||||||
|
verbose: true
|
||||||
|
|||||||
46
.mergify.yml
46
.mergify.yml
@@ -17,6 +17,7 @@ pull_request_rules:
|
|||||||
- base=version-12
|
- base=version-12
|
||||||
- base=version-14
|
- base=version-14
|
||||||
- base=version-15
|
- base=version-15
|
||||||
|
- base=version-16
|
||||||
actions:
|
actions:
|
||||||
close:
|
close:
|
||||||
comment:
|
comment:
|
||||||
@@ -24,16 +25,6 @@ pull_request_rules:
|
|||||||
@{{author}}, thanks for the contribution, but we do not accept pull requests on a stable branch. Please raise PR on an appropriate hotfix branch.
|
@{{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
|
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
|
- name: backport to develop
|
||||||
conditions:
|
conditions:
|
||||||
- label="backport develop"
|
- label="backport develop"
|
||||||
@@ -54,13 +45,13 @@ pull_request_rules:
|
|||||||
assignees:
|
assignees:
|
||||||
- "{{ author }}"
|
- "{{ author }}"
|
||||||
|
|
||||||
- name: backport to version-14-pre-release
|
- name: backport to version-15-hotfix
|
||||||
conditions:
|
conditions:
|
||||||
- label="backport version-14-pre-release"
|
- label="backport version-15-hotfix"
|
||||||
actions:
|
actions:
|
||||||
backport:
|
backport:
|
||||||
branches:
|
branches:
|
||||||
- version-14-pre-release
|
- version-15-hotfix
|
||||||
assignees:
|
assignees:
|
||||||
- "{{ author }}"
|
- "{{ author }}"
|
||||||
|
|
||||||
@@ -74,35 +65,6 @@ pull_request_rules:
|
|||||||
assignees:
|
assignees:
|
||||||
- "{{ author }}"
|
- "{{ 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
|
- name: Automatic merge on CI success and review
|
||||||
conditions:
|
conditions:
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ fail_fast: false
|
|||||||
|
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.3.0
|
rev: v4.0.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
files: "erpnext.*"
|
files: "erpnext.*"
|
||||||
@@ -15,10 +15,6 @@ repos:
|
|||||||
args: ['--branch', 'develop']
|
args: ['--branch', 'develop']
|
||||||
- id: check-merge-conflict
|
- id: check-merge-conflict
|
||||||
- id: check-ast
|
- id: check-ast
|
||||||
- id: check-json
|
|
||||||
- id: check-toml
|
|
||||||
- id: check-yaml
|
|
||||||
- id: debug-statements
|
|
||||||
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-eslint
|
- repo: https://github.com/pre-commit/mirrors-eslint
|
||||||
rev: v8.44.0
|
rev: v8.44.0
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"branches": ["version-15"],
|
"branches": ["version-13"],
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"@semantic-release/commit-analyzer", {
|
"@semantic-release/commit-analyzer", {
|
||||||
"preset": "angular",
|
"preset": "angular",
|
||||||
@@ -21,4 +21,4 @@
|
|||||||
],
|
],
|
||||||
"@semantic-release/github"
|
"@semantic-release/github"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ import inspect
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
|
||||||
__version__ = "15.8.2"
|
__version__ = "15.0.0-dev"
|
||||||
|
|
||||||
|
|
||||||
def get_default_company(user=None):
|
def get_default_company(user=None):
|
||||||
|
|||||||
@@ -23,65 +23,6 @@ class InvalidAccountMergeError(frappe.ValidationError):
|
|||||||
|
|
||||||
|
|
||||||
class Account(NestedSet):
|
class Account(NestedSet):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
account_currency: DF.Link | None
|
|
||||||
account_name: DF.Data
|
|
||||||
account_number: DF.Data | None
|
|
||||||
account_type: DF.Literal[
|
|
||||||
"",
|
|
||||||
"Accumulated Depreciation",
|
|
||||||
"Asset Received But Not Billed",
|
|
||||||
"Bank",
|
|
||||||
"Cash",
|
|
||||||
"Chargeable",
|
|
||||||
"Capital Work in Progress",
|
|
||||||
"Cost of Goods Sold",
|
|
||||||
"Current Asset",
|
|
||||||
"Current Liability",
|
|
||||||
"Depreciation",
|
|
||||||
"Direct Expense",
|
|
||||||
"Direct Income",
|
|
||||||
"Equity",
|
|
||||||
"Expense Account",
|
|
||||||
"Expenses Included In Asset Valuation",
|
|
||||||
"Expenses Included In Valuation",
|
|
||||||
"Fixed Asset",
|
|
||||||
"Income Account",
|
|
||||||
"Indirect Expense",
|
|
||||||
"Indirect Income",
|
|
||||||
"Liability",
|
|
||||||
"Payable",
|
|
||||||
"Receivable",
|
|
||||||
"Round Off",
|
|
||||||
"Stock",
|
|
||||||
"Stock Adjustment",
|
|
||||||
"Stock Received But Not Billed",
|
|
||||||
"Service Received But Not Billed",
|
|
||||||
"Tax",
|
|
||||||
"Temporary",
|
|
||||||
]
|
|
||||||
balance_must_be: DF.Literal["", "Debit", "Credit"]
|
|
||||||
company: DF.Link
|
|
||||||
disabled: DF.Check
|
|
||||||
freeze_account: DF.Literal["No", "Yes"]
|
|
||||||
include_in_gross: DF.Check
|
|
||||||
is_group: DF.Check
|
|
||||||
lft: DF.Int
|
|
||||||
old_parent: DF.Data | None
|
|
||||||
parent_account: DF.Link
|
|
||||||
report_type: DF.Literal["", "Balance Sheet", "Profit and Loss"]
|
|
||||||
rgt: DF.Int
|
|
||||||
root_type: DF.Literal["", "Asset", "Liability", "Income", "Expense", "Equity"]
|
|
||||||
tax_rate: DF.Float
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
nsm_parent_field = "parent_account"
|
nsm_parent_field = "parent_account"
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
"0360 Bauliche Investitionen in fremden (gepachteten) Betriebs- und Geschäftsgebäuden": {"account_type": "Fixed Asset"},
|
"0360 Bauliche Investitionen in fremden (gepachteten) Betriebs- und Geschäftsgebäuden": {"account_type": "Fixed Asset"},
|
||||||
"0370 Bauliche Investitionen in fremden (gepachteten) Wohn- und Sozialgebäuden": {"account_type": "Fixed Asset"},
|
"0370 Bauliche Investitionen in fremden (gepachteten) Wohn- und Sozialgebäuden": {"account_type": "Fixed Asset"},
|
||||||
"0390 Kumulierte Abschreibungen zu Grundstücken ": {"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"},
|
"0500 Maschinenwerkzeuge ": {"account_type": "Fixed Asset"},
|
||||||
"0510 Allgemeine Werkzeuge und Handwerkzeuge ": {"account_type": "Fixed Asset"},
|
"0510 Allgemeine Werkzeuge und Handwerkzeuge ": {"account_type": "Fixed Asset"},
|
||||||
"0520 Prototypen, Formen, Modelle ": {"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"},
|
"0980 Geleistete Anzahlungen auf Finanzanlagen ": {"account_type": "Fixed Asset"},
|
||||||
"0990 Kumulierte Abschreibungen zu Finanzanlagen ": {"account_type": "Fixed Asset"},
|
"0990 Kumulierte Abschreibungen zu Finanzanlagen ": {"account_type": "Fixed Asset"},
|
||||||
"root_type": "Asset"
|
"root_type": "Asset"
|
||||||
},
|
},
|
||||||
"Klasse 1 Aktiva: Vorr\u00e4te": {
|
"Klasse 1 Aktiva: Vorr\u00e4te": {
|
||||||
"1000 Bezugsverrechnung": {"account_type": "Stock"},
|
"1000 Bezugsverrechnung": {"account_type": "Stock"},
|
||||||
"1100 Rohstoffe": {"account_type": "Stock"},
|
"1100 Rohstoffe": {"account_type": "Stock"},
|
||||||
"1200 Bezogene Teile": {"account_type": "Stock"},
|
"1200 Bezogene Teile": {"account_type": "Stock"},
|
||||||
"1300 Hilfsstoffe": {"account_type": "Stock"},
|
"1300 Hilfsstoffe": {"account_type": "Stock"},
|
||||||
"1350 Betriebsstoffe": {"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"},
|
"1400 Unfertige Erzeugnisse": {"account_type": "Stock"},
|
||||||
"1500 Fertige Erzeugnisse": {"account_type": "Stock"},
|
"1500 Fertige Erzeugnisse": {"account_type": "Stock"},
|
||||||
"1600 Handelswarenvorrat": {"account_type": "Stock Received But Not Billed"},
|
"1600 Handelswarenvorrat": {"account_type": "Stock Received But Not Billed"},
|
||||||
"1700 Noch nicht abrechenbare Leistungen": {"account_type": "Stock"},
|
"1700 Noch nicht abrechenbare Leistungen": {"account_type": "Stock"},
|
||||||
|
"1900 Wertberichtigungen": {"account_type": "Stock"},
|
||||||
"1800 Geleistete Anzahlungen": {"account_type": "Stock"},
|
"1800 Geleistete Anzahlungen": {"account_type": "Stock"},
|
||||||
"1900 Wertberichtigungen": {"account_type": "Stock"},
|
"1900 Wertberichtigungen": {"account_type": "Stock"},
|
||||||
"root_type": "Asset"
|
"root_type": "Asset"
|
||||||
},
|
},
|
||||||
"Klasse 3 Passiva: Verbindlichkeiten": {
|
"Klasse 3 Passiva: Verbindlichkeiten": {
|
||||||
"3000 Allgemeine Verbindlichkeiten (Schuld)": {"account_type": "Payable"},
|
"3000 Allgemeine Verbindlichkeiten (Schuld)": {"account_type": "Payable"},
|
||||||
"3010 R\u00fcckstellungen f\u00fcr Pensionen": {"account_type": "Payable"},
|
"3010 R\u00fcckstellungen f\u00fcr Pensionen": {"account_type": "Payable"},
|
||||||
"3020 Steuerr\u00fcckstellungen": {"account_type": "Tax"},
|
"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"},
|
"3110 Verbindlichkeiten gegen\u00fcber Bank": {"account_type": "Payable"},
|
||||||
"3150 Verbindlichkeiten Darlehen": {"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": {
|
"3380 Verbindlichkeiten aus der Annahme gezogener Wechsel u. d. Ausstellungen eigener Wechsel": {
|
||||||
"account_type": "Payable"
|
"account_type": "Payable"
|
||||||
},
|
},
|
||||||
"3400 Verbindlichkeiten gegen\u00fc. verb. Untern., Verbindl. gegen\u00fc. Untern., mit denen eine Beteiligungsverh\u00e4lnis besteht": {},
|
"3400 Verbindlichkeiten gegen\u00fc. verb. Untern., Verbindl. gegen\u00fc. Untern., mit denen eine Beteiligungsverh\u00e4lnis besteht": {},
|
||||||
"3460 Verbindlichkeiten gegenueber Gesellschaftern": {"account_type": "Payable"},
|
"3460 Verbindlichkeiten gegenueber Gesellschaftern": {"account_type": "Payable"},
|
||||||
"3470 Einlagen stiller Gesellschafter": {"account_type": "Payable"},
|
"3470 Einlagen stiller Gesellschafter": {"account_type": "Payable"},
|
||||||
"3585 Verbindlichkeiten Lohnsteuer": {"account_type": "Tax"},
|
"3585 Verbindlichkeiten Lohnsteuer": {"account_type": "Tax"},
|
||||||
"3590 Verbindlichkeiten Kommunalabgaben": {"account_type": "Tax"},
|
"3590 Verbindlichkeiten Kommunalabgaben": {"account_type": "Tax"},
|
||||||
"3595 Verbindlichkeiten Dienstgeberbeitrag": {"account_type": "Tax"},
|
"3595 Verbindlichkeiten Dienstgeberbeitrag": {"account_type": "Tax"},
|
||||||
"3600 Verbindlichkeiten Sozialversicherung": {"account_type": "Payable"},
|
"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"},
|
"3700 Sonstige Verbindlichkeiten": {"account_type": "Payable"},
|
||||||
"3900 Passive Rechnungsabgrenzungsposten": {"account_type": "Payable"},
|
"3900 Passive Rechnungsabgrenzungsposten": {"account_type": "Payable"},
|
||||||
"3100 Anleihen (einschlie\u00dflich konvertibler)": {"account_type": "Payable"},
|
"3100 Anleihen (einschlie\u00dflich konvertibler)": {"account_type": "Payable"},
|
||||||
@@ -118,13 +119,13 @@
|
|||||||
},
|
},
|
||||||
"3515 Umsatzsteuer Inland 10%": {
|
"3515 Umsatzsteuer Inland 10%": {
|
||||||
"account_type": "Tax"
|
"account_type": "Tax"
|
||||||
},
|
},
|
||||||
"3520 Umsatzsteuer aus i.g. Erwerb 20%": {
|
"3520 Umsatzsteuer aus i.g. Erwerb 20%": {
|
||||||
"account_type": "Tax"
|
"account_type": "Tax"
|
||||||
},
|
},
|
||||||
"3525 Umsatzsteuer aus i.g. Erwerb 10%": {
|
"3525 Umsatzsteuer aus i.g. Erwerb 10%": {
|
||||||
"account_type": "Tax"
|
"account_type": "Tax"
|
||||||
},
|
},
|
||||||
"3560 Umsatzsteuer-Evidenzkonto f\u00fcr erhaltene Anzahlungen auf Bestellungen": {},
|
"3560 Umsatzsteuer-Evidenzkonto f\u00fcr erhaltene Anzahlungen auf Bestellungen": {},
|
||||||
"3360 Verbindlichkeiten aus Lieferungen u. Leistungen EU": {
|
"3360 Verbindlichkeiten aus Lieferungen u. Leistungen EU": {
|
||||||
"account_type": "Payable"
|
"account_type": "Payable"
|
||||||
@@ -140,7 +141,7 @@
|
|||||||
"account_type": "Tax"
|
"account_type": "Tax"
|
||||||
},
|
},
|
||||||
"root_type": "Liability"
|
"root_type": "Liability"
|
||||||
},
|
},
|
||||||
"Klasse 2 Aktiva: Umlaufverm\u00f6gen, Rechnungsabgrenzungen": {
|
"Klasse 2 Aktiva: Umlaufverm\u00f6gen, Rechnungsabgrenzungen": {
|
||||||
"2030 Forderungen aus Lieferungen und Leistungen Inland (0% USt, umsatzsteuerfrei)": {
|
"2030 Forderungen aus Lieferungen und Leistungen Inland (0% USt, umsatzsteuerfrei)": {
|
||||||
"account_type": "Receivable"
|
"account_type": "Receivable"
|
||||||
@@ -153,7 +154,7 @@
|
|||||||
},
|
},
|
||||||
"2040 Forderungen aus Lieferungen und Leistungen Inland (sonstiger USt-Satz)": {
|
"2040 Forderungen aus Lieferungen und Leistungen Inland (sonstiger USt-Satz)": {
|
||||||
"account_type": "Receivable"
|
"account_type": "Receivable"
|
||||||
},
|
},
|
||||||
"2100 Forderungen aus Lieferungen und Leistungen EU": {
|
"2100 Forderungen aus Lieferungen und Leistungen EU": {
|
||||||
"account_type": "Receivable"
|
"account_type": "Receivable"
|
||||||
},
|
},
|
||||||
@@ -191,7 +192,7 @@
|
|||||||
"account_type": "Receivable"
|
"account_type": "Receivable"
|
||||||
},
|
},
|
||||||
"2570 Einfuhrumsatzsteuer (bezahlt)": {"account_type": "Tax"},
|
"2570 Einfuhrumsatzsteuer (bezahlt)": {"account_type": "Tax"},
|
||||||
|
|
||||||
"2460 Eingeforderte aber noch nicht eingezahlte Einlagen": {
|
"2460 Eingeforderte aber noch nicht eingezahlte Einlagen": {
|
||||||
"account_type": "Receivable"
|
"account_type": "Receivable"
|
||||||
},
|
},
|
||||||
@@ -242,10 +243,10 @@
|
|||||||
},
|
},
|
||||||
"2800 Guthaben bei Bank": {
|
"2800 Guthaben bei Bank": {
|
||||||
"account_type": "Bank"
|
"account_type": "Bank"
|
||||||
},
|
},
|
||||||
"2801 Guthaben bei Bank - Sparkonto": {
|
"2801 Guthaben bei Bank - Sparkonto": {
|
||||||
"account_type": "Bank"
|
"account_type": "Bank"
|
||||||
},
|
},
|
||||||
"2810 Guthaben bei Paypal": {
|
"2810 Guthaben bei Paypal": {
|
||||||
"account_type": "Bank"
|
"account_type": "Bank"
|
||||||
},
|
},
|
||||||
@@ -263,19 +264,19 @@
|
|||||||
},
|
},
|
||||||
"2895 Schwebende Geldbewegugen": {
|
"2895 Schwebende Geldbewegugen": {
|
||||||
"account_type": "Bank"
|
"account_type": "Bank"
|
||||||
},
|
},
|
||||||
"2513 Vorsteuer Inland 5%": {
|
"2513 Vorsteuer Inland 5%": {
|
||||||
"account_type": "Tax"
|
"account_type": "Tax"
|
||||||
},
|
},
|
||||||
"2515 Vorsteuer Inland 20%": {
|
"2515 Vorsteuer Inland 20%": {
|
||||||
"account_type": "Tax"
|
"account_type": "Tax"
|
||||||
},
|
},
|
||||||
"2520 Vorsteuer aus innergemeinschaftlichem Erwerb 10%": {
|
"2520 Vorsteuer aus innergemeinschaftlichem Erwerb 10%": {
|
||||||
"account_type": "Tax"
|
"account_type": "Tax"
|
||||||
},
|
},
|
||||||
"2525 Vorsteuer aus innergemeinschaftlichem Erwerb 20%": {
|
"2525 Vorsteuer aus innergemeinschaftlichem Erwerb 20%": {
|
||||||
"account_type": "Tax"
|
"account_type": "Tax"
|
||||||
},
|
},
|
||||||
"2530 Vorsteuer \u00a719/Art 19 ( reverse charge ) ": {
|
"2530 Vorsteuer \u00a719/Art 19 ( reverse charge ) ": {
|
||||||
"account_type": "Tax"
|
"account_type": "Tax"
|
||||||
},
|
},
|
||||||
@@ -285,16 +286,16 @@
|
|||||||
"root_type": "Asset"
|
"root_type": "Asset"
|
||||||
},
|
},
|
||||||
"Klasse 4: Betriebliche Erträge": {
|
"Klasse 4: Betriebliche Erträge": {
|
||||||
"4000 Erlöse 20 %": {"account_type": "Income Account"},
|
"4000 Erlöse 20 %": {"account_type": "Income Account"},
|
||||||
"4020 Erl\u00f6se 0 % steuerbefreit": {"account_type": "Income Account"},
|
"4020 Erl\u00f6se 0 % steuerbefreit": {"account_type": "Income Account"},
|
||||||
"4010 Erl\u00f6se 10 %": {"account_type": "Income Account"},
|
"4010 Erl\u00f6se 10 %": {"account_type": "Income Account"},
|
||||||
"4030 Erl\u00f6se 13 %": {"account_type": "Income Account"},
|
"4030 Erl\u00f6se 13 %": {"account_type": "Income Account"},
|
||||||
"4040 Erl\u00f6se 0 % innergemeinschaftliche Lieferungen": {"account_type": "Income Account"},
|
"4040 Erl\u00f6se 0 % innergemeinschaftliche Lieferungen": {"account_type": "Income Account"},
|
||||||
"4400 Erl\u00f6sreduktion 0 % steuerbefreit": {"account_type": "Expense Account"},
|
"4400 Erl\u00f6sreduktion 0 % steuerbefreit": {"account_type": "Expense Account"},
|
||||||
"4410 Erl\u00f6sreduktion 10 %": {"account_type": "Expense Account"},
|
"4410 Erl\u00f6sreduktion 10 %": {"account_type": "Expense Account"},
|
||||||
"4420 Erl\u00f6sreduktion 20 %": {"account_type": "Expense Account"},
|
"4420 Erl\u00f6sreduktion 20 %": {"account_type": "Expense Account"},
|
||||||
"4430 Erl\u00f6sreduktion 13 %": {"account_type": "Expense Account"},
|
"4430 Erl\u00f6sreduktion 13 %": {"account_type": "Expense Account"},
|
||||||
"4440 Erl\u00f6sreduktion 0 % innergemeinschaftliche Lieferungen": {"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"},
|
"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"},
|
"4580 Aktivierte Eigenleistungen": {"account_type": "Income Account"},
|
||||||
"4600 Erl\u00f6se aus dem Abgang vom Anlageverm\u00f6gen, ausgen. Finanzanlagen": {"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"},
|
"4700 Ertr\u00e4ge aus der Aufl\u00f6sung von R\u00fcckstellungen": {"account_type": "Income Account"},
|
||||||
"4800 \u00dcbrige betriebliche Ertr\u00e4ge": {"account_type": "Income Account"},
|
"4800 \u00dcbrige betriebliche Ertr\u00e4ge": {"account_type": "Income Account"},
|
||||||
"root_type": "Income"
|
"root_type": "Income"
|
||||||
},
|
},
|
||||||
"Klasse 5: Aufwand f\u00fcr Material und Leistungen": {
|
"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"},
|
"5100 Verbrauch an Rohstoffen": {"account_type": "Cost of Goods Sold"},
|
||||||
"5200 Verbrauch von bezogenen Fertig- und Einzelteilen": {"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"},
|
"5300 Verbrauch von Hilfsstoffen": {"account_type": "Cost of Goods Sold"},
|
||||||
"5340 Verbrauch Verpackungsmaterial": {"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"},
|
"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"},
|
"5400 Verbrauch von Betriebsstoffen": {"account_type": "Cost of Goods Sold"},
|
||||||
"5500 Verbrauch von Werkzeugen und anderen Erzeugungshilfsmittel": {"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"},
|
"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"},
|
"6700 Sonstige Sozialaufwendungen": {"account_type": "Payable"},
|
||||||
"6900 Aufwandsstellenrechnung Personal": {"account_type": "Payable"},
|
"6900 Aufwandsstellenrechnung Personal": {"account_type": "Payable"},
|
||||||
"root_type": "Expense"
|
"root_type": "Expense"
|
||||||
},
|
},
|
||||||
"Klasse 7: Abschreibungen und sonstige betriebliche Aufwendungen": {
|
"Klasse 7: Abschreibungen und sonstige betriebliche Aufwendungen": {
|
||||||
"7010 Abschreibungen auf das Anlageverm\u00f6gen (ausgenommen Finanzanlagen)": {"account_type": "Depreciation"},
|
"7010 Abschreibungen auf das Anlageverm\u00f6gen (ausgenommen Finanzanlagen)": {"account_type": "Depreciation"},
|
||||||
"7100 Sonstige Steuern und Geb\u00fchren": {"account_type": "Tax"},
|
"7100 Sonstige Steuern und Geb\u00fchren": {"account_type": "Tax"},
|
||||||
@@ -348,7 +349,7 @@
|
|||||||
"7310 Fahrrad - Aufwand": {"account_type": "Expense Account"},
|
"7310 Fahrrad - Aufwand": {"account_type": "Expense Account"},
|
||||||
"7320 Kfz - Aufwand": {"account_type": "Expense Account"},
|
"7320 Kfz - Aufwand": {"account_type": "Expense Account"},
|
||||||
"7330 LKW - 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"},
|
"7350 Reise- und Fahraufwand": {"account_type": "Expense Account"},
|
||||||
"7360 Tag- und N\u00e4chtigungsgelder": {"account_type": "Expense Account"},
|
"7360 Tag- und N\u00e4chtigungsgelder": {"account_type": "Expense Account"},
|
||||||
"7380 Nachrichtenaufwand": {"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"},
|
"8990 Gewinnabfuhr bzw. Verlust\u00fcberrechnung aus Ergebnisabf\u00fchrungsvertr\u00e4gen": {"account_type": "Expense Account"},
|
||||||
"8350 nicht ausgenutzte Lieferantenskonti": {"account_type": "Expense Account"},
|
"8350 nicht ausgenutzte Lieferantenskonti": {"account_type": "Expense Account"},
|
||||||
"root_type": "Income"
|
"root_type": "Income"
|
||||||
},
|
},
|
||||||
"Klasse 9 Passiva: Eigenkapital, R\u00fccklagen, stille Einlagen, Abschlusskonten": {
|
"Klasse 9 Passiva: Eigenkapital, R\u00fccklagen, stille Einlagen, Abschlusskonten": {
|
||||||
"9000 Gezeichnetes bzw. gewidmetes Kapital": {
|
"9000 Gezeichnetes bzw. gewidmetes Kapital": {
|
||||||
"account_type": "Equity"
|
"account_type": "Equity"
|
||||||
@@ -434,5 +435,5 @@
|
|||||||
},
|
},
|
||||||
"root_type": "Equity"
|
"root_type": "Equity"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,9 +33,7 @@
|
|||||||
},
|
},
|
||||||
"Stocks": {
|
"Stocks": {
|
||||||
"Mati\u00e8res premi\u00e8res": {},
|
"Mati\u00e8res premi\u00e8res": {},
|
||||||
"Stock de produits fini": {
|
"Stock de produits fini": {},
|
||||||
"account_type": "Stock"
|
|
||||||
},
|
|
||||||
"Stock exp\u00e9di\u00e9 non-factur\u00e9": {},
|
"Stock exp\u00e9di\u00e9 non-factur\u00e9": {},
|
||||||
"Travaux en cours": {},
|
"Travaux en cours": {},
|
||||||
"account_type": "Stock"
|
"account_type": "Stock"
|
||||||
@@ -397,11 +395,9 @@
|
|||||||
},
|
},
|
||||||
"Produits": {
|
"Produits": {
|
||||||
"Revenus de ventes": {
|
"Revenus de ventes": {
|
||||||
"Escomptes de volume sur ventes": {},
|
" Escomptes de volume sur ventes": {},
|
||||||
"Autres produits d'exploitation": {},
|
"Autres produits d'exploitation": {},
|
||||||
"Ventes": {
|
"Ventes": {},
|
||||||
"account_type": "Income Account"
|
|
||||||
},
|
|
||||||
"Ventes avec des provinces harmonis\u00e9es": {},
|
"Ventes avec des provinces harmonis\u00e9es": {},
|
||||||
"Ventes avec des provinces non-harmonis\u00e9es": {},
|
"Ventes avec des provinces non-harmonis\u00e9es": {},
|
||||||
"Ventes \u00e0 l'\u00e9tranger": {}
|
"Ventes \u00e0 l'\u00e9tranger": {}
|
||||||
|
|||||||
@@ -53,13 +53,8 @@
|
|||||||
},
|
},
|
||||||
"II. Forderungen und sonstige Vermögensgegenstände": {
|
"II. Forderungen und sonstige Vermögensgegenstände": {
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"Forderungen aus Lieferungen und Leistungen mit Kontokorrent": {
|
"Ford. a. Lieferungen und Leistungen": {
|
||||||
"account_number": "1400",
|
"account_number": "1400",
|
||||||
"account_type": "Receivable",
|
|
||||||
"is_group": 1
|
|
||||||
},
|
|
||||||
"Forderungen aus Lieferungen und Leistungen ohne Kontokorrent": {
|
|
||||||
"account_number": "1410",
|
|
||||||
"account_type": "Receivable"
|
"account_type": "Receivable"
|
||||||
},
|
},
|
||||||
"Durchlaufende Posten": {
|
"Durchlaufende Posten": {
|
||||||
@@ -185,13 +180,8 @@
|
|||||||
},
|
},
|
||||||
"IV. Verbindlichkeiten aus Lieferungen und Leistungen": {
|
"IV. Verbindlichkeiten aus Lieferungen und Leistungen": {
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"Verbindlichkeiten aus Lieferungen und Leistungen mit Kontokorrent": {
|
"Verbindlichkeiten aus Lieferungen u. Leistungen": {
|
||||||
"account_number": "1600",
|
"account_number": "1600",
|
||||||
"account_type": "Payable",
|
|
||||||
"is_group": 1
|
|
||||||
},
|
|
||||||
"Verbindlichkeiten aus Lieferungen und Leistungen ohne Kontokorrent": {
|
|
||||||
"account_number": "1610",
|
|
||||||
"account_type": "Payable"
|
"account_type": "Payable"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -407,10 +407,13 @@
|
|||||||
"Bewertungskorrektur zu Forderungen aus Lieferungen und Leistungen": {
|
"Bewertungskorrektur zu Forderungen aus Lieferungen und Leistungen": {
|
||||||
"account_number": "9960"
|
"account_number": "9960"
|
||||||
},
|
},
|
||||||
"Forderungen aus Lieferungen und Leistungen mit Kontokorrent": {
|
"Debitoren": {
|
||||||
|
"is_group": 1,
|
||||||
|
"account_number": "10000"
|
||||||
|
},
|
||||||
|
"Forderungen aus Lieferungen und Leistungen": {
|
||||||
"account_number": "1200",
|
"account_number": "1200",
|
||||||
"account_type": "Receivable",
|
"account_type": "Receivable"
|
||||||
"is_group": 1
|
|
||||||
},
|
},
|
||||||
"Forderungen aus Lieferungen und Leistungen ohne Kontokorrent": {
|
"Forderungen aus Lieferungen und Leistungen ohne Kontokorrent": {
|
||||||
"account_number": "1210"
|
"account_number": "1210"
|
||||||
@@ -1135,15 +1138,18 @@
|
|||||||
"Bewertungskorrektur zu Verb. aus Lieferungen und Leistungen": {
|
"Bewertungskorrektur zu Verb. aus Lieferungen und Leistungen": {
|
||||||
"account_number": "9964"
|
"account_number": "9964"
|
||||||
},
|
},
|
||||||
"Verb. aus Lieferungen und Leistungen mit Kontokorrent": {
|
"Kreditoren": {
|
||||||
"account_number": "3300",
|
"account_number": "70000",
|
||||||
"account_type": "Payable",
|
|
||||||
"is_group": 1,
|
"is_group": 1,
|
||||||
"Wareneingangs-Verrechnungskonto" : {
|
"Wareneingangs-Verrechnungskonto" : {
|
||||||
"account_number": "70001",
|
"account_number": "70001",
|
||||||
"account_type": "Stock Received But Not Billed"
|
"account_type": "Stock Received But Not Billed"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Verb. aus Lieferungen und Leistungen": {
|
||||||
|
"account_number": "3300",
|
||||||
|
"account_type": "Payable"
|
||||||
|
},
|
||||||
"Verb. aus Lieferungen und Leistungen ohne Kontokorrent": {
|
"Verb. aus Lieferungen und Leistungen ohne Kontokorrent": {
|
||||||
"account_number": "3310"
|
"account_number": "3310"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -11,29 +11,6 @@ from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
|
|||||||
|
|
||||||
|
|
||||||
class AccountClosingBalance(Document):
|
class AccountClosingBalance(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
account: DF.Link | None
|
|
||||||
account_currency: DF.Link | None
|
|
||||||
closing_date: DF.Date | None
|
|
||||||
company: DF.Link | None
|
|
||||||
cost_center: DF.Link | None
|
|
||||||
credit: DF.Currency
|
|
||||||
credit_in_account_currency: DF.Currency
|
|
||||||
debit: DF.Currency
|
|
||||||
debit_in_account_currency: DF.Currency
|
|
||||||
finance_book: DF.Link | None
|
|
||||||
is_period_closing_voucher_entry: DF.Check
|
|
||||||
period_closing_voucher: DF.Link | None
|
|
||||||
project: DF.Link | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,25 +13,6 @@ from frappe.utils import cstr
|
|||||||
|
|
||||||
|
|
||||||
class AccountingDimension(Document):
|
class AccountingDimension(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.accounting_dimension_detail.accounting_dimension_detail import (
|
|
||||||
AccountingDimensionDetail,
|
|
||||||
)
|
|
||||||
|
|
||||||
dimension_defaults: DF.Table[AccountingDimensionDetail]
|
|
||||||
disabled: DF.Check
|
|
||||||
document_type: DF.Link
|
|
||||||
fieldname: DF.Data | None
|
|
||||||
label: DF.Data | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def before_insert(self):
|
def before_insert(self):
|
||||||
self.set_fieldname_and_label()
|
self.set_fieldname_and_label()
|
||||||
|
|
||||||
|
|||||||
@@ -7,24 +7,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class AccountingDimensionDetail(Document):
|
class AccountingDimensionDetail(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
automatically_post_balancing_accounting_entry: DF.Check
|
|
||||||
company: DF.Link | None
|
|
||||||
default_dimension: DF.DynamicLink | None
|
|
||||||
mandatory_for_bs: DF.Check
|
|
||||||
mandatory_for_pl: DF.Check
|
|
||||||
offsetting_account: DF.Link | None
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
reference_document: DF.Link | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -8,28 +8,6 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class AccountingDimensionFilter(Document):
|
class AccountingDimensionFilter(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.allowed_dimension.allowed_dimension import AllowedDimension
|
|
||||||
from erpnext.accounts.doctype.applicable_on_account.applicable_on_account import (
|
|
||||||
ApplicableOnAccount,
|
|
||||||
)
|
|
||||||
|
|
||||||
accounting_dimension: DF.Literal
|
|
||||||
accounts: DF.Table[ApplicableOnAccount]
|
|
||||||
allow_or_restrict: DF.Literal["Allow", "Restrict"]
|
|
||||||
apply_restriction_on_values: DF.Check
|
|
||||||
company: DF.Link
|
|
||||||
dimensions: DF.Table[AllowedDimension]
|
|
||||||
disabled: DF.Check
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def before_save(self):
|
def before_save(self):
|
||||||
# If restriction is not applied on values, then remove all the dimensions and set allow_or_restrict to Restrict
|
# If restriction is not applied on values, then remove all the dimensions and set allow_or_restrict to Restrict
|
||||||
if not self.apply_restriction_on_values:
|
if not self.apply_restriction_on_values:
|
||||||
|
|||||||
@@ -16,23 +16,6 @@ class ClosedAccountingPeriod(frappe.ValidationError):
|
|||||||
|
|
||||||
|
|
||||||
class AccountingPeriod(Document):
|
class AccountingPeriod(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.closed_document.closed_document import ClosedDocument
|
|
||||||
|
|
||||||
closed_documents: DF.Table[ClosedDocument]
|
|
||||||
company: DF.Link
|
|
||||||
end_date: DF.Date
|
|
||||||
period_name: DF.Data
|
|
||||||
start_date: DF.Date
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_overlap()
|
self.validate_overlap()
|
||||||
|
|
||||||
|
|||||||
@@ -66,12 +66,7 @@
|
|||||||
"show_balance_in_coa",
|
"show_balance_in_coa",
|
||||||
"banking_tab",
|
"banking_tab",
|
||||||
"enable_party_matching",
|
"enable_party_matching",
|
||||||
"enable_fuzzy_matching",
|
"enable_fuzzy_matching"
|
||||||
"reports_tab",
|
|
||||||
"remarks_section",
|
|
||||||
"general_ledger_remarks_length",
|
|
||||||
"column_break_lvjk",
|
|
||||||
"receivable_payable_remarks_length"
|
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -427,34 +422,6 @@
|
|||||||
"fieldname": "round_row_wise_tax",
|
"fieldname": "round_row_wise_tax",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Round Tax Amount Row-wise"
|
"label": "Round Tax Amount Row-wise"
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "reports_tab",
|
|
||||||
"fieldtype": "Tab Break",
|
|
||||||
"label": "Reports"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"description": "Truncates 'Remarks' column to set character length",
|
|
||||||
"fieldname": "general_ledger_remarks_length",
|
|
||||||
"fieldtype": "Int",
|
|
||||||
"label": "General Ledger"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"description": "Truncates 'Remarks' column to set character length",
|
|
||||||
"fieldname": "receivable_payable_remarks_length",
|
|
||||||
"fieldtype": "Int",
|
|
||||||
"label": "Accounts Receivable/Payable"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "column_break_lvjk",
|
|
||||||
"fieldtype": "Column Break"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "remarks_section",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"label": "Remarks Column Length"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "icon-cog",
|
"icon": "icon-cog",
|
||||||
@@ -462,7 +429,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-11-20 09:37:47.650347",
|
"modified": "2023-08-28 00:12:02.740633",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Accounts Settings",
|
"name": "Accounts Settings",
|
||||||
|
|||||||
@@ -14,52 +14,6 @@ from erpnext.stock.utils import check_pending_reposting
|
|||||||
|
|
||||||
|
|
||||||
class AccountsSettings(Document):
|
class AccountsSettings(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
acc_frozen_upto: DF.Date | None
|
|
||||||
add_taxes_from_item_tax_template: DF.Check
|
|
||||||
allow_multi_currency_invoices_against_single_party_account: DF.Check
|
|
||||||
allow_stale: DF.Check
|
|
||||||
auto_reconcile_payments: DF.Check
|
|
||||||
automatically_fetch_payment_terms: DF.Check
|
|
||||||
automatically_process_deferred_accounting_entry: DF.Check
|
|
||||||
book_asset_depreciation_entry_automatically: DF.Check
|
|
||||||
book_deferred_entries_based_on: DF.Literal["Days", "Months"]
|
|
||||||
book_deferred_entries_via_journal_entry: DF.Check
|
|
||||||
book_tax_discount_loss: DF.Check
|
|
||||||
check_supplier_invoice_uniqueness: DF.Check
|
|
||||||
credit_controller: DF.Link | None
|
|
||||||
delete_linked_ledger_entries: DF.Check
|
|
||||||
determine_address_tax_category_from: DF.Literal["Billing Address", "Shipping Address"]
|
|
||||||
enable_common_party_accounting: DF.Check
|
|
||||||
enable_fuzzy_matching: DF.Check
|
|
||||||
enable_party_matching: DF.Check
|
|
||||||
frozen_accounts_modifier: DF.Link | None
|
|
||||||
general_ledger_remarks_length: DF.Int
|
|
||||||
ignore_account_closing_balance: DF.Check
|
|
||||||
make_payment_via_journal_entry: DF.Check
|
|
||||||
merge_similar_account_heads: DF.Check
|
|
||||||
over_billing_allowance: DF.Currency
|
|
||||||
post_change_gl_entries: DF.Check
|
|
||||||
receivable_payable_remarks_length: DF.Int
|
|
||||||
role_allowed_to_over_bill: DF.Link | None
|
|
||||||
round_row_wise_tax: DF.Check
|
|
||||||
show_balance_in_coa: DF.Check
|
|
||||||
show_inclusive_tax_in_print: DF.Check
|
|
||||||
show_payment_schedule_in_print: DF.Check
|
|
||||||
show_taxes_as_table_in_print: DF.Check
|
|
||||||
stale_days: DF.Int
|
|
||||||
submit_journal_entries: DF.Check
|
|
||||||
unlink_advance_payment_on_cancelation_of_order: DF.Check
|
|
||||||
unlink_payment_on_cancellation_of_invoice: DF.Check
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
old_doc = self.get_doc_before_save()
|
old_doc = self.get_doc_before_save()
|
||||||
clear_cache = False
|
clear_cache = False
|
||||||
|
|||||||
@@ -6,22 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class AdvanceTax(Document):
|
class AdvanceTax(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
account_head: DF.Link | None
|
|
||||||
allocated_amount: DF.Currency
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
reference_detail: DF.Data | None
|
|
||||||
reference_name: DF.DynamicLink | None
|
|
||||||
reference_type: DF.Link | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -7,33 +7,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class AdvanceTaxesandCharges(Document):
|
class AdvanceTaxesandCharges(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
account_head: DF.Link
|
|
||||||
add_deduct_tax: DF.Literal["Add", "Deduct"]
|
|
||||||
allocated_amount: DF.Currency
|
|
||||||
base_tax_amount: DF.Currency
|
|
||||||
base_total: DF.Currency
|
|
||||||
charge_type: DF.Literal[
|
|
||||||
"", "Actual", "On Paid Amount", "On Previous Row Amount", "On Previous Row Total"
|
|
||||||
]
|
|
||||||
cost_center: DF.Link | None
|
|
||||||
currency: DF.Link | None
|
|
||||||
description: DF.SmallText
|
|
||||||
included_in_paid_amount: DF.Check
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
rate: DF.Float
|
|
||||||
row_id: DF.Data | None
|
|
||||||
tax_amount: DF.Currency
|
|
||||||
total: DF.Currency
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -7,19 +7,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class AllowedDimension(Document):
|
class AllowedDimension(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
accounting_dimension: DF.Link | None
|
|
||||||
dimension_value: DF.DynamicLink | None
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -6,18 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class AllowedToTransactWith(Document):
|
class AllowedToTransactWith(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
company: DF.Link
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -7,19 +7,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class ApplicableOnAccount(Document):
|
class ApplicableOnAccount(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
applicable_on_account: DF.Link
|
|
||||||
is_mandatory: DF.Check
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -10,25 +10,6 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class Bank(Document):
|
class Bank(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.bank_transaction_mapping.bank_transaction_mapping import (
|
|
||||||
BankTransactionMapping,
|
|
||||||
)
|
|
||||||
|
|
||||||
bank_name: DF.Data
|
|
||||||
bank_transaction_mapping: DF.Table[BankTransactionMapping]
|
|
||||||
plaid_access_token: DF.Data | None
|
|
||||||
swift_number: DF.Data | None
|
|
||||||
website: DF.Data | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def onload(self):
|
def onload(self):
|
||||||
"""Load address and contacts in `__onload`"""
|
"""Load address and contacts in `__onload`"""
|
||||||
load_address_and_contact(self)
|
load_address_and_contact(self)
|
||||||
|
|||||||
@@ -12,33 +12,6 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class BankAccount(Document):
|
class BankAccount(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
account: DF.Link | None
|
|
||||||
account_name: DF.Data
|
|
||||||
account_subtype: DF.Link | None
|
|
||||||
account_type: DF.Link | None
|
|
||||||
bank: DF.Link
|
|
||||||
bank_account_no: DF.Data | None
|
|
||||||
branch_code: DF.Data | None
|
|
||||||
company: DF.Link | None
|
|
||||||
disabled: DF.Check
|
|
||||||
iban: DF.Data | None
|
|
||||||
integration_id: DF.Data | None
|
|
||||||
is_company_account: DF.Check
|
|
||||||
is_default: DF.Check
|
|
||||||
last_integration_date: DF.Date | None
|
|
||||||
mask: DF.Data | None
|
|
||||||
party: DF.DynamicLink | None
|
|
||||||
party_type: DF.Link | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def onload(self):
|
def onload(self):
|
||||||
"""Load address and contacts in `__onload`"""
|
"""Load address and contacts in `__onload`"""
|
||||||
load_address_and_contact(self)
|
load_address_and_contact(self)
|
||||||
|
|||||||
@@ -6,15 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class BankAccountSubtype(Document):
|
class BankAccountSubtype(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
account_subtype: DF.Data | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -7,15 +7,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class BankAccountType(Document):
|
class BankAccountType(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
account_type: DF.Data | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -13,28 +13,6 @@ form_grid_templates = {"journal_entries": "templates/form_grid/bank_reconciliati
|
|||||||
|
|
||||||
|
|
||||||
class BankClearance(Document):
|
class BankClearance(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.bank_clearance_detail.bank_clearance_detail import (
|
|
||||||
BankClearanceDetail,
|
|
||||||
)
|
|
||||||
|
|
||||||
account: DF.Link
|
|
||||||
account_currency: DF.Link | None
|
|
||||||
bank_account: DF.Link | None
|
|
||||||
from_date: DF.Date
|
|
||||||
include_pos_transactions: DF.Check
|
|
||||||
include_reconciled_entries: DF.Check
|
|
||||||
payment_entries: DF.Table[BankClearanceDetail]
|
|
||||||
to_date: DF.Date
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_payment_entries(self):
|
def get_payment_entries(self):
|
||||||
if not (self.from_date and self.to_date):
|
if not (self.from_date and self.to_date):
|
||||||
|
|||||||
@@ -6,25 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class BankClearanceDetail(Document):
|
class BankClearanceDetail(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
against_account: DF.Data | None
|
|
||||||
amount: DF.Data | None
|
|
||||||
cheque_date: DF.Date | None
|
|
||||||
cheque_number: DF.Data | None
|
|
||||||
clearance_date: DF.Date | None
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
payment_document: DF.Link | None
|
|
||||||
payment_entry: DF.DynamicLink | None
|
|
||||||
posting_date: DF.Date | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -8,40 +8,6 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class BankGuarantee(Document):
|
class BankGuarantee(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
account: DF.Link | None
|
|
||||||
amended_from: DF.Link | None
|
|
||||||
amount: DF.Currency
|
|
||||||
bank: DF.Link | None
|
|
||||||
bank_account: DF.Link | None
|
|
||||||
bank_account_no: DF.Data | None
|
|
||||||
bank_guarantee_number: DF.Data | None
|
|
||||||
bg_type: DF.Literal["", "Receiving", "Providing"]
|
|
||||||
branch_code: DF.Data | None
|
|
||||||
charges: DF.Currency
|
|
||||||
customer: DF.Link | None
|
|
||||||
end_date: DF.Date | None
|
|
||||||
fixed_deposit_number: DF.Data | None
|
|
||||||
iban: DF.Data | None
|
|
||||||
margin_money: DF.Currency
|
|
||||||
more_information: DF.TextEditor | None
|
|
||||||
name_of_beneficiary: DF.Data | None
|
|
||||||
project: DF.Link | None
|
|
||||||
reference_docname: DF.DynamicLink | None
|
|
||||||
reference_doctype: DF.Link | None
|
|
||||||
start_date: DF.Date
|
|
||||||
supplier: DF.Link | None
|
|
||||||
swift_number: DF.Data | None
|
|
||||||
validity: DF.Int
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
if not (self.customer or self.supplier):
|
if not (self.customer or self.supplier):
|
||||||
frappe.throw(_("Select the customer or supplier."))
|
frappe.throw(_("Select the customer or supplier."))
|
||||||
|
|||||||
@@ -18,30 +18,9 @@ from erpnext.accounts.report.bank_reconciliation_statement.bank_reconciliation_s
|
|||||||
get_entries,
|
get_entries,
|
||||||
)
|
)
|
||||||
from erpnext.accounts.utils import get_account_currency, get_balance_on
|
from erpnext.accounts.utils import get_account_currency, get_balance_on
|
||||||
from erpnext.setup.utils import get_exchange_rate
|
|
||||||
|
|
||||||
|
|
||||||
class BankReconciliationTool(Document):
|
class BankReconciliationTool(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
account_currency: DF.Link | None
|
|
||||||
account_opening_balance: DF.Currency
|
|
||||||
bank_account: DF.Link | None
|
|
||||||
bank_statement_closing_balance: DF.Currency
|
|
||||||
bank_statement_from_date: DF.Date | None
|
|
||||||
bank_statement_to_date: DF.Date | None
|
|
||||||
company: DF.Link | None
|
|
||||||
filter_by_reference_date: DF.Check
|
|
||||||
from_reference_date: DF.Date | None
|
|
||||||
to_reference_date: DF.Date | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@@ -151,7 +130,7 @@ def create_journal_entry_bts(
|
|||||||
bank_transaction = frappe.db.get_values(
|
bank_transaction = frappe.db.get_values(
|
||||||
"Bank Transaction",
|
"Bank Transaction",
|
||||||
bank_transaction_name,
|
bank_transaction_name,
|
||||||
fieldname=["name", "deposit", "withdrawal", "bank_account", "currency"],
|
fieldname=["name", "deposit", "withdrawal", "bank_account"],
|
||||||
as_dict=True,
|
as_dict=True,
|
||||||
)[0]
|
)[0]
|
||||||
company_account = frappe.get_value("Bank Account", bank_transaction.bank_account, "account")
|
company_account = frappe.get_value("Bank Account", bank_transaction.bank_account, "account")
|
||||||
@@ -165,94 +144,29 @@ def create_journal_entry_bts(
|
|||||||
)
|
)
|
||||||
|
|
||||||
company = frappe.get_value("Account", company_account, "company")
|
company = frappe.get_value("Account", company_account, "company")
|
||||||
company_default_currency = frappe.get_cached_value("Company", company, "default_currency")
|
|
||||||
company_account_currency = frappe.get_cached_value("Account", company_account, "account_currency")
|
|
||||||
second_account_currency = frappe.get_cached_value("Account", second_account, "account_currency")
|
|
||||||
|
|
||||||
# determine if multi-currency Journal or not
|
|
||||||
is_multi_currency = (
|
|
||||||
True
|
|
||||||
if company_default_currency != company_account_currency
|
|
||||||
or company_default_currency != second_account_currency
|
|
||||||
or company_default_currency != bank_transaction.currency
|
|
||||||
else False
|
|
||||||
)
|
|
||||||
|
|
||||||
accounts = []
|
accounts = []
|
||||||
second_account_dict = {
|
# Multi Currency?
|
||||||
"account": second_account,
|
accounts.append(
|
||||||
"account_currency": second_account_currency,
|
{
|
||||||
"credit_in_account_currency": bank_transaction.deposit,
|
"account": second_account,
|
||||||
"debit_in_account_currency": bank_transaction.withdrawal,
|
"credit_in_account_currency": bank_transaction.deposit,
|
||||||
"party_type": party_type,
|
"debit_in_account_currency": bank_transaction.withdrawal,
|
||||||
"party": party,
|
"party_type": party_type,
|
||||||
"cost_center": get_default_cost_center(company),
|
"party": party,
|
||||||
}
|
"cost_center": get_default_cost_center(company),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
company_account_dict = {
|
accounts.append(
|
||||||
"account": company_account,
|
{
|
||||||
"account_currency": company_account_currency,
|
"account": company_account,
|
||||||
"bank_account": bank_transaction.bank_account,
|
"bank_account": bank_transaction.bank_account,
|
||||||
"credit_in_account_currency": bank_transaction.withdrawal,
|
"credit_in_account_currency": bank_transaction.withdrawal,
|
||||||
"debit_in_account_currency": bank_transaction.deposit,
|
"debit_in_account_currency": bank_transaction.deposit,
|
||||||
"cost_center": get_default_cost_center(company),
|
"cost_center": get_default_cost_center(company),
|
||||||
}
|
}
|
||||||
|
)
|
||||||
# convert transaction amount to company currency
|
|
||||||
if is_multi_currency:
|
|
||||||
exc_rate = get_exchange_rate(bank_transaction.currency, company_default_currency, posting_date)
|
|
||||||
withdrawal_in_company_currency = flt(exc_rate * abs(bank_transaction.withdrawal))
|
|
||||||
deposit_in_company_currency = flt(exc_rate * abs(bank_transaction.deposit))
|
|
||||||
else:
|
|
||||||
withdrawal_in_company_currency = bank_transaction.withdrawal
|
|
||||||
deposit_in_company_currency = bank_transaction.deposit
|
|
||||||
|
|
||||||
# if second account is of foreign currency, convert and set debit and credit fields.
|
|
||||||
if second_account_currency != company_default_currency:
|
|
||||||
exc_rate = get_exchange_rate(second_account_currency, company_default_currency, posting_date)
|
|
||||||
second_account_dict.update(
|
|
||||||
{
|
|
||||||
"exchange_rate": exc_rate,
|
|
||||||
"credit": deposit_in_company_currency,
|
|
||||||
"debit": withdrawal_in_company_currency,
|
|
||||||
"credit_in_account_currency": flt(deposit_in_company_currency / exc_rate) or 0,
|
|
||||||
"debit_in_account_currency": flt(withdrawal_in_company_currency / exc_rate) or 0,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
second_account_dict.update(
|
|
||||||
{
|
|
||||||
"exchange_rate": 1,
|
|
||||||
"credit": deposit_in_company_currency,
|
|
||||||
"debit": withdrawal_in_company_currency,
|
|
||||||
"credit_in_account_currency": deposit_in_company_currency,
|
|
||||||
"debit_in_account_currency": withdrawal_in_company_currency,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
# if company account is of foreign currency, convert and set debit and credit fields.
|
|
||||||
if company_account_currency != company_default_currency:
|
|
||||||
exc_rate = get_exchange_rate(company_account_currency, company_default_currency, posting_date)
|
|
||||||
company_account_dict.update(
|
|
||||||
{
|
|
||||||
"exchange_rate": exc_rate,
|
|
||||||
"credit": withdrawal_in_company_currency,
|
|
||||||
"debit": deposit_in_company_currency,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
company_account_dict.update(
|
|
||||||
{
|
|
||||||
"exchange_rate": 1,
|
|
||||||
"credit": withdrawal_in_company_currency,
|
|
||||||
"debit": deposit_in_company_currency,
|
|
||||||
"credit_in_account_currency": withdrawal_in_company_currency,
|
|
||||||
"debit_in_account_currency": deposit_in_company_currency,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
accounts.append(second_account_dict)
|
|
||||||
accounts.append(company_account_dict)
|
|
||||||
|
|
||||||
journal_entry_dict = {
|
journal_entry_dict = {
|
||||||
"voucher_type": entry_type,
|
"voucher_type": entry_type,
|
||||||
@@ -262,9 +176,6 @@ def create_journal_entry_bts(
|
|||||||
"cheque_no": reference_number,
|
"cheque_no": reference_number,
|
||||||
"mode_of_payment": mode_of_payment,
|
"mode_of_payment": mode_of_payment,
|
||||||
}
|
}
|
||||||
if is_multi_currency:
|
|
||||||
journal_entry_dict.update({"multi_currency": True})
|
|
||||||
|
|
||||||
journal_entry = frappe.new_doc("Journal Entry")
|
journal_entry = frappe.new_doc("Journal Entry")
|
||||||
journal_entry.update(journal_entry_dict)
|
journal_entry.update(journal_entry_dict)
|
||||||
journal_entry.set("accounts", accounts)
|
journal_entry.set("accounts", accounts)
|
||||||
@@ -444,9 +355,7 @@ def reconcile_vouchers(bank_transaction_name, vouchers):
|
|||||||
vouchers = json.loads(vouchers)
|
vouchers = json.loads(vouchers)
|
||||||
transaction = frappe.get_doc("Bank Transaction", bank_transaction_name)
|
transaction = frappe.get_doc("Bank Transaction", bank_transaction_name)
|
||||||
transaction.add_payment_entries(vouchers)
|
transaction.add_payment_entries(vouchers)
|
||||||
transaction.save()
|
return frappe.get_doc("Bank Transaction", bank_transaction_name)
|
||||||
|
|
||||||
return transaction
|
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
|||||||
@@ -20,30 +20,6 @@ INVALID_VALUES = ("", None)
|
|||||||
|
|
||||||
|
|
||||||
class BankStatementImport(DataImport):
|
class BankStatementImport(DataImport):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
bank: DF.Link | None
|
|
||||||
bank_account: DF.Link
|
|
||||||
company: DF.Link
|
|
||||||
google_sheets_url: DF.Data | None
|
|
||||||
import_file: DF.Attach | None
|
|
||||||
import_type: DF.Literal["", "Insert New Records", "Update Existing Records"]
|
|
||||||
mute_emails: DF.Check
|
|
||||||
reference_doctype: DF.Link
|
|
||||||
show_failed_logs: DF.Check
|
|
||||||
statement_import_log: DF.Code | None
|
|
||||||
status: DF.Literal["Pending", "Success", "Partial Success", "Error"]
|
|
||||||
submit_after_import: DF.Check
|
|
||||||
template_options: DF.Code | None
|
|
||||||
template_warnings: DF.Code | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(BankStatementImport, self).__init__(*args, **kwargs)
|
super(BankStatementImport, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
"status",
|
"status",
|
||||||
"bank_account",
|
"bank_account",
|
||||||
"company",
|
"company",
|
||||||
"amended_from",
|
|
||||||
"section_break_4",
|
"section_break_4",
|
||||||
"deposit",
|
"deposit",
|
||||||
"withdrawal",
|
"withdrawal",
|
||||||
@@ -26,10 +25,10 @@
|
|||||||
"transaction_id",
|
"transaction_id",
|
||||||
"transaction_type",
|
"transaction_type",
|
||||||
"section_break_14",
|
"section_break_14",
|
||||||
"column_break_oufv",
|
|
||||||
"payment_entries",
|
"payment_entries",
|
||||||
"section_break_18",
|
"section_break_18",
|
||||||
"allocated_amount",
|
"allocated_amount",
|
||||||
|
"amended_from",
|
||||||
"column_break_17",
|
"column_break_17",
|
||||||
"unallocated_amount",
|
"unallocated_amount",
|
||||||
"party_section",
|
"party_section",
|
||||||
@@ -139,12 +138,10 @@
|
|||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
|
||||||
"fieldname": "allocated_amount",
|
"fieldname": "allocated_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Allocated Amount",
|
"label": "Allocated Amount",
|
||||||
"options": "currency",
|
"options": "currency"
|
||||||
"read_only": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "amended_from",
|
"fieldname": "amended_from",
|
||||||
@@ -160,12 +157,10 @@
|
|||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
|
||||||
"fieldname": "unallocated_amount",
|
"fieldname": "unallocated_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Unallocated Amount",
|
"label": "Unallocated Amount",
|
||||||
"options": "currency",
|
"options": "currency"
|
||||||
"read_only": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "party_section",
|
"fieldname": "party_section",
|
||||||
@@ -230,15 +225,11 @@
|
|||||||
"fieldname": "bank_party_account_number",
|
"fieldname": "bank_party_account_number",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Party Account No. (Bank Statement)"
|
"label": "Party Account No. (Bank Statement)"
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "column_break_oufv",
|
|
||||||
"fieldtype": "Column Break"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-11-18 18:32:47.203694",
|
"modified": "2023-06-06 13:58:12.821411",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Bank Transaction",
|
"name": "Bank Transaction",
|
||||||
|
|||||||
@@ -2,108 +2,78 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
|
|
||||||
from erpnext.controllers.status_updater import StatusUpdater
|
from erpnext.controllers.status_updater import StatusUpdater
|
||||||
|
|
||||||
|
|
||||||
class BankTransaction(StatusUpdater):
|
class BankTransaction(StatusUpdater):
|
||||||
# begin: auto-generated types
|
def after_insert(self):
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
self.unallocated_amount = abs(flt(self.withdrawal) - flt(self.deposit))
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
def on_submit(self):
|
||||||
|
self.clear_linked_payment_entries()
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.bank_transaction_payments.bank_transaction_payments import (
|
|
||||||
BankTransactionPayments,
|
|
||||||
)
|
|
||||||
|
|
||||||
allocated_amount: DF.Currency
|
|
||||||
amended_from: DF.Link | None
|
|
||||||
bank_account: DF.Link | None
|
|
||||||
bank_party_account_number: DF.Data | None
|
|
||||||
bank_party_iban: DF.Data | None
|
|
||||||
bank_party_name: DF.Data | None
|
|
||||||
company: DF.Link | None
|
|
||||||
currency: DF.Link | None
|
|
||||||
date: DF.Date | None
|
|
||||||
deposit: DF.Currency
|
|
||||||
description: DF.SmallText | None
|
|
||||||
naming_series: DF.Literal["ACC-BTN-.YYYY.-"]
|
|
||||||
party: DF.DynamicLink | None
|
|
||||||
party_type: DF.Link | None
|
|
||||||
payment_entries: DF.Table[BankTransactionPayments]
|
|
||||||
reference_number: DF.Data | None
|
|
||||||
status: DF.Literal["", "Pending", "Settled", "Unreconciled", "Reconciled", "Cancelled"]
|
|
||||||
transaction_id: DF.Data | None
|
|
||||||
transaction_type: DF.Data | None
|
|
||||||
unallocated_amount: DF.Currency
|
|
||||||
withdrawal: DF.Currency
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def before_validate(self):
|
|
||||||
self.update_allocated_amount()
|
|
||||||
|
|
||||||
def validate(self):
|
|
||||||
self.validate_duplicate_references()
|
|
||||||
|
|
||||||
def validate_duplicate_references(self):
|
|
||||||
"""Make sure the same voucher is not allocated twice within the same Bank Transaction"""
|
|
||||||
if not self.payment_entries:
|
|
||||||
return
|
|
||||||
|
|
||||||
pe = []
|
|
||||||
for row in self.payment_entries:
|
|
||||||
reference = (row.payment_document, row.payment_entry)
|
|
||||||
if reference in pe:
|
|
||||||
frappe.throw(
|
|
||||||
_("{0} {1} is allocated twice in this Bank Transaction").format(
|
|
||||||
row.payment_document, row.payment_entry
|
|
||||||
)
|
|
||||||
)
|
|
||||||
pe.append(reference)
|
|
||||||
|
|
||||||
def update_allocated_amount(self):
|
|
||||||
self.allocated_amount = (
|
|
||||||
sum(p.allocated_amount for p in self.payment_entries) if self.payment_entries else 0.0
|
|
||||||
)
|
|
||||||
self.unallocated_amount = abs(flt(self.withdrawal) - flt(self.deposit)) - self.allocated_amount
|
|
||||||
|
|
||||||
def before_submit(self):
|
|
||||||
self.allocate_payment_entries()
|
|
||||||
self.set_status()
|
self.set_status()
|
||||||
|
|
||||||
if frappe.db.get_single_value("Accounts Settings", "enable_party_matching"):
|
if frappe.db.get_single_value("Accounts Settings", "enable_party_matching"):
|
||||||
self.auto_set_party()
|
self.auto_set_party()
|
||||||
|
|
||||||
def before_update_after_submit(self):
|
_saving_flag = False
|
||||||
self.validate_duplicate_references()
|
|
||||||
self.allocate_payment_entries()
|
# nosemgrep: frappe-semgrep-rules.rules.frappe-modifying-but-not-comitting
|
||||||
self.update_allocated_amount()
|
def on_update_after_submit(self):
|
||||||
|
"Run on save(). Avoid recursion caused by multiple saves"
|
||||||
|
if not self._saving_flag:
|
||||||
|
self._saving_flag = True
|
||||||
|
self.clear_linked_payment_entries()
|
||||||
|
self.update_allocations()
|
||||||
|
self._saving_flag = False
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
for payment_entry in self.payment_entries:
|
self.clear_linked_payment_entries(for_cancel=True)
|
||||||
self.clear_linked_payment_entry(payment_entry, for_cancel=True)
|
self.set_status(update=True)
|
||||||
|
|
||||||
|
def update_allocations(self):
|
||||||
|
"The doctype does not allow modifications after submission, so write to the db direct"
|
||||||
|
if self.payment_entries:
|
||||||
|
allocated_amount = sum(p.allocated_amount for p in self.payment_entries)
|
||||||
|
else:
|
||||||
|
allocated_amount = 0.0
|
||||||
|
|
||||||
|
amount = abs(flt(self.withdrawal) - flt(self.deposit))
|
||||||
|
self.db_set("allocated_amount", flt(allocated_amount))
|
||||||
|
self.db_set("unallocated_amount", amount - flt(allocated_amount))
|
||||||
|
self.reload()
|
||||||
self.set_status(update=True)
|
self.set_status(update=True)
|
||||||
|
|
||||||
def add_payment_entries(self, vouchers):
|
def add_payment_entries(self, vouchers):
|
||||||
"Add the vouchers with zero allocation. Save() will perform the allocations and clearance"
|
"Add the vouchers with zero allocation. Save() will perform the allocations and clearance"
|
||||||
if 0.0 >= self.unallocated_amount:
|
if 0.0 >= self.unallocated_amount:
|
||||||
frappe.throw(_("Bank Transaction {0} is already fully reconciled").format(self.name))
|
frappe.throw(frappe._("Bank Transaction {0} is already fully reconciled").format(self.name))
|
||||||
|
|
||||||
|
added = False
|
||||||
for voucher in vouchers:
|
for voucher in vouchers:
|
||||||
self.append(
|
# Can't add same voucher twice
|
||||||
"payment_entries",
|
found = False
|
||||||
{
|
for pe in self.payment_entries:
|
||||||
|
if (
|
||||||
|
pe.payment_document == voucher["payment_doctype"]
|
||||||
|
and pe.payment_entry == voucher["payment_name"]
|
||||||
|
):
|
||||||
|
found = True
|
||||||
|
|
||||||
|
if not found:
|
||||||
|
pe = {
|
||||||
"payment_document": voucher["payment_doctype"],
|
"payment_document": voucher["payment_doctype"],
|
||||||
"payment_entry": voucher["payment_name"],
|
"payment_entry": voucher["payment_name"],
|
||||||
"allocated_amount": 0.0, # Temporary
|
"allocated_amount": 0.0, # Temporary
|
||||||
},
|
}
|
||||||
)
|
child = self.append("payment_entries", pe)
|
||||||
|
added = True
|
||||||
|
|
||||||
|
# runs on_update_after_submit
|
||||||
|
if added:
|
||||||
|
self.save()
|
||||||
|
|
||||||
def allocate_payment_entries(self):
|
def allocate_payment_entries(self):
|
||||||
"""Refactored from bank reconciliation tool.
|
"""Refactored from bank reconciliation tool.
|
||||||
@@ -119,8 +89,8 @@ class BankTransaction(StatusUpdater):
|
|||||||
- 0 > a: Error: already over-allocated
|
- 0 > a: Error: already over-allocated
|
||||||
- clear means: set the latest transaction date as clearance date
|
- clear means: set the latest transaction date as clearance date
|
||||||
"""
|
"""
|
||||||
|
gl_bank_account = frappe.db.get_value("Bank Account", self.bank_account, "account")
|
||||||
remaining_amount = self.unallocated_amount
|
remaining_amount = self.unallocated_amount
|
||||||
to_remove = []
|
|
||||||
for payment_entry in self.payment_entries:
|
for payment_entry in self.payment_entries:
|
||||||
if payment_entry.allocated_amount == 0.0:
|
if payment_entry.allocated_amount == 0.0:
|
||||||
unallocated_amount, should_clear, latest_transaction = get_clearance_details(
|
unallocated_amount, should_clear, latest_transaction = get_clearance_details(
|
||||||
@@ -130,39 +100,49 @@ class BankTransaction(StatusUpdater):
|
|||||||
if 0.0 == unallocated_amount:
|
if 0.0 == unallocated_amount:
|
||||||
if should_clear:
|
if should_clear:
|
||||||
latest_transaction.clear_linked_payment_entry(payment_entry)
|
latest_transaction.clear_linked_payment_entry(payment_entry)
|
||||||
to_remove.append(payment_entry)
|
self.db_delete_payment_entry(payment_entry)
|
||||||
|
|
||||||
elif remaining_amount <= 0.0:
|
elif remaining_amount <= 0.0:
|
||||||
to_remove.append(payment_entry)
|
self.db_delete_payment_entry(payment_entry)
|
||||||
|
|
||||||
elif 0.0 < unallocated_amount <= remaining_amount:
|
elif 0.0 < unallocated_amount and unallocated_amount <= remaining_amount:
|
||||||
payment_entry.allocated_amount = unallocated_amount
|
payment_entry.db_set("allocated_amount", unallocated_amount)
|
||||||
remaining_amount -= unallocated_amount
|
remaining_amount -= unallocated_amount
|
||||||
if should_clear:
|
if should_clear:
|
||||||
latest_transaction.clear_linked_payment_entry(payment_entry)
|
latest_transaction.clear_linked_payment_entry(payment_entry)
|
||||||
|
|
||||||
elif 0.0 < unallocated_amount:
|
elif 0.0 < unallocated_amount and unallocated_amount > remaining_amount:
|
||||||
payment_entry.allocated_amount = remaining_amount
|
payment_entry.db_set("allocated_amount", remaining_amount)
|
||||||
remaining_amount = 0.0
|
remaining_amount = 0.0
|
||||||
|
|
||||||
elif 0.0 > unallocated_amount:
|
elif 0.0 > unallocated_amount:
|
||||||
frappe.throw(_("Voucher {0} is over-allocated by {1}").format(unallocated_amount))
|
self.db_delete_payment_entry(payment_entry)
|
||||||
|
frappe.throw(frappe._("Voucher {0} is over-allocated by {1}").format(unallocated_amount))
|
||||||
|
|
||||||
for payment_entry in to_remove:
|
self.reload()
|
||||||
self.remove(to_remove)
|
|
||||||
|
def db_delete_payment_entry(self, payment_entry):
|
||||||
|
frappe.db.delete("Bank Transaction Payments", {"name": payment_entry.name})
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def remove_payment_entries(self):
|
def remove_payment_entries(self):
|
||||||
for payment_entry in self.payment_entries:
|
for payment_entry in self.payment_entries:
|
||||||
self.remove_payment_entry(payment_entry)
|
self.remove_payment_entry(payment_entry)
|
||||||
|
# runs on_update_after_submit
|
||||||
self.save() # runs before_update_after_submit
|
self.save()
|
||||||
|
|
||||||
def remove_payment_entry(self, payment_entry):
|
def remove_payment_entry(self, payment_entry):
|
||||||
"Clear payment entry and clearance"
|
"Clear payment entry and clearance"
|
||||||
self.clear_linked_payment_entry(payment_entry, for_cancel=True)
|
self.clear_linked_payment_entry(payment_entry, for_cancel=True)
|
||||||
self.remove(payment_entry)
|
self.remove(payment_entry)
|
||||||
|
|
||||||
|
def clear_linked_payment_entries(self, for_cancel=False):
|
||||||
|
if for_cancel:
|
||||||
|
for payment_entry in self.payment_entries:
|
||||||
|
self.clear_linked_payment_entry(payment_entry, for_cancel)
|
||||||
|
else:
|
||||||
|
self.allocate_payment_entries()
|
||||||
|
|
||||||
def clear_linked_payment_entry(self, payment_entry, for_cancel=False):
|
def clear_linked_payment_entry(self, payment_entry, for_cancel=False):
|
||||||
clearance_date = None if for_cancel else self.date
|
clearance_date = None if for_cancel else self.date
|
||||||
set_voucher_clearance(
|
set_voucher_clearance(
|
||||||
@@ -183,10 +163,11 @@ class BankTransaction(StatusUpdater):
|
|||||||
deposit=self.deposit,
|
deposit=self.deposit,
|
||||||
).match()
|
).match()
|
||||||
|
|
||||||
if not result:
|
if result:
|
||||||
return
|
party_type, party = result
|
||||||
|
frappe.db.set_value(
|
||||||
self.party_type, self.party = result
|
"Bank Transaction", self.name, field={"party_type": party_type, "party": party}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@@ -218,7 +199,9 @@ def get_clearance_details(transaction, payment_entry):
|
|||||||
if gle["gl_account"] == gl_bank_account:
|
if gle["gl_account"] == gl_bank_account:
|
||||||
if gle["amount"] <= 0.0:
|
if gle["amount"] <= 0.0:
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
_("Voucher {0} value is broken: {1}").format(payment_entry.payment_entry, gle["amount"])
|
frappe._("Voucher {0} value is broken: {1}").format(
|
||||||
|
payment_entry.payment_entry, gle["amount"]
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
unmatched_gles -= 1
|
unmatched_gles -= 1
|
||||||
@@ -239,7 +222,7 @@ def get_clearance_details(transaction, payment_entry):
|
|||||||
|
|
||||||
def get_related_bank_gl_entries(doctype, docname):
|
def get_related_bank_gl_entries(doctype, docname):
|
||||||
# nosemgrep: frappe-semgrep-rules.rules.frappe-using-db-sql
|
# nosemgrep: frappe-semgrep-rules.rules.frappe-using-db-sql
|
||||||
return frappe.db.sql(
|
result = frappe.db.sql(
|
||||||
"""
|
"""
|
||||||
SELECT
|
SELECT
|
||||||
ABS(gle.credit_in_account_currency - gle.debit_in_account_currency) AS amount,
|
ABS(gle.credit_in_account_currency - gle.debit_in_account_currency) AS amount,
|
||||||
@@ -257,6 +240,7 @@ def get_related_bank_gl_entries(doctype, docname):
|
|||||||
dict(doctype=doctype, docname=docname),
|
dict(doctype=doctype, docname=docname),
|
||||||
as_dict=True,
|
as_dict=True,
|
||||||
)
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def get_total_allocated_amount(doctype, docname):
|
def get_total_allocated_amount(doctype, docname):
|
||||||
@@ -382,7 +366,6 @@ def set_voucher_clearance(doctype, docname, clearance_date, self):
|
|||||||
if clearance_date:
|
if clearance_date:
|
||||||
vouchers = [{"payment_doctype": "Bank Transaction", "payment_name": self.name}]
|
vouchers = [{"payment_doctype": "Bank Transaction", "payment_name": self.name}]
|
||||||
bt.add_payment_entries(vouchers)
|
bt.add_payment_entries(vouchers)
|
||||||
bt.save()
|
|
||||||
else:
|
else:
|
||||||
for pe in bt.payment_entries:
|
for pe in bt.payment_entries:
|
||||||
if pe.payment_document == self.doctype and pe.payment_entry == self.name:
|
if pe.payment_document == self.doctype and pe.payment_entry == self.name:
|
||||||
|
|||||||
@@ -6,19 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class BankTransactionMapping(Document):
|
class BankTransactionMapping(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
bank_transaction_field: DF.Literal
|
|
||||||
file_field: DF.Data
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -6,21 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class BankTransactionPayments(Document):
|
class BankTransactionPayments(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
allocated_amount: DF.Currency
|
|
||||||
clearance_date: DF.Date | None
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
payment_document: DF.Link
|
|
||||||
payment_entry: DF.DynamicLink
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -22,36 +22,6 @@ class DuplicateBudgetError(frappe.ValidationError):
|
|||||||
|
|
||||||
|
|
||||||
class Budget(Document):
|
class Budget(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.budget_account.budget_account import BudgetAccount
|
|
||||||
|
|
||||||
accounts: DF.Table[BudgetAccount]
|
|
||||||
action_if_accumulated_monthly_budget_exceeded: DF.Literal["", "Stop", "Warn", "Ignore"]
|
|
||||||
action_if_accumulated_monthly_budget_exceeded_on_mr: DF.Literal["", "Stop", "Warn", "Ignore"]
|
|
||||||
action_if_accumulated_monthly_budget_exceeded_on_po: DF.Literal["", "Stop", "Warn", "Ignore"]
|
|
||||||
action_if_annual_budget_exceeded: DF.Literal["", "Stop", "Warn", "Ignore"]
|
|
||||||
action_if_annual_budget_exceeded_on_mr: DF.Literal["", "Stop", "Warn", "Ignore"]
|
|
||||||
action_if_annual_budget_exceeded_on_po: DF.Literal["", "Stop", "Warn", "Ignore"]
|
|
||||||
amended_from: DF.Link | None
|
|
||||||
applicable_on_booking_actual_expenses: DF.Check
|
|
||||||
applicable_on_material_request: DF.Check
|
|
||||||
applicable_on_purchase_order: DF.Check
|
|
||||||
budget_against: DF.Literal["", "Cost Center", "Project"]
|
|
||||||
company: DF.Link
|
|
||||||
cost_center: DF.Link | None
|
|
||||||
fiscal_year: DF.Link
|
|
||||||
monthly_distribution: DF.Link | None
|
|
||||||
naming_series: DF.Data | None
|
|
||||||
project: DF.Link | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
if not self.get(frappe.scrub(self.budget_against)):
|
if not self.get(frappe.scrub(self.budget_against)):
|
||||||
frappe.throw(_("{0} is mandatory").format(self.budget_against))
|
frappe.throw(_("{0} is mandatory").format(self.budget_against))
|
||||||
|
|||||||
@@ -6,19 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class BudgetAccount(Document):
|
class BudgetAccount(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
account: DF.Link
|
|
||||||
budget_amount: DF.Currency
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -6,18 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class CampaignItem(Document):
|
class CampaignItem(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
campaign: DF.Link | None
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -9,32 +9,6 @@ from frappe.utils import flt
|
|||||||
|
|
||||||
|
|
||||||
class CashierClosing(Document):
|
class CashierClosing(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.cashier_closing_payments.cashier_closing_payments import (
|
|
||||||
CashierClosingPayments,
|
|
||||||
)
|
|
||||||
|
|
||||||
amended_from: DF.Link | None
|
|
||||||
custody: DF.Float
|
|
||||||
date: DF.Date | None
|
|
||||||
expense: DF.Float
|
|
||||||
from_time: DF.Time
|
|
||||||
naming_series: DF.Literal["POS-CLO-"]
|
|
||||||
net_amount: DF.Float
|
|
||||||
outstanding_amount: DF.Float
|
|
||||||
payments: DF.Table[CashierClosingPayments]
|
|
||||||
returns: DF.Float
|
|
||||||
time: DF.Time
|
|
||||||
user: DF.Link
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_time()
|
self.validate_time()
|
||||||
|
|
||||||
|
|||||||
@@ -6,19 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class CashierClosingPayments(Document):
|
class CashierClosingPayments(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
amount: DF.Float
|
|
||||||
mode_of_payment: DF.Link
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -53,18 +53,10 @@ frappe.ui.form.on('Chart of Accounts Importer', {
|
|||||||
of Accounts. Please enter the account names and add more rows as per your requirement.`);
|
of Accounts. Please enter the account names and add more rows as per your requirement.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
{
|
|
||||||
label : "Company",
|
|
||||||
fieldname: "company",
|
|
||||||
fieldtype: "Link",
|
|
||||||
reqd: 1,
|
|
||||||
hidden: 1,
|
|
||||||
default: frm.doc.company,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
primary_action: function() {
|
primary_action: function() {
|
||||||
let data = d.get_values();
|
var data = d.get_values();
|
||||||
|
|
||||||
if (!data.template_type) {
|
if (!data.template_type) {
|
||||||
frappe.throw(__('Please select <b>Template Type</b> to download template'));
|
frappe.throw(__('Please select <b>Template Type</b> to download template'));
|
||||||
@@ -74,8 +66,7 @@ frappe.ui.form.on('Chart of Accounts Importer', {
|
|||||||
'/api/method/erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.download_template',
|
'/api/method/erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.download_template',
|
||||||
{
|
{
|
||||||
file_type: data.file_type,
|
file_type: data.file_type,
|
||||||
template_type: data.template_type,
|
template_type: data.template_type
|
||||||
company: data.company
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ from functools import reduce
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.desk.form.linked_with import get_linked_fields
|
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import cint, cstr
|
from frappe.utils import cint, cstr
|
||||||
from frappe.utils.csvutils import UnicodeWriter
|
from frappe.utils.csvutils import UnicodeWriter
|
||||||
@@ -24,18 +23,6 @@ from erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts import
|
|||||||
|
|
||||||
|
|
||||||
class ChartofAccountsImporter(Document):
|
class ChartofAccountsImporter(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
company: DF.Link | None
|
|
||||||
import_file: DF.Attach | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
if self.import_file:
|
if self.import_file:
|
||||||
get_coa(
|
get_coa(
|
||||||
@@ -125,7 +112,7 @@ def generate_data_from_csv(file_doc, as_dict=False):
|
|||||||
if as_dict:
|
if as_dict:
|
||||||
data.append({frappe.scrub(header): row[index] for index, header in enumerate(headers)})
|
data.append({frappe.scrub(header): row[index] for index, header in enumerate(headers)})
|
||||||
else:
|
else:
|
||||||
if not row[1] and len(row) > 1:
|
if not row[1]:
|
||||||
row[1] = row[0]
|
row[1] = row[0]
|
||||||
row[3] = row[2]
|
row[3] = row[2]
|
||||||
data.append(row)
|
data.append(row)
|
||||||
@@ -307,8 +294,10 @@ def build_response_as_excel(writer):
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def download_template(file_type, template_type, company):
|
def download_template(file_type, template_type):
|
||||||
writer = get_template(template_type, company)
|
data = frappe._dict(frappe.local.form_dict)
|
||||||
|
|
||||||
|
writer = get_template(template_type)
|
||||||
|
|
||||||
if file_type == "CSV":
|
if file_type == "CSV":
|
||||||
# download csv file
|
# download csv file
|
||||||
@@ -319,7 +308,8 @@ def download_template(file_type, template_type, company):
|
|||||||
build_response_as_excel(writer)
|
build_response_as_excel(writer)
|
||||||
|
|
||||||
|
|
||||||
def get_template(template_type, company):
|
def get_template(template_type):
|
||||||
|
|
||||||
fields = [
|
fields = [
|
||||||
"Account Name",
|
"Account Name",
|
||||||
"Parent Account",
|
"Parent Account",
|
||||||
@@ -345,17 +335,34 @@ def get_template(template_type, company):
|
|||||||
["", "", "", "", 0, account_type.get("account_type"), account_type.get("root_type")]
|
["", "", "", "", 0, account_type.get("account_type"), account_type.get("root_type")]
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
writer = get_sample_template(writer, company)
|
writer = get_sample_template(writer)
|
||||||
|
|
||||||
return writer
|
return writer
|
||||||
|
|
||||||
|
|
||||||
def get_sample_template(writer, company):
|
def get_sample_template(writer):
|
||||||
currency = frappe.db.get_value("Company", company, "default_currency")
|
template = [
|
||||||
with open(os.path.join(os.path.dirname(__file__), "coa_sample_template.csv"), "r") as f:
|
["Application Of Funds(Assets)", "", "", "", 1, "", "Asset"],
|
||||||
for row in f:
|
["Sources Of Funds(Liabilities)", "", "", "", 1, "", "Liability"],
|
||||||
row = row.strip().split(",") + [currency]
|
["Equity", "", "", "", 1, "", "Equity"],
|
||||||
writer.writerow(row)
|
["Expenses", "", "", "", 1, "", "Expense"],
|
||||||
|
["Income", "", "", "", 1, "", "Income"],
|
||||||
|
["Bank Accounts", "Application Of Funds(Assets)", "", "", 1, "Bank", "Asset"],
|
||||||
|
["Cash In Hand", "Application Of Funds(Assets)", "", "", 1, "Cash", "Asset"],
|
||||||
|
["Stock Assets", "Application Of Funds(Assets)", "", "", 1, "Stock", "Asset"],
|
||||||
|
["Cost Of Goods Sold", "Expenses", "", "", 0, "Cost of Goods Sold", "Expense"],
|
||||||
|
["Asset Depreciation", "Expenses", "", "", 0, "Depreciation", "Expense"],
|
||||||
|
["Fixed Assets", "Application Of Funds(Assets)", "", "", 0, "Fixed Asset", "Asset"],
|
||||||
|
["Accounts Payable", "Sources Of Funds(Liabilities)", "", "", 0, "Payable", "Liability"],
|
||||||
|
["Accounts Receivable", "Application Of Funds(Assets)", "", "", 1, "Receivable", "Asset"],
|
||||||
|
["Stock Expenses", "Expenses", "", "", 0, "Stock Adjustment", "Expense"],
|
||||||
|
["Sample Bank", "Bank Accounts", "", "", 0, "Bank", "Asset"],
|
||||||
|
["Cash", "Cash In Hand", "", "", 0, "Cash", "Asset"],
|
||||||
|
["Stores", "Stock Assets", "", "", 0, "Stock", "Asset"],
|
||||||
|
]
|
||||||
|
|
||||||
|
for row in template:
|
||||||
|
writer.writerow(row)
|
||||||
|
|
||||||
return writer
|
return writer
|
||||||
|
|
||||||
@@ -446,11 +453,14 @@ def get_mandatory_account_types():
|
|||||||
|
|
||||||
|
|
||||||
def unset_existing_data(company):
|
def unset_existing_data(company):
|
||||||
# remove accounts data from company
|
linked = frappe.db.sql(
|
||||||
|
'''select fieldname from tabDocField
|
||||||
|
where fieldtype="Link" and options="Account" and parent="Company"''',
|
||||||
|
as_dict=True,
|
||||||
|
)
|
||||||
|
|
||||||
fieldnames = get_linked_fields("Account").get("Company", {}).get("fieldname", [])
|
# remove accounts data from company
|
||||||
linked = [{"fieldname": name} for name in fieldnames]
|
update_values = {d.fieldname: "" for d in linked}
|
||||||
update_values = {d.get("fieldname"): "" for d in linked}
|
|
||||||
frappe.db.set_value("Company", company, update_values, update_values)
|
frappe.db.set_value("Company", company, update_values, update_values)
|
||||||
|
|
||||||
# remove accounts data from various doctypes
|
# remove accounts data from various doctypes
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
Application Of Funds(Assets),,,,1,,Asset
|
|
||||||
Sources Of Funds(Liabilities),,,,1,,Liability
|
|
||||||
Equity,,,,1,,Equity
|
|
||||||
Expenses,,,,1,Expense Account,Expense
|
|
||||||
Income,,,,1,Income Account,Income
|
|
||||||
Bank Accounts,Application Of Funds(Assets),,,1,Bank,Asset
|
|
||||||
Cash In Hand,Application Of Funds(Assets),,,1,Cash,Asset
|
|
||||||
Stock Assets,Application Of Funds(Assets),,,1,Stock,Asset
|
|
||||||
Cost Of Goods Sold,Expenses,,,0,Cost of Goods Sold,Expense
|
|
||||||
Asset Depreciation,Expenses,,,0,Depreciation,Expense
|
|
||||||
Fixed Assets,Application Of Funds(Assets),,,0,Fixed Asset,Asset
|
|
||||||
Accounts Payable,Sources Of Funds(Liabilities),,,0,Payable,Liability
|
|
||||||
Accounts Receivable,Application Of Funds(Assets),,,1,Receivable,Asset
|
|
||||||
Stock Expenses,Expenses,,,0,Stock Adjustment,Expense
|
|
||||||
Sample Bank,Bank Accounts,,,0,Bank,Asset
|
|
||||||
Cash,Cash In Hand,,,0,Cash,Asset
|
|
||||||
Stores,Stock Assets,,,0,Stock,Asset
|
|
||||||
|
@@ -8,41 +8,6 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class ChequePrintTemplate(Document):
|
class ChequePrintTemplate(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
acc_no_dist_from_left_edge: DF.Float
|
|
||||||
acc_no_dist_from_top_edge: DF.Float
|
|
||||||
acc_pay_dist_from_left_edge: DF.Float
|
|
||||||
acc_pay_dist_from_top_edge: DF.Float
|
|
||||||
amt_in_figures_from_left_edge: DF.Float
|
|
||||||
amt_in_figures_from_top_edge: DF.Float
|
|
||||||
amt_in_word_width: DF.Float
|
|
||||||
amt_in_words_from_left_edge: DF.Float
|
|
||||||
amt_in_words_from_top_edge: DF.Float
|
|
||||||
amt_in_words_line_spacing: DF.Float
|
|
||||||
bank_name: DF.Data
|
|
||||||
cheque_height: DF.Float
|
|
||||||
cheque_size: DF.Literal["", "Regular", "A4"]
|
|
||||||
cheque_width: DF.Float
|
|
||||||
date_dist_from_left_edge: DF.Float
|
|
||||||
date_dist_from_top_edge: DF.Float
|
|
||||||
has_print_format: DF.Check
|
|
||||||
is_account_payable: DF.Check
|
|
||||||
message_to_show: DF.Data | None
|
|
||||||
payer_name_from_left_edge: DF.Float
|
|
||||||
payer_name_from_top_edge: DF.Float
|
|
||||||
scanned_cheque: DF.Attach | None
|
|
||||||
signatory_from_left_edge: DF.Float
|
|
||||||
signatory_from_top_edge: DF.Float
|
|
||||||
starting_position_from_top_edge: DF.Float
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,19 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class ClosedDocument(Document):
|
class ClosedDocument(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
closed: DF.Check
|
|
||||||
document_type: DF.Link
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -10,25 +10,6 @@ from erpnext.accounts.utils import validate_field_number
|
|||||||
|
|
||||||
|
|
||||||
class CostCenter(NestedSet):
|
class CostCenter(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
|
|
||||||
|
|
||||||
company: DF.Link
|
|
||||||
cost_center_name: DF.Data
|
|
||||||
cost_center_number: DF.Data | None
|
|
||||||
disabled: DF.Check
|
|
||||||
is_group: DF.Check
|
|
||||||
lft: DF.Int
|
|
||||||
old_parent: DF.Link | None
|
|
||||||
parent_cost_center: DF.Link
|
|
||||||
rgt: DF.Int
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
nsm_parent_field = "parent_cost_center"
|
nsm_parent_field = "parent_cost_center"
|
||||||
|
|
||||||
def autoname(self):
|
def autoname(self):
|
||||||
|
|||||||
@@ -28,25 +28,6 @@ class InvalidDateError(frappe.ValidationError):
|
|||||||
|
|
||||||
|
|
||||||
class CostCenterAllocation(Document):
|
class CostCenterAllocation(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.cost_center_allocation_percentage.cost_center_allocation_percentage import (
|
|
||||||
CostCenterAllocationPercentage,
|
|
||||||
)
|
|
||||||
|
|
||||||
allocation_percentages: DF.Table[CostCenterAllocationPercentage]
|
|
||||||
amended_from: DF.Link | None
|
|
||||||
company: DF.Link
|
|
||||||
main_cost_center: DF.Link
|
|
||||||
valid_from: DF.Date
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(CostCenterAllocation, self).__init__(*args, **kwargs)
|
super(CostCenterAllocation, self).__init__(*args, **kwargs)
|
||||||
self._skip_from_date_validation = False
|
self._skip_from_date_validation = False
|
||||||
|
|||||||
@@ -6,19 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class CostCenterAllocationPercentage(Document):
|
class CostCenterAllocationPercentage(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
cost_center: DF.Link
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
percentage: DF.Percent
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -9,27 +9,6 @@ from frappe.utils import strip
|
|||||||
|
|
||||||
|
|
||||||
class CouponCode(Document):
|
class CouponCode(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
amended_from: DF.Link | None
|
|
||||||
coupon_code: DF.Data | None
|
|
||||||
coupon_name: DF.Data
|
|
||||||
coupon_type: DF.Literal["Promotional", "Gift Card"]
|
|
||||||
customer: DF.Link | None
|
|
||||||
description: DF.TextEditor | None
|
|
||||||
maximum_use: DF.Int
|
|
||||||
pricing_rule: DF.Link
|
|
||||||
used: DF.Int
|
|
||||||
valid_from: DF.Date | None
|
|
||||||
valid_upto: DF.Date | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def autoname(self):
|
def autoname(self):
|
||||||
self.coupon_name = strip(self.coupon_name)
|
self.coupon_name = strip(self.coupon_name)
|
||||||
self.name = self.coupon_name
|
self.name = self.coupon_name
|
||||||
|
|||||||
@@ -9,30 +9,6 @@ from frappe.utils import nowdate
|
|||||||
|
|
||||||
|
|
||||||
class CurrencyExchangeSettings(Document):
|
class CurrencyExchangeSettings(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.currency_exchange_settings_details.currency_exchange_settings_details import (
|
|
||||||
CurrencyExchangeSettingsDetails,
|
|
||||||
)
|
|
||||||
from erpnext.accounts.doctype.currency_exchange_settings_result.currency_exchange_settings_result import (
|
|
||||||
CurrencyExchangeSettingsResult,
|
|
||||||
)
|
|
||||||
|
|
||||||
access_key: DF.Data | None
|
|
||||||
api_endpoint: DF.Data
|
|
||||||
disabled: DF.Check
|
|
||||||
req_params: DF.Table[CurrencyExchangeSettingsDetails]
|
|
||||||
result_key: DF.Table[CurrencyExchangeSettingsResult]
|
|
||||||
service_provider: DF.Literal["frankfurter.app", "exchangerate.host", "Custom"]
|
|
||||||
url: DF.Data | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.set_parameters_and_result()
|
self.set_parameters_and_result()
|
||||||
if frappe.flags.in_test or frappe.flags.in_install or frappe.flags.in_setup_wizard:
|
if frappe.flags.in_test or frappe.flags.in_install or frappe.flags.in_setup_wizard:
|
||||||
|
|||||||
@@ -6,19 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class CurrencyExchangeSettingsDetails(Document):
|
class CurrencyExchangeSettingsDetails(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
key: DF.Data
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
value: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -6,18 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class CurrencyExchangeSettingsResult(Document):
|
class CurrencyExchangeSettingsResult(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
key: DF.Data
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -6,18 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class CustomerGroupItem(Document):
|
class CustomerGroupItem(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
customer_group: DF.Link | None
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -6,18 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class CustomerItem(Document):
|
class CustomerItem(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
customer: DF.Link | None
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -7,22 +7,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class DiscountedInvoice(Document):
|
class DiscountedInvoice(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
customer: DF.Link | None
|
|
||||||
debit_to: DF.Link | None
|
|
||||||
outstanding_amount: DF.Currency
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
posting_date: DF.Date | None
|
|
||||||
sales_invoice: DF.Link
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -22,52 +22,6 @@ from erpnext.controllers.accounts_controller import AccountsController
|
|||||||
|
|
||||||
|
|
||||||
class Dunning(AccountsController):
|
class Dunning(AccountsController):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.overdue_payment.overdue_payment import OverduePayment
|
|
||||||
|
|
||||||
address_display: DF.SmallText | None
|
|
||||||
amended_from: DF.Link | None
|
|
||||||
base_dunning_amount: DF.Currency
|
|
||||||
body_text: DF.TextEditor | None
|
|
||||||
closing_text: DF.TextEditor | None
|
|
||||||
company: DF.Link
|
|
||||||
company_address: DF.Link | None
|
|
||||||
company_address_display: DF.SmallText | None
|
|
||||||
contact_display: DF.SmallText | None
|
|
||||||
contact_email: DF.Data | None
|
|
||||||
contact_mobile: DF.SmallText | None
|
|
||||||
contact_person: DF.Link | None
|
|
||||||
conversion_rate: DF.Float
|
|
||||||
cost_center: DF.Link | None
|
|
||||||
currency: DF.Link | None
|
|
||||||
customer: DF.Link
|
|
||||||
customer_address: DF.Link | None
|
|
||||||
customer_name: DF.Data | None
|
|
||||||
dunning_amount: DF.Currency
|
|
||||||
dunning_fee: DF.Currency
|
|
||||||
dunning_type: DF.Link | None
|
|
||||||
grand_total: DF.Currency
|
|
||||||
income_account: DF.Link | None
|
|
||||||
language: DF.Link | None
|
|
||||||
letter_head: DF.Link | None
|
|
||||||
naming_series: DF.Literal["DUNN-.MM.-.YY.-"]
|
|
||||||
overdue_payments: DF.Table[OverduePayment]
|
|
||||||
posting_date: DF.Date
|
|
||||||
posting_time: DF.Time | None
|
|
||||||
rate_of_interest: DF.Float
|
|
||||||
spacer: DF.Data | None
|
|
||||||
status: DF.Literal["Draft", "Resolved", "Unresolved", "Cancelled"]
|
|
||||||
total_interest: DF.Currency
|
|
||||||
total_outstanding: DF.Currency
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_same_currency()
|
self.validate_same_currency()
|
||||||
self.validate_overdue_payments()
|
self.validate_overdue_payments()
|
||||||
|
|||||||
@@ -7,21 +7,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class DunningLetterText(Document):
|
class DunningLetterText(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
body_text: DF.TextEditor | None
|
|
||||||
closing_text: DF.TextEditor | None
|
|
||||||
is_default_language: DF.Check
|
|
||||||
language: DF.Link | None
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -7,26 +7,6 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class DunningType(Document):
|
class DunningType(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.dunning_letter_text.dunning_letter_text import DunningLetterText
|
|
||||||
|
|
||||||
company: DF.Link
|
|
||||||
cost_center: DF.Link | None
|
|
||||||
dunning_fee: DF.Currency
|
|
||||||
dunning_letter_text: DF.Table[DunningLetterText]
|
|
||||||
dunning_type: DF.Data
|
|
||||||
income_account: DF.Link | None
|
|
||||||
is_default: DF.Check
|
|
||||||
rate_of_interest: DF.Float
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def autoname(self):
|
def autoname(self):
|
||||||
company_abbr = frappe.get_value("Company", self.company, "abbr")
|
company_abbr = frappe.get_value("Company", self.company, "abbr")
|
||||||
self.name = f"{self.dunning_type} - {company_abbr}"
|
self.name = f"{self.dunning_type} - {company_abbr}"
|
||||||
|
|||||||
@@ -17,28 +17,6 @@ from erpnext.setup.utils import get_exchange_rate
|
|||||||
|
|
||||||
|
|
||||||
class ExchangeRateRevaluation(Document):
|
class ExchangeRateRevaluation(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.exchange_rate_revaluation_account.exchange_rate_revaluation_account import (
|
|
||||||
ExchangeRateRevaluationAccount,
|
|
||||||
)
|
|
||||||
|
|
||||||
accounts: DF.Table[ExchangeRateRevaluationAccount]
|
|
||||||
amended_from: DF.Link | None
|
|
||||||
company: DF.Link
|
|
||||||
gain_loss_booked: DF.Currency
|
|
||||||
gain_loss_unbooked: DF.Currency
|
|
||||||
posting_date: DF.Date
|
|
||||||
rounding_loss_allowance: DF.Float
|
|
||||||
total_gain_loss: DF.Currency
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_rounding_loss_allowance()
|
self.validate_rounding_loss_allowance()
|
||||||
self.set_total_gain_loss()
|
self.set_total_gain_loss()
|
||||||
@@ -214,7 +192,7 @@ class ExchangeRateRevaluation(Document):
|
|||||||
# round off balance based on currency precision
|
# round off balance based on currency precision
|
||||||
# and consider debit-credit difference allowance
|
# and consider debit-credit difference allowance
|
||||||
currency_precision = get_currency_precision()
|
currency_precision = get_currency_precision()
|
||||||
rounding_loss_allowance = float(rounding_loss_allowance)
|
rounding_loss_allowance = float(rounding_loss_allowance) or 0.05
|
||||||
for acc in account_details:
|
for acc in account_details:
|
||||||
acc.balance_in_account_currency = flt(acc.balance_in_account_currency, currency_precision)
|
acc.balance_in_account_currency = flt(acc.balance_in_account_currency, currency_precision)
|
||||||
if abs(acc.balance_in_account_currency) <= rounding_loss_allowance:
|
if abs(acc.balance_in_account_currency) <= rounding_loss_allowance:
|
||||||
|
|||||||
@@ -6,29 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class ExchangeRateRevaluationAccount(Document):
|
class ExchangeRateRevaluationAccount(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
account: DF.Link
|
|
||||||
account_currency: DF.Link | None
|
|
||||||
balance_in_account_currency: DF.Currency
|
|
||||||
balance_in_base_currency: DF.Currency
|
|
||||||
current_exchange_rate: DF.Float
|
|
||||||
gain_loss: DF.Currency
|
|
||||||
new_balance_in_account_currency: DF.Currency
|
|
||||||
new_balance_in_base_currency: DF.Currency
|
|
||||||
new_exchange_rate: DF.Float
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
party: DF.DynamicLink | None
|
|
||||||
party_type: DF.Link | None
|
|
||||||
zero_balance: DF.Check
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -6,15 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class FinanceBook(Document):
|
class FinanceBook(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
finance_book_name: DF.Data | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -10,25 +10,6 @@ from frappe.utils import add_days, add_years, cstr, getdate
|
|||||||
|
|
||||||
|
|
||||||
class FiscalYear(Document):
|
class FiscalYear(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.fiscal_year_company.fiscal_year_company import FiscalYearCompany
|
|
||||||
|
|
||||||
auto_created: DF.Check
|
|
||||||
companies: DF.Table[FiscalYearCompany]
|
|
||||||
disabled: DF.Check
|
|
||||||
is_short_year: DF.Check
|
|
||||||
year: DF.Data
|
|
||||||
year_end_date: DF.Date
|
|
||||||
year_start_date: DF.Date
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_dates()
|
self.validate_dates()
|
||||||
self.validate_overlap()
|
self.validate_overlap()
|
||||||
|
|||||||
@@ -6,18 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class FiscalYearCompany(Document):
|
class FiscalYearCompany(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
company: DF.Link | None
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -142,7 +142,8 @@
|
|||||||
"label": "Against Voucher Type",
|
"label": "Against Voucher Type",
|
||||||
"oldfieldname": "against_voucher_type",
|
"oldfieldname": "against_voucher_type",
|
||||||
"oldfieldtype": "Data",
|
"oldfieldtype": "Data",
|
||||||
"options": "DocType"
|
"options": "DocType",
|
||||||
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "against_voucher",
|
"fieldname": "against_voucher",
|
||||||
@@ -161,7 +162,8 @@
|
|||||||
"label": "Voucher Type",
|
"label": "Voucher Type",
|
||||||
"oldfieldname": "voucher_type",
|
"oldfieldname": "voucher_type",
|
||||||
"oldfieldtype": "Select",
|
"oldfieldtype": "Select",
|
||||||
"options": "DocType"
|
"options": "DocType",
|
||||||
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "voucher_no",
|
"fieldname": "voucher_no",
|
||||||
@@ -319,4 +321,4 @@
|
|||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"states": []
|
"states": []
|
||||||
}
|
}
|
||||||
@@ -28,47 +28,6 @@ exclude_from_linked_with = True
|
|||||||
|
|
||||||
|
|
||||||
class GLEntry(Document):
|
class GLEntry(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
account: DF.Link | None
|
|
||||||
account_currency: DF.Link | None
|
|
||||||
against: DF.Text | None
|
|
||||||
against_voucher: DF.DynamicLink | None
|
|
||||||
against_voucher_type: DF.Link | None
|
|
||||||
company: DF.Link | None
|
|
||||||
cost_center: DF.Link | None
|
|
||||||
credit: DF.Currency
|
|
||||||
credit_in_account_currency: DF.Currency
|
|
||||||
credit_in_transaction_currency: DF.Currency
|
|
||||||
debit: DF.Currency
|
|
||||||
debit_in_account_currency: DF.Currency
|
|
||||||
debit_in_transaction_currency: DF.Currency
|
|
||||||
due_date: DF.Date | None
|
|
||||||
finance_book: DF.Link | None
|
|
||||||
fiscal_year: DF.Link | None
|
|
||||||
is_advance: DF.Literal["No", "Yes"]
|
|
||||||
is_cancelled: DF.Check
|
|
||||||
is_opening: DF.Literal["No", "Yes"]
|
|
||||||
party: DF.DynamicLink | None
|
|
||||||
party_type: DF.Link | None
|
|
||||||
posting_date: DF.Date | None
|
|
||||||
project: DF.Link | None
|
|
||||||
remarks: DF.Text | None
|
|
||||||
to_rename: DF.Check
|
|
||||||
transaction_currency: DF.Link | None
|
|
||||||
transaction_date: DF.Date | None
|
|
||||||
transaction_exchange_rate: DF.Float
|
|
||||||
voucher_detail_no: DF.Data | None
|
|
||||||
voucher_no: DF.DynamicLink | None
|
|
||||||
voucher_type: DF.Link | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def autoname(self):
|
def autoname(self):
|
||||||
"""
|
"""
|
||||||
Temporarily name doc for fast insertion
|
Temporarily name doc for fast insertion
|
||||||
|
|||||||
@@ -17,34 +17,6 @@ from erpnext.controllers.accounts_controller import AccountsController
|
|||||||
|
|
||||||
|
|
||||||
class InvoiceDiscounting(AccountsController):
|
class InvoiceDiscounting(AccountsController):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.discounted_invoice.discounted_invoice import DiscountedInvoice
|
|
||||||
|
|
||||||
accounts_receivable_credit: DF.Link
|
|
||||||
accounts_receivable_discounted: DF.Link
|
|
||||||
accounts_receivable_unpaid: DF.Link
|
|
||||||
amended_from: DF.Link | None
|
|
||||||
bank_account: DF.Link
|
|
||||||
bank_charges: DF.Currency
|
|
||||||
bank_charges_account: DF.Link
|
|
||||||
company: DF.Link
|
|
||||||
invoices: DF.Table[DiscountedInvoice]
|
|
||||||
loan_end_date: DF.Date | None
|
|
||||||
loan_period: DF.Int
|
|
||||||
loan_start_date: DF.Date | None
|
|
||||||
posting_date: DF.Date
|
|
||||||
short_term_loan: DF.Link
|
|
||||||
status: DF.Literal["Draft", "Sanctioned", "Disbursed", "Settled", "Cancelled"]
|
|
||||||
total_amount: DF.Currency
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_mandatory()
|
self.validate_mandatory()
|
||||||
self.validate_invoices()
|
self.validate_invoices()
|
||||||
|
|||||||
@@ -8,24 +8,6 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class ItemTaxTemplate(Document):
|
class ItemTaxTemplate(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.item_tax_template_detail.item_tax_template_detail import (
|
|
||||||
ItemTaxTemplateDetail,
|
|
||||||
)
|
|
||||||
|
|
||||||
company: DF.Link
|
|
||||||
disabled: DF.Check
|
|
||||||
taxes: DF.Table[ItemTaxTemplateDetail]
|
|
||||||
title: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_tax_accounts()
|
self.validate_tax_accounts()
|
||||||
|
|
||||||
|
|||||||
@@ -6,19 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class ItemTaxTemplateDetail(Document):
|
class ItemTaxTemplateDetail(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
tax_rate: DF.Float
|
|
||||||
tax_type: DF.Link
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ frappe.provide("erpnext.journal_entry");
|
|||||||
frappe.ui.form.on("Journal Entry", {
|
frappe.ui.form.on("Journal Entry", {
|
||||||
setup: function(frm) {
|
setup: function(frm) {
|
||||||
frm.add_fetch("bank_account", "account", "account");
|
frm.add_fetch("bank_account", "account", "account");
|
||||||
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', "Repost Payment Ledger", 'Asset', 'Asset Movement', 'Asset Depreciation Schedule', "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries"];
|
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', "Repost Payment Ledger", 'Asset', 'Asset Movement', 'Asset Depreciation Schedule', "Repost Accounting Ledger"];
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
@@ -51,7 +51,7 @@ frappe.ui.form.on("Journal Entry", {
|
|||||||
}, __('Make'));
|
}, __('Make'));
|
||||||
}
|
}
|
||||||
|
|
||||||
erpnext.accounts.unreconcile_payment.add_unreconcile_btn(frm);
|
erpnext.accounts.unreconcile_payments.add_unreconcile_btn(frm);
|
||||||
},
|
},
|
||||||
before_save: function(frm) {
|
before_save: function(frm) {
|
||||||
if ((frm.doc.docstatus == 0) && (!frm.doc.is_system_generated)) {
|
if ((frm.doc.docstatus == 0) && (!frm.doc.is_system_generated)) {
|
||||||
|
|||||||
@@ -548,16 +548,8 @@
|
|||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 176,
|
"idx": 176,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [
|
"links": [],
|
||||||
{
|
"modified": "2023-08-10 14:32:22.366895",
|
||||||
"is_child_table": 1,
|
|
||||||
"link_doctype": "Bank Transaction Payments",
|
|
||||||
"link_fieldname": "payment_entry",
|
|
||||||
"parent_doctype": "Bank Transaction",
|
|
||||||
"table_fieldname": "payment_entries"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"modified": "2023-11-23 12:11:04.128015",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Journal Entry",
|
"name": "Journal Entry",
|
||||||
|
|||||||
@@ -35,78 +35,6 @@ class StockAccountInvalidTransaction(frappe.ValidationError):
|
|||||||
|
|
||||||
|
|
||||||
class JournalEntry(AccountsController):
|
class JournalEntry(AccountsController):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.journal_entry_account.journal_entry_account import (
|
|
||||||
JournalEntryAccount,
|
|
||||||
)
|
|
||||||
|
|
||||||
accounts: DF.Table[JournalEntryAccount]
|
|
||||||
amended_from: DF.Link | None
|
|
||||||
apply_tds: DF.Check
|
|
||||||
auto_repeat: DF.Link | None
|
|
||||||
bill_date: DF.Date | None
|
|
||||||
bill_no: DF.Data | None
|
|
||||||
cheque_date: DF.Date | None
|
|
||||||
cheque_no: DF.Data | None
|
|
||||||
clearance_date: DF.Date | None
|
|
||||||
company: DF.Link
|
|
||||||
difference: DF.Currency
|
|
||||||
due_date: DF.Date | None
|
|
||||||
finance_book: DF.Link | None
|
|
||||||
from_template: DF.Link | None
|
|
||||||
inter_company_journal_entry_reference: DF.Link | None
|
|
||||||
is_opening: DF.Literal["No", "Yes"]
|
|
||||||
is_system_generated: DF.Check
|
|
||||||
letter_head: DF.Link | None
|
|
||||||
mode_of_payment: DF.Link | None
|
|
||||||
multi_currency: DF.Check
|
|
||||||
naming_series: DF.Literal["ACC-JV-.YYYY.-"]
|
|
||||||
paid_loan: DF.Data | None
|
|
||||||
pay_to_recd_from: DF.Data | None
|
|
||||||
payment_order: DF.Link | None
|
|
||||||
posting_date: DF.Date
|
|
||||||
process_deferred_accounting: DF.Link | None
|
|
||||||
remark: DF.SmallText | None
|
|
||||||
reversal_of: DF.Link | None
|
|
||||||
select_print_heading: DF.Link | None
|
|
||||||
stock_entry: DF.Link | None
|
|
||||||
tax_withholding_category: DF.Link | None
|
|
||||||
title: DF.Data | None
|
|
||||||
total_amount: DF.Currency
|
|
||||||
total_amount_currency: DF.Link | None
|
|
||||||
total_amount_in_words: DF.Data | None
|
|
||||||
total_credit: DF.Currency
|
|
||||||
total_debit: DF.Currency
|
|
||||||
user_remark: DF.SmallText | None
|
|
||||||
voucher_type: DF.Literal[
|
|
||||||
"Journal Entry",
|
|
||||||
"Inter Company Journal Entry",
|
|
||||||
"Bank Entry",
|
|
||||||
"Cash Entry",
|
|
||||||
"Credit Card Entry",
|
|
||||||
"Debit Note",
|
|
||||||
"Credit Note",
|
|
||||||
"Contra Entry",
|
|
||||||
"Excise Entry",
|
|
||||||
"Write Off Entry",
|
|
||||||
"Opening Entry",
|
|
||||||
"Depreciation Entry",
|
|
||||||
"Exchange Rate Revaluation",
|
|
||||||
"Exchange Gain Or Loss",
|
|
||||||
"Deferred Revenue",
|
|
||||||
"Deferred Expense",
|
|
||||||
]
|
|
||||||
write_off_amount: DF.Currency
|
|
||||||
write_off_based_on: DF.Literal["Accounts Receivable", "Accounts Payable"]
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(JournalEntry, self).__init__(*args, **kwargs)
|
super(JournalEntry, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
@@ -170,8 +98,6 @@ class JournalEntry(AccountsController):
|
|||||||
"Repost Payment Ledger Items",
|
"Repost Payment Ledger Items",
|
||||||
"Repost Accounting Ledger",
|
"Repost Accounting Ledger",
|
||||||
"Repost Accounting Ledger Items",
|
"Repost Accounting Ledger Items",
|
||||||
"Unreconcile Payment",
|
|
||||||
"Unreconcile Payment Entries",
|
|
||||||
)
|
)
|
||||||
self.make_gl_entries(1)
|
self.make_gl_entries(1)
|
||||||
self.update_advance_paid()
|
self.update_advance_paid()
|
||||||
@@ -582,7 +508,7 @@ class JournalEntry(AccountsController):
|
|||||||
).format(d.reference_name, d.account)
|
).format(d.reference_name, d.account)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
dr_or_cr = "debit" if flt(d.credit) > 0 else "credit"
|
dr_or_cr = "debit" if d.credit > 0 else "credit"
|
||||||
valid = False
|
valid = False
|
||||||
for jvd in against_entries:
|
for jvd in against_entries:
|
||||||
if flt(jvd[dr_or_cr]) > 0:
|
if flt(jvd[dr_or_cr]) > 0:
|
||||||
@@ -942,7 +868,7 @@ class JournalEntry(AccountsController):
|
|||||||
party_account_currency = d.account_currency
|
party_account_currency = d.account_currency
|
||||||
|
|
||||||
elif frappe.get_cached_value("Account", d.account, "account_type") in ["Bank", "Cash"]:
|
elif frappe.get_cached_value("Account", d.account, "account_type") in ["Bank", "Cash"]:
|
||||||
bank_amount += flt(d.debit_in_account_currency) or flt(d.credit_in_account_currency)
|
bank_amount += d.debit_in_account_currency or d.credit_in_account_currency
|
||||||
bank_account_currency = d.account_currency
|
bank_account_currency = d.account_currency
|
||||||
|
|
||||||
if party_type and pay_to_recd_from:
|
if party_type and pay_to_recd_from:
|
||||||
|
|||||||
@@ -1,94 +1,97 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"cheque_date": "2013-03-14",
|
"cheque_date": "2013-03-14",
|
||||||
"cheque_no": "33",
|
"cheque_no": "33",
|
||||||
"company": "_Test Company",
|
"company": "_Test Company",
|
||||||
"doctype": "Journal Entry",
|
"doctype": "Journal Entry",
|
||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"account": "Debtors - _TC",
|
"account": "Debtors - _TC",
|
||||||
"party_type": "Customer",
|
"party_type": "Customer",
|
||||||
"party": "_Test Customer",
|
"party": "_Test Customer",
|
||||||
"credit_in_account_currency": 400.0,
|
"credit_in_account_currency": 400.0,
|
||||||
"debit_in_account_currency": 0.0,
|
"debit_in_account_currency": 0.0,
|
||||||
"doctype": "Journal Entry Account",
|
"doctype": "Journal Entry Account",
|
||||||
"parentfield": "accounts",
|
"parentfield": "accounts",
|
||||||
"cost_center": "_Test Cost Center - _TC"
|
"cost_center": "_Test Cost Center - _TC"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"account": "_Test Bank - _TC",
|
"account": "_Test Bank - _TC",
|
||||||
"credit_in_account_currency": 0.0,
|
"credit_in_account_currency": 0.0,
|
||||||
"debit_in_account_currency": 400.0,
|
"debit_in_account_currency": 400.0,
|
||||||
"doctype": "Journal Entry Account",
|
"doctype": "Journal Entry Account",
|
||||||
"parentfield": "accounts",
|
"parentfield": "accounts",
|
||||||
"cost_center": "_Test Cost Center - _TC"
|
"cost_center": "_Test Cost Center - _TC"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"naming_series": "_T-Journal Entry-",
|
"naming_series": "_T-Journal Entry-",
|
||||||
"posting_date": "2013-02-14",
|
"posting_date": "2013-02-14",
|
||||||
"user_remark": "test",
|
"user_remark": "test",
|
||||||
"voucher_type": "Bank Entry"
|
"voucher_type": "Bank Entry"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
|
||||||
"cheque_date": "2013-02-14",
|
{
|
||||||
"cheque_no": "33",
|
"cheque_date": "2013-02-14",
|
||||||
"company": "_Test Company",
|
"cheque_no": "33",
|
||||||
"doctype": "Journal Entry",
|
"company": "_Test Company",
|
||||||
"accounts": [
|
"doctype": "Journal Entry",
|
||||||
{
|
"accounts": [
|
||||||
"account": "_Test Payable - _TC",
|
{
|
||||||
"party_type": "Supplier",
|
"account": "_Test Payable - _TC",
|
||||||
"party": "_Test Supplier",
|
"party_type": "Supplier",
|
||||||
"credit_in_account_currency": 0.0,
|
"party": "_Test Supplier",
|
||||||
"debit_in_account_currency": 400.0,
|
"credit_in_account_currency": 0.0,
|
||||||
"doctype": "Journal Entry Account",
|
"debit_in_account_currency": 400.0,
|
||||||
"parentfield": "accounts",
|
"doctype": "Journal Entry Account",
|
||||||
"cost_center": "_Test Cost Center - _TC"
|
"parentfield": "accounts",
|
||||||
},
|
"cost_center": "_Test Cost Center - _TC"
|
||||||
{
|
},
|
||||||
"account": "_Test Bank - _TC",
|
{
|
||||||
"credit_in_account_currency": 400.0,
|
"account": "_Test Bank - _TC",
|
||||||
"debit_in_account_currency": 0.0,
|
"credit_in_account_currency": 400.0,
|
||||||
"doctype": "Journal Entry Account",
|
"debit_in_account_currency": 0.0,
|
||||||
"parentfield": "accounts",
|
"doctype": "Journal Entry Account",
|
||||||
"cost_center": "_Test Cost Center - _TC"
|
"parentfield": "accounts",
|
||||||
}
|
"cost_center": "_Test Cost Center - _TC"
|
||||||
],
|
}
|
||||||
"naming_series": "_T-Journal Entry-",
|
],
|
||||||
"posting_date": "2013-02-14",
|
"naming_series": "_T-Journal Entry-",
|
||||||
"user_remark": "test",
|
"posting_date": "2013-02-14",
|
||||||
"voucher_type": "Bank Entry"
|
"user_remark": "test",
|
||||||
},
|
"voucher_type": "Bank Entry"
|
||||||
|
},
|
||||||
{
|
|
||||||
"cheque_date": "2013-02-14",
|
|
||||||
"cheque_no": "33",
|
{
|
||||||
"company": "_Test Company",
|
"cheque_date": "2013-02-14",
|
||||||
"doctype": "Journal Entry",
|
"cheque_no": "33",
|
||||||
"accounts": [
|
"company": "_Test Company",
|
||||||
{
|
"doctype": "Journal Entry",
|
||||||
"account": "Debtors - _TC",
|
"accounts": [
|
||||||
"party_type": "Customer",
|
{
|
||||||
"party": "_Test Customer",
|
"account": "Debtors - _TC",
|
||||||
"credit_in_account_currency": 0.0,
|
"party_type": "Customer",
|
||||||
"debit_in_account_currency": 400.0,
|
"party": "_Test Customer",
|
||||||
"doctype": "Journal Entry Account",
|
"credit_in_account_currency": 0.0,
|
||||||
"parentfield": "accounts",
|
"debit_in_account_currency": 400.0,
|
||||||
"cost_center": "_Test Cost Center - _TC"
|
"doctype": "Journal Entry Account",
|
||||||
},
|
"parentfield": "accounts",
|
||||||
{
|
"cost_center": "_Test Cost Center - _TC"
|
||||||
"account": "Sales - _TC",
|
},
|
||||||
"credit_in_account_currency": 400.0,
|
{
|
||||||
"debit_in_account_currency": 0.0,
|
"account": "Sales - _TC",
|
||||||
"doctype": "Journal Entry Account",
|
"cost_center": "_Test Cost Center - _TC",
|
||||||
"parentfield": "accounts",
|
"credit_in_account_currency": 400.0,
|
||||||
"cost_center": "_Test Cost Center - _TC"
|
"debit_in_account_currency": 0.0,
|
||||||
}
|
"doctype": "Journal Entry Account",
|
||||||
],
|
"parentfield": "accounts",
|
||||||
"naming_series": "_T-Journal Entry-",
|
"cost_center": "_Test Cost Center - _TC"
|
||||||
"posting_date": "2013-02-14",
|
}
|
||||||
"user_remark": "test",
|
],
|
||||||
"voucher_type": "Bank Entry"
|
"naming_series": "_T-Journal Entry-",
|
||||||
}
|
"posting_date": "2013-02-14",
|
||||||
|
"user_remark": "test",
|
||||||
|
"voucher_type": "Bank Entry"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -203,8 +203,7 @@
|
|||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Reference Type",
|
"label": "Reference Type",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "\nSales Invoice\nPurchase Invoice\nJournal Entry\nSales Order\nPurchase Order\nExpense Claim\nAsset\nLoan\nPayroll Entry\nEmployee Advance\nExchange Rate Revaluation\nInvoice Discounting\nFees\nFull and Final Statement\nPayment Entry",
|
"options": "\nSales Invoice\nPurchase Invoice\nJournal Entry\nSales Order\nPurchase Order\nExpense Claim\nAsset\nLoan\nPayroll Entry\nEmployee Advance\nExchange Rate Revaluation\nInvoice Discounting\nFees\nFull and Final Statement\nPayment Entry"
|
||||||
"search_index": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "reference_name",
|
"fieldname": "reference_name",
|
||||||
@@ -212,8 +211,7 @@
|
|||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Reference Name",
|
"label": "Reference Name",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "reference_type",
|
"options": "reference_type"
|
||||||
"search_index": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.reference_type&&!in_list(doc.reference_type, ['Expense Claim', 'Asset', 'Employee Loan', 'Employee Advance'])",
|
"depends_on": "eval:doc.reference_type&&!in_list(doc.reference_type, ['Expense Claim', 'Asset', 'Employee Loan', 'Employee Advance'])",
|
||||||
@@ -280,14 +278,13 @@
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Reference Detail No",
|
"label": "Reference Detail No",
|
||||||
"no_copy": 1,
|
"no_copy": 1
|
||||||
"search_index": 1
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-11-23 11:44:25.841187",
|
"modified": "2023-06-16 14:11:13.507807",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Journal Entry Account",
|
"name": "Journal Entry Account",
|
||||||
|
|||||||
@@ -6,56 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class JournalEntryAccount(Document):
|
class JournalEntryAccount(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
account: DF.Link
|
|
||||||
account_currency: DF.Link | None
|
|
||||||
account_type: DF.Data | None
|
|
||||||
against_account: DF.Text | None
|
|
||||||
balance: DF.Currency
|
|
||||||
bank_account: DF.Link | None
|
|
||||||
cost_center: DF.Link | None
|
|
||||||
credit: DF.Currency
|
|
||||||
credit_in_account_currency: DF.Currency
|
|
||||||
debit: DF.Currency
|
|
||||||
debit_in_account_currency: DF.Currency
|
|
||||||
exchange_rate: DF.Float
|
|
||||||
is_advance: DF.Literal["No", "Yes"]
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
party: DF.DynamicLink | None
|
|
||||||
party_balance: DF.Currency
|
|
||||||
party_type: DF.Link | None
|
|
||||||
project: DF.Link | None
|
|
||||||
reference_detail_no: DF.Data | None
|
|
||||||
reference_due_date: DF.Date | None
|
|
||||||
reference_name: DF.DynamicLink | None
|
|
||||||
reference_type: DF.Literal[
|
|
||||||
"",
|
|
||||||
"Sales Invoice",
|
|
||||||
"Purchase Invoice",
|
|
||||||
"Journal Entry",
|
|
||||||
"Sales Order",
|
|
||||||
"Purchase Order",
|
|
||||||
"Expense Claim",
|
|
||||||
"Asset",
|
|
||||||
"Loan",
|
|
||||||
"Payroll Entry",
|
|
||||||
"Employee Advance",
|
|
||||||
"Exchange Rate Revaluation",
|
|
||||||
"Invoice Discounting",
|
|
||||||
"Fees",
|
|
||||||
"Full and Final Statement",
|
|
||||||
"Payment Entry",
|
|
||||||
]
|
|
||||||
user_remark: DF.SmallText | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -7,41 +7,6 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class JournalEntryTemplate(Document):
|
class JournalEntryTemplate(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.journal_entry_template_account.journal_entry_template_account import (
|
|
||||||
JournalEntryTemplateAccount,
|
|
||||||
)
|
|
||||||
|
|
||||||
accounts: DF.Table[JournalEntryTemplateAccount]
|
|
||||||
company: DF.Link
|
|
||||||
is_opening: DF.Literal["No", "Yes"]
|
|
||||||
multi_currency: DF.Check
|
|
||||||
naming_series: DF.Literal
|
|
||||||
template_title: DF.Data
|
|
||||||
voucher_type: DF.Literal[
|
|
||||||
"Journal Entry",
|
|
||||||
"Inter Company Journal Entry",
|
|
||||||
"Bank Entry",
|
|
||||||
"Cash Entry",
|
|
||||||
"Credit Card Entry",
|
|
||||||
"Debit Note",
|
|
||||||
"Credit Note",
|
|
||||||
"Contra Entry",
|
|
||||||
"Excise Entry",
|
|
||||||
"Write Off Entry",
|
|
||||||
"Opening Entry",
|
|
||||||
"Depreciation Entry",
|
|
||||||
"Exchange Rate Revaluation",
|
|
||||||
]
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,18 +7,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class JournalEntryTemplateAccount(Document):
|
class JournalEntryTemplateAccount(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
account: DF.Link
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -10,27 +10,6 @@ from erpnext.accounts.doctype.account.account import merge_account
|
|||||||
|
|
||||||
|
|
||||||
class LedgerMerge(Document):
|
class LedgerMerge(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.ledger_merge_accounts.ledger_merge_accounts import (
|
|
||||||
LedgerMergeAccounts,
|
|
||||||
)
|
|
||||||
|
|
||||||
account: DF.Link
|
|
||||||
account_name: DF.Data
|
|
||||||
company: DF.Link
|
|
||||||
is_group: DF.Check
|
|
||||||
merge_accounts: DF.Table[LedgerMergeAccounts]
|
|
||||||
root_type: DF.Literal["", "Asset", "Liability", "Income", "Expense", "Equity"]
|
|
||||||
status: DF.Literal["Pending", "Success", "Partial Success", "Error"]
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def start_merge(self):
|
def start_merge(self):
|
||||||
from frappe.utils.background_jobs import enqueue
|
from frappe.utils.background_jobs import enqueue
|
||||||
from frappe.utils.scheduler import is_scheduler_inactive
|
from frappe.utils.scheduler import is_scheduler_inactive
|
||||||
|
|||||||
@@ -6,20 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class LedgerMergeAccounts(Document):
|
class LedgerMergeAccounts(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
account: DF.Link
|
|
||||||
account_name: DF.Data
|
|
||||||
merged: DF.Check
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -10,27 +10,6 @@ exclude_from_linked_with = True
|
|||||||
|
|
||||||
|
|
||||||
class LoyaltyPointEntry(Document):
|
class LoyaltyPointEntry(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
company: DF.Link | None
|
|
||||||
customer: DF.Link | None
|
|
||||||
expiry_date: DF.Date | None
|
|
||||||
invoice: DF.DynamicLink | None
|
|
||||||
invoice_type: DF.Link | None
|
|
||||||
loyalty_points: DF.Int
|
|
||||||
loyalty_program: DF.Link | None
|
|
||||||
loyalty_program_tier: DF.Data | None
|
|
||||||
posting_date: DF.Date | None
|
|
||||||
purchase_amount: DF.Currency
|
|
||||||
redeem_against: DF.Link | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,20 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class LoyaltyPointEntryRedemption(Document):
|
class LoyaltyPointEntryRedemption(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
redeemed_points: DF.Int
|
|
||||||
redemption_date: DF.Date | None
|
|
||||||
sales_invoice: DF.Data | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -9,33 +9,6 @@ from frappe.utils import flt, today
|
|||||||
|
|
||||||
|
|
||||||
class LoyaltyProgram(Document):
|
class LoyaltyProgram(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.loyalty_program_collection.loyalty_program_collection import (
|
|
||||||
LoyaltyProgramCollection,
|
|
||||||
)
|
|
||||||
|
|
||||||
auto_opt_in: DF.Check
|
|
||||||
collection_rules: DF.Table[LoyaltyProgramCollection]
|
|
||||||
company: DF.Link | None
|
|
||||||
conversion_factor: DF.Float
|
|
||||||
cost_center: DF.Link | None
|
|
||||||
customer_group: DF.Link | None
|
|
||||||
customer_territory: DF.Link | None
|
|
||||||
expense_account: DF.Link | None
|
|
||||||
expiry_duration: DF.Int
|
|
||||||
from_date: DF.Date
|
|
||||||
loyalty_program_name: DF.Data
|
|
||||||
loyalty_program_type: DF.Literal["Single Tier Program", "Multiple Tier Program"]
|
|
||||||
to_date: DF.Date | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,20 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class LoyaltyProgramCollection(Document):
|
class LoyaltyProgramCollection(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
collection_factor: DF.Currency
|
|
||||||
min_spent: DF.Currency
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
tier_name: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -8,24 +8,6 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class ModeofPayment(Document):
|
class ModeofPayment(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.mode_of_payment_account.mode_of_payment_account import (
|
|
||||||
ModeofPaymentAccount,
|
|
||||||
)
|
|
||||||
|
|
||||||
accounts: DF.Table[ModeofPaymentAccount]
|
|
||||||
enabled: DF.Check
|
|
||||||
mode_of_payment: DF.Data
|
|
||||||
type: DF.Literal["Cash", "Bank", "General", "Phone"]
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_accounts()
|
self.validate_accounts()
|
||||||
self.validate_repeating_companies()
|
self.validate_repeating_companies()
|
||||||
|
|||||||
@@ -6,19 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class ModeofPaymentAccount(Document):
|
class ModeofPaymentAccount(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
company: DF.Link | None
|
|
||||||
default_account: DF.Link | None
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -9,23 +9,6 @@ from frappe.utils import add_months, flt
|
|||||||
|
|
||||||
|
|
||||||
class MonthlyDistribution(Document):
|
class MonthlyDistribution(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.monthly_distribution_percentage.monthly_distribution_percentage import (
|
|
||||||
MonthlyDistributionPercentage,
|
|
||||||
)
|
|
||||||
|
|
||||||
distribution_id: DF.Data
|
|
||||||
fiscal_year: DF.Link | None
|
|
||||||
percentages: DF.Table[MonthlyDistributionPercentage]
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_months(self):
|
def get_months(self):
|
||||||
month_list = [
|
month_list = [
|
||||||
|
|||||||
@@ -6,19 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class MonthlyDistributionPercentage(Document):
|
class MonthlyDistributionPercentage(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
month: DF.Data
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
percentage_allocation: DF.Float
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -14,25 +14,6 @@ from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
|
|||||||
|
|
||||||
|
|
||||||
class OpeningInvoiceCreationTool(Document):
|
class OpeningInvoiceCreationTool(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.opening_invoice_creation_tool_item.opening_invoice_creation_tool_item import (
|
|
||||||
OpeningInvoiceCreationToolItem,
|
|
||||||
)
|
|
||||||
|
|
||||||
company: DF.Link
|
|
||||||
cost_center: DF.Link | None
|
|
||||||
create_missing_party: DF.Check
|
|
||||||
invoice_type: DF.Literal["Sales", "Purchase"]
|
|
||||||
invoices: DF.Table[OpeningInvoiceCreationToolItem]
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def onload(self):
|
def onload(self):
|
||||||
"""Load the Opening Invoice summary"""
|
"""Load the Opening Invoice summary"""
|
||||||
summary, max_count = self.get_opening_invoice_summary()
|
summary, max_count = self.get_opening_invoice_summary()
|
||||||
|
|||||||
@@ -6,27 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class OpeningInvoiceCreationToolItem(Document):
|
class OpeningInvoiceCreationToolItem(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
cost_center: DF.Link | None
|
|
||||||
due_date: DF.Date | None
|
|
||||||
invoice_number: DF.Data | None
|
|
||||||
item_name: DF.Data | None
|
|
||||||
outstanding_amount: DF.Currency
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
party: DF.DynamicLink
|
|
||||||
party_type: DF.Link | None
|
|
||||||
posting_date: DF.Date | None
|
|
||||||
qty: DF.Data | None
|
|
||||||
temporary_opening_account: DF.Link | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -6,31 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class OverduePayment(Document):
|
class OverduePayment(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
description: DF.SmallText | None
|
|
||||||
discounted_amount: DF.Currency
|
|
||||||
due_date: DF.Date | None
|
|
||||||
dunning_level: DF.Int
|
|
||||||
interest: DF.Currency
|
|
||||||
invoice_portion: DF.Percent
|
|
||||||
mode_of_payment: DF.Link | None
|
|
||||||
outstanding: DF.Currency
|
|
||||||
overdue_days: DF.Data | None
|
|
||||||
paid_amount: DF.Currency
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
payment_amount: DF.Currency
|
|
||||||
payment_schedule: DF.Data | None
|
|
||||||
payment_term: DF.Link | None
|
|
||||||
sales_invoice: DF.Link
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -6,20 +6,4 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class PartyAccount(Document):
|
class PartyAccount(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
account: DF.Link | None
|
|
||||||
advance_account: DF.Link | None
|
|
||||||
company: DF.Link
|
|
||||||
parent: DF.Data
|
|
||||||
parentfield: DF.Data
|
|
||||||
parenttype: DF.Data
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -7,20 +7,6 @@ from frappe.model.document import Document
|
|||||||
|
|
||||||
|
|
||||||
class PartyLink(Document):
|
class PartyLink(Document):
|
||||||
# begin: auto-generated types
|
|
||||||
# This code is auto-generated. Do not modify anything in this block.
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from frappe.types import DF
|
|
||||||
|
|
||||||
primary_party: DF.DynamicLink | None
|
|
||||||
primary_role: DF.Link
|
|
||||||
secondary_party: DF.DynamicLink | None
|
|
||||||
secondary_role: DF.Link | None
|
|
||||||
# end: auto-generated types
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
if self.primary_role not in ["Customer", "Supplier"]:
|
if self.primary_role not in ["Customer", "Supplier"]:
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ erpnext.accounts.taxes.setup_tax_filters("Advance Taxes and Charges");
|
|||||||
|
|
||||||
frappe.ui.form.on('Payment Entry', {
|
frappe.ui.form.on('Payment Entry', {
|
||||||
onload: function(frm) {
|
onload: function(frm) {
|
||||||
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', 'Repost Payment Ledger','Repost Accounting Ledger', 'Unreconcile Payment', 'Unreconcile Payment Entries'];
|
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', 'Repost Payment Ledger','Repost Accounting Ledger', 'Unreconcile Payments', 'Unreconcile Payment Entries'];
|
||||||
|
|
||||||
if(frm.doc.__islocal) {
|
if(frm.doc.__islocal) {
|
||||||
if (!frm.doc.paid_from) frm.set_value("paid_from_account_currency", null);
|
if (!frm.doc.paid_from) frm.set_value("paid_from_account_currency", null);
|
||||||
@@ -154,13 +154,13 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
frm.events.set_dynamic_labels(frm);
|
frm.events.set_dynamic_labels(frm);
|
||||||
frm.events.show_general_ledger(frm);
|
frm.events.show_general_ledger(frm);
|
||||||
erpnext.accounts.ledger_preview.show_accounting_ledger_preview(frm);
|
erpnext.accounts.ledger_preview.show_accounting_ledger_preview(frm);
|
||||||
if((frm.doc.references) && (frm.doc.references.find((elem) => {return elem.exchange_gain_loss != 0}))) {
|
if(frm.doc.references.find((elem) => {return elem.exchange_gain_loss != 0})) {
|
||||||
frm.add_custom_button(__("View Exchange Gain/Loss Journals"), function() {
|
frm.add_custom_button(__("View Exchange Gain/Loss Journals"), function() {
|
||||||
frappe.set_route("List", "Journal Entry", {"voucher_type": "Exchange Gain Or Loss", "reference_name": frm.doc.name});
|
frappe.set_route("List", "Journal Entry", {"voucher_type": "Exchange Gain Or Loss", "reference_name": frm.doc.name});
|
||||||
}, __('Actions'));
|
}, __('Actions'));
|
||||||
|
|
||||||
}
|
}
|
||||||
erpnext.accounts.unreconcile_payment.add_unreconcile_btn(frm);
|
erpnext.accounts.unreconcile_payments.add_unreconcile_btn(frm);
|
||||||
},
|
},
|
||||||
|
|
||||||
validate_company: (frm) => {
|
validate_company: (frm) => {
|
||||||
@@ -853,7 +853,6 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
|
|
||||||
var allocated_positive_outstanding = paid_amount + allocated_negative_outstanding;
|
var allocated_positive_outstanding = paid_amount + allocated_negative_outstanding;
|
||||||
} else if (in_list(["Customer", "Supplier"], frm.doc.party_type)) {
|
} else if (in_list(["Customer", "Supplier"], frm.doc.party_type)) {
|
||||||
total_negative_outstanding = flt(total_negative_outstanding, precision("outstanding_amount"))
|
|
||||||
if(paid_amount > total_negative_outstanding) {
|
if(paid_amount > total_negative_outstanding) {
|
||||||
if(total_negative_outstanding == 0) {
|
if(total_negative_outstanding == 0) {
|
||||||
frappe.msgprint(
|
frappe.msgprint(
|
||||||
|
|||||||
@@ -595,7 +595,6 @@
|
|||||||
"fieldname": "status",
|
"fieldname": "status",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Status",
|
"label": "Status",
|
||||||
"no_copy": 1,
|
|
||||||
"options": "\nDraft\nSubmitted\nCancelled",
|
"options": "\nDraft\nSubmitted\nCancelled",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
@@ -750,16 +749,8 @@
|
|||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [
|
"links": [],
|
||||||
{
|
"modified": "2023-06-23 18:07:38.023010",
|
||||||
"is_child_table": 1,
|
|
||||||
"link_doctype": "Bank Transaction Payments",
|
|
||||||
"link_fieldname": "payment_entry",
|
|
||||||
"parent_doctype": "Bank Transaction",
|
|
||||||
"table_fieldname": "payment_entries"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"modified": "2023-11-23 12:07:20.887885",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Entry",
|
"name": "Payment Entry",
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ import frappe
|
|||||||
from frappe import ValidationError, _, qb, scrub, throw
|
from frappe import ValidationError, _, qb, scrub, throw
|
||||||
from frappe.utils import cint, comma_or, flt, getdate, nowdate
|
from frappe.utils import cint, comma_or, flt, getdate, nowdate
|
||||||
from frappe.utils.data import comma_and, fmt_money
|
from frappe.utils.data import comma_and, fmt_money
|
||||||
from pypika import Case
|
|
||||||
from pypika.functions import Coalesce, Sum
|
|
||||||
|
|
||||||
import erpnext
|
import erpnext
|
||||||
from erpnext.accounts.doctype.bank_account.bank_account import (
|
from erpnext.accounts.doctype.bank_account.bank_account import (
|
||||||
@@ -35,7 +33,6 @@ from erpnext.accounts.utils import (
|
|||||||
get_account_currency,
|
get_account_currency,
|
||||||
get_balance_on,
|
get_balance_on,
|
||||||
get_outstanding_invoices,
|
get_outstanding_invoices,
|
||||||
get_party_types_from_account_type,
|
|
||||||
)
|
)
|
||||||
from erpnext.controllers.accounts_controller import (
|
from erpnext.controllers.accounts_controller import (
|
||||||
AccountsController,
|
AccountsController,
|
||||||
@@ -86,6 +83,7 @@ class PaymentEntry(AccountsController):
|
|||||||
self.apply_taxes()
|
self.apply_taxes()
|
||||||
self.set_amounts_after_tax()
|
self.set_amounts_after_tax()
|
||||||
self.clear_unallocated_reference_document_rows()
|
self.clear_unallocated_reference_document_rows()
|
||||||
|
self.validate_payment_against_negative_invoice()
|
||||||
self.validate_transaction_reference()
|
self.validate_transaction_reference()
|
||||||
self.set_title()
|
self.set_title()
|
||||||
self.set_remarks()
|
self.set_remarks()
|
||||||
@@ -106,17 +104,9 @@ class PaymentEntry(AccountsController):
|
|||||||
self.set_status()
|
self.set_status()
|
||||||
|
|
||||||
def set_liability_account(self):
|
def set_liability_account(self):
|
||||||
# Auto setting liability account should only be done during 'draft' status
|
if not self.book_advance_payments_in_separate_party_account:
|
||||||
if self.docstatus > 0:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if not frappe.db.get_value(
|
|
||||||
"Company", self.company, "book_advance_payments_in_separate_party_account"
|
|
||||||
):
|
|
||||||
return
|
|
||||||
|
|
||||||
# Important to set this flag for the gl building logic to work properly
|
|
||||||
self.book_advance_payments_in_separate_party_account = True
|
|
||||||
account_type = frappe.get_value(
|
account_type = frappe.get_value(
|
||||||
"Account", {"name": self.party_account, "company": self.company}, "account_type"
|
"Account", {"name": self.party_account, "company": self.company}, "account_type"
|
||||||
)
|
)
|
||||||
@@ -126,13 +116,11 @@ class PaymentEntry(AccountsController):
|
|||||||
):
|
):
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.references:
|
if self.unallocated_amount == 0:
|
||||||
allowed_types = frozenset(["Sales Order", "Purchase Order"])
|
for d in self.references:
|
||||||
reference_types = set([x.reference_doctype for x in self.references])
|
if d.reference_doctype in ["Sales Order", "Purchase Order"]:
|
||||||
|
break
|
||||||
# If there are referencers other than `allowed_types`, treat this as a normal payment entry
|
else:
|
||||||
if reference_types - allowed_types:
|
|
||||||
self.book_advance_payments_in_separate_party_account = False
|
|
||||||
return
|
return
|
||||||
|
|
||||||
liability_account = get_party_account(
|
liability_account = get_party_account(
|
||||||
@@ -160,7 +148,7 @@ class PaymentEntry(AccountsController):
|
|||||||
"Repost Payment Ledger Items",
|
"Repost Payment Ledger Items",
|
||||||
"Repost Accounting Ledger",
|
"Repost Accounting Ledger",
|
||||||
"Repost Accounting Ledger Items",
|
"Repost Accounting Ledger Items",
|
||||||
"Unreconcile Payment",
|
"Unreconcile Payments",
|
||||||
"Unreconcile Payment Entries",
|
"Unreconcile Payment Entries",
|
||||||
)
|
)
|
||||||
super(PaymentEntry, self).on_cancel()
|
super(PaymentEntry, self).on_cancel()
|
||||||
@@ -964,6 +952,35 @@ class PaymentEntry(AccountsController):
|
|||||||
self.name,
|
self.name,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def validate_payment_against_negative_invoice(self):
|
||||||
|
if (self.payment_type != "Pay" or self.party_type != "Customer") and (
|
||||||
|
self.payment_type != "Receive" or self.party_type != "Supplier"
|
||||||
|
):
|
||||||
|
return
|
||||||
|
|
||||||
|
total_negative_outstanding = sum(
|
||||||
|
abs(flt(d.outstanding_amount)) for d in self.get("references") if flt(d.outstanding_amount) < 0
|
||||||
|
)
|
||||||
|
|
||||||
|
paid_amount = self.paid_amount if self.payment_type == "Receive" else self.received_amount
|
||||||
|
additional_charges = sum(flt(d.amount) for d in self.deductions)
|
||||||
|
|
||||||
|
if not total_negative_outstanding:
|
||||||
|
if self.party_type == "Customer":
|
||||||
|
msg = _("Cannot pay to Customer without any negative outstanding invoice")
|
||||||
|
else:
|
||||||
|
msg = _("Cannot receive from Supplier without any negative outstanding invoice")
|
||||||
|
|
||||||
|
frappe.throw(msg, InvalidPaymentEntry)
|
||||||
|
|
||||||
|
elif paid_amount - additional_charges > total_negative_outstanding:
|
||||||
|
frappe.throw(
|
||||||
|
_("Paid Amount cannot be greater than total negative outstanding amount {0}").format(
|
||||||
|
fmt_money(total_negative_outstanding)
|
||||||
|
),
|
||||||
|
InvalidPaymentEntry,
|
||||||
|
)
|
||||||
|
|
||||||
def set_title(self):
|
def set_title(self):
|
||||||
if frappe.flags.in_import and self.title:
|
if frappe.flags.in_import and self.title:
|
||||||
# do not set title dynamically if title exists during data import.
|
# do not set title dynamically if title exists during data import.
|
||||||
@@ -1034,7 +1051,6 @@ class PaymentEntry(AccountsController):
|
|||||||
self.add_bank_gl_entries(gl_entries)
|
self.add_bank_gl_entries(gl_entries)
|
||||||
self.add_deductions_gl_entries(gl_entries)
|
self.add_deductions_gl_entries(gl_entries)
|
||||||
self.add_tax_gl_entries(gl_entries)
|
self.add_tax_gl_entries(gl_entries)
|
||||||
add_regional_gl_entries(gl_entries, self)
|
|
||||||
return gl_entries
|
return gl_entries
|
||||||
|
|
||||||
def make_gl_entries(self, cancel=0, adv_adj=0):
|
def make_gl_entries(self, cancel=0, adv_adj=0):
|
||||||
@@ -1067,105 +1083,98 @@ class PaymentEntry(AccountsController):
|
|||||||
item=self,
|
item=self,
|
||||||
)
|
)
|
||||||
|
|
||||||
dr_or_cr = "credit" if self.payment_type == "Receive" else "debit"
|
dr_or_cr = (
|
||||||
if self.book_advance_payments_in_separate_party_account:
|
"credit" if erpnext.get_party_account_type(self.party_type) == "Receivable" else "debit"
|
||||||
|
)
|
||||||
|
|
||||||
|
for d in self.get("references"):
|
||||||
|
cost_center = self.cost_center
|
||||||
|
if d.reference_doctype == "Sales Invoice" and not cost_center:
|
||||||
|
cost_center = frappe.db.get_value(d.reference_doctype, d.reference_name, "cost_center")
|
||||||
|
|
||||||
gle = party_gl_dict.copy()
|
gle = party_gl_dict.copy()
|
||||||
|
|
||||||
if self.payment_type == "Receive":
|
allocated_amount_in_company_currency = self.calculate_base_allocated_amount_for_reference(d)
|
||||||
amount = self.base_paid_amount
|
|
||||||
else:
|
if self.book_advance_payments_in_separate_party_account:
|
||||||
amount = self.base_received_amount
|
against_voucher_type = "Payment Entry"
|
||||||
|
against_voucher = self.name
|
||||||
|
else:
|
||||||
|
against_voucher_type = d.reference_doctype
|
||||||
|
against_voucher = d.reference_name
|
||||||
|
|
||||||
exchange_rate = self.get_exchange_rate()
|
|
||||||
amount_in_account_currency = amount * exchange_rate
|
|
||||||
gle.update(
|
gle.update(
|
||||||
{
|
{
|
||||||
dr_or_cr: amount,
|
dr_or_cr: allocated_amount_in_company_currency,
|
||||||
dr_or_cr + "_in_account_currency": amount_in_account_currency,
|
dr_or_cr + "_in_account_currency": d.allocated_amount,
|
||||||
"against_voucher_type": "Payment Entry",
|
"against_voucher_type": against_voucher_type,
|
||||||
"against_voucher": self.name,
|
"against_voucher": against_voucher,
|
||||||
"cost_center": self.cost_center,
|
"cost_center": cost_center,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
gl_entries.append(gle)
|
gl_entries.append(gle)
|
||||||
else:
|
|
||||||
for d in self.get("references"):
|
|
||||||
# re-defining dr_or_cr for every reference in order to avoid the last value affecting calculation of reverse
|
|
||||||
dr_or_cr = "credit" if self.payment_type == "Receive" else "debit"
|
|
||||||
cost_center = self.cost_center
|
|
||||||
if d.reference_doctype == "Sales Invoice" and not cost_center:
|
|
||||||
cost_center = frappe.db.get_value(d.reference_doctype, d.reference_name, "cost_center")
|
|
||||||
|
|
||||||
gle = party_gl_dict.copy()
|
if self.unallocated_amount:
|
||||||
|
exchange_rate = self.get_exchange_rate()
|
||||||
|
base_unallocated_amount = self.unallocated_amount * exchange_rate
|
||||||
|
|
||||||
allocated_amount_in_company_currency = self.calculate_base_allocated_amount_for_reference(d)
|
gle = party_gl_dict.copy()
|
||||||
reverse_dr_or_cr = 0
|
gle.update(
|
||||||
|
{
|
||||||
|
dr_or_cr + "_in_account_currency": self.unallocated_amount,
|
||||||
|
dr_or_cr: base_unallocated_amount,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if d.reference_doctype in ["Sales Invoice", "Purchase Invoice"]:
|
gl_entries.append(gle)
|
||||||
is_return = frappe.db.get_value(d.reference_doctype, d.reference_name, "is_return")
|
|
||||||
payable_party_types = get_party_types_from_account_type("Payable")
|
|
||||||
receivable_party_types = get_party_types_from_account_type("Receivable")
|
|
||||||
if is_return and self.party_type in receivable_party_types and (self.payment_type == "Pay"):
|
|
||||||
reverse_dr_or_cr = 1
|
|
||||||
elif (
|
|
||||||
is_return and self.party_type in payable_party_types and (self.payment_type == "Receive")
|
|
||||||
):
|
|
||||||
reverse_dr_or_cr = 1
|
|
||||||
|
|
||||||
if is_return and not reverse_dr_or_cr:
|
def make_advance_gl_entries(self, against_voucher_type=None, against_voucher=None, cancel=0):
|
||||||
dr_or_cr = "debit" if dr_or_cr == "credit" else "credit"
|
|
||||||
|
|
||||||
gle.update(
|
|
||||||
{
|
|
||||||
dr_or_cr: abs(allocated_amount_in_company_currency),
|
|
||||||
dr_or_cr + "_in_account_currency": abs(d.allocated_amount),
|
|
||||||
"against_voucher_type": d.reference_doctype,
|
|
||||||
"against_voucher": d.reference_name,
|
|
||||||
"cost_center": cost_center,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
gl_entries.append(gle)
|
|
||||||
|
|
||||||
if self.unallocated_amount:
|
|
||||||
dr_or_cr = "credit" if self.payment_type == "Receive" else "debit"
|
|
||||||
exchange_rate = self.get_exchange_rate()
|
|
||||||
base_unallocated_amount = self.unallocated_amount * exchange_rate
|
|
||||||
|
|
||||||
gle = party_gl_dict.copy()
|
|
||||||
gle.update(
|
|
||||||
{
|
|
||||||
dr_or_cr + "_in_account_currency": self.unallocated_amount,
|
|
||||||
dr_or_cr: base_unallocated_amount,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
gl_entries.append(gle)
|
|
||||||
|
|
||||||
def make_advance_gl_entries(
|
|
||||||
self, entry: object | dict = None, cancel: bool = 0, update_outstanding: str = "Yes"
|
|
||||||
):
|
|
||||||
gl_entries = []
|
|
||||||
self.add_advance_gl_entries(gl_entries, entry)
|
|
||||||
|
|
||||||
if cancel:
|
|
||||||
make_reverse_gl_entries(gl_entries, partial_cancel=True)
|
|
||||||
else:
|
|
||||||
make_gl_entries(gl_entries, update_outstanding=update_outstanding)
|
|
||||||
|
|
||||||
def add_advance_gl_entries(self, gl_entries: list, entry: object | dict | None):
|
|
||||||
"""
|
|
||||||
If 'entry' is passed, GL enties only for that reference is added.
|
|
||||||
"""
|
|
||||||
if self.book_advance_payments_in_separate_party_account:
|
if self.book_advance_payments_in_separate_party_account:
|
||||||
references = [x for x in self.get("references")]
|
gl_entries = []
|
||||||
if entry:
|
for d in self.get("references"):
|
||||||
references = [x for x in self.get("references") if x.name == entry.name]
|
if d.reference_doctype in ("Sales Invoice", "Purchase Invoice", "Journal Entry"):
|
||||||
|
if not (against_voucher_type and against_voucher) or (
|
||||||
|
d.reference_doctype == against_voucher_type and d.reference_name == against_voucher
|
||||||
|
):
|
||||||
|
self.make_invoice_liability_entry(gl_entries, d)
|
||||||
|
|
||||||
for ref in references:
|
if cancel:
|
||||||
if ref.reference_doctype in ("Sales Invoice", "Purchase Invoice", "Journal Entry"):
|
for entry in gl_entries:
|
||||||
self.add_advance_gl_for_reference(gl_entries, ref)
|
frappe.db.set_value(
|
||||||
|
"GL Entry",
|
||||||
|
{
|
||||||
|
"voucher_no": self.name,
|
||||||
|
"voucher_type": self.doctype,
|
||||||
|
"voucher_detail_no": entry.voucher_detail_no,
|
||||||
|
"against_voucher_type": entry.against_voucher_type,
|
||||||
|
"against_voucher": entry.against_voucher,
|
||||||
|
},
|
||||||
|
"is_cancelled",
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
|
||||||
def add_advance_gl_for_reference(self, gl_entries, invoice):
|
make_reverse_gl_entries(gl_entries=gl_entries, partial_cancel=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
# same reference added to payment entry
|
||||||
|
for gl_entry in gl_entries.copy():
|
||||||
|
if frappe.db.exists(
|
||||||
|
"GL Entry",
|
||||||
|
{
|
||||||
|
"account": gl_entry.account,
|
||||||
|
"voucher_type": gl_entry.voucher_type,
|
||||||
|
"voucher_no": gl_entry.voucher_no,
|
||||||
|
"voucher_detail_no": gl_entry.voucher_detail_no,
|
||||||
|
"debit": gl_entry.debit,
|
||||||
|
"credit": gl_entry.credit,
|
||||||
|
"is_cancelled": 0,
|
||||||
|
},
|
||||||
|
):
|
||||||
|
gl_entries.remove(gl_entry)
|
||||||
|
|
||||||
|
make_gl_entries(gl_entries)
|
||||||
|
|
||||||
|
def make_invoice_liability_entry(self, gl_entries, invoice):
|
||||||
args_dict = {
|
args_dict = {
|
||||||
"party_type": self.party_type,
|
"party_type": self.party_type,
|
||||||
"party": self.party,
|
"party": self.party,
|
||||||
@@ -1689,43 +1698,13 @@ def get_outstanding_reference_documents(args, validate=False):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def split_invoices_based_on_payment_terms(outstanding_invoices, company) -> list:
|
def split_invoices_based_on_payment_terms(outstanding_invoices, company):
|
||||||
"""Split a list of invoices based on their payment terms."""
|
invoice_ref_based_on_payment_terms = {}
|
||||||
exc_rates = get_currency_data(outstanding_invoices, company)
|
|
||||||
|
|
||||||
outstanding_invoices_after_split = []
|
|
||||||
for entry in outstanding_invoices:
|
|
||||||
if entry.voucher_type in ["Sales Invoice", "Purchase Invoice"]:
|
|
||||||
if payment_term_template := frappe.db.get_value(
|
|
||||||
entry.voucher_type, entry.voucher_no, "payment_terms_template"
|
|
||||||
):
|
|
||||||
split_rows = get_split_invoice_rows(entry, payment_term_template, exc_rates)
|
|
||||||
if not split_rows:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if len(split_rows) > 1:
|
|
||||||
frappe.msgprint(
|
|
||||||
_("Splitting {0} {1} into {2} rows as per Payment Terms").format(
|
|
||||||
_(entry.voucher_type), frappe.bold(entry.voucher_no), len(split_rows)
|
|
||||||
),
|
|
||||||
alert=True,
|
|
||||||
)
|
|
||||||
outstanding_invoices_after_split += split_rows
|
|
||||||
continue
|
|
||||||
|
|
||||||
# If not an invoice or no payment terms template, add as it is
|
|
||||||
outstanding_invoices_after_split.append(entry)
|
|
||||||
|
|
||||||
return outstanding_invoices_after_split
|
|
||||||
|
|
||||||
|
|
||||||
def get_currency_data(outstanding_invoices: list, company: str = None) -> dict:
|
|
||||||
"""Get currency and conversion data for a list of invoices."""
|
|
||||||
exc_rates = frappe._dict()
|
|
||||||
company_currency = (
|
company_currency = (
|
||||||
frappe.db.get_value("Company", company, "default_currency") if company else None
|
frappe.db.get_value("Company", company, "default_currency") if company else None
|
||||||
)
|
)
|
||||||
|
exc_rates = frappe._dict()
|
||||||
for doctype in ["Sales Invoice", "Purchase Invoice"]:
|
for doctype in ["Sales Invoice", "Purchase Invoice"]:
|
||||||
invoices = [x.voucher_no for x in outstanding_invoices if x.voucher_type == doctype]
|
invoices = [x.voucher_no for x in outstanding_invoices if x.voucher_type == doctype]
|
||||||
for x in frappe.db.get_all(
|
for x in frappe.db.get_all(
|
||||||
@@ -1740,54 +1719,72 @@ def get_currency_data(outstanding_invoices: list, company: str = None) -> dict:
|
|||||||
company_currency=company_currency,
|
company_currency=company_currency,
|
||||||
)
|
)
|
||||||
|
|
||||||
return exc_rates
|
for idx, d in enumerate(outstanding_invoices):
|
||||||
|
if d.voucher_type in ["Sales Invoice", "Purchase Invoice"]:
|
||||||
|
payment_term_template = frappe.db.get_value(
|
||||||
def get_split_invoice_rows(invoice: dict, payment_term_template: str, exc_rates: dict) -> list:
|
d.voucher_type, d.voucher_no, "payment_terms_template"
|
||||||
"""Split invoice based on its payment schedule table."""
|
|
||||||
split_rows = []
|
|
||||||
allocate_payment_based_on_payment_terms = frappe.db.get_value(
|
|
||||||
"Payment Terms Template", payment_term_template, "allocate_payment_based_on_payment_terms"
|
|
||||||
)
|
|
||||||
|
|
||||||
if not allocate_payment_based_on_payment_terms:
|
|
||||||
return [invoice]
|
|
||||||
|
|
||||||
payment_schedule = frappe.get_all(
|
|
||||||
"Payment Schedule", filters={"parent": invoice.voucher_no}, fields=["*"], order_by="due_date"
|
|
||||||
)
|
|
||||||
for payment_term in payment_schedule:
|
|
||||||
if not payment_term.outstanding > 0.1:
|
|
||||||
continue
|
|
||||||
|
|
||||||
doc_details = exc_rates.get(payment_term.parent, None)
|
|
||||||
is_multi_currency_acc = (doc_details.currency != doc_details.company_currency) and (
|
|
||||||
doc_details.party_account_currency != doc_details.company_currency
|
|
||||||
)
|
|
||||||
payment_term_outstanding = flt(payment_term.outstanding)
|
|
||||||
if not is_multi_currency_acc:
|
|
||||||
payment_term_outstanding = doc_details.conversion_rate * flt(payment_term.outstanding)
|
|
||||||
|
|
||||||
split_rows.append(
|
|
||||||
frappe._dict(
|
|
||||||
{
|
|
||||||
"due_date": invoice.due_date,
|
|
||||||
"currency": invoice.currency,
|
|
||||||
"voucher_no": invoice.voucher_no,
|
|
||||||
"voucher_type": invoice.voucher_type,
|
|
||||||
"posting_date": invoice.posting_date,
|
|
||||||
"invoice_amount": flt(invoice.invoice_amount),
|
|
||||||
"outstanding_amount": payment_term_outstanding
|
|
||||||
if payment_term_outstanding
|
|
||||||
else invoice.outstanding_amount,
|
|
||||||
"payment_term_outstanding": payment_term_outstanding,
|
|
||||||
"payment_amount": payment_term.payment_amount,
|
|
||||||
"payment_term": payment_term.payment_term,
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
)
|
if payment_term_template:
|
||||||
|
allocate_payment_based_on_payment_terms = frappe.get_cached_value(
|
||||||
|
"Payment Terms Template", payment_term_template, "allocate_payment_based_on_payment_terms"
|
||||||
|
)
|
||||||
|
if allocate_payment_based_on_payment_terms:
|
||||||
|
payment_schedule = frappe.get_all(
|
||||||
|
"Payment Schedule", filters={"parent": d.voucher_no}, fields=["*"]
|
||||||
|
)
|
||||||
|
|
||||||
return split_rows
|
for payment_term in payment_schedule:
|
||||||
|
if payment_term.outstanding > 0.1:
|
||||||
|
doc_details = exc_rates.get(payment_term.parent, None)
|
||||||
|
is_multi_currency_acc = (doc_details.currency != doc_details.company_currency) and (
|
||||||
|
doc_details.party_account_currency != doc_details.company_currency
|
||||||
|
)
|
||||||
|
payment_term_outstanding = flt(payment_term.outstanding)
|
||||||
|
if not is_multi_currency_acc:
|
||||||
|
payment_term_outstanding = doc_details.conversion_rate * flt(payment_term.outstanding)
|
||||||
|
|
||||||
|
invoice_ref_based_on_payment_terms.setdefault(idx, [])
|
||||||
|
invoice_ref_based_on_payment_terms[idx].append(
|
||||||
|
frappe._dict(
|
||||||
|
{
|
||||||
|
"due_date": d.due_date,
|
||||||
|
"currency": d.currency,
|
||||||
|
"voucher_no": d.voucher_no,
|
||||||
|
"voucher_type": d.voucher_type,
|
||||||
|
"posting_date": d.posting_date,
|
||||||
|
"invoice_amount": flt(d.invoice_amount),
|
||||||
|
"outstanding_amount": payment_term_outstanding
|
||||||
|
if payment_term_outstanding
|
||||||
|
else d.outstanding_amount,
|
||||||
|
"payment_term_outstanding": payment_term_outstanding,
|
||||||
|
"payment_amount": payment_term.payment_amount,
|
||||||
|
"payment_term": payment_term.payment_term,
|
||||||
|
"account": d.account,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
outstanding_invoices_after_split = []
|
||||||
|
if invoice_ref_based_on_payment_terms:
|
||||||
|
for idx, ref in invoice_ref_based_on_payment_terms.items():
|
||||||
|
voucher_no = ref[0]["voucher_no"]
|
||||||
|
voucher_type = ref[0]["voucher_type"]
|
||||||
|
|
||||||
|
frappe.msgprint(
|
||||||
|
_("Spliting {} {} into {} row(s) as per Payment Terms").format(
|
||||||
|
voucher_type, voucher_no, len(ref)
|
||||||
|
),
|
||||||
|
alert=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
outstanding_invoices_after_split += invoice_ref_based_on_payment_terms[idx]
|
||||||
|
|
||||||
|
existing_row = list(filter(lambda x: x.get("voucher_no") == voucher_no, outstanding_invoices))
|
||||||
|
index = outstanding_invoices.index(existing_row[0])
|
||||||
|
outstanding_invoices.pop(index)
|
||||||
|
|
||||||
|
outstanding_invoices_after_split += outstanding_invoices
|
||||||
|
return outstanding_invoices_after_split
|
||||||
|
|
||||||
|
|
||||||
def get_orders_to_be_billed(
|
def get_orders_to_be_billed(
|
||||||
@@ -1992,24 +1989,18 @@ def get_company_defaults(company):
|
|||||||
|
|
||||||
|
|
||||||
def get_outstanding_on_journal_entry(name):
|
def get_outstanding_on_journal_entry(name):
|
||||||
gl = frappe.qb.DocType("GL Entry")
|
res = frappe.db.sql(
|
||||||
res = (
|
"SELECT "
|
||||||
frappe.qb.from_(gl)
|
'CASE WHEN party_type IN ("Customer") '
|
||||||
.select(
|
"THEN ifnull(sum(debit_in_account_currency - credit_in_account_currency), 0) "
|
||||||
Case()
|
"ELSE ifnull(sum(credit_in_account_currency - debit_in_account_currency), 0) "
|
||||||
.when(
|
"END as outstanding_amount "
|
||||||
gl.party_type == "Customer",
|
"FROM `tabGL Entry` WHERE (voucher_no=%s OR against_voucher=%s) "
|
||||||
Coalesce(Sum(gl.debit_in_account_currency - gl.credit_in_account_currency), 0),
|
"AND party_type IS NOT NULL "
|
||||||
)
|
'AND party_type != ""',
|
||||||
.else_(Coalesce(Sum(gl.credit_in_account_currency - gl.debit_in_account_currency), 0))
|
(name, name),
|
||||||
.as_("outstanding_amount")
|
as_dict=1,
|
||||||
)
|
)
|
||||||
.where(
|
|
||||||
(Coalesce(gl.party_type, "") != "")
|
|
||||||
& (gl.is_cancelled == 0)
|
|
||||||
& ((gl.voucher_no == name) | (gl.against_voucher == name))
|
|
||||||
)
|
|
||||||
).run(as_dict=True)
|
|
||||||
|
|
||||||
outstanding_amount = res[0].get("outstanding_amount", 0) if res else 0
|
outstanding_amount = res[0].get("outstanding_amount", 0) if res else 0
|
||||||
|
|
||||||
@@ -2634,8 +2625,3 @@ def make_payment_order(source_name, target_doc=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
return doclist
|
return doclist
|
||||||
|
|
||||||
|
|
||||||
@erpnext.allow_regional
|
|
||||||
def add_regional_gl_entries(gl_entries, doc):
|
|
||||||
return
|
|
||||||
|
|||||||
@@ -6,12 +6,10 @@ import unittest
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import qb
|
from frappe import qb
|
||||||
from frappe.tests.utils import FrappeTestCase, change_settings
|
from frappe.tests.utils import FrappeTestCase, change_settings
|
||||||
from frappe.utils import add_days, flt, nowdate
|
from frappe.utils import flt, nowdate
|
||||||
|
|
||||||
from erpnext.accounts.doctype.account.test_account import create_account
|
|
||||||
from erpnext.accounts.doctype.payment_entry.payment_entry import (
|
from erpnext.accounts.doctype.payment_entry.payment_entry import (
|
||||||
InvalidPaymentEntry,
|
InvalidPaymentEntry,
|
||||||
get_outstanding_reference_documents,
|
|
||||||
get_payment_entry,
|
get_payment_entry,
|
||||||
get_reference_details,
|
get_reference_details,
|
||||||
)
|
)
|
||||||
@@ -685,6 +683,17 @@ class TestPaymentEntry(FrappeTestCase):
|
|||||||
self.validate_gl_entries(pe.name, expected_gle)
|
self.validate_gl_entries(pe.name, expected_gle)
|
||||||
|
|
||||||
def test_payment_against_negative_sales_invoice(self):
|
def test_payment_against_negative_sales_invoice(self):
|
||||||
|
pe1 = frappe.new_doc("Payment Entry")
|
||||||
|
pe1.payment_type = "Pay"
|
||||||
|
pe1.company = "_Test Company"
|
||||||
|
pe1.party_type = "Customer"
|
||||||
|
pe1.party = "_Test Customer"
|
||||||
|
pe1.paid_from = "_Test Cash - _TC"
|
||||||
|
pe1.paid_amount = 100
|
||||||
|
pe1.received_amount = 100
|
||||||
|
|
||||||
|
self.assertRaises(InvalidPaymentEntry, pe1.validate)
|
||||||
|
|
||||||
si1 = create_sales_invoice()
|
si1 = create_sales_invoice()
|
||||||
|
|
||||||
# create full payment entry against si1
|
# create full payment entry against si1
|
||||||
@@ -742,6 +751,8 @@ class TestPaymentEntry(FrappeTestCase):
|
|||||||
|
|
||||||
# pay more than outstanding against si1
|
# pay more than outstanding against si1
|
||||||
pe3 = get_payment_entry("Sales Invoice", si1.name, bank_account="_Test Cash - _TC")
|
pe3 = get_payment_entry("Sales Invoice", si1.name, bank_account="_Test Cash - _TC")
|
||||||
|
pe3.paid_amount = pe3.received_amount = 300
|
||||||
|
self.assertRaises(InvalidPaymentEntry, pe3.validate)
|
||||||
|
|
||||||
# pay negative outstanding against si1
|
# pay negative outstanding against si1
|
||||||
pe3.paid_to = "Debtors - _TC"
|
pe3.paid_to = "Debtors - _TC"
|
||||||
@@ -1251,266 +1262,6 @@ class TestPaymentEntry(FrappeTestCase):
|
|||||||
so.reload()
|
so.reload()
|
||||||
self.assertEqual(so.advance_paid, so.rounded_total)
|
self.assertEqual(so.advance_paid, so.rounded_total)
|
||||||
|
|
||||||
def test_receive_payment_from_payable_party_type(self):
|
|
||||||
"""
|
|
||||||
Checks GL entries generated while receiving payments from a Payable Party Type.
|
|
||||||
"""
|
|
||||||
pe = create_payment_entry(
|
|
||||||
party_type="Supplier",
|
|
||||||
party="_Test Supplier",
|
|
||||||
payment_type="Receive",
|
|
||||||
paid_from="Creditors - _TC",
|
|
||||||
paid_to="_Test Cash - _TC",
|
|
||||||
save=True,
|
|
||||||
submit=True,
|
|
||||||
)
|
|
||||||
self.voucher_no = pe.name
|
|
||||||
self.expected_gle = [
|
|
||||||
{"account": "Creditors - _TC", "debit": 0.0, "credit": 1000.0},
|
|
||||||
{"account": "_Test Cash - _TC", "debit": 1000.0, "credit": 0.0},
|
|
||||||
]
|
|
||||||
self.check_gl_entries()
|
|
||||||
|
|
||||||
def test_payment_against_partial_return_invoice(self):
|
|
||||||
"""
|
|
||||||
Checks GL entries generated for partial return invoice payments.
|
|
||||||
"""
|
|
||||||
si = create_sales_invoice(qty=10, rate=10, customer="_Test Customer")
|
|
||||||
credit_note = create_sales_invoice(
|
|
||||||
qty=-4, rate=10, customer="_Test Customer", is_return=1, return_against=si.name
|
|
||||||
)
|
|
||||||
pe = create_payment_entry(
|
|
||||||
party_type="Customer",
|
|
||||||
party="_Test Customer",
|
|
||||||
payment_type="Receive",
|
|
||||||
paid_from="Debtors - _TC",
|
|
||||||
paid_to="_Test Cash - _TC",
|
|
||||||
)
|
|
||||||
pe.set(
|
|
||||||
"references",
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"reference_doctype": "Sales Invoice",
|
|
||||||
"reference_name": si.name,
|
|
||||||
"due_date": si.get("due_date"),
|
|
||||||
"total_amount": si.grand_total,
|
|
||||||
"outstanding_amount": si.outstanding_amount,
|
|
||||||
"allocated_amount": si.outstanding_amount,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"reference_doctype": "Sales Invoice",
|
|
||||||
"reference_name": credit_note.name,
|
|
||||||
"due_date": credit_note.get("due_date"),
|
|
||||||
"total_amount": credit_note.grand_total,
|
|
||||||
"outstanding_amount": credit_note.outstanding_amount,
|
|
||||||
"allocated_amount": credit_note.outstanding_amount,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
)
|
|
||||||
pe.save()
|
|
||||||
pe.submit()
|
|
||||||
self.assertEqual(pe.total_allocated_amount, 60)
|
|
||||||
self.assertEqual(pe.unallocated_amount, 940)
|
|
||||||
self.voucher_no = pe.name
|
|
||||||
self.expected_gle = [
|
|
||||||
{"account": "Debtors - _TC", "debit": 40.0, "credit": 0.0},
|
|
||||||
{"account": "Debtors - _TC", "debit": 0.0, "credit": 940.0},
|
|
||||||
{"account": "Debtors - _TC", "debit": 0.0, "credit": 100.0},
|
|
||||||
{"account": "_Test Cash - _TC", "debit": 1000.0, "credit": 0.0},
|
|
||||||
]
|
|
||||||
self.check_gl_entries()
|
|
||||||
|
|
||||||
def test_ledger_entries_for_advance_as_liability(self):
|
|
||||||
from erpnext.accounts.doctype.account.test_account import create_account
|
|
||||||
|
|
||||||
company = "_Test Company"
|
|
||||||
|
|
||||||
advance_account = create_account(
|
|
||||||
parent_account="Current Assets - _TC",
|
|
||||||
account_name="Advances Received",
|
|
||||||
company=company,
|
|
||||||
account_type="Receivable",
|
|
||||||
)
|
|
||||||
|
|
||||||
frappe.db.set_value(
|
|
||||||
"Company",
|
|
||||||
company,
|
|
||||||
{
|
|
||||||
"book_advance_payments_in_separate_party_account": 1,
|
|
||||||
"default_advance_received_account": advance_account,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
# Advance Payment
|
|
||||||
pe = create_payment_entry(
|
|
||||||
party_type="Customer",
|
|
||||||
party="_Test Customer",
|
|
||||||
payment_type="Receive",
|
|
||||||
paid_from="Debtors - _TC",
|
|
||||||
paid_to="_Test Cash - _TC",
|
|
||||||
)
|
|
||||||
pe.save() # use save() to trigger set_liability_account()
|
|
||||||
pe.submit()
|
|
||||||
|
|
||||||
# Normal Invoice
|
|
||||||
si = create_sales_invoice(qty=10, rate=100, customer="_Test Customer")
|
|
||||||
|
|
||||||
pre_reconciliation_gle = [
|
|
||||||
{"account": advance_account, "debit": 0.0, "credit": 1000.0},
|
|
||||||
{"account": "_Test Cash - _TC", "debit": 1000.0, "credit": 0.0},
|
|
||||||
]
|
|
||||||
pre_reconciliation_ple = [
|
|
||||||
{
|
|
||||||
"account": advance_account,
|
|
||||||
"voucher_no": pe.name,
|
|
||||||
"against_voucher_no": pe.name,
|
|
||||||
"amount": -1000.0,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
self.voucher_no = pe.name
|
|
||||||
self.expected_gle = pre_reconciliation_gle
|
|
||||||
self.expected_ple = pre_reconciliation_ple
|
|
||||||
self.check_gl_entries()
|
|
||||||
self.check_pl_entries()
|
|
||||||
|
|
||||||
# Partially reconcile advance against invoice
|
|
||||||
pr = frappe.get_doc("Payment Reconciliation")
|
|
||||||
pr.company = company
|
|
||||||
pr.party_type = "Customer"
|
|
||||||
pr.party = "_Test Customer"
|
|
||||||
pr.receivable_payable_account = si.debit_to
|
|
||||||
pr.default_advance_account = advance_account
|
|
||||||
pr.payment_name = pe.name
|
|
||||||
pr.invoice_name = si.name
|
|
||||||
pr.get_unreconciled_entries()
|
|
||||||
|
|
||||||
self.assertEqual(len(pr.invoices), 1)
|
|
||||||
self.assertEqual(len(pr.payments), 1)
|
|
||||||
|
|
||||||
invoices = [x.as_dict() for x in pr.get("invoices")]
|
|
||||||
payments = [x.as_dict() for x in pr.get("payments")]
|
|
||||||
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
|
|
||||||
pr.allocation[0].allocated_amount = 400
|
|
||||||
pr.reconcile()
|
|
||||||
|
|
||||||
# assert General and Payment Ledger entries post partial reconciliation
|
|
||||||
self.expected_gle = [
|
|
||||||
{"account": si.debit_to, "debit": 0.0, "credit": 400.0},
|
|
||||||
{"account": advance_account, "debit": 400.0, "credit": 0.0},
|
|
||||||
{"account": advance_account, "debit": 0.0, "credit": 1000.0},
|
|
||||||
{"account": "_Test Cash - _TC", "debit": 1000.0, "credit": 0.0},
|
|
||||||
]
|
|
||||||
self.expected_ple = [
|
|
||||||
{
|
|
||||||
"account": advance_account,
|
|
||||||
"voucher_no": pe.name,
|
|
||||||
"against_voucher_no": pe.name,
|
|
||||||
"amount": -1000.0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"account": si.debit_to,
|
|
||||||
"voucher_no": pe.name,
|
|
||||||
"against_voucher_no": si.name,
|
|
||||||
"amount": -400.0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"account": advance_account,
|
|
||||||
"voucher_no": pe.name,
|
|
||||||
"against_voucher_no": pe.name,
|
|
||||||
"amount": 400.0,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
self.check_gl_entries()
|
|
||||||
self.check_pl_entries()
|
|
||||||
|
|
||||||
# Unreconcile
|
|
||||||
unrecon = (
|
|
||||||
frappe.get_doc(
|
|
||||||
{
|
|
||||||
"doctype": "Unreconcile Payment",
|
|
||||||
"company": company,
|
|
||||||
"voucher_type": pe.doctype,
|
|
||||||
"voucher_no": pe.name,
|
|
||||||
"allocations": [{"reference_doctype": si.doctype, "reference_name": si.name}],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.save()
|
|
||||||
.submit()
|
|
||||||
)
|
|
||||||
|
|
||||||
self.voucher_no = pe.name
|
|
||||||
self.expected_gle = pre_reconciliation_gle
|
|
||||||
self.expected_ple = pre_reconciliation_ple
|
|
||||||
self.check_gl_entries()
|
|
||||||
self.check_pl_entries()
|
|
||||||
|
|
||||||
def check_pl_entries(self):
|
|
||||||
ple = frappe.qb.DocType("Payment Ledger Entry")
|
|
||||||
pl_entries = (
|
|
||||||
frappe.qb.from_(ple)
|
|
||||||
.select(ple.account, ple.voucher_no, ple.against_voucher_no, ple.amount)
|
|
||||||
.where((ple.voucher_no == self.voucher_no) & (ple.delinked == 0))
|
|
||||||
.orderby(ple.creation)
|
|
||||||
).run(as_dict=True)
|
|
||||||
for row in range(len(self.expected_ple)):
|
|
||||||
for field in ["account", "voucher_no", "against_voucher_no", "amount"]:
|
|
||||||
self.assertEqual(self.expected_ple[row][field], pl_entries[row][field])
|
|
||||||
|
|
||||||
def check_gl_entries(self):
|
|
||||||
gle = frappe.qb.DocType("GL Entry")
|
|
||||||
gl_entries = (
|
|
||||||
frappe.qb.from_(gle)
|
|
||||||
.select(
|
|
||||||
gle.account,
|
|
||||||
gle.debit,
|
|
||||||
gle.credit,
|
|
||||||
)
|
|
||||||
.where((gle.voucher_no == self.voucher_no) & (gle.is_cancelled == 0))
|
|
||||||
.orderby(gle.account, gle.debit, gle.credit, order=frappe.qb.desc)
|
|
||||||
).run(as_dict=True)
|
|
||||||
for row in range(len(self.expected_gle)):
|
|
||||||
for field in ["account", "debit", "credit"]:
|
|
||||||
self.assertEqual(self.expected_gle[row][field], gl_entries[row][field])
|
|
||||||
|
|
||||||
def test_outstanding_invoices_api(self):
|
|
||||||
"""
|
|
||||||
Test if `get_outstanding_reference_documents` fetches invoices in the right order.
|
|
||||||
"""
|
|
||||||
customer = create_customer("Max Mustermann", "INR")
|
|
||||||
create_payment_terms_template()
|
|
||||||
|
|
||||||
# SI has an earlier due date and SI2 has a later due date
|
|
||||||
si = create_sales_invoice(
|
|
||||||
qty=1, rate=100, customer=customer, posting_date=add_days(nowdate(), -4)
|
|
||||||
)
|
|
||||||
si2 = create_sales_invoice(do_not_save=1, qty=1, rate=100, customer=customer)
|
|
||||||
si2.payment_terms_template = "Test Receivable Template"
|
|
||||||
si2.submit()
|
|
||||||
|
|
||||||
args = {
|
|
||||||
"posting_date": nowdate(),
|
|
||||||
"company": "_Test Company",
|
|
||||||
"party_type": "Customer",
|
|
||||||
"payment_type": "Pay",
|
|
||||||
"party": customer,
|
|
||||||
"party_account": "Debtors - _TC",
|
|
||||||
}
|
|
||||||
args.update(
|
|
||||||
{
|
|
||||||
"get_outstanding_invoices": True,
|
|
||||||
"from_posting_date": add_days(nowdate(), -4),
|
|
||||||
"to_posting_date": add_days(nowdate(), 2),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
references = get_outstanding_reference_documents(args)
|
|
||||||
|
|
||||||
self.assertEqual(len(references), 3)
|
|
||||||
self.assertEqual(references[0].voucher_no, si.name)
|
|
||||||
self.assertEqual(references[1].voucher_no, si2.name)
|
|
||||||
self.assertEqual(references[2].voucher_no, si2.name)
|
|
||||||
self.assertEqual(references[1].payment_term, "Basic Amount Receivable")
|
|
||||||
self.assertEqual(references[2].payment_term, "Tax Receivable")
|
|
||||||
|
|
||||||
|
|
||||||
def create_payment_entry(**args):
|
def create_payment_entry(**args):
|
||||||
payment_entry = frappe.new_doc("Payment Entry")
|
payment_entry = frappe.new_doc("Payment Entry")
|
||||||
@@ -1571,9 +1322,6 @@ def create_payment_terms_template():
|
|||||||
def create_payment_terms_template_with_discount(
|
def create_payment_terms_template_with_discount(
|
||||||
name=None, discount_type=None, discount=None, template_name=None
|
name=None, discount_type=None, discount=None, template_name=None
|
||||||
):
|
):
|
||||||
"""
|
|
||||||
Create a Payment Terms Template with % or amount discount.
|
|
||||||
"""
|
|
||||||
create_payment_term(name or "30 Credit Days with 10% Discount")
|
create_payment_term(name or "30 Credit Days with 10% Discount")
|
||||||
template_name = template_name or "Test Discount Template"
|
template_name = template_name or "Test Discount Template"
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user