mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-02 19:59:12 +00:00
Merge remote-tracking branch 'origin/develop' into feat/employee-milestone-indicators
This commit is contained in:
6
.github/workflows/initiate_release.yml
vendored
6
.github/workflows/initiate_release.yml
vendored
@@ -8,8 +8,8 @@ permissions:
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
# 9:30 UTC => 3 PM IST Tuesday
|
# 9:30 UTC => 3 PM IST
|
||||||
- cron: "30 9 * * 2"
|
- cron: "30 9 * * 1,4"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -19,7 +19,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
version: ["14", "15", "16"]
|
version: ["15", "16"]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: octokit/request-action@v2.x
|
- uses: octokit/request-action@v2.x
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: server-individual-tests-develop-${{ github.event_name }}-${{ github.event.number || github.event_name == 'workflow_dispatch' && github.run_id || '' }}
|
group: server-individual-tests-lightmode-develop
|
||||||
cancel-in-progress: false
|
cancel-in-progress: true
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
@@ -21,7 +21,7 @@ jobs:
|
|||||||
- id: set-matrix
|
- id: set-matrix
|
||||||
run: |
|
run: |
|
||||||
# Use grep and find to get the list of test files
|
# Use grep and find to get the list of test files
|
||||||
matrix=$(find . -path '*/doctype/*/test_*.py' | xargs grep -l 'def test_' | awk '{
|
matrix=$(find . -path '*/test_*.py' | xargs grep -l 'def test_' | sort | awk '{
|
||||||
# Remove ./ prefix, file extension, and replace / with .
|
# Remove ./ prefix, file extension, and replace / with .
|
||||||
gsub(/^\.\//, "", $0)
|
gsub(/^\.\//, "", $0)
|
||||||
gsub(/\.py$/, "", $0)
|
gsub(/\.py$/, "", $0)
|
||||||
@@ -58,6 +58,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix: ${{fromJson(needs.discover.outputs.matrix)}}
|
matrix: ${{fromJson(needs.discover.outputs.matrix)}}
|
||||||
|
max-parallel: 14
|
||||||
|
|
||||||
name: Test
|
name: Test
|
||||||
|
|
||||||
@@ -130,4 +131,13 @@ 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-tests --app erpnext --module ${{ matrix.test }}'
|
run: |
|
||||||
|
site_name=$(echo "${{matrix.test}}" | sed -e 's/.*\.\(test_.*$\)/\1/')
|
||||||
|
echo "$site_name"
|
||||||
|
mkdir ~/frappe-bench/sites/$site_name
|
||||||
|
cp -r "${GITHUB_WORKSPACE}/.github/helper/site_config_mariadb.json" ~/frappe-bench/sites/$site_name/site_config.json
|
||||||
|
cd ~/frappe-bench/
|
||||||
|
bench --site $site_name reinstall --yes
|
||||||
|
bench --site $site_name set-config allow_tests true
|
||||||
|
bench --site $site_name run-tests --module ${{ matrix.test }} --lightmode
|
||||||
|
|
||||||
2
.github/workflows/server-tests-mariadb.yml
vendored
2
.github/workflows/server-tests-mariadb.yml
vendored
@@ -129,7 +129,7 @@ jobs:
|
|||||||
FRAPPE_BRANCH: ${{ github.event.client_payload.sha || github.event.inputs.branch }}
|
FRAPPE_BRANCH: ${{ github.event.client_payload.sha || 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 ${{ strategy.job-total }} --build-number ${{ matrix.container }} --with-coverage'
|
run: 'cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --lightmode --app erpnext --total-builds ${{ strategy.job-total }} --build-number ${{ matrix.container }} --with-coverage'
|
||||||
env:
|
env:
|
||||||
TYPE: server
|
TYPE: server
|
||||||
|
|
||||||
|
|||||||
12
CODEOWNERS
12
CODEOWNERS
@@ -7,17 +7,17 @@ erpnext/accounts/ @ruthra-kumar
|
|||||||
erpnext/assets/ @khushi8112
|
erpnext/assets/ @khushi8112
|
||||||
erpnext/regional @ruthra-kumar
|
erpnext/regional @ruthra-kumar
|
||||||
erpnext/selling @ruthra-kumar
|
erpnext/selling @ruthra-kumar
|
||||||
erpnext/support/ @ruthra-kumar
|
|
||||||
|
|
||||||
erpnext/buying/ @rohitwaghchaure @mihir-kandoi
|
erpnext/buying/ @rohitwaghchaure @mihir-kandoi
|
||||||
erpnext/maintenance/ @rohitwaghchaure
|
erpnext/maintenance/ @rohitwaghchaure @mihir-kandoi
|
||||||
erpnext/manufacturing/ @rohitwaghchaure @mihir-kandoi
|
erpnext/manufacturing/ @rohitwaghchaure @mihir-kandoi
|
||||||
erpnext/quality_management/ @rohitwaghchaure
|
erpnext/quality_management/ @rohitwaghchaure @mihir-kandoi
|
||||||
erpnext/stock/ @rohitwaghchaure @mihir-kandoi
|
erpnext/stock/ @rohitwaghchaure @mihir-kandoi
|
||||||
erpnext/subcontracting @mihir-kandoi
|
erpnext/subcontracting/ @mihir-kandoi
|
||||||
|
erpnext/projects/ @nishkagosalia
|
||||||
|
|
||||||
erpnext/controllers/ @ruthra-kumar @rohitwaghchaure @mihir-kandoi
|
erpnext/controllers/ @ruthra-kumar @rohitwaghchaure @mihir-kandoi
|
||||||
erpnext/patches/ @ruthra-kumar
|
erpnext/patches/ @ruthra-kumar @rohitwaghchaure @mihir-kandoi
|
||||||
|
|
||||||
.github/ @ruthra-kumar
|
.github/ @ruthra-kumar @mihir-kandoi
|
||||||
pyproject.toml @ruthra-kumar
|
pyproject.toml @ruthra-kumar
|
||||||
|
|||||||
41
README.md
41
README.md
@@ -75,25 +75,48 @@ It takes care of installation, setup, upgrades, monitoring, maintenance and supp
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Self-Hosted
|
### Self-Hosted
|
||||||
#### Docker
|
#### Docker
|
||||||
|
|
||||||
Prerequisites: docker, docker-compose, git. Refer [Docker Documentation](https://docs.docker.com) for more details on Docker setup.
|
See [Frappe Docker Documentation](https://github.com/frappe/frappe_docker) for full documentation & FAQ on docker setup
|
||||||
|
|
||||||
Run following commands:
|
#### Prerequisites
|
||||||
|
|
||||||
```
|
- [Docker](https://docs.docker.com/get-docker/)
|
||||||
|
- [Docker Compose v2](https://docs.docker.com/compose/)
|
||||||
|
- [git](https://docs.github.com/en/get-started/getting-started-with-git/set-up-git)
|
||||||
|
|
||||||
|
> For Docker basics and best practices refer to Docker's [documentation](https://docs.docker.com)
|
||||||
|
|
||||||
|
#### Demo setup
|
||||||
|
|
||||||
|
The fastest way to try ERPNext is to play in an already set up sandbox, in your browser, click the button below:
|
||||||
|
|
||||||
|
<a href="https://labs.play-with-docker.com/?stack=https://raw.githubusercontent.com/frappe/frappe_docker/main/pwd.yml">
|
||||||
|
<img src="https://raw.githubusercontent.com/play-with-docker/stacks/master/assets/images/button.png" alt="Try in PWD"/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
### Try on your environment
|
||||||
|
|
||||||
|
> **⚠️ Disposable demo only**
|
||||||
|
>
|
||||||
|
> **This setup is intended for quick evaluation. Expect to throw the environment away.** You will not be able to install custom apps to this setup. For production deployments, custom configurations, and detailed explanations, see the full documentation.
|
||||||
|
|
||||||
|
First clone the repo:
|
||||||
|
|
||||||
|
```sh
|
||||||
git clone https://github.com/frappe/frappe_docker
|
git clone https://github.com/frappe/frappe_docker
|
||||||
cd frappe_docker
|
cd frappe_docker
|
||||||
docker compose -f pwd.yml up -d
|
|
||||||
```
|
```
|
||||||
|
|
||||||
After a couple of minutes, site should be accessible on your localhost port: 8080. Use below default login credentials to access the site.
|
Then run:
|
||||||
- Username: Administrator
|
|
||||||
- Password: admin
|
|
||||||
|
|
||||||
See [Frappe Docker](https://github.com/frappe/frappe_docker?tab=readme-ov-file#to-run-on-arm64-architecture-follow-this-instructions) for ARM based docker setup.
|
```sh
|
||||||
|
docker compose -f pwd.yml up -d
|
||||||
|
```
|
||||||
|
Wait for a couple of minutes for ERPNext site to be created or check `create-site` container logs before opening browser on port `8080`. (username: `Administrator`, password: `admin`)
|
||||||
|
|
||||||
|
See [Frappe Docker](https://github.com/frappe/frappe_docker/blob/main/docs/01-getting-started/03-arm64.md) for ARM based docker setup
|
||||||
|
|
||||||
|
|
||||||
## Development Setup
|
## Development Setup
|
||||||
|
|||||||
@@ -17,6 +17,15 @@ frappe.dashboards.chart_sources["Account Balance Timeline"] = {
|
|||||||
fieldtype: "Link",
|
fieldtype: "Link",
|
||||||
options: "Account",
|
options: "Account",
|
||||||
reqd: 1,
|
reqd: 1,
|
||||||
|
default: locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"],
|
||||||
|
get_query: () => {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
account_type: "Bank",
|
||||||
|
is_group: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import add_to_date, formatdate, get_link_to_form, getdate, nowdate
|
from frappe.utils import add_to_date, formatdate, getdate, nowdate
|
||||||
from frappe.utils.dashboard import cache_source
|
from frappe.utils.dashboard import cache_source
|
||||||
from frappe.utils.dateutils import get_from_date_from_timespan, get_period_ending
|
from frappe.utils.dateutils import get_from_date_from_timespan, get_period_ending
|
||||||
from frappe.utils.nestedset import get_descendants_of
|
from frappe.utils.nestedset import get_descendants_of
|
||||||
@@ -37,21 +37,14 @@ def get(
|
|||||||
filters = frappe.parse_json(filters) or frappe.parse_json(chart.filters_json)
|
filters = frappe.parse_json(filters) or frappe.parse_json(chart.filters_json)
|
||||||
|
|
||||||
account = filters.get("account")
|
account = filters.get("account")
|
||||||
filters.get("company")
|
company = filters.get("company")
|
||||||
|
|
||||||
if not account and chart_name:
|
if not company and not account:
|
||||||
frappe.throw(
|
frappe.throw(_("Company and account filters not set!"))
|
||||||
_("Account is not set for the dashboard chart {0}").format(
|
if not company:
|
||||||
get_link_to_form("Dashboard Chart", chart_name)
|
frappe.throw(_("Company filter not set!"))
|
||||||
)
|
if not account:
|
||||||
)
|
frappe.throw(_("Account filter not set!"))
|
||||||
|
|
||||||
if not frappe.db.exists("Account", account) and chart_name:
|
|
||||||
frappe.throw(
|
|
||||||
_("Account {0} does not exists in the dashboard chart {1}").format(
|
|
||||||
account, get_link_to_form("Dashboard Chart", chart_name)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if not to_date:
|
if not to_date:
|
||||||
to_date = nowdate()
|
to_date = nowdate()
|
||||||
|
|||||||
@@ -523,7 +523,8 @@ def make_gl_entries(
|
|||||||
if gl_entries:
|
if gl_entries:
|
||||||
try:
|
try:
|
||||||
make_gl_entries(gl_entries, cancel=(doc.docstatus == 2), merge_entries=True)
|
make_gl_entries(gl_entries, cancel=(doc.docstatus == 2), merge_entries=True)
|
||||||
frappe.db.commit()
|
if not frappe.in_test:
|
||||||
|
frappe.db.commit()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if frappe.in_test:
|
if frappe.in_test:
|
||||||
doc.log_error(f"Error while processing deferred accounting for Invoice {doc.name}")
|
doc.log_error(f"Error while processing deferred accounting for Invoice {doc.name}")
|
||||||
@@ -605,7 +606,8 @@ def book_revenue_via_journal_entry(
|
|||||||
if submit:
|
if submit:
|
||||||
journal_entry.submit()
|
journal_entry.submit()
|
||||||
|
|
||||||
frappe.db.commit()
|
if not frappe.in_test:
|
||||||
|
frappe.db.commit()
|
||||||
except Exception:
|
except Exception:
|
||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
doc.log_error(f"Error while processing deferred accounting for Invoice {doc.name}")
|
doc.log_error(f"Error while processing deferred accounting for Invoice {doc.name}")
|
||||||
|
|||||||
@@ -52,60 +52,55 @@ frappe.treeview_settings["Account"] = {
|
|||||||
],
|
],
|
||||||
root_label: "Accounts",
|
root_label: "Accounts",
|
||||||
get_tree_nodes: "erpnext.accounts.utils.get_children",
|
get_tree_nodes: "erpnext.accounts.utils.get_children",
|
||||||
on_get_node: function (nodes, deep = false) {
|
on_node_render: function (node, deep) {
|
||||||
if (frappe.boot.user.can_read.indexOf("GL Entry") == -1) return;
|
const render_balances = () => {
|
||||||
|
for (let account of cur_tree.account_balance_data) {
|
||||||
|
const node = cur_tree.nodes && cur_tree.nodes[account.value];
|
||||||
|
if (!node || node.is_root) continue;
|
||||||
|
|
||||||
let accounts = [];
|
// show Dr if positive since balance is calculated as debit - credit else show Cr
|
||||||
if (deep) {
|
const balance = account.balance_in_account_currency || account.balance;
|
||||||
// in case of `get_all_nodes`
|
const dr_or_cr = balance > 0 ? __("Dr") : __("Cr");
|
||||||
accounts = nodes.reduce((acc, node) => [...acc, ...node.data], []);
|
const format = (value, currency) => format_currency(Math.abs(value), currency);
|
||||||
} else {
|
|
||||||
accounts = nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
frappe.db.get_single_value("Accounts Settings", "show_balance_in_coa").then((value) => {
|
if (account.balance !== undefined) {
|
||||||
if (value) {
|
node.parent && node.parent.find(".balance-area").remove();
|
||||||
const get_balances = frappe.call({
|
$(
|
||||||
method: "erpnext.accounts.utils.get_account_balances",
|
'<span class="balance-area pull-right">' +
|
||||||
args: {
|
(account.account_currency != account.company_currency
|
||||||
accounts: accounts,
|
? format(account.balance_in_account_currency, account.account_currency) +
|
||||||
company: cur_tree.args.company,
|
" / "
|
||||||
include_default_fb_balances: true,
|
: "") +
|
||||||
},
|
format(account.balance, account.company_currency) +
|
||||||
});
|
" " +
|
||||||
|
dr_or_cr +
|
||||||
get_balances.then((r) => {
|
"</span>"
|
||||||
if (!r.message || r.message.length == 0) return;
|
).insertBefore(node.$ul);
|
||||||
|
}
|
||||||
for (let account of r.message) {
|
|
||||||
const node = cur_tree.nodes && cur_tree.nodes[account.value];
|
|
||||||
if (!node || node.is_root) continue;
|
|
||||||
|
|
||||||
// show Dr if positive since balance is calculated as debit - credit else show Cr
|
|
||||||
const balance = account.balance_in_account_currency || account.balance;
|
|
||||||
const dr_or_cr = balance > 0 ? __("Dr") : __("Cr");
|
|
||||||
const format = (value, currency) => format_currency(Math.abs(value), currency);
|
|
||||||
|
|
||||||
if (account.balance !== undefined) {
|
|
||||||
node.parent && node.parent.find(".balance-area").remove();
|
|
||||||
$(
|
|
||||||
'<span class="balance-area pull-right">' +
|
|
||||||
(account.balance_in_account_currency
|
|
||||||
? format(
|
|
||||||
account.balance_in_account_currency,
|
|
||||||
account.account_currency
|
|
||||||
) + " / "
|
|
||||||
: "") +
|
|
||||||
format(account.balance, account.company_currency) +
|
|
||||||
" " +
|
|
||||||
dr_or_cr +
|
|
||||||
"</span>"
|
|
||||||
).insertBefore(node.$ul);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
if (frappe.boot.user.can_read.indexOf("GL Entry") == -1) return;
|
||||||
|
if (!cur_tree.account_balance_data) {
|
||||||
|
frappe.db.get_single_value("Accounts Settings", "show_balance_in_coa").then((value) => {
|
||||||
|
if (value) {
|
||||||
|
frappe.call({
|
||||||
|
method: "erpnext.accounts.utils.get_account_balances_coa",
|
||||||
|
args: {
|
||||||
|
company: cur_tree.args.company,
|
||||||
|
include_default_fb_balances: true,
|
||||||
|
},
|
||||||
|
callback: function (r) {
|
||||||
|
if (!r.message || r.message.length === 0) return;
|
||||||
|
cur_tree.account_balance_data = r.message || [];
|
||||||
|
render_balances();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
render_balances();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
add_tree_node: "erpnext.accounts.utils.add_ac",
|
add_tree_node: "erpnext.accounts.utils.add_ac",
|
||||||
menu_items: [
|
menu_items: [
|
||||||
|
|||||||
@@ -6,64 +6,83 @@
|
|||||||
"Current Assets": {
|
"Current Assets": {
|
||||||
"Accounts Receivable": {
|
"Accounts Receivable": {
|
||||||
"Debtors": {
|
"Debtors": {
|
||||||
"account_type": "Receivable"
|
"account_type": "Receivable",
|
||||||
|
"account_category": "Trade Receivables"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Bank Accounts": {
|
"Bank Accounts": {
|
||||||
"account_type": "Bank",
|
"account_type": "Bank",
|
||||||
"is_group": 1
|
"is_group": 1,
|
||||||
|
"account_category": "Cash and Cash Equivalents"
|
||||||
},
|
},
|
||||||
"Cash In Hand": {
|
"Cash In Hand": {
|
||||||
"Cash": {
|
"Cash": {
|
||||||
"account_type": "Cash"
|
"account_type": "Cash",
|
||||||
|
"account_category": "Cash and Cash Equivalents"
|
||||||
},
|
},
|
||||||
"account_type": "Cash"
|
"account_type": "Cash",
|
||||||
|
"account_category": "Cash and Cash Equivalents"
|
||||||
},
|
},
|
||||||
"Loans and Advances (Assets)": {
|
"Loans and Advances (Assets)": {
|
||||||
"is_group": 1
|
"is_group": 1,
|
||||||
|
"account_category": "Other Receivables"
|
||||||
},
|
},
|
||||||
"Securities and Deposits": {
|
"Securities and Deposits": {
|
||||||
"Earnest Money": {}
|
"Earnest Money": {
|
||||||
|
"account_category": "Other Current Assets"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Stock Assets": {
|
"Stock Assets": {
|
||||||
"Stock In Hand": {
|
"Stock In Hand": {
|
||||||
"account_type": "Stock"
|
"account_type": "Stock",
|
||||||
|
"account_category": "Stock Assets"
|
||||||
},
|
},
|
||||||
"account_type": "Stock"
|
"account_type": "Stock",
|
||||||
|
"account_category": "Stock Assets"
|
||||||
},
|
},
|
||||||
"Tax Assets": {
|
"Tax Assets": {
|
||||||
"is_group": 1
|
"is_group": 1,
|
||||||
|
"account_category": "Other Current Assets"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Fixed Assets": {
|
"Fixed Assets": {
|
||||||
"Capital Equipment": {
|
"Capital Equipment": {
|
||||||
"account_type": "Fixed Asset"
|
"account_type": "Fixed Asset",
|
||||||
|
"account_category": "Tangible Assets"
|
||||||
},
|
},
|
||||||
"Electronic Equipment": {
|
"Electronic Equipment": {
|
||||||
"account_type": "Fixed Asset"
|
"account_type": "Fixed Asset",
|
||||||
|
"account_category": "Tangible Assets"
|
||||||
},
|
},
|
||||||
"Furniture and Fixtures": {
|
"Furniture and Fixtures": {
|
||||||
"account_type": "Fixed Asset"
|
"account_type": "Fixed Asset",
|
||||||
|
"account_category": "Tangible Assets"
|
||||||
},
|
},
|
||||||
"Office Equipment": {
|
"Office Equipment": {
|
||||||
"account_type": "Fixed Asset"
|
"account_type": "Fixed Asset",
|
||||||
|
"account_category": "Tangible Assets"
|
||||||
},
|
},
|
||||||
"Plants and Machineries": {
|
"Plants and Machineries": {
|
||||||
"account_type": "Fixed Asset"
|
"account_type": "Fixed Asset",
|
||||||
|
"account_category": "Tangible Assets"
|
||||||
},
|
},
|
||||||
"Buildings": {
|
"Buildings": {
|
||||||
"account_type": "Fixed Asset"
|
"account_type": "Fixed Asset",
|
||||||
|
"account_category": "Tangible Assets"
|
||||||
},
|
},
|
||||||
"Accumulated Depreciations": {
|
"Accumulated Depreciations": {
|
||||||
"account_type": "Accumulated Depreciation"
|
"account_type": "Accumulated Depreciation",
|
||||||
|
"account_category": "Tangible Assets"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Investments": {
|
"Investments": {
|
||||||
"is_group": 1
|
"is_group": 1,
|
||||||
|
"account_category": "Long-term Investments"
|
||||||
},
|
},
|
||||||
"Temporary Accounts": {
|
"Temporary Accounts": {
|
||||||
"Temporary Opening": {
|
"Temporary Opening": {
|
||||||
"account_type": "Temporary"
|
"account_type": "Temporary",
|
||||||
|
"account_category": "Other Non-current Assets"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root_type": "Asset"
|
"root_type": "Asset"
|
||||||
@@ -72,55 +91,103 @@
|
|||||||
"Direct Expenses": {
|
"Direct Expenses": {
|
||||||
"Stock Expenses": {
|
"Stock Expenses": {
|
||||||
"Cost of Goods Sold": {
|
"Cost of Goods Sold": {
|
||||||
"account_type": "Cost of Goods Sold"
|
"account_type": "Cost of Goods Sold",
|
||||||
|
"account_category": "Cost of Goods Sold"
|
||||||
},
|
},
|
||||||
"Expenses Included In Valuation": {
|
"Expenses Included In Valuation": {
|
||||||
"account_type": "Expenses Included In Valuation"
|
"account_type": "Expenses Included In Valuation",
|
||||||
|
"account_category": "Other Direct Costs"
|
||||||
},
|
},
|
||||||
"Stock Adjustment": {
|
"Stock Adjustment": {
|
||||||
"account_type": "Stock Adjustment"
|
"account_type": "Stock Adjustment",
|
||||||
|
"account_category": "Other Direct Costs"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Indirect Expenses": {
|
"Indirect Expenses": {
|
||||||
"Administrative Expenses": {},
|
"Administrative Expenses": {
|
||||||
"Commission on Sales": {},
|
"account_category": "Operating Expenses"
|
||||||
|
},
|
||||||
|
"Commission on Sales": {
|
||||||
|
"account_category": "Operating Expenses"
|
||||||
|
},
|
||||||
"Depreciation": {
|
"Depreciation": {
|
||||||
"account_type": "Depreciation"
|
"account_type": "Depreciation",
|
||||||
|
"account_category": "Operating Expenses"
|
||||||
|
},
|
||||||
|
"Entertainment Expenses": {
|
||||||
|
"account_category": "Operating Expenses"
|
||||||
},
|
},
|
||||||
"Entertainment Expenses": {},
|
|
||||||
"Freight and Forwarding Charges": {
|
"Freight and Forwarding Charges": {
|
||||||
"account_type": "Chargeable"
|
"account_type": "Chargeable",
|
||||||
|
"account_category": "Operating Expenses"
|
||||||
|
},
|
||||||
|
"Legal Expenses": {
|
||||||
|
"account_category": "Operating Expenses"
|
||||||
|
},
|
||||||
|
"Marketing Expenses": {
|
||||||
|
"account_type": "Chargeable",
|
||||||
|
"account_category": "Operating Expenses"
|
||||||
|
},
|
||||||
|
"Miscellaneous Expenses": {
|
||||||
|
"account_type": "Chargeable",
|
||||||
|
"account_category": "Operating Expenses"
|
||||||
|
},
|
||||||
|
"Office Maintenance Expenses": {
|
||||||
|
"account_category": "Operating Expenses"
|
||||||
|
},
|
||||||
|
"Office Rent": {
|
||||||
|
"account_category": "Operating Expenses"
|
||||||
|
},
|
||||||
|
"Postal Expenses": {
|
||||||
|
"account_category": "Operating Expenses"
|
||||||
|
},
|
||||||
|
"Print and Stationery": {
|
||||||
|
"account_category": "Operating Expenses"
|
||||||
},
|
},
|
||||||
"Legal Expenses": {},
|
|
||||||
"Marketing Expenses": {},
|
|
||||||
"Miscellaneous Expenses": {},
|
|
||||||
"Office Maintenance Expenses": {},
|
|
||||||
"Office Rent": {},
|
|
||||||
"Postal Expenses": {},
|
|
||||||
"Print and Stationery": {},
|
|
||||||
"Rounded Off": {
|
"Rounded Off": {
|
||||||
"account_type": "Round Off"
|
"account_type": "Round Off",
|
||||||
|
"account_category": "Operating Expenses"
|
||||||
},
|
},
|
||||||
"Salary": {},
|
"Salary": {
|
||||||
"Sales Expenses": {},
|
"account_category": "Operating Expenses"
|
||||||
"Telephone Expenses": {},
|
},
|
||||||
"Travel Expenses": {},
|
"Sales Expenses": {
|
||||||
"Utility Expenses": {},
|
"account_category": "Operating Expenses"
|
||||||
"Write Off": {},
|
},
|
||||||
"Exchange Gain/Loss": {},
|
"Telephone Expenses": {
|
||||||
"Gain/Loss on Asset Disposal": {},
|
"account_category": "Operating Expenses"
|
||||||
"Impairment": {}
|
},
|
||||||
|
"Travel Expenses": {
|
||||||
|
"account_category": "Operating Expenses"
|
||||||
|
},
|
||||||
|
"Utility Expenses": {
|
||||||
|
"account_category": "Operating Expenses"
|
||||||
|
},
|
||||||
|
"Write Off": {
|
||||||
|
"account_category": "Operating Expenses"
|
||||||
|
},
|
||||||
|
"Exchange Gain/Loss": {
|
||||||
|
"account_category": "Operating Expenses"
|
||||||
|
},
|
||||||
|
"Gain/Loss on Asset Disposal": {
|
||||||
|
"account_category": "Other Operating Income"
|
||||||
|
},
|
||||||
|
"Impairment": {
|
||||||
|
"account_category": "Operating Expenses"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"root_type": "Expense"
|
"root_type": "Expense"
|
||||||
},
|
},
|
||||||
"Income": {
|
"Income": {
|
||||||
"Direct Income": {
|
"Direct Income": {
|
||||||
"Sales": {
|
"Sales": {
|
||||||
"account_type": "Income Account"
|
"account_type": "Income Account",
|
||||||
|
"account_category": "Revenue from Operations"
|
||||||
},
|
},
|
||||||
"Service": {
|
"Service": {
|
||||||
"account_type": "Income Account"
|
"account_type": "Income Account",
|
||||||
|
"account_category": "Revenue from Operations"
|
||||||
},
|
},
|
||||||
"account_type": "Income Account"
|
"account_type": "Income Account"
|
||||||
},
|
},
|
||||||
@@ -132,31 +199,51 @@
|
|||||||
},
|
},
|
||||||
"Source of Funds (Liabilities)": {
|
"Source of Funds (Liabilities)": {
|
||||||
"Capital Account": {
|
"Capital Account": {
|
||||||
"Reserves and Surplus": {},
|
"Reserves and Surplus": {
|
||||||
"Shareholders Funds": {},
|
"account_category": "Reserves and Surplus"
|
||||||
"Revaluation Surplus": {}
|
},
|
||||||
|
"Shareholders Funds": {
|
||||||
|
"account_category": "Share Capital"
|
||||||
|
},
|
||||||
|
"Revaluation Surplus": {
|
||||||
|
"account_category": "Reserves and Surplus"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Current Liabilities": {
|
"Current Liabilities": {
|
||||||
"Accounts Payable": {
|
"Accounts Payable": {
|
||||||
"Creditors": {
|
"Creditors": {
|
||||||
"account_type": "Payable"
|
"account_type": "Payable",
|
||||||
|
"account_category": "Trade Payables"
|
||||||
},
|
},
|
||||||
"Payroll Payable": {}
|
"Payroll Payable": {
|
||||||
|
"account_category": "Other Payables"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Stock Liabilities": {
|
"Stock Liabilities": {
|
||||||
"Stock Received But Not Billed": {
|
"Stock Received But Not Billed": {
|
||||||
"account_type": "Stock Received But Not Billed"
|
"account_type": "Stock Received But Not Billed",
|
||||||
|
"account_category": "Trade Payables"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Duties and Taxes": {
|
"Duties and Taxes": {
|
||||||
"TDS": {
|
"TDS": {
|
||||||
"account_type": "Tax"
|
"account_type": "Tax",
|
||||||
}
|
"account_category": "Current Tax Liabilities"
|
||||||
|
},
|
||||||
|
"account_type": "Tax",
|
||||||
|
"is_group": 1,
|
||||||
|
"account_category": "Current Tax Liabilities"
|
||||||
},
|
},
|
||||||
"Loans (Liabilities)": {
|
"Loans (Liabilities)": {
|
||||||
"Secured Loans": {},
|
"Secured Loans": {
|
||||||
"Unsecured Loans": {},
|
"account_category": "Long-term Borrowings"
|
||||||
"Bank Overdraft Account": {}
|
},
|
||||||
|
"Unsecured Loans": {
|
||||||
|
"account_category": "Long-term Borrowings"
|
||||||
|
},
|
||||||
|
"Bank Overdraft Account": {
|
||||||
|
"account_category": "Short-term Borrowings"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root_type": "Liability"
|
"root_type": "Liability"
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import nowdate
|
from frappe.utils import nowdate
|
||||||
|
|
||||||
from erpnext.accounts.doctype.account.account import (
|
from erpnext.accounts.doctype.account.account import (
|
||||||
@@ -11,11 +10,10 @@ from erpnext.accounts.doctype.account.account import (
|
|||||||
update_account_number,
|
update_account_number,
|
||||||
)
|
)
|
||||||
from erpnext.stock import get_company_default_inventory_account, get_warehouse_account
|
from erpnext.stock import get_company_default_inventory_account, get_warehouse_account
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
EXTRA_TEST_RECORD_DEPENDENCIES = ["Company"]
|
|
||||||
|
|
||||||
|
|
||||||
class TestAccount(IntegrationTestCase):
|
class TestAccount(ERPNextTestSuite):
|
||||||
def test_rename_account(self):
|
def test_rename_account(self):
|
||||||
if not frappe.db.exists("Account", "1210 - Debtors - _TC"):
|
if not frappe.db.exists("Account", "1210 - Debtors - _TC"):
|
||||||
acc = frappe.new_doc("Account")
|
acc = frappe.new_doc("Account")
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"doctype": "Account",
|
|
||||||
"name": "_Test Account 1"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -2,19 +2,3 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
# import frappe
|
# import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
|
|
||||||
# On IntegrationTestCase, the doctype test records and all
|
|
||||||
# link-field test record dependencies are recursively loaded
|
|
||||||
# Use these module variables to add/remove to/from that list
|
|
||||||
EXTRA_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
|
|
||||||
IGNORE_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
|
|
||||||
|
|
||||||
|
|
||||||
class IntegrationTestAccountCategory(IntegrationTestCase):
|
|
||||||
"""
|
|
||||||
Integration tests for AccountCategory.
|
|
||||||
Use this class for testing interactions between multiple components.
|
|
||||||
"""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
// frappe.ui.form.on("Account Closing Balance", {
|
frappe.ui.form.on("Account Closing Balance", {
|
||||||
// refresh(frm) {
|
refresh(frm) {
|
||||||
|
frm.page.btn_secondary.hide();
|
||||||
// },
|
},
|
||||||
// });
|
});
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Document",
|
"document_type": "Document",
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"is_submittable": 1,
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"closing_date",
|
"closing_date",
|
||||||
"account",
|
"account",
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
# import frappe
|
# import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestAccountClosingBalance(IntegrationTestCase):
|
class TestAccountClosingBalance(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -2,18 +2,13 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
|
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
EXTRA_TEST_RECORD_DEPENDENCIES = ["Cost Center", "Location", "Warehouse", "Department"]
|
|
||||||
|
|
||||||
|
|
||||||
class TestAccountingDimension(IntegrationTestCase):
|
class TestAccountingDimension(ERPNextTestSuite):
|
||||||
def setUp(self):
|
|
||||||
create_dimension()
|
|
||||||
|
|
||||||
def test_dimension_against_sales_invoice(self):
|
def test_dimension_against_sales_invoice(self):
|
||||||
si = create_sales_invoice(do_not_save=1)
|
si = create_sales_invoice(do_not_save=1)
|
||||||
|
|
||||||
@@ -78,68 +73,3 @@ class TestAccountingDimension(IntegrationTestCase):
|
|||||||
|
|
||||||
si.save()
|
si.save()
|
||||||
self.assertRaises(frappe.ValidationError, si.submit)
|
self.assertRaises(frappe.ValidationError, si.submit)
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
disable_dimension()
|
|
||||||
frappe.flags.accounting_dimensions_details = None
|
|
||||||
frappe.flags.dimension_filter_map = None
|
|
||||||
|
|
||||||
|
|
||||||
def create_dimension():
|
|
||||||
frappe.set_user("Administrator")
|
|
||||||
|
|
||||||
if not frappe.db.exists("Accounting Dimension", {"document_type": "Department"}):
|
|
||||||
dimension = frappe.get_doc(
|
|
||||||
{
|
|
||||||
"doctype": "Accounting Dimension",
|
|
||||||
"document_type": "Department",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
dimension.append(
|
|
||||||
"dimension_defaults",
|
|
||||||
{
|
|
||||||
"company": "_Test Company",
|
|
||||||
"reference_document": "Department",
|
|
||||||
"default_dimension": "_Test Department - _TC",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
dimension.insert()
|
|
||||||
dimension.save()
|
|
||||||
else:
|
|
||||||
dimension = frappe.get_doc("Accounting Dimension", "Department")
|
|
||||||
dimension.disabled = 0
|
|
||||||
dimension.save()
|
|
||||||
|
|
||||||
if not frappe.db.exists("Accounting Dimension", {"document_type": "Location"}):
|
|
||||||
dimension1 = frappe.get_doc(
|
|
||||||
{
|
|
||||||
"doctype": "Accounting Dimension",
|
|
||||||
"document_type": "Location",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
dimension1.append(
|
|
||||||
"dimension_defaults",
|
|
||||||
{
|
|
||||||
"company": "_Test Company",
|
|
||||||
"reference_document": "Location",
|
|
||||||
"default_dimension": "Block 1",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
dimension1.insert()
|
|
||||||
dimension1.save()
|
|
||||||
else:
|
|
||||||
dimension1 = frappe.get_doc("Accounting Dimension", "Location")
|
|
||||||
dimension1.disabled = 0
|
|
||||||
dimension1.save()
|
|
||||||
|
|
||||||
|
|
||||||
def disable_dimension():
|
|
||||||
dimension1 = frappe.get_doc("Accounting Dimension", "Department")
|
|
||||||
dimension1.disabled = 1
|
|
||||||
dimension1.save()
|
|
||||||
|
|
||||||
dimension2 = frappe.get_doc("Accounting Dimension", "Location")
|
|
||||||
dimension2.disabled = 1
|
|
||||||
dimension2.save()
|
|
||||||
|
|||||||
@@ -1,23 +1,15 @@
|
|||||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
|
||||||
from erpnext.accounts.doctype.accounting_dimension.test_accounting_dimension import (
|
|
||||||
create_dimension,
|
|
||||||
disable_dimension,
|
|
||||||
)
|
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
from erpnext.exceptions import InvalidAccountDimensionError, MandatoryAccountDimensionError
|
from erpnext.exceptions import InvalidAccountDimensionError, MandatoryAccountDimensionError
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
EXTRA_TEST_RECORD_DEPENDENCIES = ["Location", "Cost Center", "Department"]
|
|
||||||
|
|
||||||
|
|
||||||
class TestAccountingDimensionFilter(unittest.TestCase):
|
class TestAccountingDimensionFilter(ERPNextTestSuite):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
create_dimension()
|
|
||||||
create_accounting_dimension_filter()
|
create_accounting_dimension_filter()
|
||||||
self.invoice_list = []
|
self.invoice_list = []
|
||||||
|
|
||||||
@@ -44,17 +36,6 @@ class TestAccountingDimensionFilter(unittest.TestCase):
|
|||||||
self.assertRaises(MandatoryAccountDimensionError, si.submit)
|
self.assertRaises(MandatoryAccountDimensionError, si.submit)
|
||||||
self.invoice_list.append(si)
|
self.invoice_list.append(si)
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
disable_dimension_filter()
|
|
||||||
disable_dimension()
|
|
||||||
frappe.flags.accounting_dimensions_details = None
|
|
||||||
frappe.flags.dimension_filter_map = None
|
|
||||||
|
|
||||||
for si in self.invoice_list:
|
|
||||||
si.load_from_db()
|
|
||||||
if si.docstatus == 1:
|
|
||||||
si.cancel()
|
|
||||||
|
|
||||||
|
|
||||||
def create_accounting_dimension_filter():
|
def create_accounting_dimension_filter():
|
||||||
if not frappe.db.get_value("Accounting Dimension Filter", {"accounting_dimension": "Cost Center"}):
|
if not frappe.db.get_value("Accounting Dimension Filter", {"accounting_dimension": "Cost Center"}):
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "period_name",
|
"fieldname": "period_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Period Name",
|
"label": "Period Name",
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"unique": 1
|
"unique": 1
|
||||||
@@ -79,7 +78,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2025-12-01 16:53:44.631299",
|
"modified": "2026-03-09 17:15:33.577217",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Accounting Period",
|
"name": "Accounting Period",
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import add_months, nowdate
|
from frappe.utils import add_months, nowdate
|
||||||
|
|
||||||
from erpnext.accounts.doctype.accounting_period.accounting_period import (
|
from erpnext.accounts.doctype.accounting_period.accounting_period import (
|
||||||
@@ -10,11 +9,10 @@ from erpnext.accounts.doctype.accounting_period.accounting_period import (
|
|||||||
OverlapError,
|
OverlapError,
|
||||||
)
|
)
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
EXTRA_TEST_RECORD_DEPENDENCIES = ["Item"]
|
|
||||||
|
|
||||||
|
|
||||||
class TestAccountingPeriod(IntegrationTestCase):
|
class TestAccountingPeriod(ERPNextTestSuite):
|
||||||
def test_overlap(self):
|
def test_overlap(self):
|
||||||
ap1 = create_accounting_period(
|
ap1 = create_accounting_period(
|
||||||
start_date="2018-04-01", end_date="2018-06-30", company="Wind Power LLC"
|
start_date="2018-04-01", end_date="2018-06-30", company="Wind Power LLC"
|
||||||
@@ -89,10 +87,6 @@ class TestAccountingPeriod(IntegrationTestCase):
|
|||||||
doc.submit() # Should not raise
|
doc.submit() # Should not raise
|
||||||
self.assertEqual(doc.docstatus, 1)
|
self.assertEqual(doc.docstatus, 1)
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
for d in frappe.get_all("Accounting Period"):
|
|
||||||
frappe.delete_doc("Accounting Period", d.name)
|
|
||||||
|
|
||||||
|
|
||||||
def create_accounting_period(**args):
|
def create_accounting_period(**args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
|
|||||||
@@ -1,15 +1,9 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestAccountsSettings(IntegrationTestCase):
|
class TestAccountsSettings(ERPNextTestSuite):
|
||||||
def tearDown(self):
|
|
||||||
# Just in case `save` method succeeds, we need to take things back to default so that other tests
|
|
||||||
# don't break
|
|
||||||
cur_settings = frappe.get_doc("Accounts Settings", "Accounts Settings")
|
|
||||||
cur_settings.allow_stale = 1
|
|
||||||
cur_settings.save()
|
|
||||||
|
|
||||||
def test_stale_days(self):
|
def test_stale_days(self):
|
||||||
cur_settings = frappe.get_doc("Accounts Settings", "Accounts Settings")
|
cur_settings = frappe.get_doc("Accounts Settings", "Accounts Settings")
|
||||||
cur_settings.allow_stale = 0
|
cur_settings.allow_stale = 0
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
frappe.ui.form.on("Advance Payment Ledger Entry", {
|
frappe.ui.form.on("Advance Payment Ledger Entry", {
|
||||||
refresh(frm) {
|
refresh(frm) {
|
||||||
|
frm.page.btn_secondary.hide();
|
||||||
frm.set_currency_labels(["amount"], frm.doc.currency);
|
frm.set_currency_labels(["amount"], frm.doc.currency);
|
||||||
frm.set_currency_labels(["base_amount"], erpnext.get_currency(frm.doc.company));
|
frm.set_currency_labels(["base_amount"], erpnext.get_currency(frm.doc.company));
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
"creation": "2024-10-16 16:57:12.085072",
|
"creation": "2024-10-16 16:57:12.085072",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"is_submittable": 1,
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"company",
|
"company",
|
||||||
"voucher_type",
|
"voucher_type",
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import nowdate, today
|
from frappe.utils import nowdate, today
|
||||||
|
|
||||||
from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
|
from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
|
||||||
@@ -10,14 +9,13 @@ from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
|
|||||||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
||||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||||
|
|
||||||
# On IntegrationTestCase, the doctype test records and all
|
# On ERPNextTestSuite, the doctype test records and all
|
||||||
# link-field test record depdendencies are recursively loaded
|
# link-field test record depdendencies are recursively loaded
|
||||||
# Use these module variables to add/remove to/from that list
|
# Use these module variables to add/remove to/from that list
|
||||||
EXTRA_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
IGNORE_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
|
|
||||||
|
|
||||||
|
|
||||||
class TestAdvancePaymentLedgerEntry(AccountsTestMixin, IntegrationTestCase):
|
class TestAdvancePaymentLedgerEntry(AccountsTestMixin, ERPNextTestSuite):
|
||||||
"""
|
"""
|
||||||
Integration tests for AdvancePaymentLedgerEntry.
|
Integration tests for AdvancePaymentLedgerEntry.
|
||||||
Use this class for testing interactions between multiple components.
|
Use this class for testing interactions between multiple components.
|
||||||
@@ -30,9 +28,6 @@ class TestAdvancePaymentLedgerEntry(AccountsTestMixin, IntegrationTestCase):
|
|||||||
self.create_item()
|
self.create_item()
|
||||||
self.clear_old_entries()
|
self.clear_old_entries()
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
frappe.db.rollback()
|
|
||||||
|
|
||||||
def create_sales_order(self, qty=1, rate=100, currency="INR", do_not_submit=False):
|
def create_sales_order(self, qty=1, rate=100, currency="INR", do_not_submit=False):
|
||||||
"""
|
"""
|
||||||
Helper method
|
Helper method
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
from frappe.tests import IntegrationTestCase
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestBank(IntegrationTestCase):
|
class TestBank(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
from frappe.tests import IntegrationTestCase
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestBankAccount(IntegrationTestCase):
|
class TestBankAccount(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
from frappe.tests import IntegrationTestCase
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestBankAccountSubtype(IntegrationTestCase):
|
class TestBankAccountSubtype(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
# import frappe
|
# import frappe
|
||||||
|
|
||||||
from frappe.tests import IntegrationTestCase
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestBankAccountType(IntegrationTestCase):
|
class TestBankAccountType(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _, msgprint
|
from frappe import _, msgprint
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
from frappe.query_builder import Case
|
||||||
from frappe.query_builder.custom import ConstantColumn
|
from frappe.query_builder.custom import ConstantColumn
|
||||||
|
from frappe.query_builder.functions import Coalesce, Sum
|
||||||
from frappe.utils import cint, flt, fmt_money, getdate
|
from frappe.utils import cint, flt, fmt_money, getdate
|
||||||
from pypika import Order
|
from pypika import Order
|
||||||
|
|
||||||
@@ -182,65 +184,162 @@ def get_payment_entries_for_bank_clearance(
|
|||||||
):
|
):
|
||||||
entries = []
|
entries = []
|
||||||
|
|
||||||
condition = ""
|
journal_entry = frappe.qb.DocType("Journal Entry")
|
||||||
pe_condition = ""
|
journal_entry_account = frappe.qb.DocType("Journal Entry Account")
|
||||||
|
|
||||||
|
journal_entry_query = (
|
||||||
|
frappe.qb.from_(journal_entry_account)
|
||||||
|
.inner_join(journal_entry)
|
||||||
|
.on(journal_entry_account.parent == journal_entry.name)
|
||||||
|
.select(
|
||||||
|
ConstantColumn("Journal Entry").as_("payment_document"),
|
||||||
|
journal_entry.name.as_("payment_entry"),
|
||||||
|
journal_entry.cheque_no.as_("cheque_number"),
|
||||||
|
journal_entry.cheque_date,
|
||||||
|
Sum(journal_entry_account.debit_in_account_currency).as_("debit"),
|
||||||
|
Sum(journal_entry_account.credit_in_account_currency).as_("credit"),
|
||||||
|
journal_entry.posting_date,
|
||||||
|
journal_entry_account.against_account,
|
||||||
|
journal_entry.clearance_date,
|
||||||
|
journal_entry_account.account_currency,
|
||||||
|
)
|
||||||
|
.where(
|
||||||
|
(journal_entry_account.account == account)
|
||||||
|
& (journal_entry.docstatus == 1)
|
||||||
|
& (journal_entry.posting_date >= from_date)
|
||||||
|
& (journal_entry.posting_date <= to_date)
|
||||||
|
& (journal_entry.is_opening == "No")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if not include_reconciled_entries:
|
if not include_reconciled_entries:
|
||||||
condition = "and (clearance_date IS NULL or clearance_date='0000-00-00')"
|
journal_entry_query = journal_entry_query.where(
|
||||||
pe_condition = "and (pe.clearance_date IS NULL or pe.clearance_date='0000-00-00')"
|
(journal_entry.clearance_date.isnull()) | (journal_entry.clearance_date == "0000-00-00")
|
||||||
|
)
|
||||||
|
|
||||||
journal_entries = frappe.db.sql(
|
journal_entries = (
|
||||||
f"""
|
journal_entry_query.groupby(journal_entry_account.account, journal_entry.name)
|
||||||
select
|
.orderby(journal_entry.posting_date)
|
||||||
"Journal Entry" as payment_document, t1.name as payment_entry,
|
.orderby(journal_entry.name, order=Order.desc)
|
||||||
t1.cheque_no as cheque_number, t1.cheque_date,
|
).run(as_dict=True)
|
||||||
sum(t2.debit_in_account_currency) as debit, sum(t2.credit_in_account_currency) as credit,
|
|
||||||
t1.posting_date, t2.against_account, t1.clearance_date, t2.account_currency
|
pe = frappe.qb.DocType("Payment Entry")
|
||||||
from
|
company = frappe.qb.DocType("Company")
|
||||||
`tabJournal Entry` t1, `tabJournal Entry Account` t2
|
payment_entry_query = (
|
||||||
where
|
frappe.qb.from_(pe)
|
||||||
t2.parent = t1.name and t2.account = %(account)s and t1.docstatus=1
|
.join(company)
|
||||||
and t1.posting_date >= %(from)s and t1.posting_date <= %(to)s
|
.on(pe.company == company.name)
|
||||||
and ifnull(t1.is_opening, 'No') = 'No' {condition}
|
.select(
|
||||||
group by t2.account, t1.name
|
ConstantColumn("Payment Entry").as_("payment_document"),
|
||||||
order by t1.posting_date ASC, t1.name DESC
|
pe.name.as_("payment_entry"),
|
||||||
""",
|
pe.reference_no.as_("cheque_number"),
|
||||||
{"account": account, "from": from_date, "to": to_date},
|
pe.reference_date.as_("cheque_date"),
|
||||||
as_dict=1,
|
(
|
||||||
|
Case()
|
||||||
|
.when(
|
||||||
|
pe.paid_from == account,
|
||||||
|
(
|
||||||
|
pe.paid_amount
|
||||||
|
+ (
|
||||||
|
Case()
|
||||||
|
.when(
|
||||||
|
(pe.payment_type == "Pay")
|
||||||
|
& (company.default_currency == pe.paid_from_account_currency),
|
||||||
|
pe.base_total_taxes_and_charges,
|
||||||
|
)
|
||||||
|
.else_(pe.total_taxes_and_charges)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.else_(0)
|
||||||
|
).as_("credit"),
|
||||||
|
(
|
||||||
|
Case()
|
||||||
|
.when(pe.paid_from == account, 0)
|
||||||
|
.else_(
|
||||||
|
pe.received_amount
|
||||||
|
+ (
|
||||||
|
Case()
|
||||||
|
.when(
|
||||||
|
company.default_currency == pe.paid_to_account_currency,
|
||||||
|
pe.base_total_taxes_and_charges,
|
||||||
|
)
|
||||||
|
.else_(pe.total_taxes_and_charges)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).as_("debit"),
|
||||||
|
pe.posting_date,
|
||||||
|
Coalesce(pe.party, Case().when(pe.paid_from == account, pe.paid_to).else_(pe.paid_from)).as_(
|
||||||
|
"against_account"
|
||||||
|
),
|
||||||
|
pe.clearance_date,
|
||||||
|
(
|
||||||
|
Case()
|
||||||
|
.when(pe.paid_to == account, pe.paid_to_account_currency)
|
||||||
|
.else_(pe.paid_from_account_currency)
|
||||||
|
).as_("account_currency"),
|
||||||
|
)
|
||||||
|
.where(
|
||||||
|
((pe.paid_from == account) | (pe.paid_to == account))
|
||||||
|
& (pe.docstatus == 1)
|
||||||
|
& (pe.posting_date >= from_date)
|
||||||
|
& (pe.posting_date <= to_date)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
payment_entries = frappe.db.sql(
|
if not include_reconciled_entries:
|
||||||
f"""
|
payment_entry_query = payment_entry_query.where(
|
||||||
select
|
(pe.clearance_date.isnull()) | (pe.clearance_date == "0000-00-00")
|
||||||
"Payment Entry" as payment_document, pe.name as payment_entry,
|
)
|
||||||
pe.reference_no as cheque_number, pe.reference_date as cheque_date,
|
|
||||||
if(pe.paid_from=%(account)s, pe.paid_amount + if(pe.payment_type = 'Pay' and c.default_currency = pe.paid_from_account_currency, pe.base_total_taxes_and_charges, pe.total_taxes_and_charges) , 0) as credit,
|
payment_entries = (payment_entry_query.orderby(pe.posting_date).orderby(pe.name, order=Order.desc)).run(
|
||||||
if(pe.paid_from=%(account)s, 0, pe.received_amount + pe.total_taxes_and_charges) as debit,
|
as_dict=True
|
||||||
pe.posting_date, ifnull(pe.party,if(pe.paid_from=%(account)s,pe.paid_to,pe.paid_from)) as against_account, pe.clearance_date,
|
|
||||||
if(pe.paid_to=%(account)s, pe.paid_to_account_currency, pe.paid_from_account_currency) as account_currency
|
|
||||||
from `tabPayment Entry` as pe
|
|
||||||
join `tabCompany` c on c.name = pe.company
|
|
||||||
where
|
|
||||||
(pe.paid_from=%(account)s or pe.paid_to=%(account)s) and pe.docstatus=1
|
|
||||||
and pe.posting_date >= %(from)s and pe.posting_date <= %(to)s
|
|
||||||
{pe_condition}
|
|
||||||
order by
|
|
||||||
pe.posting_date ASC, pe.name DESC
|
|
||||||
""",
|
|
||||||
{
|
|
||||||
"account": account,
|
|
||||||
"from": from_date,
|
|
||||||
"to": to_date,
|
|
||||||
},
|
|
||||||
as_dict=1,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
pos_sales_invoices, pos_purchase_invoices = [], []
|
acc = frappe.qb.DocType("Account")
|
||||||
|
|
||||||
|
pi = frappe.qb.DocType("Purchase Invoice")
|
||||||
|
|
||||||
|
paid_purchase_invoices_query = (
|
||||||
|
frappe.qb.from_(pi)
|
||||||
|
.inner_join(acc)
|
||||||
|
.on(pi.cash_bank_account == acc.name)
|
||||||
|
.select(
|
||||||
|
ConstantColumn("Purchase Invoice").as_("payment_document"),
|
||||||
|
pi.name.as_("payment_entry"),
|
||||||
|
pi.paid_amount.as_("credit"),
|
||||||
|
pi.posting_date,
|
||||||
|
pi.supplier.as_("against_account"),
|
||||||
|
pi.bill_no.as_("cheque_number"),
|
||||||
|
pi.clearance_date,
|
||||||
|
acc.account_currency,
|
||||||
|
ConstantColumn(0).as_("debit"),
|
||||||
|
)
|
||||||
|
.where(
|
||||||
|
(pi.docstatus == 1)
|
||||||
|
& (pi.is_paid == 1)
|
||||||
|
& (pi.cash_bank_account == account)
|
||||||
|
& (pi.posting_date >= from_date)
|
||||||
|
& (pi.posting_date <= to_date)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if not include_reconciled_entries:
|
||||||
|
paid_purchase_invoices_query = paid_purchase_invoices_query.where(
|
||||||
|
(pi.clearance_date.isnull()) | (pi.clearance_date == "0000-00-00")
|
||||||
|
)
|
||||||
|
|
||||||
|
paid_purchase_invoices = (
|
||||||
|
paid_purchase_invoices_query.orderby(pi.posting_date).orderby(pi.name, order=Order.desc)
|
||||||
|
).run(as_dict=True)
|
||||||
|
|
||||||
|
pos_sales_invoices = []
|
||||||
|
|
||||||
if include_pos_transactions:
|
if include_pos_transactions:
|
||||||
si_payment = frappe.qb.DocType("Sales Invoice Payment")
|
si_payment = frappe.qb.DocType("Sales Invoice Payment")
|
||||||
si = frappe.qb.DocType("Sales Invoice")
|
si = frappe.qb.DocType("Sales Invoice")
|
||||||
acc = frappe.qb.DocType("Account")
|
|
||||||
|
|
||||||
pos_sales_invoices = (
|
pos_sales_invoices_query = (
|
||||||
frappe.qb.from_(si_payment)
|
frappe.qb.from_(si_payment)
|
||||||
.inner_join(si)
|
.inner_join(si)
|
||||||
.on(si_payment.parent == si.name)
|
.on(si_payment.parent == si.name)
|
||||||
@@ -263,38 +362,22 @@ def get_payment_entries_for_bank_clearance(
|
|||||||
& (si.posting_date >= from_date)
|
& (si.posting_date >= from_date)
|
||||||
& (si.posting_date <= to_date)
|
& (si.posting_date <= to_date)
|
||||||
)
|
)
|
||||||
.orderby(si.posting_date)
|
)
|
||||||
.orderby(si.name, order=Order.desc)
|
|
||||||
).run(as_dict=True)
|
|
||||||
|
|
||||||
pi = frappe.qb.DocType("Purchase Invoice")
|
if not include_reconciled_entries:
|
||||||
|
pos_sales_invoices_query = pos_sales_invoices_query.where(
|
||||||
|
(si_payment.clearance_date.isnull()) | (si_payment.clearance_date == "0000-00-00")
|
||||||
|
)
|
||||||
|
|
||||||
pos_purchase_invoices = (
|
pos_sales_invoices = (
|
||||||
frappe.qb.from_(pi)
|
pos_sales_invoices_query.orderby(si.posting_date).orderby(si.name, order=Order.desc)
|
||||||
.inner_join(acc)
|
|
||||||
.on(pi.cash_bank_account == acc.name)
|
|
||||||
.select(
|
|
||||||
ConstantColumn("Purchase Invoice").as_("payment_document"),
|
|
||||||
pi.name.as_("payment_entry"),
|
|
||||||
pi.paid_amount.as_("credit"),
|
|
||||||
pi.posting_date,
|
|
||||||
pi.supplier.as_("against_account"),
|
|
||||||
pi.clearance_date,
|
|
||||||
acc.account_currency,
|
|
||||||
ConstantColumn(0).as_("debit"),
|
|
||||||
)
|
|
||||||
.where(
|
|
||||||
(pi.docstatus == 1)
|
|
||||||
& (pi.cash_bank_account == account)
|
|
||||||
& (pi.posting_date >= from_date)
|
|
||||||
& (pi.posting_date <= to_date)
|
|
||||||
)
|
|
||||||
.orderby(pi.posting_date)
|
|
||||||
.orderby(pi.name, order=Order.desc)
|
|
||||||
).run(as_dict=True)
|
).run(as_dict=True)
|
||||||
|
|
||||||
entries = (
|
entries = (
|
||||||
list(payment_entries) + list(journal_entries) + list(pos_sales_invoices) + list(pos_purchase_invoices)
|
list(payment_entries)
|
||||||
|
+ list(journal_entries)
|
||||||
|
+ list(pos_sales_invoices)
|
||||||
|
+ list(paid_purchase_invoices)
|
||||||
)
|
)
|
||||||
|
|
||||||
return entries
|
return entries
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import add_months, getdate
|
from frappe.utils import add_months, getdate
|
||||||
|
|
||||||
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
|
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
|
||||||
@@ -14,13 +13,12 @@ from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make
|
|||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
from erpnext.stock.doctype.item.test_item import create_item
|
from erpnext.stock.doctype.item.test_item import create_item
|
||||||
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||||
from erpnext.tests.utils import if_lending_app_installed, if_lending_app_not_installed
|
from erpnext.tests.utils import ERPNextTestSuite, if_lending_app_installed, if_lending_app_not_installed
|
||||||
|
|
||||||
|
|
||||||
class TestBankClearance(IntegrationTestCase):
|
class TestBankClearance(ERPNextTestSuite):
|
||||||
@classmethod
|
def setUp(self):
|
||||||
def setUpClass(cls):
|
frappe.clear_cache()
|
||||||
super().setUpClass()
|
|
||||||
create_warehouse(
|
create_warehouse(
|
||||||
warehouse_name="_Test Warehouse",
|
warehouse_name="_Test Warehouse",
|
||||||
properties={"parent_warehouse": "All Warehouses - _TC"},
|
properties={"parent_warehouse": "All Warehouses - _TC"},
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
from frappe.tests import IntegrationTestCase
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestBankGuarantee(IntegrationTestCase):
|
class TestBankGuarantee(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ def get_bank_transactions(
|
|||||||
filters.append(["date", "<=", to_date])
|
filters.append(["date", "<=", to_date])
|
||||||
if from_date:
|
if from_date:
|
||||||
filters.append(["date", ">=", from_date])
|
filters.append(["date", ">=", from_date])
|
||||||
transactions = frappe.get_all(
|
transactions = frappe.get_list(
|
||||||
"Bank Transaction",
|
"Bank Transaction",
|
||||||
fields=[
|
fields=[
|
||||||
"date",
|
"date",
|
||||||
@@ -84,6 +84,7 @@ def get_bank_transactions(
|
|||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_account_balance(bank_account: str, till_date: str | date, company: str):
|
def get_account_balance(bank_account: str, till_date: str | date, company: str):
|
||||||
# returns account balance till the specified date
|
# returns account balance till the specified date
|
||||||
|
frappe.has_permission("Bank Account", "read", bank_account, throw=True)
|
||||||
account = frappe.db.get_value("Bank Account", bank_account, "account")
|
account = frappe.db.get_value("Bank Account", bank_account, "account")
|
||||||
filters = frappe._dict(
|
filters = frappe._dict(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import qb
|
from frappe import qb
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import add_days, today
|
from frappe.utils import add_days, today
|
||||||
|
|
||||||
from erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool import (
|
from erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool import (
|
||||||
@@ -13,9 +12,10 @@ from erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool
|
|||||||
)
|
)
|
||||||
from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry
|
from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry
|
||||||
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
|
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestBankReconciliationTool(AccountsTestMixin, IntegrationTestCase):
|
class TestBankReconciliationTool(AccountsTestMixin, ERPNextTestSuite):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.create_company()
|
self.create_company()
|
||||||
self.create_customer()
|
self.create_customer()
|
||||||
@@ -24,9 +24,6 @@ class TestBankReconciliationTool(AccountsTestMixin, IntegrationTestCase):
|
|||||||
qb.from_(bank_dt).delete().where(bank_dt.name == "HDFC").run()
|
qb.from_(bank_dt).delete().where(bank_dt.name == "HDFC").run()
|
||||||
self.create_bank_account()
|
self.create_bank_account()
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
frappe.db.rollback()
|
|
||||||
|
|
||||||
def create_bank_account(self):
|
def create_bank_account(self):
|
||||||
bank = frappe.get_doc(
|
bank = frappe.get_doc(
|
||||||
{
|
{
|
||||||
@@ -43,6 +40,7 @@ class TestBankReconciliationTool(AccountsTestMixin, IntegrationTestCase):
|
|||||||
"bank": bank.name,
|
"bank": bank.name,
|
||||||
"is_company_account": True,
|
"is_company_account": True,
|
||||||
"account": self.bank, # account from Chart of Accounts
|
"account": self.bank, # account from Chart of Accounts
|
||||||
|
"company": self.company,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.insert()
|
.insert()
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
# Copyright (c) 2020, Frappe Technologies and Contributors
|
# Copyright (c) 2020, Frappe Technologies and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.bank_statement_import.bank_statement_import import (
|
from erpnext.accounts.doctype.bank_statement_import.bank_statement_import import (
|
||||||
is_mt940_format,
|
is_mt940_format,
|
||||||
preprocess_mt940_content,
|
preprocess_mt940_content,
|
||||||
)
|
)
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestBankStatementImport(unittest.TestCase):
|
class TestBankStatementImport(ERPNextTestSuite):
|
||||||
"""Unit tests for Bank Statement Import functions"""
|
"""Unit tests for Bank Statement Import functions"""
|
||||||
|
|
||||||
def test_preprocess_mt940_content_with_long_statement_number(self):
|
def test_preprocess_mt940_content_with_long_statement_number(self):
|
||||||
|
|||||||
@@ -2,27 +2,20 @@
|
|||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import nowdate
|
from frappe.utils import nowdate
|
||||||
|
|
||||||
from erpnext.accounts.doctype.bank_transaction.test_bank_transaction import create_bank_account
|
from erpnext.accounts.doctype.bank_transaction.test_bank_transaction import create_bank_account
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
IBAN_1 = "DE02000000003716541159"
|
IBAN_1 = "DE02000000003716541159"
|
||||||
IBAN_2 = "DE02500105170137075030"
|
IBAN_2 = "DE02500105170137075030"
|
||||||
|
|
||||||
|
|
||||||
class TestAutoMatchParty(IntegrationTestCase):
|
class TestAutoMatchParty(ERPNextTestSuite):
|
||||||
@classmethod
|
def setUp(self):
|
||||||
def setUpClass(cls):
|
|
||||||
create_bank_account()
|
create_bank_account()
|
||||||
frappe.db.set_single_value("Accounts Settings", "enable_party_matching", 1)
|
frappe.db.set_single_value("Accounts Settings", "enable_party_matching", 1)
|
||||||
frappe.db.set_single_value("Accounts Settings", "enable_fuzzy_matching", 1)
|
frappe.db.set_single_value("Accounts Settings", "enable_fuzzy_matching", 1)
|
||||||
return super().setUpClass()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def tearDownClass(cls):
|
|
||||||
frappe.db.set_single_value("Accounts Settings", "enable_party_matching", 0)
|
|
||||||
frappe.db.set_single_value("Accounts Settings", "enable_fuzzy_matching", 0)
|
|
||||||
|
|
||||||
def test_match_by_account_number(self):
|
def test_match_by_account_number(self):
|
||||||
create_supplier_for_match(account_no=IBAN_1[11:])
|
create_supplier_for_match(account_no=IBAN_1[11:])
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import json
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import utils
|
from frappe import utils
|
||||||
from frappe.model.docstatus import DocStatus
|
from frappe.model.docstatus import DocStatus
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool import (
|
from erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool import (
|
||||||
get_linked_payments,
|
get_linked_payments,
|
||||||
@@ -19,12 +18,10 @@ from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_paymen
|
|||||||
from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profile
|
from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profile
|
||||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
|
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
from erpnext.tests.utils import if_lending_app_installed
|
from erpnext.tests.utils import ERPNextTestSuite, if_lending_app_installed
|
||||||
|
|
||||||
EXTRA_TEST_RECORD_DEPENDENCIES = ["Item", "Cost Center"]
|
|
||||||
|
|
||||||
|
|
||||||
class TestBankTransaction(IntegrationTestCase):
|
class TestBankTransaction(ERPNextTestSuite):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
make_pos_profile()
|
make_pos_profile()
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
# import frappe
|
# import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
|
|
||||||
|
|
||||||
class TestBisectAccountingStatements(IntegrationTestCase):
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
|
class TestBisectAccountingStatements(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
# import frappe
|
# import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
|
|
||||||
|
|
||||||
class TestBisectNodes(IntegrationTestCase):
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
|
class TestBisectNodes(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -17,12 +17,6 @@ from erpnext.tests.utils import ERPNextTestSuite
|
|||||||
|
|
||||||
|
|
||||||
class TestBudget(ERPNextTestSuite):
|
class TestBudget(ERPNextTestSuite):
|
||||||
@classmethod
|
|
||||||
def setUpClass(cls):
|
|
||||||
super().setUpClass()
|
|
||||||
cls.make_monthly_distribution()
|
|
||||||
cls.make_projects()
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
frappe.db.set_single_value("Accounts Settings", "use_legacy_budget_controller", False)
|
frappe.db.set_single_value("Accounts Settings", "use_legacy_budget_controller", False)
|
||||||
self.company = "_Test Company"
|
self.company = "_Test Company"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
from frappe.tests import IntegrationTestCase
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestCashierClosing(IntegrationTestCase):
|
class TestCashierClosing(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
from frappe.tests import IntegrationTestCase
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestChartofAccountsImporter(IntegrationTestCase):
|
class TestChartofAccountsImporter(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
from frappe.tests import IntegrationTestCase
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestChequePrintTemplate(IntegrationTestCase):
|
class TestChequePrintTemplate(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestCostCenter(IntegrationTestCase):
|
class TestCostCenter(ERPNextTestSuite):
|
||||||
def test_cost_center_creation_against_child_node(self):
|
def test_cost_center_creation_against_child_node(self):
|
||||||
cost_center = frappe.get_doc(
|
cost_center = frappe.get_doc(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"company": "_Test Company",
|
|
||||||
"cost_center_name": "_Test Cost Center",
|
|
||||||
"doctype": "Cost Center",
|
|
||||||
"is_group": 0,
|
|
||||||
"parent_cost_center": "_Test Company - _TC"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"company": "_Test Company",
|
|
||||||
"cost_center_name": "_Test Cost Center 2",
|
|
||||||
"doctype": "Cost Center",
|
|
||||||
"is_group": 0,
|
|
||||||
"parent_cost_center": "_Test Company - _TC"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"company": "_Test Company",
|
|
||||||
"cost_center_name": "_Test Write Off Cost Center",
|
|
||||||
"doctype": "Cost Center",
|
|
||||||
"is_group": 0,
|
|
||||||
"parent_cost_center": "_Test Company - _TC"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.query_builder.functions import Sum
|
from frappe.query_builder.functions import Sum
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import add_days, today
|
from frappe.utils import add_days, today
|
||||||
|
|
||||||
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
|
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
|
||||||
@@ -15,9 +14,10 @@ from erpnext.accounts.doctype.cost_center_allocation.cost_center_allocation impo
|
|||||||
WrongPercentageAllocation,
|
WrongPercentageAllocation,
|
||||||
)
|
)
|
||||||
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
|
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestCostCenterAllocation(IntegrationTestCase):
|
class TestCostCenterAllocation(ERPNextTestSuite):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
cost_centers = [
|
cost_centers = [
|
||||||
"Main Cost Center 1",
|
"Main Cost Center 1",
|
||||||
@@ -190,7 +190,7 @@ class TestCostCenterAllocation(IntegrationTestCase):
|
|||||||
coa2.cancel()
|
coa2.cancel()
|
||||||
jv.cancel()
|
jv.cancel()
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings("System Settings", {"rounding_method": "Commercial Rounding"})
|
@ERPNextTestSuite.change_settings("System Settings", {"rounding_method": "Commercial Rounding"})
|
||||||
def test_debit_credit_on_cost_center_allocation_for_commercial_rounding(self):
|
def test_debit_credit_on_cost_center_allocation_for_commercial_rounding(self):
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,9 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
|
|
||||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
EXTRA_TEST_RECORD_DEPENDENCIES = ["Item"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_create_test_data():
|
def test_create_test_data():
|
||||||
@@ -87,6 +85,7 @@ def test_create_test_data():
|
|||||||
"partner_name": "_Test Coupon Partner",
|
"partner_name": "_Test Coupon Partner",
|
||||||
"commission_rate": 2,
|
"commission_rate": 2,
|
||||||
"referral_code": "COPART",
|
"referral_code": "COPART",
|
||||||
|
"territory": "All Territories",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
sales_partner.insert()
|
sales_partner.insert()
|
||||||
@@ -109,13 +108,10 @@ def test_create_test_data():
|
|||||||
coupon_code.insert()
|
coupon_code.insert()
|
||||||
|
|
||||||
|
|
||||||
class TestCouponCode(IntegrationTestCase):
|
class TestCouponCode(ERPNextTestSuite):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
test_create_test_data()
|
test_create_test_data()
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
frappe.set_user("Administrator")
|
|
||||||
|
|
||||||
def test_sales_order_with_coupon_code(self):
|
def test_sales_order_with_coupon_code(self):
|
||||||
frappe.db.set_value("Coupon Code", "SAVE30", "used", 0)
|
frappe.db.set_value("Coupon Code", "SAVE30", "used", 0)
|
||||||
|
|
||||||
|
|||||||
@@ -101,11 +101,11 @@
|
|||||||
"label": "Use HTTP Protocol"
|
"label": "Use HTTP Protocol"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"hide_toolbar": 1,
|
"hide_toolbar": 0,
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2026-01-02 18:19:02.873815",
|
"modified": "2026-03-16 13:28:21.075743",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Currency Exchange Settings",
|
"name": "Currency Exchange Settings",
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
# import frappe
|
# import frappe
|
||||||
|
|
||||||
from frappe.tests import IntegrationTestCase
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestCurrencyExchangeSettings(IntegrationTestCase):
|
class TestCurrencyExchangeSettings(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -4,37 +4,20 @@ import json
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.model import mapper
|
from frappe.model import mapper
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import add_days, nowdate, today
|
from frappe.utils import add_days, nowdate, today
|
||||||
|
|
||||||
from erpnext import get_default_cost_center
|
from erpnext import get_default_cost_center
|
||||||
from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
|
from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
|
||||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import (
|
|
||||||
unlink_payment_on_cancel_of_invoice,
|
|
||||||
)
|
|
||||||
from erpnext.accounts.doctype.sales_invoice.sales_invoice import (
|
from erpnext.accounts.doctype.sales_invoice.sales_invoice import (
|
||||||
create_dunning as create_dunning_from_sales_invoice,
|
create_dunning as create_dunning_from_sales_invoice,
|
||||||
)
|
)
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import (
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import (
|
||||||
create_sales_invoice_against_cost_center,
|
create_sales_invoice_against_cost_center,
|
||||||
)
|
)
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
EXTRA_TEST_RECORD_DEPENDENCIES = ["Company", "Cost Center"]
|
|
||||||
|
|
||||||
|
|
||||||
class TestDunning(IntegrationTestCase):
|
class TestDunning(ERPNextTestSuite):
|
||||||
@classmethod
|
|
||||||
def setUpClass(cls):
|
|
||||||
super().setUpClass()
|
|
||||||
create_dunning_type("First Notice", fee=0.0, interest=0.0, is_default=1)
|
|
||||||
create_dunning_type("Second Notice", fee=10.0, interest=10.0, is_default=0)
|
|
||||||
unlink_payment_on_cancel_of_invoice()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def tearDownClass(cls):
|
|
||||||
unlink_payment_on_cancel_of_invoice(0)
|
|
||||||
super().tearDownClass()
|
|
||||||
|
|
||||||
def test_dunning_without_fees(self):
|
def test_dunning_without_fees(self):
|
||||||
dunning = create_dunning(overdue_days=20)
|
dunning = create_dunning(overdue_days=20)
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
# import frappe
|
# import frappe
|
||||||
|
|
||||||
from frappe.tests import IntegrationTestCase
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestDunningType(IntegrationTestCase):
|
class TestDunningType(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"doctype": "Dunning Type",
|
|
||||||
"dunning_type": "_Test First Notice",
|
|
||||||
"company": "_Test Company",
|
|
||||||
"is_default": 1,
|
|
||||||
"dunning_fee": 0.0,
|
|
||||||
"rate_of_interest": 0.0,
|
|
||||||
"dunning_letter_text": [
|
|
||||||
{
|
|
||||||
"language": "en",
|
|
||||||
"body_text": "We have still not received payment for our invoice",
|
|
||||||
"closing_text": "We kindly request that you pay the outstanding amount immediately, including interest and late fees."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"income_account": "Sales - _TC",
|
|
||||||
"cost_center": "_Test Cost Center - _TC"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "Dunning Type",
|
|
||||||
"dunning_type": "_Test Second Notice",
|
|
||||||
"company": "_Test Company",
|
|
||||||
"is_default": 0,
|
|
||||||
"dunning_fee": 10.0,
|
|
||||||
"rate_of_interest": 10.0,
|
|
||||||
"dunning_letter_text": [
|
|
||||||
{
|
|
||||||
"language": "en",
|
|
||||||
"body_text": "We have still not received payment for our invoice",
|
|
||||||
"closing_text": "We kindly request that you pay the outstanding amount immediately, including interest and late fees."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"income_account": "Sales - _TC",
|
|
||||||
"cost_center": "_Test Cost Center - _TC"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -5,15 +5,15 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.query_builder import functions
|
from frappe.query_builder import functions
|
||||||
from frappe.query_builder.utils import DocType
|
from frappe.query_builder.utils import DocType
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import add_days, flt, today
|
from frappe.utils import add_days, flt, today
|
||||||
|
|
||||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
|
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestExchangeRateRevaluation(AccountsTestMixin, IntegrationTestCase):
|
class TestExchangeRateRevaluation(AccountsTestMixin, ERPNextTestSuite):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.create_company()
|
self.create_company()
|
||||||
self.create_usd_receivable_account()
|
self.create_usd_receivable_account()
|
||||||
@@ -22,14 +22,13 @@ class TestExchangeRateRevaluation(AccountsTestMixin, IntegrationTestCase):
|
|||||||
self.clear_old_entries()
|
self.clear_old_entries()
|
||||||
self.set_system_and_company_settings()
|
self.set_system_and_company_settings()
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
frappe.db.rollback()
|
|
||||||
|
|
||||||
def set_system_and_company_settings(self):
|
def set_system_and_company_settings(self):
|
||||||
# set number and currency precision
|
# set number and currency precision
|
||||||
system_settings = frappe.get_doc("System Settings")
|
system_settings = frappe.get_doc("System Settings")
|
||||||
system_settings.float_precision = 2
|
system_settings.float_precision = 2
|
||||||
system_settings.currency_precision = 2
|
system_settings.currency_precision = 2
|
||||||
|
system_settings.language = "en"
|
||||||
|
system_settings.time_zone = "Asia/Kolkata"
|
||||||
system_settings.save()
|
system_settings.save()
|
||||||
|
|
||||||
# Using Exchange Gain/Loss account for unrealized as well.
|
# Using Exchange Gain/Loss account for unrealized as well.
|
||||||
@@ -37,7 +36,7 @@ class TestExchangeRateRevaluation(AccountsTestMixin, IntegrationTestCase):
|
|||||||
company_doc.unrealized_exchange_gain_loss_account = company_doc.exchange_gain_loss_account
|
company_doc.unrealized_exchange_gain_loss_account = company_doc.exchange_gain_loss_account
|
||||||
company_doc.save()
|
company_doc.save()
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings(
|
@ERPNextTestSuite.change_settings(
|
||||||
"Accounts Settings",
|
"Accounts Settings",
|
||||||
{"allow_multi_currency_invoices_against_single_party_account": 1, "allow_stale": 0},
|
{"allow_multi_currency_invoices_against_single_party_account": 1, "allow_stale": 0},
|
||||||
)
|
)
|
||||||
@@ -91,7 +90,7 @@ class TestExchangeRateRevaluation(AccountsTestMixin, IntegrationTestCase):
|
|||||||
)[0]
|
)[0]
|
||||||
self.assertEqual(acc_balance.balance, 8500.0)
|
self.assertEqual(acc_balance.balance, 8500.0)
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings(
|
@ERPNextTestSuite.change_settings(
|
||||||
"Accounts Settings",
|
"Accounts Settings",
|
||||||
{"allow_multi_currency_invoices_against_single_party_account": 1, "allow_stale": 0},
|
{"allow_multi_currency_invoices_against_single_party_account": 1, "allow_stale": 0},
|
||||||
)
|
)
|
||||||
@@ -164,7 +163,7 @@ class TestExchangeRateRevaluation(AccountsTestMixin, IntegrationTestCase):
|
|||||||
self.assertEqual(acc_balance.balance, 0.0)
|
self.assertEqual(acc_balance.balance, 0.0)
|
||||||
self.assertEqual(acc_balance.balance_in_account_currency, 0.0)
|
self.assertEqual(acc_balance.balance_in_account_currency, 0.0)
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings(
|
@ERPNextTestSuite.change_settings(
|
||||||
"Accounts Settings",
|
"Accounts Settings",
|
||||||
{"allow_multi_currency_invoices_against_single_party_account": 1, "allow_stale": 0},
|
{"allow_multi_currency_invoices_against_single_party_account": 1, "allow_stale": 0},
|
||||||
)
|
)
|
||||||
@@ -259,7 +258,7 @@ class TestExchangeRateRevaluation(AccountsTestMixin, IntegrationTestCase):
|
|||||||
self.assertEqual(flt(acc_balance.balance, precision), 0.0)
|
self.assertEqual(flt(acc_balance.balance, precision), 0.0)
|
||||||
self.assertEqual(flt(acc_balance.balance_in_account_currency, precision), 0.0)
|
self.assertEqual(flt(acc_balance.balance_in_account_currency, precision), 0.0)
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings(
|
@ERPNextTestSuite.change_settings(
|
||||||
"Accounts Settings",
|
"Accounts Settings",
|
||||||
{"allow_multi_currency_invoices_against_single_party_account": 1, "allow_stale": 0},
|
{"allow_multi_currency_invoices_against_single_party_account": 1, "allow_stale": 0},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
|
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestFinanceBook(IntegrationTestCase):
|
class TestFinanceBook(ERPNextTestSuite):
|
||||||
def test_finance_book(self):
|
def test_finance_book(self):
|
||||||
finance_book = create_finance_book()
|
finance_book = create_finance_book()
|
||||||
|
|
||||||
|
|||||||
@@ -16,12 +16,6 @@ from erpnext.accounts.doctype.financial_report_template.test_financial_report_te
|
|||||||
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
|
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
|
||||||
from erpnext.accounts.utils import get_currency_precision, get_fiscal_year
|
from erpnext.accounts.utils import get_currency_precision, get_fiscal_year
|
||||||
|
|
||||||
# On IntegrationTestCase, the doctype test records and all
|
|
||||||
# link-field test record dependencies are recursively loaded
|
|
||||||
# Use these module variables to add/remove to/from that list
|
|
||||||
EXTRA_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
|
|
||||||
IGNORE_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
|
|
||||||
|
|
||||||
|
|
||||||
class TestDependencyResolver(FinancialReportTemplateTestCase):
|
class TestDependencyResolver(FinancialReportTemplateTestCase):
|
||||||
"""Test cases for DependencyResolver class"""
|
"""Test cases for DependencyResolver class"""
|
||||||
|
|||||||
@@ -2,29 +2,16 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.tests.utils import make_test_records
|
|
||||||
|
|
||||||
# On IntegrationTestCase, the doctype test records and all
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
# link-field test record dependencies are recursively loaded
|
|
||||||
# Use these module variables to add/remove to/from that list
|
|
||||||
EXTRA_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
|
|
||||||
IGNORE_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
|
|
||||||
|
|
||||||
|
|
||||||
class TestFinancialReportTemplate(IntegrationTestCase):
|
class FinancialReportTemplateTestCase(ERPNextTestSuite):
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class FinancialReportTemplateTestCase(IntegrationTestCase):
|
|
||||||
"""Utility class with common setup and helper methods for all test classes"""
|
"""Utility class with common setup and helper methods for all test classes"""
|
||||||
|
|
||||||
@classmethod
|
def setUp(self):
|
||||||
def setUpClass(cls):
|
|
||||||
"""Set up test data"""
|
"""Set up test data"""
|
||||||
make_test_records("Company")
|
self.create_test_template()
|
||||||
make_test_records("Fiscal Year")
|
|
||||||
cls.create_test_template()
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_test_template(cls):
|
def create_test_template(cls):
|
||||||
|
|||||||
@@ -2,13 +2,12 @@
|
|||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import now_datetime
|
from frappe.utils import now_datetime
|
||||||
|
|
||||||
IGNORE_TEST_RECORD_DEPENDENCIES = ["Company"]
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestFiscalYear(IntegrationTestCase):
|
class TestFiscalYear(ERPNextTestSuite):
|
||||||
def test_extra_year(self):
|
def test_extra_year(self):
|
||||||
if frappe.db.exists("Fiscal Year", "_Test Fiscal Year 2000"):
|
if frappe.db.exists("Fiscal Year", "_Test Fiscal Year 2000"):
|
||||||
frappe.delete_doc("Fiscal Year", "_Test Fiscal Year 2000")
|
frappe.delete_doc("Fiscal Year", "_Test Fiscal Year 2000")
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Document",
|
"document_type": "Document",
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"is_submittable": 1,
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"dates_section",
|
"dates_section",
|
||||||
"posting_date",
|
"posting_date",
|
||||||
|
|||||||
@@ -489,4 +489,5 @@ def rename_temporarily_named_docs(doctype):
|
|||||||
for hook in frappe.get_hooks(hook_type):
|
for hook in frappe.get_hooks(hook_type):
|
||||||
frappe.call(hook, newname=newname, oldname=oldname)
|
frappe.call(hook, newname=newname, oldname=oldname)
|
||||||
|
|
||||||
frappe.db.commit()
|
if not frappe.in_test:
|
||||||
|
frappe.db.commit()
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.model.naming import parse_naming_series
|
from frappe.model.naming import parse_naming_series
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.gl_entry.gl_entry import rename_gle_sle_docs
|
from erpnext.accounts.doctype.gl_entry.gl_entry import rename_gle_sle_docs
|
||||||
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
|
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestGLEntry(IntegrationTestCase):
|
class TestGLEntry(ERPNextTestSuite):
|
||||||
def test_round_off_entry(self):
|
def test_round_off_entry(self):
|
||||||
frappe.db.set_value("Company", "_Test Company", "round_off_account", "_Test Write Off - _TC")
|
frappe.db.set_value("Company", "_Test Company", "round_off_account", "_Test Write Off - _TC")
|
||||||
frappe.db.set_value("Company", "_Test Company", "round_off_cost_center", "_Test Cost Center - _TC")
|
frappe.db.set_value("Company", "_Test Company", "round_off_cost_center", "_Test Cost Center - _TC")
|
||||||
|
|||||||
@@ -2,16 +2,16 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import add_days, flt, nowdate
|
from frappe.utils import add_days, flt, nowdate
|
||||||
|
|
||||||
from erpnext.accounts.doctype.account.test_account import create_account
|
from erpnext.accounts.doctype.account.test_account import create_account
|
||||||
from erpnext.accounts.doctype.journal_entry.journal_entry import get_payment_entry_against_invoice
|
from erpnext.accounts.doctype.journal_entry.journal_entry import get_payment_entry_against_invoice
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import get_gl_entries
|
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import get_gl_entries
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestInvoiceDiscounting(IntegrationTestCase):
|
class TestInvoiceDiscounting(ERPNextTestSuite):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.ar_credit = create_account(
|
self.ar_credit = create_account(
|
||||||
account_name="_Test Accounts Receivable Credit",
|
account_name="_Test Accounts Receivable Credit",
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
from frappe.tests import IntegrationTestCase
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestItemTaxTemplate(IntegrationTestCase):
|
class TestItemTaxTemplate(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"doctype": "Item Tax Template",
|
|
||||||
"title": "_Test Account Excise Duty @ 10",
|
|
||||||
"company": "_Test Company",
|
|
||||||
"taxes": [
|
|
||||||
{
|
|
||||||
"doctype": "Item Tax Template Detail",
|
|
||||||
"parentfield": "taxes",
|
|
||||||
"tax_rate": 10,
|
|
||||||
"tax_type": "_Test Account Excise Duty - _TC"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "Item Tax Template",
|
|
||||||
"title": "_Test Account Excise Duty @ 12",
|
|
||||||
"company": "_Test Company",
|
|
||||||
"taxes": [
|
|
||||||
{
|
|
||||||
"doctype": "Item Tax Template Detail",
|
|
||||||
"parentfield": "taxes",
|
|
||||||
"tax_rate": 12,
|
|
||||||
"tax_type": "_Test Account Excise Duty - _TC"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "Item Tax Template",
|
|
||||||
"title": "_Test Account Excise Duty @ 15",
|
|
||||||
"company": "_Test Company",
|
|
||||||
"taxes": [
|
|
||||||
{
|
|
||||||
"doctype": "Item Tax Template Detail",
|
|
||||||
"parentfield": "taxes",
|
|
||||||
"tax_rate": 15,
|
|
||||||
"tax_type": "_Test Account Excise Duty - _TC"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "Item Tax Template",
|
|
||||||
"title": "_Test Account Excise Duty @ 20",
|
|
||||||
"company": "_Test Company",
|
|
||||||
"taxes": [
|
|
||||||
{
|
|
||||||
"doctype": "Item Tax Template Detail",
|
|
||||||
"parentfield": "taxes",
|
|
||||||
"tax_rate": 20,
|
|
||||||
"tax_type": "_Test Account Excise Duty - _TC"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "Item Tax Template",
|
|
||||||
"title": "_Test Item Tax Template 1",
|
|
||||||
"company": "_Test Company",
|
|
||||||
"taxes": [
|
|
||||||
{
|
|
||||||
"doctype": "Item Tax Template Detail",
|
|
||||||
"parentfield": "taxes",
|
|
||||||
"tax_rate": 5,
|
|
||||||
"tax_type": "_Test Account Excise Duty - _TC"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "Item Tax Template Detail",
|
|
||||||
"parentfield": "taxes",
|
|
||||||
"tax_rate": 10,
|
|
||||||
"tax_type": "_Test Account Education Cess - _TC"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "Item Tax Template Detail",
|
|
||||||
"parentfield": "taxes",
|
|
||||||
"tax_rate": 15,
|
|
||||||
"tax_type": "_Test Account S&H Education Cess - _TC"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -140,6 +140,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "company",
|
"fieldname": "company",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Company",
|
"label": "Company",
|
||||||
"oldfieldname": "company",
|
"oldfieldname": "company",
|
||||||
@@ -181,7 +182,6 @@
|
|||||||
"fieldname": "cheque_no",
|
"fieldname": "cheque_no",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_global_search": 1,
|
"in_global_search": 1,
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Reference Number",
|
"label": "Reference Number",
|
||||||
"mandatory_depends_on": "eval:doc.voucher_type == \"Bank Entry\"",
|
"mandatory_depends_on": "eval:doc.voucher_type == \"Bank Entry\"",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
@@ -665,7 +665,7 @@
|
|||||||
"table_fieldname": "payment_entries"
|
"table_fieldname": "payment_entries"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2026-02-16 16:06:10.468482",
|
"modified": "2026-03-09 17:15:26.569327",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Journal Entry",
|
"name": "Journal Entry",
|
||||||
|
|||||||
@@ -294,6 +294,8 @@ class JournalEntry(AccountsController):
|
|||||||
|
|
||||||
# References for this Journal are removed on the `on_cancel` event in accounts_controller
|
# References for this Journal are removed on the `on_cancel` event in accounts_controller
|
||||||
super().on_cancel()
|
super().on_cancel()
|
||||||
|
|
||||||
|
from_doc_events = getattr(self, "ignore_linked_doctypes", ())
|
||||||
self.ignore_linked_doctypes = (
|
self.ignore_linked_doctypes = (
|
||||||
"GL Entry",
|
"GL Entry",
|
||||||
"Stock Ledger Entry",
|
"Stock Ledger Entry",
|
||||||
@@ -307,6 +309,10 @@ class JournalEntry(AccountsController):
|
|||||||
"Advance Payment Ledger Entry",
|
"Advance Payment Ledger Entry",
|
||||||
"Tax Withholding Entry",
|
"Tax Withholding Entry",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if from_doc_events and from_doc_events != self.ignore_linked_doctypes:
|
||||||
|
self.ignore_linked_doctypes = self.ignore_linked_doctypes + from_doc_events
|
||||||
|
|
||||||
self.make_gl_entries(1)
|
self.make_gl_entries(1)
|
||||||
JournalTaxWithholding(self).on_cancel()
|
JournalTaxWithholding(self).on_cancel()
|
||||||
self.unlink_advance_entry_reference()
|
self.unlink_advance_entry_reference()
|
||||||
|
|||||||
@@ -2,19 +2,20 @@
|
|||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import flt, nowdate
|
from frappe.utils import flt, nowdate
|
||||||
|
|
||||||
from erpnext.accounts.doctype.account.test_account import get_inventory_account
|
from erpnext.accounts.doctype.account.test_account import get_inventory_account
|
||||||
from erpnext.accounts.doctype.journal_entry.journal_entry import StockAccountInvalidTransaction
|
from erpnext.accounts.doctype.journal_entry.journal_entry import StockAccountInvalidTransaction
|
||||||
from erpnext.exceptions import InvalidAccountCurrency
|
from erpnext.exceptions import InvalidAccountCurrency
|
||||||
from erpnext.selling.doctype.customer.test_customer import make_customer, set_credit_limit
|
from erpnext.selling.doctype.customer.test_customer import make_customer, set_credit_limit
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestJournalEntry(IntegrationTestCase):
|
class TestJournalEntry(ERPNextTestSuite):
|
||||||
@IntegrationTestCase.change_settings(
|
def setUp(self):
|
||||||
"Accounts Settings", {"unlink_payment_on_cancellation_of_invoice": 1}
|
self.load_test_records("Journal Entry")
|
||||||
)
|
|
||||||
|
@ERPNextTestSuite.change_settings("Accounts Settings", {"unlink_payment_on_cancellation_of_invoice": 1})
|
||||||
def test_journal_entry_with_against_jv(self):
|
def test_journal_entry_with_against_jv(self):
|
||||||
jv_invoice = frappe.copy_doc(self.globalTestRecords["Journal Entry"][2])
|
jv_invoice = frappe.copy_doc(self.globalTestRecords["Journal Entry"][2])
|
||||||
base_jv = frappe.copy_doc(self.globalTestRecords["Journal Entry"][0])
|
base_jv = frappe.copy_doc(self.globalTestRecords["Journal Entry"][0])
|
||||||
@@ -149,7 +150,6 @@ class TestJournalEntry(IntegrationTestCase):
|
|||||||
|
|
||||||
if account_bal == stock_bal:
|
if account_bal == stock_bal:
|
||||||
self.assertRaises(StockAccountInvalidTransaction, jv.save)
|
self.assertRaises(StockAccountInvalidTransaction, jv.save)
|
||||||
frappe.db.rollback()
|
|
||||||
else:
|
else:
|
||||||
jv.submit()
|
jv.submit()
|
||||||
jv.cancel()
|
jv.cancel()
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
# import frappe
|
# import frappe
|
||||||
|
|
||||||
from frappe.tests import IntegrationTestCase
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestJournalEntryTemplate(IntegrationTestCase):
|
class TestJournalEntryTemplate(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -3,23 +3,20 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import qb
|
from frappe import qb
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import nowdate
|
from frappe.utils import nowdate
|
||||||
|
|
||||||
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
|
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
|
||||||
from erpnext.accounts.utils import run_ledger_health_checks
|
from erpnext.accounts.utils import run_ledger_health_checks
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestLedgerHealth(AccountsTestMixin, IntegrationTestCase):
|
class TestLedgerHealth(AccountsTestMixin, ERPNextTestSuite):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.create_company()
|
self.create_company()
|
||||||
self.create_customer()
|
self.create_customer()
|
||||||
self.configure_monitoring_tool()
|
self.configure_monitoring_tool()
|
||||||
self.clear_old_entries()
|
self.clear_old_entries()
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
frappe.db.rollback()
|
|
||||||
|
|
||||||
def configure_monitoring_tool(self):
|
def configure_monitoring_tool(self):
|
||||||
monitor_settings = frappe.get_doc("Ledger Health Monitor")
|
monitor_settings = frappe.get_doc("Ledger Health Monitor")
|
||||||
monitor_settings.enable_health_monitor = True
|
monitor_settings.enable_health_monitor = True
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
# import frappe
|
# import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
|
|
||||||
|
|
||||||
class TestLedgerHealthMonitor(IntegrationTestCase):
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
|
class TestLedgerHealthMonitor(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -71,14 +71,16 @@ def start_merge(docname):
|
|||||||
ledger_merge.account,
|
ledger_merge.account,
|
||||||
)
|
)
|
||||||
row.db_set("merged", 1)
|
row.db_set("merged", 1)
|
||||||
frappe.db.commit()
|
if not frappe.in_test:
|
||||||
|
frappe.db.commit()
|
||||||
successful_merges += 1
|
successful_merges += 1
|
||||||
frappe.publish_realtime(
|
frappe.publish_realtime(
|
||||||
"ledger_merge_progress",
|
"ledger_merge_progress",
|
||||||
{"ledger_merge": ledger_merge.name, "current": successful_merges, "total": total},
|
{"ledger_merge": ledger_merge.name, "current": successful_merges, "total": total},
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
frappe.db.rollback()
|
if not frappe.in_test:
|
||||||
|
frappe.db.rollback()
|
||||||
ledger_merge.log_error("Ledger merge failed")
|
ledger_merge.log_error("Ledger merge failed")
|
||||||
finally:
|
finally:
|
||||||
if successful_merges == total:
|
if successful_merges == total:
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.ledger_merge.ledger_merge import start_merge
|
from erpnext.accounts.doctype.ledger_merge.ledger_merge import start_merge
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestLedgerMerge(IntegrationTestCase):
|
class TestLedgerMerge(ERPNextTestSuite):
|
||||||
def test_merge_success(self):
|
def test_merge_success(self):
|
||||||
if not frappe.db.exists("Account", "Indirect Expenses - _TC"):
|
if not frappe.db.exists("Account", "Indirect Expenses - _TC"):
|
||||||
acc = frappe.new_doc("Account")
|
acc = frappe.new_doc("Account")
|
||||||
@@ -100,16 +100,3 @@ class TestLedgerMerge(IntegrationTestCase):
|
|||||||
|
|
||||||
self.assertFalse(frappe.db.exists("Account", "Indirect Test Income - _TC"))
|
self.assertFalse(frappe.db.exists("Account", "Indirect Test Income - _TC"))
|
||||||
self.assertTrue(frappe.db.exists("Account", "Administrative Test Income - _TC"))
|
self.assertTrue(frappe.db.exists("Account", "Administrative Test Income - _TC"))
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
for entry in frappe.db.get_all("Ledger Merge"):
|
|
||||||
frappe.delete_doc("Ledger Merge", entry.name)
|
|
||||||
|
|
||||||
test_accounts = [
|
|
||||||
"Indirect Test Expenses - _TC",
|
|
||||||
"Administrative Test Expenses - _TC",
|
|
||||||
"Indirect Test Income - _TC",
|
|
||||||
"Administrative Test Income - _TC",
|
|
||||||
]
|
|
||||||
for account in test_accounts:
|
|
||||||
frappe.delete_doc_if_exists("Account", account)
|
|
||||||
|
|||||||
@@ -2,31 +2,20 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import today
|
from frappe.utils import today
|
||||||
|
|
||||||
from erpnext.accounts.doctype.loyalty_program.test_loyalty_program import create_records
|
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestLoyaltyPointEntry(IntegrationTestCase):
|
class TestLoyaltyPointEntry(ERPNextTestSuite):
|
||||||
@classmethod
|
def setUp(self):
|
||||||
def setUpClass(cls):
|
|
||||||
super().setUpClass()
|
|
||||||
# Create test records
|
# Create test records
|
||||||
create_records()
|
self.loyalty_program_name = "Test Single Loyalty"
|
||||||
cls.loyalty_program_name = "Test Single Loyalty"
|
self.customer_name = "Test Loyalty Customer"
|
||||||
cls.customer_name = "Test Loyalty Customer"
|
customer = frappe.get_doc("Customer", self.customer_name)
|
||||||
customer = frappe.get_doc("Customer", cls.customer_name)
|
customer.loyalty_program = self.loyalty_program_name
|
||||||
customer.db_set("loyalty_program", cls.loyalty_program_name)
|
customer.save()
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def tearDownClass(cls):
|
|
||||||
# Delete all Loyalty Point Entries
|
|
||||||
frappe.db.sql("DELETE FROM `tabLoyalty Point Entry` WHERE customer = %s", cls.customer_name)
|
|
||||||
frappe.db.sql("DELETE FROM `tabSales Invoice` WHERE customer = %s", cls.customer_name)
|
|
||||||
frappe.db.commit()
|
|
||||||
# cls.customer.delete()
|
|
||||||
|
|
||||||
def create_test_invoice(self, redeem=None):
|
def create_test_invoice(self, redeem=None):
|
||||||
if redeem:
|
if redeem:
|
||||||
@@ -68,9 +57,10 @@ class TestLoyaltyPointEntry(IntegrationTestCase):
|
|||||||
self.assertEqual(entry.discretionary_reason, "Customer Appreciation")
|
self.assertEqual(entry.discretionary_reason, "Customer Appreciation")
|
||||||
|
|
||||||
def test_redeem_loyalty_points(self):
|
def test_redeem_loyalty_points(self):
|
||||||
self.create_test_invoice(redeem=10)
|
self.create_test_invoice()
|
||||||
|
self.create_test_invoice(redeem=7)
|
||||||
doc = frappe.get_last_doc("Loyalty Point Entry")
|
doc = frappe.get_last_doc("Loyalty Point Entry")
|
||||||
self.assertEqual(doc.loyalty_points, -10)
|
self.assertEqual(doc.loyalty_points, -7)
|
||||||
|
|
||||||
# Check balance
|
# Check balance
|
||||||
balance = frappe.db.sql(
|
balance = frappe.db.sql(
|
||||||
@@ -82,4 +72,4 @@ class TestLoyaltyPointEntry(IntegrationTestCase):
|
|||||||
(self.customer_name,),
|
(self.customer_name,),
|
||||||
)[0][0]
|
)[0][0]
|
||||||
|
|
||||||
self.assertEqual(balance, 75) # 85 added, 10 redeemed
|
self.assertEqual(balance, 3) # 10 added, 7 redeemed
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import cint, flt, getdate, today
|
from frappe.utils import cint, flt, getdate, today
|
||||||
|
|
||||||
from erpnext.accounts.doctype.loyalty_program.loyalty_program import (
|
from erpnext.accounts.doctype.loyalty_program.loyalty_program import (
|
||||||
@@ -11,15 +10,10 @@ from erpnext.accounts.doctype.loyalty_program.loyalty_program import (
|
|||||||
get_loyalty_program_details_with_points,
|
get_loyalty_program_details_with_points,
|
||||||
)
|
)
|
||||||
from erpnext.accounts.party import get_dashboard_info
|
from erpnext.accounts.party import get_dashboard_info
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestLoyaltyProgram(IntegrationTestCase):
|
class TestLoyaltyProgram(ERPNextTestSuite):
|
||||||
@classmethod
|
|
||||||
def setUpClass(cls):
|
|
||||||
super().setUpClass()
|
|
||||||
# create relevant item, customer, loyalty program, etc
|
|
||||||
create_records()
|
|
||||||
|
|
||||||
def test_loyalty_points_earned_single_tier(self):
|
def test_loyalty_points_earned_single_tier(self):
|
||||||
frappe.db.set_value("Customer", "Test Loyalty Customer", "loyalty_program", "Test Single Loyalty")
|
frappe.db.set_value("Customer", "Test Loyalty Customer", "loyalty_program", "Test Single Loyalty")
|
||||||
# create a new sales invoice
|
# create a new sales invoice
|
||||||
@@ -323,96 +317,3 @@ def create_sales_invoice_record(qty=1):
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_records():
|
|
||||||
# create a new loyalty Account
|
|
||||||
if not frappe.db.exists("Account", "Loyalty - _TC"):
|
|
||||||
frappe.get_doc(
|
|
||||||
{
|
|
||||||
"doctype": "Account",
|
|
||||||
"account_name": "Loyalty",
|
|
||||||
"parent_account": "Direct Expenses - _TC",
|
|
||||||
"company": "_Test Company",
|
|
||||||
"is_group": 0,
|
|
||||||
"account_type": "Expense Account",
|
|
||||||
}
|
|
||||||
).insert()
|
|
||||||
|
|
||||||
# create a new loyalty program Single tier
|
|
||||||
if not frappe.db.exists("Loyalty Program", "Test Single Loyalty"):
|
|
||||||
frappe.get_doc(
|
|
||||||
{
|
|
||||||
"doctype": "Loyalty Program",
|
|
||||||
"loyalty_program_name": "Test Single Loyalty",
|
|
||||||
"auto_opt_in": 1,
|
|
||||||
"from_date": today(),
|
|
||||||
"loyalty_program_type": "Single Tier Program",
|
|
||||||
"conversion_factor": 1,
|
|
||||||
"expiry_duration": 10,
|
|
||||||
"company": "_Test Company",
|
|
||||||
"cost_center": "Main - _TC",
|
|
||||||
"expense_account": "Loyalty - _TC",
|
|
||||||
"collection_rules": [{"tier_name": "Bronce", "collection_factor": 1000, "min_spent": 0}],
|
|
||||||
}
|
|
||||||
).insert()
|
|
||||||
|
|
||||||
# create a new customer
|
|
||||||
if not frappe.db.exists("Customer", "Test Loyalty Customer"):
|
|
||||||
frappe.get_doc(
|
|
||||||
{
|
|
||||||
"customer_group": "_Test Customer Group",
|
|
||||||
"customer_name": "Test Loyalty Customer",
|
|
||||||
"customer_type": "Individual",
|
|
||||||
"doctype": "Customer",
|
|
||||||
"territory": "_Test Territory",
|
|
||||||
}
|
|
||||||
).insert()
|
|
||||||
|
|
||||||
# create a new loyalty program Multiple tier
|
|
||||||
if not frappe.db.exists("Loyalty Program", "Test Multiple Loyalty"):
|
|
||||||
frappe.get_doc(
|
|
||||||
{
|
|
||||||
"doctype": "Loyalty Program",
|
|
||||||
"loyalty_program_name": "Test Multiple Loyalty",
|
|
||||||
"auto_opt_in": 1,
|
|
||||||
"from_date": today(),
|
|
||||||
"loyalty_program_type": "Multiple Tier Program",
|
|
||||||
"conversion_factor": 1,
|
|
||||||
"expiry_duration": 10,
|
|
||||||
"company": "_Test Company",
|
|
||||||
"cost_center": "Main - _TC",
|
|
||||||
"expense_account": "Loyalty - _TC",
|
|
||||||
"collection_rules": [
|
|
||||||
{"tier_name": "Bronze", "collection_factor": 1000, "min_spent": 0},
|
|
||||||
{"tier_name": "Silver", "collection_factor": 1000, "min_spent": 10000},
|
|
||||||
{"tier_name": "Gold", "collection_factor": 1000, "min_spent": 19000},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
).insert()
|
|
||||||
|
|
||||||
# create an item
|
|
||||||
if not frappe.db.exists("Item", "Loyal Item"):
|
|
||||||
frappe.get_doc(
|
|
||||||
{
|
|
||||||
"doctype": "Item",
|
|
||||||
"item_code": "Loyal Item",
|
|
||||||
"item_name": "Loyal Item",
|
|
||||||
"item_group": "All Item Groups",
|
|
||||||
"company": "_Test Company",
|
|
||||||
"is_stock_item": 1,
|
|
||||||
"opening_stock": 100,
|
|
||||||
"valuation_rate": 10000,
|
|
||||||
}
|
|
||||||
).insert()
|
|
||||||
|
|
||||||
# create item price
|
|
||||||
if not frappe.db.exists("Item Price", {"price_list": "Standard Selling", "item_code": "Loyal Item"}):
|
|
||||||
frappe.get_doc(
|
|
||||||
{
|
|
||||||
"doctype": "Item Price",
|
|
||||||
"price_list": "Standard Selling",
|
|
||||||
"item_code": "Loyal Item",
|
|
||||||
"price_list_rate": 10000,
|
|
||||||
}
|
|
||||||
).insert()
|
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestModeofPayment(IntegrationTestCase):
|
class TestModeofPayment(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and Contributors
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
from frappe.tests import IntegrationTestCase
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestMonthlyDistribution(IntegrationTestCase):
|
class TestMonthlyDistribution(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ frappe.ui.form.on("Opening Invoice Creation Tool", {
|
|||||||
|
|
||||||
refresh: function (frm) {
|
refresh: function (frm) {
|
||||||
frm.disable_save();
|
frm.disable_save();
|
||||||
|
frm.trigger("create_missing_party");
|
||||||
!frm.doc.import_in_progress && frm.trigger("make_dashboard");
|
!frm.doc.import_in_progress && frm.trigger("make_dashboard");
|
||||||
frm.page.set_primary_action(__("Create Invoices"), () => {
|
frm.page.set_primary_action(__("Create Invoices"), () => {
|
||||||
let btn_primary = frm.page.btn_primary.get(0);
|
let btn_primary = frm.page.btn_primary.get(0);
|
||||||
@@ -123,7 +124,8 @@ frappe.ui.form.on("Opening Invoice Creation Tool", {
|
|||||||
invoice_type: function (frm) {
|
invoice_type: function (frm) {
|
||||||
$.each(frm.doc.invoices, (idx, row) => {
|
$.each(frm.doc.invoices, (idx, row) => {
|
||||||
row.party_type = frm.doc.invoice_type == "Sales" ? "Customer" : "Supplier";
|
row.party_type = frm.doc.invoice_type == "Sales" ? "Customer" : "Supplier";
|
||||||
row.party = "";
|
frappe.model.set_value(row.doctype, row.name, "party", "");
|
||||||
|
frappe.model.set_value(row.doctype, row.name, "party_name", "");
|
||||||
});
|
});
|
||||||
frm.refresh_fields();
|
frm.refresh_fields();
|
||||||
},
|
},
|
||||||
@@ -162,9 +164,35 @@ frappe.ui.form.on("Opening Invoice Creation Tool", {
|
|||||||
row.party_type = frm.doc.invoice_type == "Sales" ? "Customer" : "Supplier";
|
row.party_type = frm.doc.invoice_type == "Sales" ? "Customer" : "Supplier";
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
create_missing_party: function (frm) {
|
||||||
|
if (frm.doc.create_missing_party) {
|
||||||
|
frm.fields_dict["invoices"].grid.update_docfield_property("party", "reqd", 0);
|
||||||
|
frm.fields_dict["invoices"].grid.update_docfield_property("party_name", "read_only", 0);
|
||||||
|
} else {
|
||||||
|
frm.fields_dict["invoices"].grid.update_docfield_property("party", "reqd", 1);
|
||||||
|
frm.fields_dict["invoices"].grid.update_docfield_property("party_name", "read_only", 1);
|
||||||
|
}
|
||||||
|
frm.refresh_field("invoices");
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
frappe.ui.form.on("Opening Invoice Creation Tool Item", {
|
frappe.ui.form.on("Opening Invoice Creation Tool Item", {
|
||||||
|
party: function (frm, cdt, cdn) {
|
||||||
|
let row = locals[cdt][cdn];
|
||||||
|
if (!row.party) {
|
||||||
|
frappe.model.set_value(cdt, cdn, "party_name", "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let party_type = frm.doc.invoice_type == "Sales" ? "Customer" : "Supplier";
|
||||||
|
let name_field = party_type === "Customer" ? "customer_name" : "supplier_name";
|
||||||
|
|
||||||
|
frappe.db.get_value(party_type, row.party, name_field, (r) => {
|
||||||
|
frappe.model.set_value(cdt, cdn, "party_name", r?.[name_field] || "");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
invoices_add: (frm) => {
|
invoices_add: (frm) => {
|
||||||
frm.trigger("update_invoice_table");
|
frm.trigger("update_invoice_table");
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"company",
|
"company",
|
||||||
"create_missing_party",
|
|
||||||
"column_break_3",
|
"column_break_3",
|
||||||
"invoice_type",
|
"invoice_type",
|
||||||
|
"create_missing_party",
|
||||||
"accounting_dimensions_section",
|
"accounting_dimensions_section",
|
||||||
"cost_center",
|
"cost_center",
|
||||||
"dimension_col_break",
|
"dimension_col_break",
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"description": "Create missing customer or supplier.",
|
"description": "If party does not exist, create it using the Party Name field.",
|
||||||
"fieldname": "create_missing_party",
|
"fieldname": "create_missing_party",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Create Missing Party"
|
"label": "Create Missing Party"
|
||||||
@@ -65,10 +65,10 @@
|
|||||||
"options": "Cost Center"
|
"options": "Cost Center"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "project",
|
"fieldname": "project",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Project",
|
"label": "Project",
|
||||||
"options": "Project"
|
"options": "Project"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
"hide_toolbar": 1,
|
"hide_toolbar": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-03-27 13:10:06.564397",
|
"modified": "2026-03-23 00:32:15.600086",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Opening Invoice Creation Tool",
|
"name": "Opening Invoice Creation Tool",
|
||||||
@@ -101,6 +101,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
|
"row_format": "Dynamic",
|
||||||
"sort_field": "creation",
|
"sort_field": "creation",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"states": [],
|
"states": [],
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ class OpeningInvoiceCreationTool(Document):
|
|||||||
create_missing_party: DF.Check
|
create_missing_party: DF.Check
|
||||||
invoice_type: DF.Literal["Sales", "Purchase"]
|
invoice_type: DF.Literal["Sales", "Purchase"]
|
||||||
invoices: DF.Table[OpeningInvoiceCreationToolItem]
|
invoices: DF.Table[OpeningInvoiceCreationToolItem]
|
||||||
|
project: DF.Link | None
|
||||||
# end: auto-generated types
|
# end: auto-generated types
|
||||||
|
|
||||||
def onload(self):
|
def onload(self):
|
||||||
@@ -102,10 +103,20 @@ class OpeningInvoiceCreationTool(Document):
|
|||||||
row.due_date = row.due_date or nowdate()
|
row.due_date = row.due_date or nowdate()
|
||||||
|
|
||||||
def validate_mandatory_invoice_fields(self, row):
|
def validate_mandatory_invoice_fields(self, row):
|
||||||
if not frappe.db.exists(row.party_type, row.party):
|
if self.create_missing_party:
|
||||||
if self.create_missing_party:
|
if not row.party and not row.party_name:
|
||||||
self.add_party(row.party_type, row.party)
|
frappe.throw(_("Row #{}: Either Party ID or Party Name is required").format(row.idx))
|
||||||
else:
|
|
||||||
|
if not row.party and row.party_name:
|
||||||
|
row.party = self.add_party(row.party_type, row.party_name)
|
||||||
|
|
||||||
|
if row.party and not frappe.db.exists(row.party_type, row.party):
|
||||||
|
row.party = self.add_party(row.party_type, row.party)
|
||||||
|
|
||||||
|
else:
|
||||||
|
if not row.party:
|
||||||
|
frappe.throw(_("Row #{}: Party ID is required").format(row.idx))
|
||||||
|
if not frappe.db.exists(row.party_type, row.party):
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
_("Row #{}: {} {} does not exist.").format(
|
_("Row #{}: {} {} does not exist.").format(
|
||||||
row.idx, frappe.bold(row.party_type), frappe.bold(row.party)
|
row.idx, frappe.bold(row.party_type), frappe.bold(row.party)
|
||||||
@@ -113,7 +124,7 @@ class OpeningInvoiceCreationTool(Document):
|
|||||||
)
|
)
|
||||||
|
|
||||||
mandatory_error_msg = _("Row #{0}: {1} is required to create the Opening {2} Invoices")
|
mandatory_error_msg = _("Row #{0}: {1} is required to create the Opening {2} Invoices")
|
||||||
for d in ("Party", "Outstanding Amount", "Temporary Opening Account"):
|
for d in ("Outstanding Amount", "Temporary Opening Account"):
|
||||||
if not row.get(scrub(d)):
|
if not row.get(scrub(d)):
|
||||||
frappe.throw(mandatory_error_msg.format(row.idx, d, self.invoice_type))
|
frappe.throw(mandatory_error_msg.format(row.idx, d, self.invoice_type))
|
||||||
|
|
||||||
@@ -159,6 +170,7 @@ class OpeningInvoiceCreationTool(Document):
|
|||||||
|
|
||||||
party_doc.flags.ignore_mandatory = True
|
party_doc.flags.ignore_mandatory = True
|
||||||
party_doc.save(ignore_permissions=True)
|
party_doc.save(ignore_permissions=True)
|
||||||
|
return party_doc.name
|
||||||
|
|
||||||
def get_invoice_dict(self, row=None):
|
def get_invoice_dict(self, row=None):
|
||||||
def get_item_dict():
|
def get_item_dict():
|
||||||
@@ -262,7 +274,8 @@ def start_import(invoices):
|
|||||||
doc.flags.ignore_mandatory = True
|
doc.flags.ignore_mandatory = True
|
||||||
doc.insert(set_name=invoice_number)
|
doc.insert(set_name=invoice_number)
|
||||||
doc.submit()
|
doc.submit()
|
||||||
frappe.db.commit()
|
if not frappe.in_test:
|
||||||
|
frappe.db.commit()
|
||||||
names.append(doc.name)
|
names.append(doc.name)
|
||||||
except Exception:
|
except Exception:
|
||||||
errors += 1
|
errors += 1
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% $.each(data, (company, summary) => { %}
|
{% $.each(data, (company, summary) => { %}
|
||||||
<h6 style="margin: 15px 0px -10px 0px;"><a class="company-link"> {{ company }}</a></h6>
|
<div style="margin: 15px 0px -10px 0px;"> {{ company }}</div>
|
||||||
|
|
||||||
<table class="table table-bordered small">
|
<table class="table table-bordered small">
|
||||||
<thead>
|
<thead>
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
{{ format_currency(summary[doctype].outstanding_amount, summary.currency, 2) }}
|
{{ format_currency(summary[doctype].outstanding_amount, summary.currency, 2) }}
|
||||||
</td>
|
</td>
|
||||||
</div>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% }); %}
|
{% }); %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -2,27 +2,14 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.accounting_dimension.test_accounting_dimension import (
|
|
||||||
create_dimension,
|
|
||||||
disable_dimension,
|
|
||||||
)
|
|
||||||
from erpnext.accounts.doctype.opening_invoice_creation_tool.opening_invoice_creation_tool import (
|
from erpnext.accounts.doctype.opening_invoice_creation_tool.opening_invoice_creation_tool import (
|
||||||
get_temporary_opening_account,
|
get_temporary_opening_account,
|
||||||
)
|
)
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
EXTRA_TEST_RECORD_DEPENDENCIES = ["Customer", "Supplier", "Accounting Dimension"]
|
|
||||||
|
|
||||||
|
|
||||||
class TestOpeningInvoiceCreationTool(IntegrationTestCase):
|
class TestOpeningInvoiceCreationTool(ERPNextTestSuite):
|
||||||
@classmethod
|
|
||||||
def setUpClass(cls):
|
|
||||||
if not frappe.db.exists("Company", "_Test Opening Invoice Company"):
|
|
||||||
make_company()
|
|
||||||
create_dimension()
|
|
||||||
return super().setUpClass()
|
|
||||||
|
|
||||||
def make_invoices(
|
def make_invoices(
|
||||||
self,
|
self,
|
||||||
invoice_type="Sales",
|
invoice_type="Sales",
|
||||||
@@ -149,9 +136,6 @@ class TestOpeningInvoiceCreationTool(IntegrationTestCase):
|
|||||||
}
|
}
|
||||||
self.check_expected_values(invoices, expected_value, invoice_type="Sales")
|
self.check_expected_values(invoices, expected_value, invoice_type="Sales")
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
disable_dimension()
|
|
||||||
|
|
||||||
|
|
||||||
def get_opening_invoice_creation_dict(**args):
|
def get_opening_invoice_creation_dict(**args):
|
||||||
party = "Customer" if args.get("invoice_type", "Sales") == "Sales" else "Supplier"
|
party = "Customer" if args.get("invoice_type", "Sales") == "Sales" else "Supplier"
|
||||||
@@ -190,19 +174,6 @@ def get_opening_invoice_creation_dict(**args):
|
|||||||
return invoice_dict
|
return invoice_dict
|
||||||
|
|
||||||
|
|
||||||
def make_company():
|
|
||||||
if frappe.db.exists("Company", "_Test Opening Invoice Company"):
|
|
||||||
return frappe.get_doc("Company", "_Test Opening Invoice Company")
|
|
||||||
|
|
||||||
company = frappe.new_doc("Company")
|
|
||||||
company.company_name = "_Test Opening Invoice Company"
|
|
||||||
company.abbr = "_TOIC"
|
|
||||||
company.default_currency = "INR"
|
|
||||||
company.country = "Pakistan"
|
|
||||||
company.insert()
|
|
||||||
return company
|
|
||||||
|
|
||||||
|
|
||||||
def make_customer(customer=None):
|
def make_customer(customer=None):
|
||||||
customer_name = customer or "Opening Customer"
|
customer_name = customer or "Opening Customer"
|
||||||
customer = frappe.get_doc(
|
customer = frappe.get_doc(
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
"invoice_number",
|
"invoice_number",
|
||||||
"party_type",
|
"party_type",
|
||||||
"party",
|
"party",
|
||||||
|
"party_name",
|
||||||
"temporary_opening_account",
|
"temporary_opening_account",
|
||||||
"column_break_3",
|
"column_break_3",
|
||||||
"posting_date",
|
"posting_date",
|
||||||
@@ -35,9 +36,9 @@
|
|||||||
"fieldname": "party",
|
"fieldname": "party",
|
||||||
"fieldtype": "Dynamic Link",
|
"fieldtype": "Dynamic Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Party",
|
"label": "Party ID",
|
||||||
"options": "party_type",
|
"mandatory_depends_on": "eval: !parent.create_missing_party",
|
||||||
"reqd": 1
|
"options": "party_type"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "temporary_opening_account",
|
"fieldname": "temporary_opening_account",
|
||||||
@@ -118,11 +119,17 @@
|
|||||||
"fieldname": "supplier_invoice_date",
|
"fieldname": "supplier_invoice_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Supplier Invoice Date"
|
"label": "Supplier Invoice Date"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "party_name",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Party Name"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2025-12-01 16:18:07.997594",
|
"modified": "2026-03-20 02:11:42.023575",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Opening Invoice Creation Tool Item",
|
"name": "Opening Invoice Creation Tool Item",
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ class OpeningInvoiceCreationToolItem(Document):
|
|||||||
parent: DF.Data
|
parent: DF.Data
|
||||||
parentfield: DF.Data
|
parentfield: DF.Data
|
||||||
parenttype: DF.Data
|
parenttype: DF.Data
|
||||||
party: DF.DynamicLink
|
party: DF.DynamicLink | None
|
||||||
|
party_name: DF.Data | None
|
||||||
party_type: DF.Link | None
|
party_type: DF.Link | None
|
||||||
posting_date: DF.Date | None
|
posting_date: DF.Date | None
|
||||||
qty: DF.Data | None
|
qty: DF.Data | None
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
# import frappe
|
# import frappe
|
||||||
|
|
||||||
from frappe.tests import IntegrationTestCase
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestPartyLink(IntegrationTestCase):
|
class TestPartyLink(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -138,6 +138,7 @@
|
|||||||
"fieldname": "posting_date",
|
"fieldname": "posting_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 1,
|
||||||
"label": "Posting Date",
|
"label": "Posting Date",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
@@ -160,7 +161,6 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "mode_of_payment",
|
"fieldname": "mode_of_payment",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Mode of Payment",
|
"label": "Mode of Payment",
|
||||||
"options": "Mode of Payment"
|
"options": "Mode of Payment"
|
||||||
},
|
},
|
||||||
@@ -228,6 +228,7 @@
|
|||||||
"fieldname": "paid_from",
|
"fieldname": "paid_from",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_global_search": 1,
|
"in_global_search": 1,
|
||||||
|
"in_list_view": 1,
|
||||||
"label": "Account Paid From",
|
"label": "Account Paid From",
|
||||||
"options": "Account",
|
"options": "Account",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
@@ -252,6 +253,7 @@
|
|||||||
"fieldname": "paid_to",
|
"fieldname": "paid_to",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_global_search": 1,
|
"in_global_search": 1,
|
||||||
|
"in_list_view": 1,
|
||||||
"label": "Account Paid To",
|
"label": "Account Paid To",
|
||||||
"options": "Account",
|
"options": "Account",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
@@ -414,6 +416,7 @@
|
|||||||
"depends_on": "eval:(doc.paid_from && doc.paid_to)",
|
"depends_on": "eval:(doc.paid_from && doc.paid_to)",
|
||||||
"fieldname": "reference_no",
|
"fieldname": "reference_no",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
|
"in_standard_filter": 1,
|
||||||
"label": "Cheque/Reference No",
|
"label": "Cheque/Reference No",
|
||||||
"mandatory_depends_on": "eval:(doc.paid_from_account_type == 'Bank' || doc.paid_to_account_type == 'Bank')"
|
"mandatory_depends_on": "eval:(doc.paid_from_account_type == 'Bank' || doc.paid_to_account_type == 'Bank')"
|
||||||
},
|
},
|
||||||
@@ -792,7 +795,7 @@
|
|||||||
"table_fieldname": "payment_entries"
|
"table_fieldname": "payment_entries"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2026-02-03 16:08:49.800381",
|
"modified": "2026-03-09 17:15:30.453920",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Entry",
|
"name": "Payment Entry",
|
||||||
|
|||||||
@@ -2378,9 +2378,7 @@ def get_outstanding_reference_documents(args: str | dict, validate: bool = False
|
|||||||
vouchers=args.get("vouchers") or None,
|
vouchers=args.get("vouchers") or None,
|
||||||
)
|
)
|
||||||
|
|
||||||
outstanding_invoices = split_invoices_based_on_payment_terms(
|
outstanding_invoices = split_refdocs_based_on_payment_terms(outstanding_invoices, args.get("company"))
|
||||||
outstanding_invoices, args.get("company")
|
|
||||||
)
|
|
||||||
|
|
||||||
for d in outstanding_invoices:
|
for d in outstanding_invoices:
|
||||||
d["exchange_rate"] = 1
|
d["exchange_rate"] = 1
|
||||||
@@ -2418,6 +2416,8 @@ def get_outstanding_reference_documents(args: str | dict, validate: bool = False
|
|||||||
filters=args,
|
filters=args,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
orders_to_be_billed = split_refdocs_based_on_payment_terms(orders_to_be_billed, args.get("company"))
|
||||||
|
|
||||||
data = negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
|
data = negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
|
||||||
|
|
||||||
if not data:
|
if not data:
|
||||||
@@ -2440,13 +2440,13 @@ def get_outstanding_reference_documents(args: str | dict, validate: bool = False
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def split_invoices_based_on_payment_terms(outstanding_invoices, company) -> list:
|
def split_refdocs_based_on_payment_terms(refdocs, company) -> list:
|
||||||
"""Split a list of invoices based on their payment terms."""
|
"""Split a list of invoices based on their payment terms."""
|
||||||
exc_rates = get_currency_data(outstanding_invoices, company)
|
exc_rates = get_currency_data(refdocs, company)
|
||||||
|
|
||||||
outstanding_invoices_after_split = []
|
outstanding_refdoc_after_split = []
|
||||||
for entry in outstanding_invoices:
|
for entry in refdocs:
|
||||||
if entry.voucher_type in ["Sales Invoice", "Purchase Invoice"]:
|
if entry.voucher_type in ["Sales Invoice", "Purchase Invoice", "Sales Order", "Purchase Order"]:
|
||||||
if payment_term_template := frappe.db.get_value(
|
if payment_term_template := frappe.db.get_value(
|
||||||
entry.voucher_type, entry.voucher_no, "payment_terms_template"
|
entry.voucher_type, entry.voucher_no, "payment_terms_template"
|
||||||
):
|
):
|
||||||
@@ -2461,25 +2461,25 @@ def split_invoices_based_on_payment_terms(outstanding_invoices, company) -> list
|
|||||||
),
|
),
|
||||||
alert=True,
|
alert=True,
|
||||||
)
|
)
|
||||||
outstanding_invoices_after_split += split_rows
|
outstanding_refdoc_after_split += split_rows
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# If not an invoice or no payment terms template, add as it is
|
# If not an invoice or no payment terms template, add as it is
|
||||||
outstanding_invoices_after_split.append(entry)
|
outstanding_refdoc_after_split.append(entry)
|
||||||
|
|
||||||
return outstanding_invoices_after_split
|
return outstanding_refdoc_after_split
|
||||||
|
|
||||||
|
|
||||||
def get_currency_data(outstanding_invoices: list, company: str | None = None) -> dict:
|
def get_currency_data(outstanding_refdocs: list, company: str | None = None) -> dict:
|
||||||
"""Get currency and conversion data for a list of invoices."""
|
"""Get currency and conversion data for a list of invoices."""
|
||||||
exc_rates = frappe._dict()
|
exc_rates = frappe._dict()
|
||||||
company_currency = frappe.db.get_value("Company", company, "default_currency") if company else None
|
company_currency = frappe.db.get_value("Company", company, "default_currency") if company else None
|
||||||
|
|
||||||
for doctype in ["Sales Invoice", "Purchase Invoice"]:
|
for doctype in ["Sales Invoice", "Purchase Invoice", "Sales Order", "Purchase Order"]:
|
||||||
invoices = [x.voucher_no for x in outstanding_invoices if x.voucher_type == doctype]
|
refdoc = [x.voucher_no for x in outstanding_refdocs if x.voucher_type == doctype]
|
||||||
for x in frappe.db.get_all(
|
for x in frappe.db.get_all(
|
||||||
doctype,
|
doctype,
|
||||||
filters={"name": ["in", invoices]},
|
filters={"name": ["in", refdoc]},
|
||||||
fields=["name", "currency", "conversion_rate", "party_account_currency"],
|
fields=["name", "currency", "conversion_rate", "party_account_currency"],
|
||||||
):
|
):
|
||||||
exc_rates[x.name] = frappe._dict(
|
exc_rates[x.name] = frappe._dict(
|
||||||
@@ -2558,14 +2558,9 @@ def get_orders_to_be_billed(
|
|||||||
if not voucher_type:
|
if not voucher_type:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
# Add cost center condition
|
|
||||||
doc = frappe.get_doc({"doctype": voucher_type})
|
|
||||||
condition = ""
|
|
||||||
if doc and hasattr(doc, "cost_center") and doc.cost_center:
|
|
||||||
condition = " and cost_center='%s'" % cost_center
|
|
||||||
|
|
||||||
# dynamic dimension filters
|
# dynamic dimension filters
|
||||||
active_dimensions = get_dimensions()[0]
|
condition = ""
|
||||||
|
active_dimensions = get_dimensions(True)[0]
|
||||||
for dim in active_dimensions:
|
for dim in active_dimensions:
|
||||||
if filters.get(dim.fieldname):
|
if filters.get(dim.fieldname):
|
||||||
condition += f" and {dim.fieldname}='{filters.get(dim.fieldname)}'"
|
condition += f" and {dim.fieldname}='{filters.get(dim.fieldname)}'"
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import qb
|
from frappe import qb
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import add_days, flt, nowdate
|
from frappe.utils import add_days, flt, nowdate
|
||||||
|
|
||||||
from erpnext.accounts.doctype.account.test_account import create_account
|
from erpnext.accounts.doctype.account.test_account import create_account
|
||||||
@@ -24,14 +23,10 @@ from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import (
|
|||||||
)
|
)
|
||||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||||
from erpnext.setup.doctype.employee.test_employee import make_employee
|
from erpnext.setup.doctype.employee.test_employee import make_employee
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
EXTRA_TEST_RECORD_DEPENDENCIES = ["Item", "Currency Exchange"]
|
|
||||||
|
|
||||||
|
|
||||||
class TestPaymentEntry(IntegrationTestCase):
|
class TestPaymentEntry(ERPNextTestSuite):
|
||||||
def tearDown(self):
|
|
||||||
frappe.db.rollback()
|
|
||||||
|
|
||||||
def get_journals_for(self, voucher_type: str, voucher_no: str) -> list:
|
def get_journals_for(self, voucher_type: str, voucher_no: str) -> list:
|
||||||
journals = []
|
journals = []
|
||||||
if voucher_type and voucher_no:
|
if voucher_type and voucher_no:
|
||||||
@@ -427,7 +422,7 @@ class TestPaymentEntry(IntegrationTestCase):
|
|||||||
self.assertEqual(si.payment_schedule[0].outstanding, 0)
|
self.assertEqual(si.payment_schedule[0].outstanding, 0)
|
||||||
self.assertEqual(si.payment_schedule[0].discounted_amount, 50)
|
self.assertEqual(si.payment_schedule[0].discounted_amount, 50)
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings(
|
@ERPNextTestSuite.change_settings(
|
||||||
"Accounts Settings",
|
"Accounts Settings",
|
||||||
{
|
{
|
||||||
"allow_multi_currency_invoices_against_single_party_account": 1,
|
"allow_multi_currency_invoices_against_single_party_account": 1,
|
||||||
@@ -645,6 +640,7 @@ class TestPaymentEntry(IntegrationTestCase):
|
|||||||
def test_payment_entry_retrieves_last_exchange_rate(self):
|
def test_payment_entry_retrieves_last_exchange_rate(self):
|
||||||
from erpnext.setup.doctype.currency_exchange.test_currency_exchange import save_new_records
|
from erpnext.setup.doctype.currency_exchange.test_currency_exchange import save_new_records
|
||||||
|
|
||||||
|
self.load_test_records("Currency Exchange")
|
||||||
save_new_records(self.globalTestRecords["Currency Exchange"])
|
save_new_records(self.globalTestRecords["Currency Exchange"])
|
||||||
|
|
||||||
pe = frappe.new_doc("Payment Entry")
|
pe = frappe.new_doc("Payment Entry")
|
||||||
@@ -982,6 +978,7 @@ class TestPaymentEntry(IntegrationTestCase):
|
|||||||
def test_gl_of_multi_currency_payment_transaction(self):
|
def test_gl_of_multi_currency_payment_transaction(self):
|
||||||
from erpnext.setup.doctype.currency_exchange.test_currency_exchange import save_new_records
|
from erpnext.setup.doctype.currency_exchange.test_currency_exchange import save_new_records
|
||||||
|
|
||||||
|
self.load_test_records("Currency Exchange")
|
||||||
save_new_records(self.globalTestRecords["Currency Exchange"])
|
save_new_records(self.globalTestRecords["Currency Exchange"])
|
||||||
paid_from = create_account(
|
paid_from = create_account(
|
||||||
parent_account="Current Liabilities - _TC",
|
parent_account="Current Liabilities - _TC",
|
||||||
@@ -1158,7 +1155,7 @@ class TestPaymentEntry(IntegrationTestCase):
|
|||||||
}
|
}
|
||||||
self.assertDictEqual(ref_details, expected_response)
|
self.assertDictEqual(ref_details, expected_response)
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings(
|
@ERPNextTestSuite.change_settings(
|
||||||
"Accounts Settings",
|
"Accounts Settings",
|
||||||
{
|
{
|
||||||
"unlink_payment_on_cancellation_of_invoice": 1,
|
"unlink_payment_on_cancellation_of_invoice": 1,
|
||||||
@@ -1253,7 +1250,7 @@ class TestPaymentEntry(IntegrationTestCase):
|
|||||||
si3.cancel()
|
si3.cancel()
|
||||||
si3.delete()
|
si3.delete()
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings(
|
@ERPNextTestSuite.change_settings(
|
||||||
"Accounts Settings",
|
"Accounts Settings",
|
||||||
{
|
{
|
||||||
"unlink_payment_on_cancellation_of_invoice": 1,
|
"unlink_payment_on_cancellation_of_invoice": 1,
|
||||||
@@ -1949,7 +1946,7 @@ class TestPaymentEntry(IntegrationTestCase):
|
|||||||
# 'Is Opening' should always be 'No' for normal advance payments
|
# 'Is Opening' should always be 'No' for normal advance payments
|
||||||
self.assertEqual(gl_with_opening_set, [])
|
self.assertEqual(gl_with_opening_set, [])
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings("Accounts Settings", {"delete_linked_ledger_entries": 1})
|
@ERPNextTestSuite.change_settings("Accounts Settings", {"delete_linked_ledger_entries": 1})
|
||||||
def test_delete_linked_exchange_gain_loss_journal(self):
|
def test_delete_linked_exchange_gain_loss_journal(self):
|
||||||
from erpnext.accounts.doctype.account.test_account import create_account
|
from erpnext.accounts.doctype.account.test_account import create_account
|
||||||
from erpnext.accounts.doctype.opening_invoice_creation_tool.test_opening_invoice_creation_tool import (
|
from erpnext.accounts.doctype.opening_invoice_creation_tool.test_opening_invoice_creation_tool import (
|
||||||
@@ -2022,6 +2019,92 @@ class TestPaymentEntry(IntegrationTestCase):
|
|||||||
self.assertRaises(frappe.DoesNotExistError, frappe.get_doc, pe.doctype, pe.name)
|
self.assertRaises(frappe.DoesNotExistError, frappe.get_doc, pe.doctype, pe.name)
|
||||||
self.assertRaises(frappe.DoesNotExistError, frappe.get_doc, "Journal Entry", jv[0])
|
self.assertRaises(frappe.DoesNotExistError, frappe.get_doc, "Journal Entry", jv[0])
|
||||||
|
|
||||||
|
def test_outstanding_orders_split_by_payment_terms(self):
|
||||||
|
create_payment_terms_template()
|
||||||
|
|
||||||
|
so = make_sales_order(do_not_save=1, qty=1, rate=200)
|
||||||
|
so.payment_terms_template = "Test Receivable Template"
|
||||||
|
so.save().submit()
|
||||||
|
|
||||||
|
args = {
|
||||||
|
"posting_date": nowdate(),
|
||||||
|
"company": so.company,
|
||||||
|
"party_type": "Customer",
|
||||||
|
"payment_type": "Receive",
|
||||||
|
"party": so.customer,
|
||||||
|
"party_account": "Debtors - _TC",
|
||||||
|
"get_orders_to_be_billed": True,
|
||||||
|
}
|
||||||
|
|
||||||
|
references = get_outstanding_reference_documents(args)
|
||||||
|
|
||||||
|
self.assertEqual(len(references), 2)
|
||||||
|
self.assertEqual(references[0].voucher_no, so.name)
|
||||||
|
self.assertEqual(references[1].voucher_no, so.name)
|
||||||
|
self.assertEqual(references[0].payment_term, "Basic Amount Receivable")
|
||||||
|
self.assertEqual(references[1].payment_term, "Tax Receivable")
|
||||||
|
|
||||||
|
def test_outstanding_orders_no_split_when_allocate_disabled(self):
|
||||||
|
create_payment_terms_template()
|
||||||
|
|
||||||
|
template = frappe.get_doc("Payment Terms Template", "Test Receivable Template")
|
||||||
|
template.allocate_payment_based_on_payment_terms = 0
|
||||||
|
template.save()
|
||||||
|
|
||||||
|
so = make_sales_order(do_not_save=1, qty=1, rate=200)
|
||||||
|
so.payment_terms_template = "Test Receivable Template"
|
||||||
|
so.save().submit()
|
||||||
|
|
||||||
|
args = {
|
||||||
|
"posting_date": nowdate(),
|
||||||
|
"company": so.company,
|
||||||
|
"party_type": "Customer",
|
||||||
|
"payment_type": "Receive",
|
||||||
|
"party": so.customer,
|
||||||
|
"party_account": "Debtors - _TC",
|
||||||
|
"get_orders_to_be_billed": True,
|
||||||
|
}
|
||||||
|
|
||||||
|
references = get_outstanding_reference_documents(args)
|
||||||
|
|
||||||
|
self.assertEqual(len(references), 1)
|
||||||
|
self.assertIsNone(references[0].payment_term)
|
||||||
|
|
||||||
|
template.allocate_payment_based_on_payment_terms = 1
|
||||||
|
template.save()
|
||||||
|
|
||||||
|
def test_outstanding_multicurrency_sales_order_split(self):
|
||||||
|
create_payment_terms_template()
|
||||||
|
|
||||||
|
so = make_sales_order(
|
||||||
|
customer="_Test Customer USD",
|
||||||
|
currency="USD",
|
||||||
|
qty=1,
|
||||||
|
rate=100,
|
||||||
|
do_not_submit=True,
|
||||||
|
)
|
||||||
|
so.payment_terms_template = "Test Receivable Template"
|
||||||
|
so.conversion_rate = 50
|
||||||
|
so.save().submit()
|
||||||
|
|
||||||
|
args = {
|
||||||
|
"posting_date": nowdate(),
|
||||||
|
"company": so.company,
|
||||||
|
"party_type": "Customer",
|
||||||
|
"payment_type": "Receive",
|
||||||
|
"party": so.customer,
|
||||||
|
"party_account": "Debtors - _TC",
|
||||||
|
"get_orders_to_be_billed": True,
|
||||||
|
}
|
||||||
|
|
||||||
|
references = get_outstanding_reference_documents(args)
|
||||||
|
|
||||||
|
# Should split without throwing currency errors
|
||||||
|
self.assertEqual(len(references), 2)
|
||||||
|
for ref in references:
|
||||||
|
self.assertEqual(ref.voucher_no, so.name)
|
||||||
|
self.assertIsNotNone(ref.payment_term)
|
||||||
|
|
||||||
|
|
||||||
def create_payment_entry(**args):
|
def create_payment_entry(**args):
|
||||||
payment_entry = frappe.new_doc("Payment Entry")
|
payment_entry = frappe.new_doc("Payment Entry")
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_on_submit": 1,
|
||||||
"fieldname": "cost_center",
|
"fieldname": "cost_center",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@@ -59,7 +60,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2025-08-13 06:52:46.130142",
|
"modified": "2026-03-11 14:26:11.312950",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Entry Deduction",
|
"name": "Payment Entry Deduction",
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
from frappe.tests import IntegrationTestCase
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
IGNORE_TEST_RECORD_DEPENDENCIES = ["Payment Gateway"]
|
|
||||||
|
|
||||||
|
|
||||||
class TestPaymentGatewayAccount(IntegrationTestCase):
|
class TestPaymentGatewayAccount(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on("Payment Ledger Entry", {
|
frappe.ui.form.on("Payment Ledger Entry", {
|
||||||
// refresh: function(frm) {
|
refresh(frm) {
|
||||||
// }
|
frm.page.btn_secondary.hide();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"is_submittable": 1,
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"posting_date",
|
"posting_date",
|
||||||
"company",
|
"company",
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import qb
|
from frappe import qb
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import nowdate
|
from frappe.utils import nowdate
|
||||||
|
|
||||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
||||||
@@ -11,9 +10,10 @@ from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_pay
|
|||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||||
from erpnext.stock.doctype.item.test_item import create_item
|
from erpnext.stock.doctype.item.test_item import create_item
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestPaymentLedgerEntry(IntegrationTestCase):
|
class TestPaymentLedgerEntry(ERPNextTestSuite):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.ple = qb.DocType("Payment Ledger Entry")
|
self.ple = qb.DocType("Payment Ledger Entry")
|
||||||
self.create_company()
|
self.create_company()
|
||||||
@@ -21,9 +21,6 @@ class TestPaymentLedgerEntry(IntegrationTestCase):
|
|||||||
self.create_customer()
|
self.create_customer()
|
||||||
self.clear_old_entries()
|
self.clear_old_entries()
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
frappe.db.rollback()
|
|
||||||
|
|
||||||
def create_company(self):
|
def create_company(self):
|
||||||
company_name = "_Test Payment Ledger"
|
company_name = "_Test Payment Ledger"
|
||||||
company = None
|
company = None
|
||||||
@@ -445,7 +442,7 @@ class TestPaymentLedgerEntry(IntegrationTestCase):
|
|||||||
self.assertEqual(pl_entries_for_crnote[0], expected_values[0])
|
self.assertEqual(pl_entries_for_crnote[0], expected_values[0])
|
||||||
self.assertEqual(pl_entries_for_crnote[1], expected_values[1])
|
self.assertEqual(pl_entries_for_crnote[1], expected_values[1])
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings(
|
@ERPNextTestSuite.change_settings(
|
||||||
"Accounts Settings",
|
"Accounts Settings",
|
||||||
{"unlink_payment_on_cancellation_of_invoice": 1, "delete_linked_ledger_entries": 1},
|
{"unlink_payment_on_cancellation_of_invoice": 1, "delete_linked_ledger_entries": 1},
|
||||||
)
|
)
|
||||||
@@ -474,7 +471,7 @@ class TestPaymentLedgerEntry(IntegrationTestCase):
|
|||||||
si.delete()
|
si.delete()
|
||||||
self.assertRaises(frappe.DoesNotExistError, frappe.get_doc, si.doctype, si.name)
|
self.assertRaises(frappe.DoesNotExistError, frappe.get_doc, si.doctype, si.name)
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings(
|
@ERPNextTestSuite.change_settings(
|
||||||
"Accounts Settings",
|
"Accounts Settings",
|
||||||
{"unlink_payment_on_cancellation_of_invoice": 1, "delete_linked_ledger_entries": 1},
|
{"unlink_payment_on_cancellation_of_invoice": 1, "delete_linked_ledger_entries": 1},
|
||||||
)
|
)
|
||||||
@@ -507,7 +504,7 @@ class TestPaymentLedgerEntry(IntegrationTestCase):
|
|||||||
si.delete()
|
si.delete()
|
||||||
self.assertRaises(frappe.DoesNotExistError, frappe.get_doc, si.doctype, si.name)
|
self.assertRaises(frappe.DoesNotExistError, frappe.get_doc, si.doctype, si.name)
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings(
|
@ERPNextTestSuite.change_settings(
|
||||||
"Accounts Settings",
|
"Accounts Settings",
|
||||||
{
|
{
|
||||||
"unlink_payment_on_cancellation_of_invoice": 1,
|
"unlink_payment_on_cancellation_of_invoice": 1,
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import getdate
|
from frappe.utils import getdate
|
||||||
|
|
||||||
from erpnext.accounts.doctype.bank_transaction.test_bank_transaction import (
|
from erpnext.accounts.doctype.bank_transaction.test_bank_transaction import (
|
||||||
@@ -15,9 +14,10 @@ from erpnext.accounts.doctype.payment_entry.payment_entry import (
|
|||||||
make_payment_order,
|
make_payment_order,
|
||||||
)
|
)
|
||||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
|
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestPaymentOrder(IntegrationTestCase):
|
class TestPaymentOrder(ERPNextTestSuite):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
# generate and use a uniq hash identifier for 'Bank Account' and it's linked GL 'Account' to avoid validation error
|
# generate and use a uniq hash identifier for 'Bank Account' and it's linked GL 'Account' to avoid validation error
|
||||||
uniq_identifier = frappe.generate_hash(length=10)
|
uniq_identifier = frappe.generate_hash(length=10)
|
||||||
@@ -26,9 +26,6 @@ class TestPaymentOrder(IntegrationTestCase):
|
|||||||
gl_account=self.gl_account, bank_account_name="Checking Account " + uniq_identifier
|
gl_account=self.gl_account, bank_account_name="Checking Account " + uniq_identifier
|
||||||
)
|
)
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
frappe.db.rollback()
|
|
||||||
|
|
||||||
def test_payment_order_creation_against_payment_entry(self):
|
def test_payment_order_creation_against_payment_entry(self):
|
||||||
purchase_invoice = make_purchase_invoice()
|
purchase_invoice = make_purchase_invoice()
|
||||||
payment_entry = get_payment_entry(
|
payment_entry = get_payment_entry(
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import qb
|
from frappe import qb
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import add_days, add_years, flt, getdate, nowdate, today
|
from frappe.utils import add_days, add_years, flt, getdate, nowdate, today
|
||||||
from frappe.utils.data import getdate as convert_to_date
|
from frappe.utils.data import getdate as convert_to_date
|
||||||
|
|
||||||
@@ -17,11 +16,10 @@ from erpnext.accounts.party import get_party_account
|
|||||||
from erpnext.accounts.utils import get_fiscal_year
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
||||||
from erpnext.stock.doctype.item.test_item import create_item
|
from erpnext.stock.doctype.item.test_item import create_item
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
EXTRA_TEST_RECORD_DEPENDENCIES = ["Item"]
|
|
||||||
|
|
||||||
|
|
||||||
class TestPaymentReconciliation(IntegrationTestCase):
|
class TestPaymentReconciliation(ERPNextTestSuite):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.create_company()
|
self.create_company()
|
||||||
self.create_item()
|
self.create_item()
|
||||||
@@ -30,9 +28,6 @@ class TestPaymentReconciliation(IntegrationTestCase):
|
|||||||
self.create_cost_center()
|
self.create_cost_center()
|
||||||
self.clear_old_entries()
|
self.clear_old_entries()
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
frappe.db.rollback()
|
|
||||||
|
|
||||||
def create_company(self):
|
def create_company(self):
|
||||||
company = None
|
company = None
|
||||||
if frappe.db.exists("Company", "_Test Payment Reconciliation"):
|
if frappe.db.exists("Company", "_Test Payment Reconciliation"):
|
||||||
@@ -1235,7 +1230,7 @@ class TestPaymentReconciliation(IntegrationTestCase):
|
|||||||
payment_vouchers = [x.get("reference_name") for x in pr.get("payments")]
|
payment_vouchers = [x.get("reference_name") for x in pr.get("payments")]
|
||||||
self.assertCountEqual(payment_vouchers, [je2.name, pe2.name])
|
self.assertCountEqual(payment_vouchers, [je2.name, pe2.name])
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings(
|
@ERPNextTestSuite.change_settings(
|
||||||
"Accounts Settings",
|
"Accounts Settings",
|
||||||
{
|
{
|
||||||
"allow_multi_currency_invoices_against_single_party_account": 1,
|
"allow_multi_currency_invoices_against_single_party_account": 1,
|
||||||
|
|||||||
@@ -750,7 +750,8 @@ def make_payment_request(**args):
|
|||||||
pr.submit()
|
pr.submit()
|
||||||
|
|
||||||
if args.order_type == "Shopping Cart":
|
if args.order_type == "Shopping Cart":
|
||||||
frappe.db.commit()
|
if not frappe.in_test:
|
||||||
|
frappe.db.commit()
|
||||||
frappe.local.response["type"] = "redirect"
|
frappe.local.response["type"] = "redirect"
|
||||||
frappe.local.response["location"] = pr.get_payment_url()
|
frappe.local.response["location"] = pr.get_payment_url()
|
||||||
|
|
||||||
@@ -955,6 +956,7 @@ def resend_payment_email(docname: str):
|
|||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_payment_entry(docname: str):
|
def make_payment_entry(docname: str):
|
||||||
doc = frappe.get_doc("Payment Request", docname)
|
doc = frappe.get_doc("Payment Request", docname)
|
||||||
|
doc.check_permission("read")
|
||||||
return doc.create_payment_entry(submit=False).as_dict()
|
return doc.create_payment_entry(submit=False).as_dict()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import re
|
|||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import add_days, nowdate
|
from frappe.utils import add_days, nowdate
|
||||||
|
|
||||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
||||||
@@ -17,8 +16,7 @@ from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sal
|
|||||||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
||||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||||
from erpnext.setup.utils import get_exchange_rate
|
from erpnext.setup.utils import get_exchange_rate
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
EXTRA_TEST_RECORD_DEPENDENCIES = ["Currency Exchange", "Journal Entry", "Contact", "Address"]
|
|
||||||
|
|
||||||
PAYMENT_URL = "https://example.com/payment"
|
PAYMENT_URL = "https://example.com/payment"
|
||||||
|
|
||||||
@@ -63,7 +61,7 @@ payment_method = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class TestPaymentRequest(IntegrationTestCase):
|
class TestPaymentRequest(ERPNextTestSuite):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
for payment_gateway in payment_gateways:
|
for payment_gateway in payment_gateways:
|
||||||
if not frappe.db.get_value("Payment Gateway", payment_gateway["gateway"], "name"):
|
if not frappe.db.get_value("Payment Gateway", payment_gateway["gateway"], "name"):
|
||||||
@@ -100,9 +98,6 @@ class TestPaymentRequest(IntegrationTestCase):
|
|||||||
self._get_payment_gateway_controller = _get_payment_gateway_controller.start()
|
self._get_payment_gateway_controller = _get_payment_gateway_controller.start()
|
||||||
self.addCleanup(_get_payment_gateway_controller.stop)
|
self.addCleanup(_get_payment_gateway_controller.stop)
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
frappe.db.rollback()
|
|
||||||
|
|
||||||
def test_payment_request_linkings(self):
|
def test_payment_request_linkings(self):
|
||||||
so_inr = make_sales_order(currency="INR", do_not_save=True)
|
so_inr = make_sales_order(currency="INR", do_not_save=True)
|
||||||
so_inr.disable_rounded_total = 1
|
so_inr.disable_rounded_total = 1
|
||||||
@@ -503,7 +498,7 @@ class TestPaymentRequest(IntegrationTestCase):
|
|||||||
return_doc=1,
|
return_doc=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings(
|
@ERPNextTestSuite.change_settings(
|
||||||
"Accounts Settings", {"allow_multi_currency_invoices_against_single_party_account": 1}
|
"Accounts Settings", {"allow_multi_currency_invoices_against_single_party_account": 1}
|
||||||
)
|
)
|
||||||
def test_multiple_payment_if_partially_paid_for_multi_currency(self):
|
def test_multiple_payment_if_partially_paid_for_multi_currency(self):
|
||||||
@@ -621,7 +616,7 @@ class TestPaymentRequest(IntegrationTestCase):
|
|||||||
self.assertEqual(pr.outstanding_amount, 0)
|
self.assertEqual(pr.outstanding_amount, 0)
|
||||||
self.assertEqual(pr.grand_total, 20000)
|
self.assertEqual(pr.grand_total, 20000)
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings(
|
@ERPNextTestSuite.change_settings(
|
||||||
"Accounts Settings", {"allow_multi_currency_invoices_against_single_party_account": 1}
|
"Accounts Settings", {"allow_multi_currency_invoices_against_single_party_account": 1}
|
||||||
)
|
)
|
||||||
def test_single_payment_with_payment_term_for_multi_currency(self):
|
def test_single_payment_with_payment_term_for_multi_currency(self):
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
from frappe.tests import IntegrationTestCase
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestPaymentTerm(IntegrationTestCase):
|
class TestPaymentTerm(ERPNextTestSuite):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"doctype":"Payment Term",
|
|
||||||
"due_date_based_on":"Day(s) after invoice date",
|
|
||||||
"payment_term_name":"_Test N30",
|
|
||||||
"description":"_Test Net 30 Days",
|
|
||||||
"invoice_portion":50,
|
|
||||||
"credit_days":30
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype":"Payment Term",
|
|
||||||
"due_date_based_on":"Day(s) after invoice date",
|
|
||||||
"payment_term_name":"_Test COD",
|
|
||||||
"description":"_Test Cash on Delivery",
|
|
||||||
"invoice_portion":50,
|
|
||||||
"credit_days":0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype":"Payment Term",
|
|
||||||
"due_date_based_on":"Month(s) after the end of the invoice month",
|
|
||||||
"payment_term_name":"_Test EONM",
|
|
||||||
"description":"_Test End of Next Month",
|
|
||||||
"invoice_portion":100,
|
|
||||||
"credit_months":1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype":"Payment Term",
|
|
||||||
"due_date_based_on":"Day(s) after invoice date",
|
|
||||||
"payment_term_name":"_Test N30 1",
|
|
||||||
"description":"_Test Net 30 Days",
|
|
||||||
"invoice_portion":100,
|
|
||||||
"credit_days":30
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -2,13 +2,11 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestPaymentTermsTemplate(IntegrationTestCase):
|
class TestPaymentTermsTemplate(ERPNextTestSuite):
|
||||||
def tearDown(self):
|
|
||||||
frappe.delete_doc("Payment Terms Template", "_Test Payment Terms Template For Test", force=1)
|
|
||||||
|
|
||||||
def test_create_template(self):
|
def test_create_template(self):
|
||||||
template = frappe.get_doc(
|
template = frappe.get_doc(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"doctype":"Payment Terms Template",
|
|
||||||
"terms":[
|
|
||||||
{
|
|
||||||
"doctype":"Payment Terms Template Detail",
|
|
||||||
"due_date_based_on":"Day(s) after invoice date",
|
|
||||||
"idx":1,
|
|
||||||
"description":"Cash on Delivery",
|
|
||||||
"invoice_portion":50,
|
|
||||||
"credit_days":0,
|
|
||||||
"credit_months":0,
|
|
||||||
"payment_term":"_Test COD"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype":"Payment Terms Template Detail",
|
|
||||||
"due_date_based_on":"Day(s) after invoice date",
|
|
||||||
"idx":2,
|
|
||||||
"description":"Net 30 Days ",
|
|
||||||
"invoice_portion":50,
|
|
||||||
"credit_days":30,
|
|
||||||
"credit_months":0,
|
|
||||||
"payment_term":"_Test N30"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"template_name":"_Test Payment Term Template"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype":"Payment Terms Template",
|
|
||||||
"terms":[
|
|
||||||
{
|
|
||||||
"doctype":"Payment Terms Template Detail",
|
|
||||||
"due_date_based_on":"Month(s) after the end of the invoice month",
|
|
||||||
"idx":1,
|
|
||||||
"description":"_Test End of Next Months",
|
|
||||||
"invoice_portion":100,
|
|
||||||
"credit_days":0,
|
|
||||||
"credit_months":1,
|
|
||||||
"payment_term":"_Test EONM"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"template_name":"_Test Payment Term Template 1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype":"Payment Terms Template",
|
|
||||||
"terms":[
|
|
||||||
{
|
|
||||||
"doctype":"Payment Terms Template Detail",
|
|
||||||
"due_date_based_on":"Day(s) after invoice date",
|
|
||||||
"idx":1,
|
|
||||||
"description":"_Test Net Within 30 days",
|
|
||||||
"invoice_portion":100,
|
|
||||||
"credit_days":30,
|
|
||||||
"credit_months":0,
|
|
||||||
"payment_term":"_Test N30 1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"template_name":"_Test Payment Term Template 3"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -2,28 +2,3 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
# import frappe
|
# import frappe
|
||||||
from frappe.tests import IntegrationTestCase, UnitTestCase
|
|
||||||
|
|
||||||
# On IntegrationTestCase, the doctype test records and all
|
|
||||||
# link-field test record dependencies are recursively loaded
|
|
||||||
# Use these module variables to add/remove to/from that list
|
|
||||||
EXTRA_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
|
|
||||||
IGNORE_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
|
|
||||||
|
|
||||||
|
|
||||||
class UnitTestPeggedCurrencies(UnitTestCase):
|
|
||||||
"""
|
|
||||||
Unit tests for PeggedCurrencies.
|
|
||||||
Use this class for testing individual functions and methods.
|
|
||||||
"""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class IntegrationTestPeggedCurrencies(IntegrationTestCase):
|
|
||||||
"""
|
|
||||||
Integration tests for PeggedCurrencies.
|
|
||||||
Use this class for testing interactions between multiple components.
|
|
||||||
"""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|||||||
@@ -2,16 +2,16 @@
|
|||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
|
||||||
from frappe.utils import today
|
from frappe.utils import today
|
||||||
|
|
||||||
from erpnext.accounts.doctype.finance_book.test_finance_book import create_finance_book
|
from erpnext.accounts.doctype.finance_book.test_finance_book import create_finance_book
|
||||||
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
|
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
from erpnext.accounts.utils import get_fiscal_year
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
class TestPeriodClosingVoucher(IntegrationTestCase):
|
class TestPeriodClosingVoucher(ERPNextTestSuite):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
frappe.db.set_single_value("Accounts Settings", "use_legacy_controller_for_pcv", 1)
|
frappe.db.set_single_value("Accounts Settings", "use_legacy_controller_for_pcv", 1)
|
||||||
@@ -390,6 +390,3 @@ def create_cost_center(cc_name):
|
|||||||
)
|
)
|
||||||
costcenter.insert(ignore_if_duplicate=True)
|
costcenter.insert(ignore_if_duplicate=True)
|
||||||
return costcenter.name
|
return costcenter.name
|
||||||
|
|
||||||
|
|
||||||
EXTRA_TEST_RECORD_DEPENDENCIES = ["Customer", "Cost Center"]
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user