Merge pull request #40040 from GursheenK/skip-discount-validation-for-rate-adjustment-entries
fix: skip max discount validation for rate adjustment
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 622b724..3a930e0 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -1478,9 +1478,7 @@
"credit_in_account_currency": payment_mode.base_amount
if self.party_account_currency == self.company_currency
else payment_mode.amount,
- "against_voucher": self.return_against
- if cint(self.is_return) and self.return_against
- else self.name,
+ "against_voucher": self.name,
"against_voucher_type": self.doctype,
"cost_center": self.cost_center,
},
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 8c3aede..c6a8362 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -1105,6 +1105,44 @@
self.assertEqual(pos.grand_total, 100.0)
self.assertEqual(pos.write_off_amount, 10)
+ def test_ledger_entries_of_return_pos_invoice(self):
+ make_pos_profile()
+
+ pos = create_sales_invoice(do_not_save=True)
+ pos.is_pos = 1
+ pos.append("payments", {"mode_of_payment": "Cash", "account": "Cash - _TC", "amount": 100})
+ pos.save().submit()
+ self.assertEqual(pos.outstanding_amount, 0.0)
+ self.assertEqual(pos.status, "Paid")
+
+ from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_sales_return
+
+ pos_return = make_sales_return(pos.name)
+ pos_return.save().submit()
+ pos_return.reload()
+ pos.reload()
+ self.assertEqual(pos_return.is_return, 1)
+ self.assertEqual(pos_return.return_against, pos.name)
+ self.assertEqual(pos_return.outstanding_amount, 0.0)
+ self.assertEqual(pos_return.status, "Return")
+ self.assertEqual(pos.outstanding_amount, 0.0)
+ self.assertEqual(pos.status, "Credit Note Issued")
+
+ expected = (
+ ("Cash - _TC", 0.0, 100.0, pos_return.name, None),
+ ("Debtors - _TC", 0.0, 100.0, pos_return.name, pos_return.name),
+ ("Debtors - _TC", 100.0, 0.0, pos_return.name, pos_return.name),
+ ("Sales - _TC", 100.0, 0.0, pos_return.name, None),
+ )
+ res = frappe.db.get_all(
+ "GL Entry",
+ filters={"voucher_no": pos_return.name, "is_cancelled": 0},
+ fields=["account", "debit", "credit", "voucher_no", "against_voucher"],
+ order_by="account, debit, credit",
+ as_list=1,
+ )
+ self.assertEqual(expected, res)
+
def test_pos_with_no_gl_entry_for_change_amount(self):
frappe.db.set_single_value("Accounts Settings", "post_change_gl_entries", 0)
diff --git a/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py b/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py
index 3f178f4..eaeaa62 100644
--- a/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py
+++ b/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.py
@@ -163,7 +163,7 @@
"""select
voucher_type, voucher_no, party_type, party, posting_date, debit, credit, remarks, against_voucher
from `tabGL Entry`
- where company=%(company)s and voucher_type in ('Journal Entry', 'Payment Entry') {0}
+ where company=%(company)s and voucher_type in ('Journal Entry', 'Payment Entry') and is_cancelled = 0 {0}
""".format(
get_conditions(filters)
),
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 063c1e3..32a5a61 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -216,7 +216,8 @@
)
)
- if self.get("is_return") and self.get("return_against"):
+ if self.get("is_return") and self.get("return_against") and not self.get("is_pos"):
+ # if self.get("is_return") and self.get("return_against"):
document_type = "Credit Note" if self.doctype == "Sales Invoice" else "Debit Note"
frappe.msgprint(
_(
@@ -345,6 +346,12 @@
ple = frappe.qb.DocType("Payment Ledger Entry")
frappe.qb.from_(ple).delete().where(
(ple.voucher_type == self.doctype) & (ple.voucher_no == self.name)
+ | (
+ (ple.against_voucher_type == self.doctype)
+ & (ple.against_voucher_no == self.name)
+ & ple.delinked
+ == 1
+ )
).run()
frappe.db.sql(
"delete from `tabGL Entry` where voucher_type=%s and voucher_no=%s", (self.doctype, self.name)
diff --git a/erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py b/erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py
index dea3f2d..4f7436f 100644
--- a/erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py
+++ b/erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py
@@ -41,7 +41,9 @@
month_list = self.get_month_list()
for month in month_list:
- self.columns.append({"fieldname": month, "fieldtype": based_on, "label": month, "width": 200})
+ self.columns.append(
+ {"fieldname": month, "fieldtype": based_on, "label": _(month), "width": 200}
+ )
elif self.filters.get("range") == "Quarterly":
for quarter in range(1, 5):
@@ -156,7 +158,7 @@
for column in self.columns:
if column["fieldname"] != "opportunity_owner" and column["fieldname"] != "sales_stage":
- labels.append(column["fieldname"])
+ labels.append(_(column["fieldname"]))
self.chart = {"data": {"labels": labels, "datasets": datasets}, "type": "line"}
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 05198e2..5d24af5 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -942,25 +942,35 @@
due_date() {
// due_date is to be changed, payment terms template and/or payment schedule must
// be removed as due_date is automatically changed based on payment terms
- if (this.frm.doc.due_date && !this.frm.updating_party_details && !this.frm.doc.is_pos) {
- if (this.frm.doc.payment_terms_template ||
- (this.frm.doc.payment_schedule && this.frm.doc.payment_schedule.length)) {
- var message1 = "";
- var message2 = "";
- var final_message = __("Please clear the") + " ";
-
- if (this.frm.doc.payment_terms_template) {
- message1 = __("selected Payment Terms Template");
- final_message = final_message + message1;
- }
-
- if ((this.frm.doc.payment_schedule || []).length) {
- message2 = __("Payment Schedule Table");
- if (message1.length !== 0) message2 = " and " + message2;
- final_message = final_message + message2;
- }
- frappe.msgprint(final_message);
+ if (
+ this.frm.doc.due_date &&
+ !this.frm.updating_party_details &&
+ !this.frm.doc.is_pos &&
+ (
+ this.frm.doc.payment_terms_template ||
+ this.frm.doc.payment_schedule?.length
+ )
+ ) {
+ const to_clear = [];
+ if (this.frm.doc.payment_terms_template) {
+ to_clear.push("Payment Terms Template");
}
+
+ if (this.frm.doc.payment_schedule?.length) {
+ to_clear.push("Payment Schedule Table");
+ }
+
+ frappe.confirm(
+ __(
+ "Do you want to clear the selected {0}?",
+ [frappe.utils.comma_and(to_clear.map(dt => __(dt)))]
+ ),
+ () => {
+ this.frm.set_value("payment_terms_template", "");
+ this.frm.clear_table("payment_schedule");
+ this.frm.refresh_field("payment_schedule");
+ }
+ );
}
}