Skip to content

Commit

Permalink
Merge pull request #41854 from frappe/version-15-hotfix
Browse files Browse the repository at this point in the history
chore: release v15
  • Loading branch information
rohitwaghchaure authored Jun 11, 2024
2 parents 6157119 + 3e4c568 commit b87b438
Show file tree
Hide file tree
Showing 20 changed files with 252 additions and 49 deletions.
13 changes: 12 additions & 1 deletion erpnext/accounts/doctype/payment_entry/payment_entry.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"custom_remarks",
"remarks",
"base_in_words",
"is_opening",
"column_break_16",
"letter_head",
"print_heading",
Expand Down Expand Up @@ -777,6 +778,16 @@
"label": "Reconcile on Advance Payment Date",
"no_copy": 1,
"read_only": 1
},
{
"default": "No",
"depends_on": "eval: doc.book_advance_payments_in_separate_party_account == 1",
"fieldname": "is_opening",
"fieldtype": "Select",
"label": "Is Opening",
"options": "No\nYes",
"print_hide": 1,
"search_index": 1
}
],
"index_web_pages_for_search": 1,
Expand All @@ -790,7 +801,7 @@
"table_fieldname": "payment_entries"
}
],
"modified": "2024-05-17 10:21:11.199445",
"modified": "2024-05-31 17:07:06.197249",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry",
Expand Down
4 changes: 4 additions & 0 deletions erpnext/accounts/doctype/payment_entry/payment_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,13 @@ def set_liability_account(self):

self.book_advance_payments_in_separate_party_account = False
if self.party_type not in ("Customer", "Supplier"):
self.is_opening = "No"
return

if not frappe.db.get_value(
"Company", self.company, "book_advance_payments_in_separate_party_account"
):
self.is_opening = "No"
return

# Important to set this flag for the gl building logic to work properly
Expand All @@ -132,6 +134,7 @@ def set_liability_account(self):
if (account_type == "Payable" and self.party_type == "Customer") or (
account_type == "Receivable" and self.party_type == "Supplier"
):
self.is_opening = "No"
return

if self.references:
Expand All @@ -141,6 +144,7 @@ def set_liability_account(self):
# If there are referencers other than `allowed_types`, treat this as a normal payment entry
if reference_types - allowed_types:
self.book_advance_payments_in_separate_party_account = False
self.is_opening = "No"
return

liability_account = get_party_account(
Expand Down
62 changes: 62 additions & 0 deletions erpnext/accounts/doctype/payment_entry/test_payment_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -1729,6 +1729,68 @@ def test_advance_reverse_payment_reconciliation(self):
self.check_gl_entries()
self.check_pl_entries()

def test_opening_flag_for_advance_as_liability(self):
company = "_Test Company"

advance_account = create_account(
parent_account="Current Assets - _TC",
account_name="Advances Received",
company=company,
account_type="Receivable",
)

# Enable Advance in separate party account
frappe.db.set_value(
"Company",
company,
{
"book_advance_payments_in_separate_party_account": 1,
"default_advance_received_account": advance_account,
},
)
# Advance Payment
adv = create_payment_entry(
party_type="Customer",
party="_Test Customer",
payment_type="Receive",
paid_from="Debtors - _TC",
paid_to="_Test Cash - _TC",
)
adv.is_opening = "Yes"
adv.save() # use save() to trigger set_liability_account()
adv.submit()

gl_with_opening_set = frappe.db.get_all(
"GL Entry", filters={"voucher_no": adv.name, "is_opening": "Yes"}
)
# 'Is Opening' can be 'Yes' for Advances in separate party account
self.assertNotEqual(gl_with_opening_set, [])

# Disable Advance in separate party account
frappe.db.set_value(
"Company",
company,
{
"book_advance_payments_in_separate_party_account": 0,
"default_advance_received_account": None,
},
)
payment = create_payment_entry(
party_type="Customer",
party="_Test Customer",
payment_type="Receive",
paid_from="Debtors - _TC",
paid_to="_Test Cash - _TC",
)
payment.is_opening = "Yes"
payment.save()
payment.submit()
gl_with_opening_set = frappe.db.get_all(
"GL Entry", filters={"voucher_no": payment.name, "is_opening": "Yes"}
)
# 'Is Opening' should always be 'No' for normal advance payments
self.assertEqual(gl_with_opening_set, [])


def create_payment_entry(**args):
payment_entry = frappe.new_doc("Payment Entry")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,7 @@ frappe.ui.form.on("Purchase Invoice", {
if (frm.doc.supplier) {
frm.doc.apply_tds = frm.doc.__onload.supplier_tds ? 1 : 0;
}
if (!frm.doc.__onload.supplier_tds) {
if (!frm.doc.__onload.enable_apply_tds) {
frm.set_df_property("apply_tds", "read_only", 1);
}
}
Expand Down
18 changes: 17 additions & 1 deletion erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@


import frappe
from frappe import _, throw
from frappe import _, qb, throw
from frappe.model.mapper import get_mapped_doc
from frappe.query_builder.functions import Sum
from frappe.utils import cint, cstr, flt, formatdate, get_link_to_form, getdate, nowdate
Expand Down Expand Up @@ -347,6 +347,22 @@ def set_missing_values(self, for_validate=False):
self.tax_withholding_category = tds_category
self.set_onload("supplier_tds", tds_category)

# If Linked Purchase Order has TDS applied, enable 'apply_tds' checkbox
if purchase_orders := [x.purchase_order for x in self.items if x.purchase_order]:
po = qb.DocType("Purchase Order")
po_with_tds = (
qb.from_(po)
.select(po.name)
.where(
po.docstatus.eq(1)
& (po.name.isin(purchase_orders))
& (po.apply_tds.eq(1))
& (po.tax_withholding_category.notnull())
)
.run()
)
self.set_onload("enable_apply_tds", True if po_with_tds else False)

super().set_missing_values(for_validate)

def validate_credit_to_acc(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"in_create": 1,
"issingle": 1,
"links": [],
"modified": "2023-11-07 14:24:13.321522",
"modified": "2024-06-06 13:56:37.908879",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Repost Accounting Ledger Settings",
Expand All @@ -30,13 +30,17 @@
"print": 1,
"read": 1,
"role": "Administrator",
"select": 1,
"share": 1,
"write": 1
},
{
"create": 1,
"delete": 1,
"read": 1,
"role": "System Manager",
"select": 1
"select": 1,
"write": 1
}
],
"sort_field": "modified",
Expand Down
3 changes: 2 additions & 1 deletion erpnext/accounts/doctype/sales_invoice/sales_invoice.json
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,7 @@
"hide_days": 1,
"hide_seconds": 1,
"label": "Time Sheets",
"no_copy": 1,
"options": "Sales Invoice Timesheet",
"print_hide": 1
},
Expand Down Expand Up @@ -2187,7 +2188,7 @@
"link_fieldname": "consolidated_invoice"
}
],
"modified": "2024-05-08 18:02:28.549041",
"modified": "2024-06-07 16:49:32.458402",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,48 +69,50 @@ def get_asset_categories_for_grouped_by_category(filters):
condition = ""
if filters.get("asset_category"):
condition += " and asset_category = %(asset_category)s"
# nosemgrep
return frappe.db.sql(
f"""
SELECT asset_category,
ifnull(sum(case when purchase_date < %(from_date)s then
case when ifnull(disposal_date, 0) = 0 or disposal_date >= %(from_date)s then
gross_purchase_amount
SELECT a.asset_category,
ifnull(sum(case when a.purchase_date < %(from_date)s then
case when ifnull(a.disposal_date, 0) = 0 or a.disposal_date >= %(from_date)s then
a.gross_purchase_amount
else
0
end
else
0
end), 0) as cost_as_on_from_date,
ifnull(sum(case when purchase_date >= %(from_date)s then
gross_purchase_amount
ifnull(sum(case when a.purchase_date >= %(from_date)s then
a.gross_purchase_amount
else
0
end), 0) as cost_of_new_purchase,
ifnull(sum(case when ifnull(disposal_date, 0) != 0
and disposal_date >= %(from_date)s
and disposal_date <= %(to_date)s then
case when status = "Sold" then
gross_purchase_amount
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0
and a.disposal_date >= %(from_date)s
and a.disposal_date <= %(to_date)s then
case when a.status = "Sold" then
a.gross_purchase_amount
else
0
end
else
0
end), 0) as cost_of_sold_asset,
ifnull(sum(case when ifnull(disposal_date, 0) != 0
and disposal_date >= %(from_date)s
and disposal_date <= %(to_date)s then
case when status = "Scrapped" then
gross_purchase_amount
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0
and a.disposal_date >= %(from_date)s
and a.disposal_date <= %(to_date)s then
case when a.status = "Scrapped" then
a.gross_purchase_amount
else
0
end
else
0
end), 0) as cost_of_scrapped_asset
from `tabAsset`
from `tabAsset` a
where docstatus=1 and company=%(company)s and purchase_date <= %(to_date)s {condition}
group by asset_category
and not exists(select name from `tabAsset Capitalization Asset Item` where asset = a.name)
group by a.asset_category
""",
{
"to_date": filters.to_date,
Expand Down
3 changes: 3 additions & 0 deletions erpnext/controllers/stock_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,9 @@ def delete_auto_created_batches(self):

row.db_set("rejected_serial_and_batch_bundle", None)

if row.get("current_serial_and_batch_bundle"):
row.db_set("current_serial_and_batch_bundle", None)

def set_serial_and_batch_bundle(self, table_name=None, ignore_validate=False):
if not table_name:
table_name = "items"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -452,14 +452,18 @@ def add_items(self, items):
{"sales_order": data.parent, "sales_order_item": data.name, "qty": data.pending_qty}
)

bom_no = data.bom_no or item_details and item_details.bom_no or ""
if not bom_no:
continue

pi = self.append(
"po_items",
{
"warehouse": data.warehouse,
"item_code": data.item_code,
"description": data.description or item_details.description,
"stock_uom": item_details and item_details.stock_uom or "",
"bom_no": data.bom_no or item_details and item_details.bom_no or "",
"bom_no": bom_no,
"planned_qty": data.pending_qty,
"pending_qty": data.pending_qty,
"planned_start_date": now_datetime(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,28 @@ def test_so_based_bill_of_material(self):

self.assertEqual(pln2.po_items[0].bom_no, bom2.name)

def test_production_plan_with_non_active_bom_item(self):
item = make_item("Test Production Item 1 for Non Active BOM", {"is_stock_item": 1}).name

so1 = make_sales_order(item_code=item, qty=1)

pln = frappe.new_doc("Production Plan")
pln.company = so1.company
pln.get_items_from = "Sales Order"
pln.append(
"sales_orders",
{
"sales_order": so1.name,
"sales_order_date": so1.transaction_date,
"customer": so1.customer,
"grand_total": so1.grand_total,
},
)

pln.get_items()

self.assertFalse(pln.po_items)

def test_production_plan_combine_items(self):
"Test combining FG items in Production Plan."
item = "Test Production Item 1"
Expand Down
4 changes: 2 additions & 2 deletions erpnext/public/js/controllers/taxes_and_totals.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
this.frm.doc.paid_amount = flt(this.frm.doc.grand_total, precision("grand_total"));
}

this.frm.refresh_field("taxes");
this.frm.refresh_fields();
}

calculate_discount_amount() {
Expand Down Expand Up @@ -841,7 +841,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
});
}

this.frm.refresh_field("taxes");
this.frm.refresh_fields();
}

set_default_payment(total_amount_to_pay, update_paid_amount) {
Expand Down
4 changes: 2 additions & 2 deletions erpnext/public/js/controllers/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -1246,8 +1246,8 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
}

qty(doc, cdt, cdn) {
if (!this.frm.doc.__onload?.load_after_mapping) {
let item = frappe.get_doc(cdt, cdn);
let item = frappe.get_doc(cdt, cdn);
if (!this.is_a_mapped_document(item)) {
// item.pricing_rules = ''
frappe.run_serially([
() => this.remove_pricing_rule_for_item(item),
Expand Down
6 changes: 6 additions & 0 deletions erpnext/selling/doctype/sales_order/sales_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,11 @@ def get_requested_item_qty(sales_order):
def make_material_request(source_name, target_doc=None):
requested_item_qty = get_requested_item_qty(source_name)

def postprocess(source, target):
if source.tc_name and frappe.db.get_value("Terms and Conditions", source.tc_name, "buying") != 1:
target.tc_name = None
target.terms = None

def get_remaining_qty(so_item):
return flt(
flt(so_item.qty)
Expand Down Expand Up @@ -849,6 +854,7 @@ def update_item(source, target, source_parent):
},
},
target_doc,
postprocess,
)

return doc
Expand Down
Loading

0 comments on commit b87b438

Please sign in to comment.