Merge pull request #30244 from nextchamp-saqib/fix-gl-representation
fix: incorrect debit credit amount in presentation currency
diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
index 9b3b3aa..91c07ad 100644
--- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
+++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
@@ -53,7 +53,7 @@
def on_submit(self):
# create the loyalty point ledger entry if the customer is enrolled in any loyalty program
- if self.loyalty_program:
+ if not self.is_return and self.loyalty_program:
self.make_loyalty_point_entry()
elif self.is_return and self.return_against and self.loyalty_program:
against_psi_doc = frappe.get_doc("POS Invoice", self.return_against)
@@ -87,7 +87,7 @@
def on_cancel(self):
# run on cancel method of selling controller
super(SalesInvoice, self).on_cancel()
- if self.loyalty_program:
+ if not self.is_return and self.loyalty_program:
self.delete_loyalty_point_entry()
elif self.is_return and self.return_against and self.loyalty_program:
against_psi_doc = frappe.get_doc("POS Invoice", self.return_against)
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 54217fb..bfe72dc 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -1411,12 +1411,19 @@
frappe.db.set_value("Customer", self.customer, "loyalty_program_tier", lp_details.tier_name)
def get_returned_amount(self):
- returned_amount = frappe.db.sql("""
- select sum(grand_total)
- from `tabSales Invoice`
- where docstatus=1 and is_return=1 and ifnull(return_against, '')=%s
- """, self.name)
- return abs(flt(returned_amount[0][0])) if returned_amount else 0
+ from frappe.query_builder.functions import Coalesce, Sum
+ doc = frappe.qb.DocType(self.doctype)
+ returned_amount = (
+ frappe.qb.from_(doc)
+ .select(Sum(doc.grand_total))
+ .where(
+ (doc.docstatus == 1)
+ & (doc.is_return == 1)
+ & (Coalesce(doc.return_against, '') == self.name)
+ )
+ ).run()
+
+ return abs(returned_amount[0][0]) if returned_amount[0][0] else 0
# redeem the loyalty points.
def apply_loyalty_points(self):
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 2e7d306..2c66542 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -402,7 +402,6 @@
frappe.local.message_log = []
def set_missing_values(source, target):
- target.ignore_pricing_rule = 1
target.run_method("set_missing_values")
target.run_method("calculate_taxes_and_totals")
diff --git a/erpnext/e_commerce/product_ui/views.js b/erpnext/e_commerce/product_ui/views.js
index 1b5c440..6dce79d 100644
--- a/erpnext/e_commerce/product_ui/views.js
+++ b/erpnext/e_commerce/product_ui/views.js
@@ -495,7 +495,7 @@
categories.forEach(category => {
sub_group_html += `
- <a href="${ category.route || '#' }" style="text-decoration: none;">
+ <a href="/${ category.route || '#' }" style="text-decoration: none;">
<div class="category-pill">
${ category.name }
</div>
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py
index 9f4ace2..5f492d7 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.py
+++ b/erpnext/manufacturing/doctype/job_card/job_card.py
@@ -48,7 +48,7 @@
self.validate_work_order()
def set_sub_operations(self):
- if self.operation:
+ if not self.sub_operations and self.operation:
self.sub_operations = []
for row in frappe.get_all('Sub Operation',
filters = {'parent': self.operation}, fields=['operation', 'idx'], order_by='idx'):
diff --git a/erpnext/manufacturing/doctype/job_card/job_card_list.js b/erpnext/manufacturing/doctype/job_card/job_card_list.js
index 8017209..7f60bdc 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card_list.js
+++ b/erpnext/manufacturing/doctype/job_card/job_card_list.js
@@ -1,4 +1,5 @@
frappe.listview_settings['Job Card'] = {
+ has_indicator_for_draft: true,
get_indicator: function(doc) {
if (doc.status === "Work In Progress") {
return [__("Work In Progress"), "orange", "status,=,Work In Progress"];
diff --git a/erpnext/patches/v13_0/create_leave_policy_assignment_based_on_employee_current_leave_policy.py b/erpnext/patches/v13_0/create_leave_policy_assignment_based_on_employee_current_leave_policy.py
index 5512543..8cf1037 100644
--- a/erpnext/patches/v13_0/create_leave_policy_assignment_based_on_employee_current_leave_policy.py
+++ b/erpnext/patches/v13_0/create_leave_policy_assignment_based_on_employee_current_leave_policy.py
@@ -6,14 +6,13 @@
def execute():
+ frappe.reload_doc('hr', 'doctype', 'leave_policy_assignment')
+ employee_with_assignment = []
+ leave_policy = []
+
if "leave_policy" in frappe.db.get_table_columns("Employee"):
employees_with_leave_policy = frappe.db.sql("SELECT name, leave_policy FROM `tabEmployee` WHERE leave_policy IS NOT NULL and leave_policy != ''", as_dict = 1)
- employee_with_assignment = []
- leave_policy =[]
-
- #for employee
-
for employee in employees_with_leave_policy:
alloc = frappe.db.exists("Leave Allocation", {"employee":employee.name, "leave_policy": employee.leave_policy, "docstatus": 1})
if not alloc:
@@ -22,12 +21,10 @@
employee_with_assignment.append(employee.name)
leave_policy.append(employee.leave_policy)
-
- if "default_leave_policy" in frappe.db.get_table_columns("Employee"):
+ if "default_leave_policy" in frappe.db.get_table_columns("Employee Grade"):
employee_grade_with_leave_policy = frappe.db.sql("SELECT name, default_leave_policy FROM `tabEmployee Grade` WHERE default_leave_policy IS NOT NULL and default_leave_policy!=''", as_dict = 1)
#for whole employee Grade
-
for grade in employee_grade_with_leave_policy:
employees = get_employee_with_grade(grade.name)
for employee in employees:
@@ -47,13 +44,13 @@
allocation_exists=True)
def create_assignment(employee, leave_policy, leave_period=None, allocation_exists = False):
+ if frappe.db.get_value("Leave Policy", leave_policy, "docstatus") == 2:
+ return
filters = {"employee":employee, "leave_policy": leave_policy}
if leave_period:
filters["leave_period"] = leave_period
- frappe.reload_doc('hr', 'doctype', 'leave_policy_assignment')
-
if not frappe.db.exists("Leave Policy Assignment" , filters):
lpa = frappe.new_doc("Leave Policy Assignment")
lpa.employee = employee
diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.py b/erpnext/payroll/doctype/salary_slip/salary_slip.py
index 181a2b5..caaed1f 100644
--- a/erpnext/payroll/doctype/salary_slip/salary_slip.py
+++ b/erpnext/payroll/doctype/salary_slip/salary_slip.py
@@ -1002,7 +1002,7 @@
# apply rounding
if frappe.get_cached_value("Salary Component", row.salary_component, "round_to_the_nearest_integer"):
- amount, additional_amount = rounded(amount), rounded(additional_amount)
+ amount, additional_amount = rounded(amount or 0), rounded(additional_amount or 0)
return amount, additional_amount
@@ -1279,9 +1279,9 @@
def set_base_totals(self):
self.base_gross_pay = flt(self.gross_pay) * flt(self.exchange_rate)
self.base_total_deduction = flt(self.total_deduction) * flt(self.exchange_rate)
- self.rounded_total = rounded(self.net_pay)
+ self.rounded_total = rounded(self.net_pay or 0)
self.base_net_pay = flt(self.net_pay) * flt(self.exchange_rate)
- self.base_rounded_total = rounded(self.base_net_pay)
+ self.base_rounded_total = rounded(self.base_net_pay or 0)
self.set_net_total_in_words()
#calculate total working hours, earnings based on hourly wages and totals
diff --git a/erpnext/public/scss/shopping_cart.scss b/erpnext/public/scss/shopping_cart.scss
index 666043b..019496d 100644
--- a/erpnext/public/scss/shopping_cart.scss
+++ b/erpnext/public/scss/shopping_cart.scss
@@ -569,15 +569,12 @@
}
.scroll-categories {
- white-space: nowrap;
- overflow-x: auto;
-
.category-pill {
- margin: 0px 4px;
display: inline-block;
- padding: 6px 12px;
- background-color: #ecf5fe;
width: fit-content;
+ padding: 6px 12px;
+ margin-bottom: 8px;
+ background-color: #ecf5fe;
font-size: 14px;
border-radius: 18px;
color: var(--blue-500);
diff --git a/erpnext/regional/saudi_arabia/utils.py b/erpnext/regional/saudi_arabia/utils.py
index a03c3f0..515862d 100644
--- a/erpnext/regional/saudi_arabia/utils.py
+++ b/erpnext/regional/saudi_arabia/utils.py
@@ -90,7 +90,7 @@
tlv_array.append(''.join([tag, length, value]))
# VAT Amount
- vat_amount = str(doc.total_taxes_and_charges)
+ vat_amount = str(get_vat_amount(doc))
tag = bytes([5]).hex()
length = bytes([len(vat_amount)]).hex()
@@ -127,6 +127,22 @@
doc.db_set('ksa_einv_qr', _file.file_url)
doc.notify_update()
+def get_vat_amount(doc):
+ vat_settings = frappe.db.get_value('KSA VAT Setting', {'company': doc.company})
+ vat_accounts = []
+ vat_amount = 0
+
+ if vat_settings:
+ vat_settings_doc = frappe.get_cached_doc('KSA VAT Setting', vat_settings)
+
+ for row in vat_settings_doc.get('ksa_vat_sales_accounts'):
+ vat_accounts.append(row.account)
+
+ for tax in doc.get('taxes'):
+ if tax.account_head in vat_accounts:
+ vat_amount += tax.tax_amount
+
+ return vat_amount
def delete_qr_code_file(doc, method=None):
region = get_region(doc.company)
diff --git a/erpnext/regional/united_arab_emirates/utils.py b/erpnext/regional/united_arab_emirates/utils.py
index f350ec4..bdede84 100644
--- a/erpnext/regional/united_arab_emirates/utils.py
+++ b/erpnext/regional/united_arab_emirates/utils.py
@@ -26,9 +26,12 @@
elif row.item_code and itemised_tax.get(row.item_code):
tax_rate = sum([tax.get('tax_rate', 0) for d, tax in itemised_tax.get(row.item_code).items()])
- row.tax_rate = flt(tax_rate, row.precision("tax_rate"))
- row.tax_amount = flt((row.net_amount * tax_rate) / 100, row.precision("net_amount"))
- row.total_amount = flt((row.net_amount + row.tax_amount), row.precision("total_amount"))
+ meta = frappe.get_meta(row.doctype)
+
+ if meta.has_field('tax_rate'):
+ row.tax_rate = flt(tax_rate, row.precision("tax_rate"))
+ row.tax_amount = flt((row.net_amount * tax_rate) / 100, row.precision("net_amount"))
+ row.total_amount = flt((row.net_amount + row.tax_amount), row.precision("total_amount"))
def get_account_currency(account):
"""Helper function to get account currency."""
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index abbb3c9..94581b6 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -520,7 +520,6 @@
@frappe.whitelist()
def make_delivery_note(source_name, target_doc=None, skip_item_mapping=False):
def set_missing_values(source, target):
- target.ignore_pricing_rule = 1
target.run_method("set_missing_values")
target.run_method("set_po_nos")
target.run_method("calculate_taxes_and_totals")
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index 5c7194b..2c53246 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -132,7 +132,8 @@
return frappe.get_all(
"Item Group",
filters=filters,
- fields=["name", "route"]
+ fields=["name", "route"],
+ order_by="name"
)
def get_child_item_groups(item_group_name):
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 75ccd86..e9ef331 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -445,7 +445,6 @@
invoiced_qty_map = get_invoiced_qty_map(source_name)
def set_missing_values(source, target):
- target.ignore_pricing_rule = 1
target.run_method("set_missing_values")
target.run_method("set_po_nos")
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 52f10ea..5bb337e 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -762,7 +762,6 @@
frappe.throw(_("All items have already been Invoiced/Returned"))
doc = frappe.get_doc(target)
- doc.ignore_pricing_rule = 1
doc.payment_terms_template = get_payment_terms_template(source.supplier, "Supplier", source.company)
doc.run_method("onload")
doc.run_method("set_missing_values")