diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.js b/erpnext/accounts/doctype/accounts_settings/accounts_settings.js
index 5b9a52e8f8b..74c623c8acb 100644
--- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.js
+++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.js
@@ -3,4 +3,44 @@
frappe.ui.form.on("Accounts Settings", {
refresh: function (frm) {},
+<<<<<<< HEAD
+=======
+ enable_immutable_ledger: function (frm) {
+ if (!frm.doc.enable_immutable_ledger) {
+ return;
+ }
+
+ let msg = __("Enabling this will change the way how cancelled transactions are handled.");
+ msg += " ";
+ msg += __("Please enable only if the understand the effects of enabling this.");
+ msg += "
";
+ msg += __("Do you still want to enable immutable ledger?");
+
+ frappe.confirm(
+ msg,
+ () => {},
+ () => {
+ frm.set_value("enable_immutable_ledger", 0);
+ }
+ );
+ },
+
+ add_taxes_from_taxes_and_charges_template(frm) {
+ toggle_tax_settings(frm, "add_taxes_from_taxes_and_charges_template");
+ },
+
+ add_taxes_from_item_tax_template(frm) {
+ toggle_tax_settings(frm, "add_taxes_from_item_tax_template");
+ },
+
+ drop_ar_procedures: function (frm) {
+ frm.call({
+ doc: frm.doc,
+ method: "drop_ar_sql_procedures",
+ callback: function (r) {
+ frappe.show_alert(__("Procedures dropped"), 5);
+ },
+ });
+ },
+>>>>>>> da32bb5f51 (refactor: utility to drop existing procedures and include cost center)
});
diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
index 5c20f47749f..a2b75df6b5e 100644
--- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
+++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
@@ -77,6 +77,8 @@
"receivable_payable_remarks_length",
"accounts_receivable_payable_tuning_section",
"receivable_payable_fetch_method",
+ "column_break_ntmi",
+ "drop_ar_procedures",
"legacy_section",
"ignore_is_opening_check_for_reporting"
],
@@ -499,6 +501,84 @@
"fieldname": "legacy_section",
"fieldtype": "Section Break",
"label": "Legacy Fields"
+<<<<<<< HEAD
+=======
+ },
+ {
+ "default": "0",
+ "fieldname": "maintain_same_internal_transaction_rate",
+ "fieldtype": "Check",
+ "label": "Maintain Same Rate Throughout Internal Transaction"
+ },
+ {
+ "default": "Stop",
+ "depends_on": "maintain_same_internal_transaction_rate",
+ "fieldname": "maintain_same_rate_action",
+ "fieldtype": "Select",
+ "label": "Action if Same Rate is Not Maintained Throughout Internal Transaction",
+ "mandatory_depends_on": "maintain_same_internal_transaction_rate",
+ "options": "Stop\nWarn"
+ },
+ {
+ "depends_on": "eval: doc.maintain_same_internal_transaction_rate && doc.maintain_same_rate_action == 'Stop'",
+ "fieldname": "role_to_override_stop_action",
+ "fieldtype": "Link",
+ "label": "Role Allowed to Override Stop Action",
+ "options": "Role"
+ },
+ {
+ "fieldname": "budget_settings",
+ "fieldtype": "Tab Break",
+ "label": "Budget"
+ },
+ {
+ "default": "1",
+ "fieldname": "use_new_budget_controller",
+ "fieldtype": "Check",
+ "label": "Use New Budget Controller"
+ },
+ {
+ "default": "1",
+ "description": "If enabled, user will be alerted before resetting posting date to current date in relevant transactions",
+ "fieldname": "confirm_before_resetting_posting_date",
+ "fieldtype": "Check",
+ "label": "Confirm before resetting posting date"
+ },
+ {
+ "fieldname": "item_price_settings_section",
+ "fieldtype": "Section Break",
+ "label": "Item Price Settings"
+ },
+ {
+ "fieldname": "column_break_feyo",
+ "fieldtype": "Column Break"
+ },
+ {
+ "default": "0",
+ "description": "System will do an implicit conversion using the pegged currency.
\nEx: Instead of AED -> INR, system will do AED -> USD -> INR using the pegged exchange rate of AED against USD.",
+ "documentation_url": "/app/pegged-currencies/Pegged Currencies",
+ "fieldname": "allow_pegged_currencies_exchange_rates",
+ "fieldtype": "Check",
+ "label": "Allow Implicit Pegged Currency Conversion"
+ },
+ {
+ "default": "0",
+ "description": "If no taxes are set, and Taxes and Charges Template is selected, the system will automatically apply the taxes from the chosen template.",
+ "fieldname": "add_taxes_from_taxes_and_charges_template",
+ "fieldtype": "Check",
+ "label": "Automatically Add Taxes from Taxes and Charges Template"
+ },
+ {
+ "fieldname": "column_break_ntmi",
+ "fieldtype": "Column Break"
+ },
+ {
+ "depends_on": "eval:doc.receivable_payable_fetch_method == \"Raw SQL\"",
+ "description": "Drops existing SQL Procedures and Function setup by Accounts Receivable report",
+ "fieldname": "drop_ar_procedures",
+ "fieldtype": "Button",
+ "label": "Drop Procedures"
+>>>>>>> da32bb5f51 (refactor: utility to drop existing procedures and include cost center)
}
],
"icon": "icon-cog",
diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py
index 1244e19c96d..abfa0abc92f 100644
--- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py
+++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py
@@ -129,3 +129,38 @@ class AccountsSettings(Document):
def validate_pending_reposts(self):
if self.acc_frozen_upto:
check_pending_reposting(self.acc_frozen_upto)
+<<<<<<< HEAD
+=======
+
+ def validate_and_sync_auto_reconcile_config(self):
+ if self.has_value_changed("auto_reconciliation_job_trigger"):
+ if (
+ cint(self.auto_reconciliation_job_trigger) > 0
+ and cint(self.auto_reconciliation_job_trigger) < 60
+ ):
+ sync_auto_reconcile_config(self.auto_reconciliation_job_trigger)
+ else:
+ frappe.throw(_("Cron Interval should be between 1 and 59 Min"))
+
+ if self.has_value_changed("reconciliation_queue_size"):
+ if cint(self.reconciliation_queue_size) < 5 or cint(self.reconciliation_queue_size) > 100:
+ frappe.throw(_("Queue Size should be between 5 and 100"))
+
+ def validate_auto_tax_settings(self):
+ if self.add_taxes_from_item_tax_template and self.add_taxes_from_taxes_and_charges_template:
+ frappe.throw(
+ _("You cannot enable both the settings '{0}' and '{1}'.").format(
+ frappe.bold(_(self.meta.get_label("add_taxes_from_item_tax_template"))),
+ frappe.bold(_(self.meta.get_label("add_taxes_from_taxes_and_charges_template"))),
+ ),
+ title=_("Auto Tax Settings Error"),
+ )
+
+ @frappe.whitelist()
+ def drop_ar_sql_procedures(self):
+ from erpnext.accounts.report.accounts_receivable.accounts_receivable import InitSQLProceduresForAR
+
+ frappe.db.sql(f"drop function if exists {InitSQLProceduresForAR.genkey_function_name}")
+ frappe.db.sql(f"drop procedure if exists {InitSQLProceduresForAR.init_procedure_name}")
+ frappe.db.sql(f"drop procedure if exists {InitSQLProceduresForAR.allocate_procedure_name}")
+>>>>>>> da32bb5f51 (refactor: utility to drop existing procedures and include cost center)
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index 99608e58d25..b8f88f4a4d8 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -351,6 +351,7 @@ class ReceivablePayableReport:
party_account `account`,
posting_date,
account_currency,
+ cost_center,
sum(invoiced) `invoiced`,
sum(paid) `paid`,
sum(credit_note) `credit_note`,
@@ -378,6 +379,7 @@ class ReceivablePayableReport:
"paid_in_account_currency",
"credit_note_in_account_currency",
"outstanding_in_account_currency",
+ "cost_center",
]:
_d[field] = x.get(field)
@@ -1333,14 +1335,13 @@ class InitSQLProceduresForAR:
party_account varchar(140),
posting_date date,
account_currency varchar(140),
+ cost_center varchar(140),
invoiced decimal(21,9),
paid decimal(21,9),
credit_note decimal(21,9),
- outstanding decimal(21,9),
invoiced_in_account_currency decimal(21,9),
paid_in_account_currency decimal(21,9),
- credit_note_in_account_currency decimal(21,9),
- outstanding_in_account_currency decimal(21,9)) engine=memory;
+ credit_note_in_account_currency decimal(21,9)) engine=memory;
"""
_row_def_table_name = "_ple_row"
_row_def_table_definition = f"""
@@ -1381,7 +1382,7 @@ class InitSQLProceduresForAR:
begin
if not exists (select name from `{_voucher_balance_name}` where name = genkey(ple, false))
then
- insert into `{_voucher_balance_name}` values (genkey(ple, false), ple.voucher_type, ple.voucher_no, ple.party, ple.account, ple.posting_date, ple.account_currency, 0, 0, 0, 0, 0, 0, 0, 0);
+ insert into `{_voucher_balance_name}` values (genkey(ple, false), ple.voucher_type, ple.voucher_no, ple.party, ple.account, ple.posting_date, ple.account_currency, ple.cost_center, 0, 0, 0, 0, 0, 0);
end if;
end;
"""
@@ -1423,17 +1424,21 @@ class InitSQLProceduresForAR:
end if;
- insert into `{_voucher_balance_name}` values (`{genkey_function_name}`(ple, true), ple.against_voucher_type, ple.against_voucher_no, ple.party, ple.account, ple.posting_date, ple.account_currency, invoiced, paid, 0, 0, invoiced_in_account_currency, paid_in_account_currency, 0, 0);
+ insert into `{_voucher_balance_name}` values (`{genkey_function_name}`(ple, true), ple.against_voucher_type, ple.against_voucher_no, ple.party, ple.account, ple.posting_date, ple.account_currency,'', invoiced, paid, 0, invoiced_in_account_currency, paid_in_account_currency, 0);
end;
"""
- def __init__(self):
- existing_procedures = frappe.db.sql(
+ def get_existing_procedures(self):
+ procedures = frappe.db.sql(
f"select routine_name from information_schema.routines where routine_type in ('FUNCTION','PROCEDURE') and routine_schema='{frappe.conf.db_name}';"
)
- if existing_procedures:
+ if procedures:
# normalize
- existing_procedures = [x[0] for x in existing_procedures]
+ procedures = [x[0] for x in procedures]
+ return procedures
+
+ def __init__(self):
+ existing_procedures = self.get_existing_procedures()
if self.genkey_function_name not in existing_procedures:
frappe.db.sql(self.genkey_function_sql)