diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index 9402e3da09..2954d2fc3f 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -933,7 +933,7 @@ frappe.ui.form.on('Payment Entry', {
if(frm.doc.payment_type == "Receive"
&& frm.doc.base_total_allocated_amount < frm.doc.base_received_amount + total_deductions
&& frm.doc.total_allocated_amount < frm.doc.paid_amount + (total_deductions / frm.doc.source_exchange_rate)) {
- unallocated_amount = (frm.doc.base_received_amount + total_deductions + flt(frm.doc.base_total_taxes_and_charges)
+ unallocated_amount = (frm.doc.base_received_amount + total_deductions - flt(frm.doc.base_total_taxes_and_charges)
- frm.doc.base_total_allocated_amount) / frm.doc.source_exchange_rate;
} else if (frm.doc.payment_type == "Pay"
&& frm.doc.base_total_allocated_amount < frm.doc.base_paid_amount - total_deductions
diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
index 9cf4e4fd7c..26984d96ef 100644
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
@@ -64,6 +64,7 @@
"warehouse",
"from_warehouse",
"quality_inspection",
+ "add_serial_batch_bundle",
"serial_and_batch_bundle",
"serial_no",
"col_br_wh",
@@ -913,12 +914,18 @@
"fieldtype": "Link",
"label": "WIP Composite Asset",
"options": "Asset"
+ },
+ {
+ "depends_on": "eval:parent.update_stock === 1",
+ "fieldname": "add_serial_batch_bundle",
+ "fieldtype": "Button",
+ "label": "Add Serial / Batch No"
}
],
"idx": 1,
"istable": 1,
"links": [],
- "modified": "2023-12-25 22:00:28.043555",
+ "modified": "2024-01-21 19:46:25.537861",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice Item",
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
index ed3b991559..7d8d33c46b 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
@@ -10,10 +10,8 @@
@@ -141,7 +139,7 @@
| {%= __("Reference") %} |
{% } %}
{% if(!filters.show_future_payments) { %}
- {%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %} |
+ {%= (filters.party) ? __("Remarks"): __("Party") %} |
{% } %}
{%= __("Invoiced Amount") %} |
{% if(!filters.show_future_payments) { %}
@@ -158,7 +156,7 @@
{%= __("Remaining Balance") %} |
{% } %}
{% } else { %}
- {%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %} |
+ {%= (filters.party) ? __("Remarks"): __("Party") %} |
{%= __("Total Invoiced Amount") %} |
{%= __("Total Paid Amount") %} |
{%= report.report_name === "Accounts Receivable Summary" ? __('Credit Note Amount') : __('Debit Note Amount') %} |
@@ -187,7 +185,7 @@
{% if(!filters.show_future_payments) { %}
- {% if(!(filters.customer || filters.supplier)) { %}
+ {% if(!(filters.party)) { %}
{%= data[i]["party"] %}
{% if(data[i]["customer_name"] && data[i]["customer_name"] != data[i]["party"]) { %}
{%= data[i]["customer_name"] %}
@@ -260,7 +258,7 @@
{% if(data[i]["party"]|| " ") { %}
{% if(!data[i]["is_total_row"]) { %}
|
- {% if(!(filters.customer || filters.supplier)) { %}
+ {% if(!(filters.party)) { %}
{%= data[i]["party"] %}
{% if(data[i]["customer_name"] && data[i]["customer_name"] != data[i]["party"]) { %}
{%= data[i]["customer_name"] %}
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index 004a9299ea..aadd8731ca 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -8,17 +8,7 @@ import re
import frappe
from frappe import _
-from frappe.utils import (
- add_days,
- add_months,
- cint,
- cstr,
- flt,
- formatdate,
- get_first_day,
- getdate,
- today,
-)
+from frappe.utils import add_days, add_months, cint, cstr, flt, formatdate, get_first_day, getdate
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_accounting_dimensions,
@@ -53,8 +43,6 @@ def get_period_list(
year_start_date = getdate(period_start_date)
year_end_date = getdate(period_end_date)
- year_end_date = getdate(today()) if year_end_date > getdate(today()) else year_end_date
-
months_to_add = {"Yearly": 12, "Half-Yearly": 6, "Quarterly": 3, "Monthly": 1}[periodicity]
period_list = []
diff --git a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py
index f0ca405401..5ccd4f0f16 100644
--- a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py
+++ b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py
@@ -134,7 +134,7 @@ def get_revenue(data, period_list, include_in_gross=1):
def remove_parent_with_no_child(data):
data_to_be_removed = False
- for parent in data:
+ for parent in list(data):
if "is_group" in parent and parent.get("is_group") == 1:
have_child = False
for child in data:
diff --git a/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py b/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py
index 9513f2c153..0c324c8bf1 100644
--- a/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py
+++ b/erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py
@@ -46,12 +46,10 @@ def get_result(
out = []
for name, details in gle_map.items():
- tax_amount, total_amount, grand_total, base_total = 0, 0, 0, 0
- bill_no, bill_date = "", ""
- tax_withholding_category = tax_category_map.get(name)
- rate = tax_rate_map.get(tax_withholding_category)
-
for entry in details:
+ tax_amount, total_amount, grand_total, base_total = 0, 0, 0, 0
+ tax_withholding_category, rate = None, None
+ bill_no, bill_date = "", ""
party = entry.party or entry.against
posting_date = entry.posting_date
voucher_type = entry.voucher_type
@@ -61,12 +59,19 @@ def get_result(
if party_list:
party = party_list[0]
- if not tax_withholding_category:
- tax_withholding_category = party_map.get(party, {}).get("tax_withholding_category")
- rate = tax_rate_map.get(tax_withholding_category)
-
- if entry.account in tds_accounts:
+ if entry.account in tds_accounts.keys():
tax_amount += entry.credit - entry.debit
+ # infer tax withholding category from the account if it's the single account for this category
+ tax_withholding_category = tds_accounts.get(entry.account)
+ rate = tax_rate_map.get(tax_withholding_category)
+ # or else the consolidated value from the voucher document
+ if not tax_withholding_category:
+ # or else from the party default
+ tax_withholding_category = tax_category_map.get(name)
+ rate = tax_rate_map.get(tax_withholding_category)
+ if not tax_withholding_category:
+ tax_withholding_category = party_map.get(party, {}).get("tax_withholding_category")
+ rate = tax_rate_map.get(tax_withholding_category)
if net_total_map.get(name):
if voucher_type == "Journal Entry":
@@ -80,41 +85,41 @@ def get_result(
else:
total_amount += entry.credit
- if tax_amount:
- if party_map.get(party, {}).get("party_type") == "Supplier":
- party_name = "supplier_name"
- party_type = "supplier_type"
- else:
- party_name = "customer_name"
- party_type = "customer_type"
+ if tax_amount:
+ if party_map.get(party, {}).get("party_type") == "Supplier":
+ party_name = "supplier_name"
+ party_type = "supplier_type"
+ else:
+ party_name = "customer_name"
+ party_type = "customer_type"
- row = {
- "pan"
- if frappe.db.has_column(filters.party_type, "pan")
- else "tax_id": party_map.get(party, {}).get("pan"),
- "party": party_map.get(party, {}).get("name"),
- }
-
- if filters.naming_series == "Naming Series":
- row.update({"party_name": party_map.get(party, {}).get(party_name)})
-
- row.update(
- {
- "section_code": tax_withholding_category or "",
- "entity_type": party_map.get(party, {}).get(party_type),
- "rate": rate,
- "total_amount": total_amount,
- "grand_total": grand_total,
- "base_total": base_total,
- "tax_amount": tax_amount,
- "transaction_date": posting_date,
- "transaction_type": voucher_type,
- "ref_no": name,
- "supplier_invoice_no": bill_no,
- "supplier_invoice_date": bill_date,
+ row = {
+ "pan"
+ if frappe.db.has_column(filters.party_type, "pan")
+ else "tax_id": party_map.get(party, {}).get("pan"),
+ "party": party_map.get(party, {}).get("name"),
}
- )
- out.append(row)
+
+ if filters.naming_series == "Naming Series":
+ row.update({"party_name": party_map.get(party, {}).get(party_name)})
+
+ row.update(
+ {
+ "section_code": tax_withholding_category or "",
+ "entity_type": party_map.get(party, {}).get(party_type),
+ "rate": rate,
+ "total_amount": total_amount,
+ "grand_total": grand_total,
+ "base_total": base_total,
+ "tax_amount": tax_amount,
+ "transaction_date": posting_date,
+ "transaction_type": voucher_type,
+ "ref_no": name,
+ "supplier_invoice_no": bill_no,
+ "supplier_invoice_date": bill_date,
+ }
+ )
+ out.append(row)
out.sort(key=lambda x: x["section_code"])
@@ -282,11 +287,20 @@ def get_tds_docs(filters):
journal_entry_party_map = frappe._dict()
bank_accounts = frappe.get_all("Account", {"is_group": 0, "account_type": "Bank"}, pluck="name")
- tds_accounts = frappe.get_all(
- "Tax Withholding Account", {"company": filters.get("company")}, pluck="account"
+ _tds_accounts = frappe.get_all(
+ "Tax Withholding Account",
+ {"company": filters.get("company")},
+ ["account", "parent"],
)
+ tds_accounts = {}
+ for tds_acc in _tds_accounts:
+ # if it turns out not to be the only tax withholding category, then don't include in the map
+ if tds_accounts.get(tds_acc["account"]):
+ tds_accounts[tds_acc["account"]] = None
+ else:
+ tds_accounts[tds_acc["account"]] = tds_acc["parent"]
- tds_docs = get_tds_docs_query(filters, bank_accounts, tds_accounts).run(as_dict=True)
+ tds_docs = get_tds_docs_query(filters, bank_accounts, list(tds_accounts.keys())).run(as_dict=True)
for d in tds_docs:
if d.voucher_type == "Purchase Invoice":
diff --git a/erpnext/accounts/workspace/accounting/accounting.json b/erpnext/accounts/workspace/accounting/accounting.json
index dfdae1dec6..45ab92e2c5 100644
--- a/erpnext/accounts/workspace/accounting/accounting.json
+++ b/erpnext/accounts/workspace/accounting/accounting.json
@@ -5,7 +5,7 @@
"label": "Profit and Loss"
}
],
- "content": "[{\"id\":\"MmUf9abwxg\",\"type\":\"onboarding\",\"data\":{\"onboarding_name\":\"Accounts\",\"col\":12}},{\"id\":\"VVvJ1lUcfc\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Outgoing Bills\",\"col\":3}},{\"id\":\"Vlj2FZtlHV\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Incoming Bills\",\"col\":3}},{\"id\":\"VVVjQVAhPf\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Incoming Payment\",\"col\":3}},{\"id\":\"DySNdlysIW\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Outgoing Payment\",\"col\":3}},{\"id\":\"i0EtSjDAXq\",\"type\":\"chart\",\"data\":{\"chart_name\":\"Profit and Loss\",\"col\":12}},{\"id\":\"X78jcbq1u3\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"vikWSkNm6_\",\"type\":\"header\",\"data\":{\"text\":\"Your Shortcuts\",\"col\":12}},{\"id\":\"pMywM0nhlj\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Chart of Accounts\",\"col\":3}},{\"id\":\"_pRdD6kqUG\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Sales Invoice\",\"col\":3}},{\"id\":\"G984SgVRJN\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Invoice\",\"col\":3}},{\"id\":\"1ArNvt9qhz\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Journal Entry\",\"col\":3}},{\"id\":\"F9f4I1viNr\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Payment Entry\",\"col\":3}},{\"id\":\"4IBBOIxfqW\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Accounts Receivable\",\"col\":3}},{\"id\":\"El2anpPaFY\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"General Ledger\",\"col\":3}},{\"id\":\"1nwcM9upJo\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Trial Balance\",\"col\":3}},{\"id\":\"OF9WOi1Ppc\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"id\":\"iAwpe-Chra\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Learn Accounting\",\"col\":3}},{\"id\":\"B7-uxs8tkU\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"tHb3yxthkR\",\"type\":\"header\",\"data\":{\"text\":\"Reports & Masters\",\"col\":12}},{\"id\":\"DnNtsmxpty\",\"type\":\"card\",\"data\":{\"card_name\":\"Accounting Masters\",\"col\":4}},{\"id\":\"nKKr6fjgjb\",\"type\":\"card\",\"data\":{\"card_name\":\"General Ledger\",\"col\":4}},{\"id\":\"xOHTyD8b5l\",\"type\":\"card\",\"data\":{\"card_name\":\"Accounts Receivable\",\"col\":4}},{\"id\":\"_Cb7C8XdJJ\",\"type\":\"card\",\"data\":{\"card_name\":\"Accounts Payable\",\"col\":4}},{\"id\":\"p7NY6MHe2Y\",\"type\":\"card\",\"data\":{\"card_name\":\"Financial Statements\",\"col\":4}},{\"id\":\"KlqilF5R_V\",\"type\":\"card\",\"data\":{\"card_name\":\"Taxes\",\"col\":4}},{\"id\":\"jTUy8LB0uw\",\"type\":\"card\",\"data\":{\"card_name\":\"Cost Center and Budgeting\",\"col\":4}},{\"id\":\"Wn2lhs7WLn\",\"type\":\"card\",\"data\":{\"card_name\":\"Multi Currency\",\"col\":4}},{\"id\":\"PAQMqqNkBM\",\"type\":\"card\",\"data\":{\"card_name\":\"Bank Statement\",\"col\":4}},{\"id\":\"Q_hBCnSeJY\",\"type\":\"card\",\"data\":{\"card_name\":\"Reports\",\"col\":4}},{\"id\":\"3AK1Zf0oew\",\"type\":\"card\",\"data\":{\"card_name\":\"Profitability\",\"col\":4}},{\"id\":\"kxhoaiqdLq\",\"type\":\"card\",\"data\":{\"card_name\":\"Opening and Closing\",\"col\":4}},{\"id\":\"q0MAlU2j_Z\",\"type\":\"card\",\"data\":{\"card_name\":\"Subscription Management\",\"col\":4}},{\"id\":\"ptm7T6Hwu-\",\"type\":\"card\",\"data\":{\"card_name\":\"Share Management\",\"col\":4}},{\"id\":\"OX7lZHbiTr\",\"type\":\"card\",\"data\":{\"card_name\":\"Settings\",\"col\":4}}]",
+ "content": "[{\"id\":\"MmUf9abwxg\",\"type\":\"onboarding\",\"data\":{\"onboarding_name\":\"Accounts\",\"col\":12}},{\"id\":\"nDhfcJYbKH\",\"type\":\"chart\",\"data\":{\"chart_name\":\"Profit and Loss\",\"col\":12}},{\"id\":\"VVvJ1lUcfc\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Outgoing Bills\",\"col\":3}},{\"id\":\"Vlj2FZtlHV\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Incoming Bills\",\"col\":3}},{\"id\":\"VVVjQVAhPf\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Incoming Payment\",\"col\":3}},{\"id\":\"DySNdlysIW\",\"type\":\"number_card\",\"data\":{\"number_card_name\":\"Total Outgoing Payment\",\"col\":3}},{\"id\":\"9k1rDm2C0l\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"vikWSkNm6_\",\"type\":\"header\",\"data\":{\"text\":\"Shortcuts\",\"col\":12}},{\"id\":\"pMywM0nhlj\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Chart of Accounts\",\"col\":3}},{\"id\":\"_pRdD6kqUG\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Sales Invoice\",\"col\":3}},{\"id\":\"G984SgVRJN\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Invoice\",\"col\":3}},{\"id\":\"1ArNvt9qhz\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Journal Entry\",\"col\":3}},{\"id\":\"F9f4I1viNr\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Payment Entry\",\"col\":3}},{\"id\":\"4IBBOIxfqW\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Accounts Receivable\",\"col\":3}},{\"id\":\"El2anpPaFY\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"General Ledger\",\"col\":3}},{\"id\":\"1nwcM9upJo\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Trial Balance\",\"col\":3}},{\"id\":\"OF9WOi1Ppc\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"id\":\"iAwpe-Chra\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Learn Accounting\",\"col\":3}},{\"id\":\"B7-uxs8tkU\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"tHb3yxthkR\",\"type\":\"header\",\"data\":{\"text\":\"Reports & Masters\",\"col\":12}},{\"id\":\"DnNtsmxpty\",\"type\":\"card\",\"data\":{\"card_name\":\"Accounting Masters\",\"col\":4}},{\"id\":\"nKKr6fjgjb\",\"type\":\"card\",\"data\":{\"card_name\":\"Payments\",\"col\":4}},{\"id\":\"KlqilF5R_V\",\"type\":\"card\",\"data\":{\"card_name\":\"Tax Masters\",\"col\":4}},{\"id\":\"jTUy8LB0uw\",\"type\":\"card\",\"data\":{\"card_name\":\"Cost Center and Budgeting\",\"col\":4}},{\"id\":\"Wn2lhs7WLn\",\"type\":\"card\",\"data\":{\"card_name\":\"Multi Currency\",\"col\":4}},{\"id\":\"PAQMqqNkBM\",\"type\":\"card\",\"data\":{\"card_name\":\"Banking\",\"col\":4}},{\"id\":\"kxhoaiqdLq\",\"type\":\"card\",\"data\":{\"card_name\":\"Opening and Closing\",\"col\":4}},{\"id\":\"q0MAlU2j_Z\",\"type\":\"card\",\"data\":{\"card_name\":\"Subscription Management\",\"col\":4}},{\"id\":\"ptm7T6Hwu-\",\"type\":\"card\",\"data\":{\"card_name\":\"Share Management\",\"col\":4}}]",
"creation": "2020-03-02 15:41:59.515192",
"custom_blocks": [],
"docstatus": 0,
@@ -14,562 +14,10 @@
"hide_custom": 0,
"icon": "accounting",
"idx": 0,
+ "indicator_color": "",
"is_hidden": 0,
"label": "Accounting",
"links": [
- {
- "hidden": 0,
- "is_query_report": 0,
- "label": "Accounting Masters",
- "link_count": 0,
- "onboard": 0,
- "type": "Card Break"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Company",
- "link_count": 0,
- "link_to": "Company",
- "link_type": "DocType",
- "onboard": 1,
- "type": "Link"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Chart of Accounts",
- "link_count": 0,
- "link_to": "Account",
- "link_type": "DocType",
- "onboard": 1,
- "type": "Link"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Accounts Settings",
- "link_count": 0,
- "link_to": "Accounts Settings",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Fiscal Year",
- "link_count": 0,
- "link_to": "Fiscal Year",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Accounting Dimension",
- "link_count": 0,
- "link_to": "Accounting Dimension",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Finance Book",
- "link_count": 0,
- "link_to": "Finance Book",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Accounting Period",
- "link_count": 0,
- "link_to": "Accounting Period",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Payment Term",
- "link_count": 0,
- "link_to": "Payment Term",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "hidden": 0,
- "is_query_report": 0,
- "label": "General Ledger",
- "link_count": 0,
- "onboard": 0,
- "type": "Card Break"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Journal Entry",
- "link_count": 0,
- "link_to": "Journal Entry",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Journal Entry Template",
- "link_count": 0,
- "link_to": "Journal Entry Template",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "GL Entry",
- "hidden": 0,
- "is_query_report": 1,
- "label": "General Ledger",
- "link_count": 0,
- "link_to": "General Ledger",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Sales Invoice",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Customer Ledger Summary",
- "link_count": 0,
- "link_to": "Customer Ledger Summary",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Sales Invoice",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Supplier Ledger Summary",
- "link_count": 0,
- "link_to": "Supplier Ledger Summary",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "hidden": 0,
- "is_query_report": 0,
- "label": "Accounts Receivable",
- "link_count": 0,
- "onboard": 0,
- "type": "Card Break"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Sales Invoice",
- "link_count": 0,
- "link_to": "Sales Invoice",
- "link_type": "DocType",
- "onboard": 1,
- "type": "Link"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Customer",
- "link_count": 0,
- "link_to": "Customer",
- "link_type": "DocType",
- "onboard": 1,
- "type": "Link"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Payment Entry",
- "link_count": 0,
- "link_to": "Payment Entry",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Payment Request",
- "link_count": 0,
- "link_to": "Payment Request",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "hidden": 0,
- "is_query_report": 0,
- "label": "Payment Reconciliation",
- "link_count": 0,
- "link_to": "Payment Reconciliation",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Sales Invoice",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Accounts Receivable",
- "link_count": 0,
- "link_to": "Accounts Receivable",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Sales Invoice",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Accounts Receivable Summary",
- "link_count": 0,
- "link_to": "Accounts Receivable Summary",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Sales Invoice",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Sales Register",
- "link_count": 0,
- "link_to": "Sales Register",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Sales Invoice",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Item-wise Sales Register",
- "link_count": 0,
- "link_to": "Item-wise Sales Register",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Sales Invoice",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Sales Order Analysis",
- "link_count": 0,
- "link_to": "Sales Order Analysis",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Sales Invoice",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Delivered Items To Be Billed",
- "link_count": 0,
- "link_to": "Delivered Items To Be Billed",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "hidden": 0,
- "is_query_report": 0,
- "label": "Accounts Payable",
- "link_count": 0,
- "onboard": 0,
- "type": "Card Break"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Purchase Invoice",
- "link_count": 0,
- "link_to": "Purchase Invoice",
- "link_type": "DocType",
- "onboard": 1,
- "type": "Link"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Supplier",
- "link_count": 0,
- "link_to": "Supplier",
- "link_type": "DocType",
- "onboard": 1,
- "type": "Link"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Payment Entry",
- "link_count": 0,
- "link_to": "Payment Entry",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "hidden": 0,
- "is_query_report": 0,
- "label": "Payment Reconciliation",
- "link_count": 0,
- "link_to": "Payment Reconciliation",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Purchase Invoice",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Accounts Payable",
- "link_count": 0,
- "link_to": "Accounts Payable",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Purchase Invoice",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Accounts Payable Summary",
- "link_count": 0,
- "link_to": "Accounts Payable Summary",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Purchase Invoice",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Purchase Register",
- "link_count": 0,
- "link_to": "Purchase Register",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Purchase Invoice",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Item-wise Purchase Register",
- "link_count": 0,
- "link_to": "Item-wise Purchase Register",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Purchase Order",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Purchase Order Analysis",
- "link_count": 0,
- "link_to": "Purchase Order Analysis",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Purchase Invoice",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Received Items To Be Billed",
- "link_count": 0,
- "link_to": "Received Items To Be Billed",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "hidden": 0,
- "is_query_report": 0,
- "label": "Reports",
- "link_count": 0,
- "onboard": 0,
- "type": "Card Break"
- },
- {
- "dependencies": "GL Entry",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Trial Balance for Party",
- "link_count": 0,
- "link_to": "Trial Balance for Party",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Journal Entry",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Payment Period Based On Invoice Date",
- "link_count": 0,
- "link_to": "Payment Period Based On Invoice Date",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Sales Invoice",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Sales Partners Commission",
- "link_count": 0,
- "link_to": "Sales Partners Commission",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Customer",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Customer Credit Balance",
- "link_count": 0,
- "link_to": "Customer Credit Balance",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Sales Invoice",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Sales Payment Summary",
- "link_count": 0,
- "link_to": "Sales Payment Summary",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "Address",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Address And Contacts",
- "link_count": 0,
- "link_to": "Address And Contacts",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "GL Entry",
- "hidden": 0,
- "is_query_report": 1,
- "label": "UAE VAT 201",
- "link_count": 0,
- "link_to": "UAE VAT 201",
- "link_type": "Report",
- "onboard": 0,
- "only_for": "United Arab Emirates",
- "type": "Link"
- },
- {
- "hidden": 0,
- "is_query_report": 0,
- "label": "Financial Statements",
- "link_count": 0,
- "onboard": 0,
- "type": "Card Break"
- },
- {
- "dependencies": "GL Entry",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Trial Balance",
- "link_count": 0,
- "link_to": "Trial Balance",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "GL Entry",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Profit and Loss Statement",
- "link_count": 0,
- "link_to": "Profit and Loss Statement",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "GL Entry",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Balance Sheet",
- "link_count": 0,
- "link_to": "Balance Sheet",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "GL Entry",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Cash Flow",
- "link_count": 0,
- "link_to": "Cash Flow",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "GL Entry",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Consolidated Financial Statement",
- "link_count": 0,
- "link_to": "Consolidated Financial Statement",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
{
"hidden": 0,
"is_query_report": 0,
@@ -611,110 +59,6 @@
"onboard": 0,
"type": "Link"
},
- {
- "hidden": 0,
- "is_query_report": 0,
- "label": "Settings",
- "link_count": 0,
- "onboard": 0,
- "type": "Card Break"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Payment Gateway Account",
- "link_count": 0,
- "link_to": "Payment Gateway Account",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Terms and Conditions Template",
- "link_count": 0,
- "link_to": "Terms and Conditions",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Mode of Payment",
- "link_count": 0,
- "link_to": "Mode of Payment",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "hidden": 0,
- "is_query_report": 0,
- "label": "Bank Statement",
- "link_count": 0,
- "onboard": 0,
- "type": "Card Break"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Bank",
- "link_count": 0,
- "link_to": "Bank",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Bank Account",
- "link_count": 0,
- "link_to": "Bank Account",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Bank Clearance",
- "link_count": 0,
- "link_to": "Bank Clearance",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "",
- "hidden": 0,
- "is_query_report": 0,
- "label": "Bank Reconciliation Tool",
- "link_count": 0,
- "link_to": "Bank Reconciliation Tool",
- "link_type": "DocType",
- "onboard": 0,
- "type": "Link"
- },
- {
- "dependencies": "GL Entry",
- "hidden": 0,
- "is_query_report": 1,
- "label": "Bank Reconciliation Statement",
- "link_count": 0,
- "link_to": "Bank Reconciliation Statement",
- "link_type": "Report",
- "onboard": 0,
- "type": "Link"
- },
{
"hidden": 0,
"is_query_report": 0,
@@ -926,8 +270,83 @@
{
"hidden": 0,
"is_query_report": 0,
- "label": "Taxes",
+ "label": "Banking",
+ "link_count": 6,
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Card Break"
+ },
+ {
+ "dependencies": "",
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Bank",
"link_count": 0,
+ "link_to": "Bank",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "",
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Bank Account",
+ "link_count": 0,
+ "link_to": "Bank Account",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "",
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Bank Clearance",
+ "link_count": 0,
+ "link_to": "Bank Clearance",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "",
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Bank Reconciliation Tool",
+ "link_count": 0,
+ "link_to": "Bank Reconciliation Tool",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "GL Entry",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Bank Reconciliation Statement",
+ "link_count": 0,
+ "link_to": "Bank Reconciliation Statement",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Plaid Settings",
+ "link_count": 0,
+ "link_to": "Plaid Settings",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Tax Masters",
+ "link_count": 7,
+ "link_type": "DocType",
"onboard": 0,
"type": "Card Break"
},
@@ -1011,57 +430,163 @@
{
"hidden": 0,
"is_query_report": 0,
- "label": "Profitability",
- "link_count": 0,
+ "label": "Accounting Masters",
+ "link_count": 8,
+ "link_type": "DocType",
"onboard": 0,
"type": "Card Break"
},
{
- "dependencies": "Sales Invoice",
+ "dependencies": "",
"hidden": 0,
- "is_query_report": 1,
- "label": "Gross Profit",
+ "is_query_report": 0,
+ "label": "Company",
"link_count": 0,
- "link_to": "Gross Profit",
- "link_type": "Report",
+ "link_to": "Company",
+ "link_type": "DocType",
+ "onboard": 1,
+ "type": "Link"
+ },
+ {
+ "dependencies": "",
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Chart of Accounts",
+ "link_count": 0,
+ "link_to": "Account",
+ "link_type": "DocType",
+ "onboard": 1,
+ "type": "Link"
+ },
+ {
+ "dependencies": "",
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Accounts Settings",
+ "link_count": 0,
+ "link_to": "Accounts Settings",
+ "link_type": "DocType",
"onboard": 0,
"type": "Link"
},
{
- "dependencies": "GL Entry",
+ "dependencies": "",
"hidden": 0,
- "is_query_report": 1,
- "label": "Profitability Analysis",
+ "is_query_report": 0,
+ "label": "Fiscal Year",
"link_count": 0,
- "link_to": "Profitability Analysis",
- "link_type": "Report",
+ "link_to": "Fiscal Year",
+ "link_type": "DocType",
"onboard": 0,
"type": "Link"
},
{
- "dependencies": "Sales Invoice",
+ "dependencies": "",
"hidden": 0,
- "is_query_report": 1,
- "label": "Sales Invoice Trends",
+ "is_query_report": 0,
+ "label": "Accounting Dimension",
"link_count": 0,
- "link_to": "Sales Invoice Trends",
- "link_type": "Report",
+ "link_to": "Accounting Dimension",
+ "link_type": "DocType",
"onboard": 0,
"type": "Link"
},
{
- "dependencies": "Purchase Invoice",
+ "dependencies": "",
"hidden": 0,
- "is_query_report": 1,
- "label": "Purchase Invoice Trends",
+ "is_query_report": 0,
+ "label": "Finance Book",
"link_count": 0,
- "link_to": "Purchase Invoice Trends",
- "link_type": "Report",
+ "link_to": "Finance Book",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "",
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Accounting Period",
+ "link_count": 0,
+ "link_to": "Accounting Period",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "",
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Payment Term",
+ "link_count": 0,
+ "link_to": "Payment Term",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Payments",
+ "link_count": 5,
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Card Break"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Payment Entry",
+ "link_count": 0,
+ "link_to": "Payment Entry",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "",
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Journal Entry",
+ "link_count": 0,
+ "link_to": "Journal Entry",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "",
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Journal Entry Template",
+ "link_count": 0,
+ "link_to": "Journal Entry Template",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Terms and Conditions",
+ "link_count": 0,
+ "link_to": "Terms and Conditions",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Mode of Payment",
+ "link_count": 0,
+ "link_to": "Mode of Payment",
+ "link_type": "DocType",
"onboard": 0,
"type": "Link"
}
],
- "modified": "2023-08-10 17:41:14.059005",
+ "modified": "2024-01-18 22:15:40.941711",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounting",
diff --git a/erpnext/accounts/workspace/financial_reports/financial_reports.json b/erpnext/accounts/workspace/financial_reports/financial_reports.json
new file mode 100644
index 0000000000..3ab4a3e22d
--- /dev/null
+++ b/erpnext/accounts/workspace/financial_reports/financial_reports.json
@@ -0,0 +1,277 @@
+{
+ "charts": [],
+ "content": "[{\"id\":\"nKKr6fjgjb\",\"type\":\"card\",\"data\":{\"card_name\":\"Ledgers\",\"col\":4}},{\"id\":\"p7NY6MHe2Y\",\"type\":\"card\",\"data\":{\"card_name\":\"Financial Statements\",\"col\":4}},{\"id\":\"3AK1Zf0oew\",\"type\":\"card\",\"data\":{\"card_name\":\"Profitability\",\"col\":4}},{\"id\":\"Q_hBCnSeJY\",\"type\":\"card\",\"data\":{\"card_name\":\"Other Reports\",\"col\":4}}]",
+ "creation": "2024-01-05 16:09:16.766939",
+ "custom_blocks": [],
+ "docstatus": 0,
+ "doctype": "Workspace",
+ "for_user": "",
+ "hide_custom": 0,
+ "icon": "file",
+ "idx": 0,
+ "indicator_color": "",
+ "is_hidden": 0,
+ "label": "Financial Reports",
+ "links": [
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Profitability",
+ "link_count": 0,
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Card Break"
+ },
+ {
+ "dependencies": "Sales Invoice",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Gross Profit",
+ "link_count": 0,
+ "link_to": "Gross Profit",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "GL Entry",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Profitability Analysis",
+ "link_count": 0,
+ "link_to": "Profitability Analysis",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "Sales Invoice",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Sales Invoice Trends",
+ "link_count": 0,
+ "link_to": "Sales Invoice Trends",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "Purchase Invoice",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Purchase Invoice Trends",
+ "link_count": 0,
+ "link_to": "Purchase Invoice Trends",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Financial Statements",
+ "link_count": 5,
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Card Break"
+ },
+ {
+ "dependencies": "GL Entry",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Trial Balance",
+ "link_count": 0,
+ "link_to": "Trial Balance",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "GL Entry",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Profit and Loss Statement",
+ "link_count": 0,
+ "link_to": "Profit and Loss Statement",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "GL Entry",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Balance Sheet",
+ "link_count": 0,
+ "link_to": "Balance Sheet",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "GL Entry",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Cash Flow",
+ "link_count": 0,
+ "link_to": "Cash Flow",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "GL Entry",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Consolidated Financial Statement",
+ "link_count": 0,
+ "link_to": "Consolidated Financial Statement",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Ledgers",
+ "link_count": 3,
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Card Break"
+ },
+ {
+ "dependencies": "GL Entry",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "General Ledger",
+ "link_count": 0,
+ "link_to": "General Ledger",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "Sales Invoice",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Customer Ledger Summary",
+ "link_count": 0,
+ "link_to": "Customer Ledger Summary",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "Sales Invoice",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Supplier Ledger Summary",
+ "link_count": 0,
+ "link_to": "Supplier Ledger Summary",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Other Reports",
+ "link_count": 7,
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Card Break"
+ },
+ {
+ "dependencies": "GL Entry",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Trial Balance for Party",
+ "link_count": 0,
+ "link_to": "Trial Balance for Party",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "Journal Entry",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Payment Period Based On Invoice Date",
+ "link_count": 0,
+ "link_to": "Payment Period Based On Invoice Date",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "Sales Invoice",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Sales Partners Commission",
+ "link_count": 0,
+ "link_to": "Sales Partners Commission",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "Customer",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Customer Credit Balance",
+ "link_count": 0,
+ "link_to": "Customer Credit Balance",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "Sales Invoice",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Sales Payment Summary",
+ "link_count": 0,
+ "link_to": "Sales Payment Summary",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "Address",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Address And Contacts",
+ "link_count": 0,
+ "link_to": "Address And Contacts",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "GL Entry",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "UAE VAT 201",
+ "link_count": 0,
+ "link_to": "UAE VAT 201",
+ "link_type": "Report",
+ "onboard": 0,
+ "only_for": "United Arab Emirates",
+ "type": "Link"
+ }
+ ],
+ "modified": "2024-01-18 22:13:07.596844",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Financial Reports",
+ "number_cards": [],
+ "owner": "Administrator",
+ "parent_page": "Accounting",
+ "public": 1,
+ "quick_lists": [],
+ "restrict_to_domain": "",
+ "roles": [],
+ "sequence_id": 5.0,
+ "shortcuts": [],
+ "title": "Financial Reports"
+}
\ No newline at end of file
diff --git a/erpnext/accounts/workspace/payables/payables.json b/erpnext/accounts/workspace/payables/payables.json
new file mode 100644
index 0000000000..f8c8564875
--- /dev/null
+++ b/erpnext/accounts/workspace/payables/payables.json
@@ -0,0 +1,204 @@
+{
+ "charts": [],
+ "content": "[{\"id\":\"rMMsfn2eB4\",\"type\":\"header\",\"data\":{\"text\":\"Shortcuts\",\"col\":12}},{\"id\":\"G984SgVRJN\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Invoice\",\"col\":3}},{\"id\":\"F9f4I1viNr\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Payment Entry\",\"col\":3}},{\"id\":\"1ArNvt9qhz\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Journal Entry\",\"col\":3}},{\"id\":\"4IBBOIxfqW\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Accounts Payable\",\"col\":3}},{\"id\":\"B7-uxs8tkU\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"jAcOH-cC-Q\",\"type\":\"header\",\"data\":{\"text\":\"Reports & Masters\",\"col\":12}},{\"id\":\"7dj93PEUjW\",\"type\":\"card\",\"data\":{\"card_name\":\"Invoicing\",\"col\":4}},{\"id\":\"_Cb7C8XdJJ\",\"type\":\"card\",\"data\":{\"card_name\":\"Payments\",\"col\":4}},{\"id\":\"9yseIkdG50\",\"type\":\"card\",\"data\":{\"card_name\":\"Reports\",\"col\":4}}]",
+ "creation": "2024-01-05 15:29:11.144373",
+ "custom_blocks": [],
+ "docstatus": 0,
+ "doctype": "Workspace",
+ "for_user": "",
+ "hide_custom": 0,
+ "icon": "arrow-left",
+ "idx": 0,
+ "indicator_color": "",
+ "is_hidden": 0,
+ "label": "Payables",
+ "links": [
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Invoicing",
+ "link_count": 2,
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Card Break"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Purchase Invoice",
+ "link_count": 0,
+ "link_to": "Purchase Invoice",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Supplier",
+ "link_count": 0,
+ "link_to": "Supplier",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Payments",
+ "link_count": 3,
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Card Break"
+ },
+ {
+ "dependencies": "",
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Payment Entry",
+ "link_count": 0,
+ "link_to": "Payment Entry",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Journal Entry",
+ "link_count": 0,
+ "link_to": "Journal Entry",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Payment Reconciliation",
+ "link_count": 0,
+ "link_to": "Payment Reconciliation",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Reports",
+ "link_count": 7,
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Card Break"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Accounts Payable",
+ "link_count": 0,
+ "link_to": "Accounts Payable",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Accounts Payable Summary",
+ "link_count": 0,
+ "link_to": "Accounts Payable Summary",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Purchase Register",
+ "link_count": 0,
+ "link_to": "Purchase Register",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Item-wise Purchase Register",
+ "link_count": 0,
+ "link_to": "Item-wise Purchase Register",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Purchase Order Analysis",
+ "link_count": 0,
+ "link_to": "Purchase Order Analysis",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Received Items To Be Billed",
+ "link_count": 0,
+ "link_to": "Received Items To Be Billed",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Supplier Ledger Summary",
+ "link_count": 0,
+ "link_to": "Supplier Ledger Summary",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ }
+ ],
+ "modified": "2024-01-18 22:09:46.221549",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Payables",
+ "number_cards": [],
+ "owner": "Administrator",
+ "parent_page": "Accounting",
+ "public": 1,
+ "quick_lists": [],
+ "restrict_to_domain": "",
+ "roles": [],
+ "sequence_id": 3.0,
+ "shortcuts": [
+ {
+ "doc_view": "",
+ "label": "Accounts Payable",
+ "link_to": "Accounts Payable",
+ "type": "Report"
+ },
+ {
+ "doc_view": "",
+ "label": "Purchase Invoice",
+ "link_to": "Purchase Invoice",
+ "type": "DocType"
+ },
+ {
+ "doc_view": "",
+ "label": "Journal Entry",
+ "link_to": "Journal Entry",
+ "type": "DocType"
+ },
+ {
+ "doc_view": "",
+ "label": "Payment Entry",
+ "link_to": "Payment Entry",
+ "type": "DocType"
+ }
+ ],
+ "title": "Payables"
+}
\ No newline at end of file
diff --git a/erpnext/accounts/workspace/receivables/receivables.json b/erpnext/accounts/workspace/receivables/receivables.json
new file mode 100644
index 0000000000..6fa8c099a4
--- /dev/null
+++ b/erpnext/accounts/workspace/receivables/receivables.json
@@ -0,0 +1,254 @@
+{
+ "charts": [],
+ "content": "[{\"id\":\"vikWSkNm6_\",\"type\":\"header\",\"data\":{\"text\":\"Shortcuts\",\"col\":12}},{\"id\":\"G984SgVRJN\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Sales Invoice\",\"col\":3}},{\"id\":\"5yHldR0JNk\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"POS Invoice\",\"col\":3}},{\"id\":\"F9f4I1viNr\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Payment Entry\",\"col\":3}},{\"id\":\"1ArNvt9qhz\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Journal Entry\",\"col\":3}},{\"id\":\"4IBBOIxfqW\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Accounts Receivable\",\"col\":3}},{\"id\":\"ILlIxJuexy\",\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Cost Center\",\"col\":3}},{\"id\":\"B7-uxs8tkU\",\"type\":\"spacer\",\"data\":{\"col\":12}},{\"id\":\"tHb3yxthkR\",\"type\":\"header\",\"data\":{\"text\":\"Reports & Masters\",\"col\":12}},{\"id\":\"jLgv00c6ek\",\"type\":\"card\",\"data\":{\"card_name\":\"Invoicing\",\"col\":4}},{\"id\":\"npwfXlz0u1\",\"type\":\"card\",\"data\":{\"card_name\":\"Payments\",\"col\":4}},{\"id\":\"am70C27Jrb\",\"type\":\"card\",\"data\":{\"card_name\":\"Dunning\",\"col\":4}},{\"id\":\"xOHTyD8b5l\",\"type\":\"card\",\"data\":{\"card_name\":\"Reports\",\"col\":4}}]",
+ "creation": "2024-01-05 15:29:21.084241",
+ "custom_blocks": [],
+ "docstatus": 0,
+ "doctype": "Workspace",
+ "for_user": "",
+ "hide_custom": 0,
+ "icon": "arrow-right",
+ "idx": 0,
+ "indicator_color": "",
+ "is_hidden": 0,
+ "label": "Receivables",
+ "links": [
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Invoicing",
+ "link_count": 2,
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Card Break"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Sales Invoice",
+ "link_count": 0,
+ "link_to": "Sales Invoice",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Customer",
+ "link_count": 0,
+ "link_to": "Customer",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Payments",
+ "link_count": 4,
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Card Break"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Payment Entry",
+ "link_count": 0,
+ "link_to": "Payment Entry",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Payment Request",
+ "link_count": 0,
+ "link_to": "Payment Request",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Payment Reconciliation",
+ "link_count": 0,
+ "link_to": "Payment Reconciliation",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Payment Gateway Account",
+ "link_count": 0,
+ "link_to": "Payment Gateway Account",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Dunning",
+ "link_count": 2,
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Card Break"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Dunning",
+ "link_count": 0,
+ "link_to": "Dunning",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Dunning Type",
+ "link_count": 0,
+ "link_to": "Dunning Type",
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "hidden": 0,
+ "is_query_report": 0,
+ "label": "Reports",
+ "link_count": 6,
+ "link_type": "DocType",
+ "onboard": 0,
+ "type": "Card Break"
+ },
+ {
+ "dependencies": "Sales Invoice",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Accounts Receivable",
+ "link_count": 0,
+ "link_to": "Accounts Receivable",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "Sales Invoice",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Accounts Receivable Summary",
+ "link_count": 0,
+ "link_to": "Accounts Receivable Summary",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "Sales Invoice",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Sales Register",
+ "link_count": 0,
+ "link_to": "Sales Register",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "Sales Invoice",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Item-wise Sales Register",
+ "link_count": 0,
+ "link_to": "Item-wise Sales Register",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "Sales Invoice",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Sales Order Analysis",
+ "link_count": 0,
+ "link_to": "Sales Order Analysis",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ },
+ {
+ "dependencies": "Sales Invoice",
+ "hidden": 0,
+ "is_query_report": 1,
+ "label": "Delivered Items To Be Billed",
+ "link_count": 0,
+ "link_to": "Delivered Items To Be Billed",
+ "link_type": "Report",
+ "onboard": 0,
+ "type": "Link"
+ }
+ ],
+ "modified": "2024-01-18 22:11:51.474477",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Receivables",
+ "number_cards": [],
+ "owner": "Administrator",
+ "parent_page": "Accounting",
+ "public": 1,
+ "quick_lists": [],
+ "restrict_to_domain": "",
+ "roles": [],
+ "sequence_id": 4.0,
+ "shortcuts": [
+ {
+ "color": "Grey",
+ "doc_view": "List",
+ "label": "POS Invoice",
+ "link_to": "POS Invoice",
+ "stats_filter": "[]",
+ "type": "DocType"
+ },
+ {
+ "color": "Grey",
+ "doc_view": "List",
+ "label": "Cost Center",
+ "link_to": "Cost Center",
+ "type": "DocType"
+ },
+ {
+ "doc_view": "",
+ "label": "Sales Invoice",
+ "link_to": "Sales Invoice",
+ "stats_filter": "[]",
+ "type": "DocType"
+ },
+ {
+ "doc_view": "",
+ "label": "Journal Entry",
+ "link_to": "Journal Entry",
+ "type": "DocType"
+ },
+ {
+ "doc_view": "",
+ "label": "Payment Entry",
+ "link_to": "Payment Entry",
+ "type": "DocType"
+ },
+ {
+ "doc_view": "",
+ "label": "Accounts Receivable",
+ "link_to": "Accounts Receivable",
+ "type": "Report"
+ }
+ ],
+ "title": "Receivables"
+}
\ No newline at end of file
diff --git a/erpnext/assets/workspace/assets/assets.json b/erpnext/assets/workspace/assets/assets.json
index c6b321e9c1..26e8d8a2a4 100644
--- a/erpnext/assets/workspace/assets/assets.json
+++ b/erpnext/assets/workspace/assets/assets.json
@@ -196,18 +196,18 @@
"type": "Link"
}
],
- "modified": "2023-05-24 14:47:20.243146",
+ "modified": "2024-01-05 17:40:34.570041",
"modified_by": "Administrator",
"module": "Assets",
"name": "Assets",
"number_cards": [],
"owner": "Administrator",
- "parent_page": "Accounting",
+ "parent_page": "",
"public": 1,
"quick_lists": [],
"restrict_to_domain": "",
"roles": [],
- "sequence_id": 4.0,
+ "sequence_id": 7.0,
"shortcuts": [
{
"label": "Asset",
diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py
index 19d8b9a1b2..c8f3872622 100644
--- a/erpnext/manufacturing/doctype/work_order/test_work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py
@@ -997,12 +997,6 @@ class TestWorkOrder(FrappeTestCase):
make_job_card(wo_order.name, operations)
job_card = frappe.db.get_value("Job Card", {"work_order": wo_order.name, "docstatus": 0}, "name")
- update_job_card(job_card, 10, 2)
-
- stock_entry = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 10))
- for row in stock_entry.items:
- if row.is_scrap_item:
- self.assertEqual(row.qty, 2)
def test_close_work_order(self):
items = [
diff --git a/erpnext/public/js/utils/barcode_scanner.js b/erpnext/public/js/utils/barcode_scanner.js
index cf7fab89ff..aacab0fe6c 100644
--- a/erpnext/public/js/utils/barcode_scanner.js
+++ b/erpnext/public/js/utils/barcode_scanner.js
@@ -105,32 +105,47 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
this.frm.has_items = false;
}
- if (serial_no && this.is_duplicate_serial_no(row, item_code, serial_no)) {
- this.clean_up();
- reject();
- return;
+ if (serial_no) {
+ this.is_duplicate_serial_no(row, item_code, serial_no)
+ .then((is_duplicate) => {
+ if (!is_duplicate) {
+ this.run_serially_tasks(row, data, resolve);
+ } else {
+ this.clean_up();
+ reject();
+ return;
+ }
+ });
+ } else {
+ this.run_serially_tasks(row, data, resolve);
}
- frappe.run_serially([
- () => this.set_serial_and_batch(row, item_code, serial_no, batch_no),
- () => this.set_barcode(row, barcode),
- () => this.set_item(row, item_code, barcode, batch_no, serial_no).then(qty => {
- this.show_scan_message(row.idx, row.item_code, qty);
- }),
- () => this.set_barcode_uom(row, uom),
- () => this.clean_up(),
- () => resolve(row),
- () => {
- if (row.serial_and_batch_bundle && !this.frm.is_new()) {
- this.frm.save();
- }
- frappe.flags.trigger_from_barcode_scanner = false;
- }
- ]);
});
}
+ run_serially_tasks(row, data, resolve) {
+ const {item_code, barcode, batch_no, serial_no, uom} = data;
+
+ frappe.run_serially([
+ () => this.set_serial_and_batch(row, item_code, serial_no, batch_no),
+ () => this.set_barcode(row, barcode),
+ () => this.set_item(row, item_code, barcode, batch_no, serial_no).then(qty => {
+ this.show_scan_message(row.idx, row.item_code, qty);
+ }),
+ () => this.set_barcode_uom(row, uom),
+ () => this.clean_up(),
+ () => {
+ if (row.serial_and_batch_bundle && !this.frm.is_new()) {
+ this.frm.save();
+ }
+
+ frappe.flags.trigger_from_barcode_scanner = false;
+ },
+ () => resolve(row),
+ ]);
+ }
+
set_item(row, item_code, barcode, batch_no, serial_no) {
return new Promise(resolve => {
const increment = async (value = 1) => {
@@ -475,26 +490,32 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
}
}
- is_duplicate_serial_no(row, item_code, serial_no) {
- if (this.frm.is_new() || !row.serial_and_batch_bundle) {
- let is_duplicate = this.check_duplicate_serial_no_in_localstorage(item_code, serial_no);
- if (is_duplicate) {
- this.show_alert(__("Serial No {0} is already added", [serial_no]), "orange");
- }
-
- return is_duplicate;
- } else if (row.serial_and_batch_bundle) {
- this.check_duplicate_serial_no_in_db(row, serial_no, (r) => {
- if (r.message) {
+ async is_duplicate_serial_no(row, item_code, serial_no) {
+ let is_duplicate = false;
+ const promise = new Promise((resolve, reject) => {
+ if (this.frm.is_new() || !row.serial_and_batch_bundle) {
+ is_duplicate = this.check_duplicate_serial_no_in_localstorage(item_code, serial_no);
+ if (is_duplicate) {
this.show_alert(__("Serial No {0} is already added", [serial_no]), "orange");
}
- return r.message;
- })
- }
+ resolve(is_duplicate);
+ } else if (row.serial_and_batch_bundle) {
+ this.check_duplicate_serial_no_in_db(row, serial_no, (r) => {
+ if (r.message) {
+ this.show_alert(__("Serial No {0} is already added", [serial_no]), "orange");
+ }
+
+ is_duplicate = r.message;
+ resolve(is_duplicate);
+ })
+ }
+ });
+
+ return await promise;
}
- async check_duplicate_serial_no_in_db(row, serial_no, response) {
+ check_duplicate_serial_no_in_db(row, serial_no, response) {
frappe.call({
method: "erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.is_duplicate_serial_no",
args: {
@@ -504,7 +525,7 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
callback(r) {
response(r);
}
- })
+ });
}
check_duplicate_serial_no_in_localstorage(item_code, serial_no) {
diff --git a/erpnext/public/js/utils/sales_common.js b/erpnext/public/js/utils/sales_common.js
index b92b02e826..b8ec77f8e5 100644
--- a/erpnext/public/js/utils/sales_common.js
+++ b/erpnext/public/js/utils/sales_common.js
@@ -22,6 +22,15 @@ erpnext.sales_common = {
}
};
});
+
+ this.frm.set_query('project', function(doc) {
+ return {
+ query: "erpnext.controllers.queries.get_project_name",
+ filters: {
+ 'customer': doc.customer
+ }
+ }
+ });
}
setup_queries() {
@@ -439,4 +448,4 @@ erpnext.pre_sales = {
}
});
}
-}
\ No newline at end of file
+}
diff --git a/erpnext/public/js/utils/serial_no_batch_selector.js b/erpnext/public/js/utils/serial_no_batch_selector.js
index bf362e338e..44a4957b41 100644
--- a/erpnext/public/js/utils/serial_no_batch_selector.js
+++ b/erpnext/public/js/utils/serial_no_batch_selector.js
@@ -135,7 +135,7 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
filters: this.get_serial_no_filters()
};
},
- onchange: () => this.update_serial_batch_no()
+ onchange: () => this.scan_barcode_data()
});
}
@@ -145,7 +145,7 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
options: 'Barcode',
fieldname: 'scan_batch_no',
label: __('Scan Batch No'),
- onchange: () => this.update_serial_batch_no()
+ onchange: () => this.scan_barcode_data()
});
}
@@ -179,11 +179,54 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
label = __('Serial Nos / Batch Nos');
}
- return [
+ let fields = [
{
fieldtype: 'Section Break',
label: __('{0} {1} via CSV File', [primary_label, label])
- },
+ }
+ ]
+
+ if (this.item?.has_serial_no) {
+ fields = [...fields,
+ {
+ fieldtype: 'Check',
+ label: __('Import Using CSV file'),
+ fieldname: 'import_using_csv_file',
+ default: 0,
+ },
+ {
+ fieldtype: 'Section Break',
+ label: __('{0} {1} Manually', [primary_label, label]),
+ depends_on: 'eval:doc.import_using_csv_file === 0',
+ },
+ {
+ fieldtype: 'Small Text',
+ label: __('Enter Serial Nos'),
+ fieldname: 'upload_serial_nos',
+ depends_on: 'eval:doc.import_using_csv_file === 0',
+ description: __('Enter each serial no in a new line'),
+ },
+ {
+ fieldtype: 'Column Break',
+ depends_on: 'eval:doc.import_using_csv_file === 0',
+ },
+ {
+ fieldtype: 'Button',
+ fieldname: 'make_serial_nos',
+ label: __('Create Serial Nos'),
+ depends_on: 'eval:doc.import_using_csv_file === 0',
+ click: () => {
+ this.create_serial_nos();
+ }
+ },
+ {
+ fieldtype: 'Section Break',
+ depends_on: 'eval:doc.import_using_csv_file === 1',
+ }
+ ];
+ }
+
+ fields = [...fields,
{
fieldtype: 'Button',
fieldname: 'download_csv',
@@ -199,7 +242,32 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
label: __('Attach CSV File'),
onchange: () => this.upload_csv_file()
}
- ]
+ ];
+
+ return fields;
+ }
+
+ create_serial_nos() {
+ let {upload_serial_nos} = this.dialog.get_values();
+
+ if (!upload_serial_nos) {
+ frappe.throw(__('Please enter Serial Nos'));
+ }
+
+ frappe.call({
+ method: 'erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.create_serial_nos',
+ args: {
+ item_code: this.item.item_code,
+ serial_nos: upload_serial_nos
+ },
+ callback: (r) => {
+ if (r.message) {
+ this.dialog.fields_dict.entries.df.data = [];
+ this.set_data(r.message);
+ this.update_bundle_entries();
+ }
+ }
+ });
}
download_csv_file() {
@@ -374,6 +442,26 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
}
}
+ scan_barcode_data() {
+ const { scan_serial_no, scan_batch_no } = this.dialog.get_values();
+
+ if (scan_serial_no || scan_batch_no) {
+ frappe.call({
+ method: 'erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.is_serial_batch_no_exists',
+ args: {
+ item_code: this.item.item_code,
+ type_of_transaction: this.item.type_of_transaction,
+ serial_no: scan_serial_no,
+ batch_no: scan_batch_no,
+ },
+ callback: (r) => {
+ this.update_serial_batch_no();
+ }
+
+ })
+ }
+ }
+
update_serial_batch_no() {
const { scan_serial_no, scan_batch_no } = this.dialog.get_values();
diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py
index ab74f7f738..654f2978fe 100644
--- a/erpnext/selling/doctype/quotation/quotation.py
+++ b/erpnext/selling/doctype/quotation/quotation.py
@@ -127,7 +127,8 @@ class Quotation(SellingController):
def validate(self):
super(Quotation, self).validate()
self.set_status()
- self.validate_uom_is_integer("stock_uom", "qty")
+ self.validate_uom_is_integer("stock_uom", "stock_qty")
+ self.validate_uom_is_integer("uom", "qty")
self.validate_valid_till()
self.set_customer_name()
if self.items:
diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py
index 590cd3d0cf..41463eb2e5 100644
--- a/erpnext/selling/doctype/quotation/test_quotation.py
+++ b/erpnext/selling/doctype/quotation/test_quotation.py
@@ -581,6 +581,22 @@ class TestQuotation(FrappeTestCase):
quotation.reload()
self.assertEqual(quotation.status, "Ordered")
+ def test_uom_validation(self):
+ from erpnext.stock.doctype.item.test_item import make_item
+
+ item = "_Test Item FOR UOM Validation"
+ make_item(item, {"is_stock_item": 1})
+
+ if not frappe.db.exists("UOM", "lbs"):
+ frappe.get_doc({"doctype": "UOM", "uom_name": "lbs", "must_be_whole_number": 1}).insert()
+ else:
+ frappe.db.set_value("UOM", "lbs", "must_be_whole_number", 1)
+
+ quotation = make_quotation(item_code=item, qty=1, rate=100, do_not_submit=1)
+ quotation.items[0].uom = "lbs"
+ quotation.items[0].conversion_factor = 2.23
+ self.assertRaises(frappe.ValidationError, quotation.save)
+
test_records = frappe.get_test_records("Quotation")
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 56c745c00a..2bb093dbaf 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -144,15 +144,6 @@ frappe.ui.form.on("Sales Order", {
};
});
- frm.set_query('project', function(doc, cdt, cdn) {
- return {
- query: "erpnext.controllers.queries.get_project_name",
- filters: {
- 'customer': doc.customer
- }
- }
- });
-
frm.set_query('warehouse', 'items', function(doc, cdt, cdn) {
let row = locals[cdt][cdn];
let query = {
diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js
index 15944a56f0..3359835358 100644
--- a/erpnext/setup/doctype/company/company.js
+++ b/erpnext/setup/doctype/company/company.js
@@ -140,38 +140,48 @@ frappe.ui.form.on("Company", {
},
delete_company_transactions: function(frm) {
- frappe.verify_password(function() {
- var d = frappe.prompt({
- fieldtype:"Data",
- fieldname: "company_name",
- label: __("Please enter the company name to confirm"),
- reqd: 1,
- description: __("Please make sure you really want to delete all the transactions for this company. Your master data will remain as it is. This action cannot be undone.")
+ frappe.call({
+ method: "erpnext.setup.doctype.company.company.is_deletion_job_running",
+ args: {
+ company: frm.doc.name
},
- function(data) {
- if(data.company_name !== frm.doc.name) {
- frappe.msgprint(__("Company name not same"));
- return;
+ freeze: true,
+ callback: function(r) {
+ if(!r.exc) {
+ frappe.verify_password(function() {
+ var d = frappe.prompt({
+ fieldtype:"Data",
+ fieldname: "company_name",
+ label: __("Please enter the company name to confirm"),
+ reqd: 1,
+ description: __("Please make sure you really want to delete all the transactions for this company. Your master data will remain as it is. This action cannot be undone.")
+ },
+ function(data) {
+ if(data.company_name !== frm.doc.name) {
+ frappe.msgprint(__("Company name not same"));
+ return;
+ }
+ frappe.call({
+ method: "erpnext.setup.doctype.company.company.create_transaction_deletion_request",
+ args: {
+ company: data.company_name
+ },
+ freeze: true,
+ callback: function(r, rt) { },
+ onerror: function() {
+ frappe.msgprint(__("Wrong Password"));
+ }
+ });
+ },
+ __("Delete all the Transactions for this Company"), __("Delete")
+ );
+ d.get_primary_btn().addClass("btn-danger");
+ });
}
- frappe.call({
- method: "erpnext.setup.doctype.company.company.create_transaction_deletion_request",
- args: {
- company: data.company_name
- },
- freeze: true,
- callback: function(r, rt) {
- if(!r.exc)
- frappe.msgprint(__("Successfully deleted all transactions related to this company!"));
- },
- onerror: function() {
- frappe.msgprint(__("Wrong Password"));
- }
- });
+
},
- __("Delete all the Transactions for this Company"), __("Delete")
- );
- d.get_primary_btn().addClass("btn-danger");
});
+
}
});
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 6b6dba4f1d..27d7df33a3 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -11,7 +11,8 @@ from frappe.cache_manager import clear_defaults_cache
from frappe.contacts.address_and_contact import load_address_and_contact
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
from frappe.desk.page.setup_wizard.setup_wizard import make_records
-from frappe.utils import cint, formatdate, get_timestamp, today
+from frappe.utils import cint, formatdate, get_link_to_form, get_timestamp, today
+from frappe.utils.background_jobs import get_job, is_job_enqueued
from frappe.utils.nestedset import NestedSet, rebuild_tree
from erpnext.accounts.doctype.account.account import get_account_currency
@@ -903,8 +904,37 @@ def get_default_company_address(name, sort_key="is_primary_address", existing_ad
return None
+def generate_id_for_deletion_job(company):
+ return "delete_company_transactions_" + company
+
+
+@frappe.whitelist()
+def is_deletion_job_running(company):
+ job_id = generate_id_for_deletion_job(company)
+ job_name = get_job(job_id).get_id() # job name will have site prefix
+ if is_job_enqueued(job_id):
+ frappe.throw(
+ _("A Transaction Deletion Job: {0} is already running for {1}").format(
+ frappe.bold(get_link_to_form("RQ Job", job_name)), frappe.bold(company)
+ )
+ )
+
+
@frappe.whitelist()
def create_transaction_deletion_request(company):
+ is_deletion_job_running(company)
+ job_id = generate_id_for_deletion_job(company)
+
tdr = frappe.get_doc({"doctype": "Transaction Deletion Record", "company": company})
tdr.insert()
- tdr.submit()
+
+ frappe.enqueue(
+ "frappe.utils.background_jobs.run_doc_method",
+ doctype=tdr.doctype,
+ name=tdr.name,
+ doc_method="submit",
+ job_id=job_id,
+ queue="long",
+ enqueue_after_commit=True,
+ )
+ frappe.msgprint(_("A Transaction Deletion Job is triggered for {0}").format(frappe.bold(company)))
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js
index ec68549846..14aedca39e 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.js
@@ -31,15 +31,6 @@ frappe.ui.form.on("Delivery Note", {
});
erpnext.queries.setup_warehouse_query(frm);
- frm.set_query('project', function(doc) {
- return {
- query: "erpnext.controllers.queries.get_project_name",
- filters: {
- 'customer': doc.customer
- }
- }
- })
-
frm.set_query('transporter', function() {
return {
filters: {
diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.js b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.js
index 9f01ee9ae6..91b743016b 100644
--- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.js
+++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.js
@@ -74,7 +74,7 @@ frappe.ui.form.on('Serial and Batch Bundle', {
let fields = [
{
- "label": __("Using CSV File"),
+ "label": __("Import Using CSV file"),
"fieldname": "using_csv_file",
"default": 1,
"fieldtype": "Check",
diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py
index 2b87fcd175..63cc938c09 100644
--- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py
+++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py
@@ -999,9 +999,25 @@ def get_serial_batch_from_data(item_code, kwargs):
make_serial_nos(item_code, serial_nos)
+ if kwargs.get("_has_serial_nos"):
+ return serial_nos
+
return serial_nos, batch_nos
+@frappe.whitelist()
+def create_serial_nos(item_code, serial_nos):
+ serial_nos = get_serial_batch_from_data(
+ item_code,
+ {
+ "serial_nos": serial_nos,
+ "_has_serial_nos": True,
+ },
+ )
+
+ return serial_nos
+
+
def make_serial_nos(item_code, serial_nos):
item = frappe.get_cached_value("Item", item_code, ["description", "item_code"], as_dict=1)
@@ -2079,6 +2095,35 @@ def get_batch_no_from_serial_no(serial_no):
return frappe.get_cached_value("Serial No", serial_no, "batch_no")
+@frappe.whitelist()
+def is_serial_batch_no_exists(item_code, type_of_transaction, serial_no=None, batch_no=None):
+ if serial_no and not frappe.db.exists("Serial No", serial_no):
+ if type_of_transaction != "Inward":
+ frappe.throw(_("Serial No {0} does not exists").format(serial_no))
+
+ make_serial_no(serial_no, item_code)
+
+ if batch_no and frappe.db.exists("Batch", batch_no):
+ if type_of_transaction != "Inward":
+ frappe.throw(_("Batch No {0} does not exists").format(batch_no))
+
+ make_batch_no(batch_no, item_code)
+
+
+def make_serial_no(serial_no, item_code):
+ serial_no_doc = frappe.new_doc("Serial No")
+ serial_no_doc.serial_no = serial_no
+ serial_no_doc.item_code = item_code
+ serial_no_doc.save(ignore_permissions=True)
+
+
+def make_batch_no(batch_no, item_code):
+ batch_doc = frappe.new_doc("Batch")
+ batch_doc.batch_id = batch_no
+ batch_doc.item = item_code
+ batch_doc.save(ignore_permissions=True)
+
+
@frappe.whitelist()
def is_duplicate_serial_no(bundle_id, serial_no):
return frappe.db.exists("Serial and Batch Entry", {"parent": bundle_id, "serial_no": serial_no})
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index b19a34a354..a221e006af 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -439,7 +439,7 @@ def get_distinct_item_warehouse(args=None, doc=None, reposting_data=None):
reposting_data = get_reposting_data(doc.reposting_data_file)
if reposting_data and reposting_data.distinct_item_and_warehouse:
- return reposting_data.distinct_item_and_warehouse
+ return parse_distinct_items_and_warehouses(reposting_data.distinct_item_and_warehouse)
distinct_item_warehouses = {}
@@ -457,6 +457,16 @@ def get_distinct_item_warehouse(args=None, doc=None, reposting_data=None):
return distinct_item_warehouses
+def parse_distinct_items_and_warehouses(distinct_items_and_warehouses):
+ new_dict = frappe._dict({})
+
+ # convert string keys to tuple
+ for k, v in distinct_items_and_warehouses.items():
+ new_dict[frappe.safe_eval(k)] = frappe._dict(v)
+
+ return new_dict
+
+
def get_affected_transactions(doc, reposting_data=None) -> Set[Tuple[str, str]]:
if not reposting_data and doc and doc.reposting_data_file:
reposting_data = get_reposting_data(doc.reposting_data_file)
|