fix: Ambiguous column error while submitting stock entry
fix: Ambiguous column error while submitting stock entry
diff --git a/erpnext/accounts/doctype/bank/bank.js b/erpnext/accounts/doctype/bank/bank.js
index 35d606b..6667193 100644
--- a/erpnext/accounts/doctype/bank/bank.js
+++ b/erpnext/accounts/doctype/bank/bank.js
@@ -8,9 +8,6 @@
},
refresh: function(frm) {
add_fields_to_mapping_table(frm);
-
- frappe.dynamic_link = { doc: frm.doc, fieldname: 'name', doctype: 'Bank' };
-
frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
if (frm.doc.__islocal) {
diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py
index c52ea24..3b5698b 100644
--- a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py
+++ b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py
@@ -258,8 +258,8 @@
new_balance_in_base_currency = 0
new_balance_in_account_currency = 0
- current_exchange_rate = calculate_exchange_rate_using_last_gle(
- company, d.account, d.party_type, d.party
+ current_exchange_rate = (
+ calculate_exchange_rate_using_last_gle(company, d.account, d.party_type, d.party) or 0.0
)
gain_loss = new_balance_in_account_currency - (
diff --git a/erpnext/accounts/doctype/item_tax_template/item_tax_template.json b/erpnext/accounts/doctype/item_tax_template/item_tax_template.json
index b42d712..87f0ad1 100644
--- a/erpnext/accounts/doctype/item_tax_template/item_tax_template.json
+++ b/erpnext/accounts/doctype/item_tax_template/item_tax_template.json
@@ -35,6 +35,7 @@
{
"fieldname": "company",
"fieldtype": "Link",
+ "in_filter": 1,
"in_list_view": 1,
"label": "Company",
"options": "Company",
@@ -56,7 +57,7 @@
}
],
"links": [],
- "modified": "2022-01-18 21:11:23.105589",
+ "modified": "2023-07-09 18:11:23.105589",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Item Tax Template",
@@ -102,4 +103,4 @@
"states": [],
"title_field": "title",
"track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 65ed466..dcd7295 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -237,10 +237,9 @@
_("{0} {1} has already been fully paid.").format(_(d.reference_doctype), d.reference_name)
)
# The reference has already been partly paid
- elif (
- latest.outstanding_amount < latest.invoice_amount
- and flt(d.outstanding_amount, d.precision("outstanding_amount")) != latest.outstanding_amount
- ):
+ elif latest.outstanding_amount < latest.invoice_amount and flt(
+ d.outstanding_amount, d.precision("outstanding_amount")
+ ) != flt(latest.outstanding_amount, d.precision("outstanding_amount")):
frappe.throw(
_(
"{0} {1} has already been partly paid. Please use the 'Get Outstanding Invoice' or the 'Get Outstanding Orders' button to get the latest outstanding amounts."
@@ -1433,6 +1432,9 @@
if args.get("party_type") == "Member":
return
+ if not args.get("get_outstanding_invoices") and not args.get("get_orders_to_be_billed"):
+ args["get_outstanding_invoices"] = True
+
ple = qb.DocType("Payment Ledger Entry")
common_filter = []
accounting_dimensions_filter = []
@@ -1627,60 +1629,59 @@
cost_center=None,
filters=None,
):
+ voucher_type = None
if party_type == "Customer":
voucher_type = "Sales Order"
elif party_type == "Supplier":
voucher_type = "Purchase Order"
- elif party_type == "Employee":
- voucher_type = None
+
+ if not voucher_type:
+ return []
# Add cost center condition
- if voucher_type:
- doc = frappe.get_doc({"doctype": voucher_type})
- condition = ""
- if doc and hasattr(doc, "cost_center") and doc.cost_center:
- condition = " and cost_center='%s'" % cost_center
+ doc = frappe.get_doc({"doctype": voucher_type})
+ condition = ""
+ if doc and hasattr(doc, "cost_center") and doc.cost_center:
+ condition = " and cost_center='%s'" % cost_center
- orders = []
- if voucher_type:
- if party_account_currency == company_currency:
- grand_total_field = "base_grand_total"
- rounded_total_field = "base_rounded_total"
- else:
- grand_total_field = "grand_total"
- rounded_total_field = "rounded_total"
+ if party_account_currency == company_currency:
+ grand_total_field = "base_grand_total"
+ rounded_total_field = "base_rounded_total"
+ else:
+ grand_total_field = "grand_total"
+ rounded_total_field = "rounded_total"
- orders = frappe.db.sql(
- """
- select
- name as voucher_no,
- if({rounded_total_field}, {rounded_total_field}, {grand_total_field}) as invoice_amount,
- (if({rounded_total_field}, {rounded_total_field}, {grand_total_field}) - advance_paid) as outstanding_amount,
- transaction_date as posting_date
- from
- `tab{voucher_type}`
- where
- {party_type} = %s
- and docstatus = 1
- and company = %s
- and ifnull(status, "") != "Closed"
- and if({rounded_total_field}, {rounded_total_field}, {grand_total_field}) > advance_paid
- and abs(100 - per_billed) > 0.01
- {condition}
- order by
- transaction_date, name
- """.format(
- **{
- "rounded_total_field": rounded_total_field,
- "grand_total_field": grand_total_field,
- "voucher_type": voucher_type,
- "party_type": scrub(party_type),
- "condition": condition,
- }
- ),
- (party, company),
- as_dict=True,
- )
+ orders = frappe.db.sql(
+ """
+ select
+ name as voucher_no,
+ if({rounded_total_field}, {rounded_total_field}, {grand_total_field}) as invoice_amount,
+ (if({rounded_total_field}, {rounded_total_field}, {grand_total_field}) - advance_paid) as outstanding_amount,
+ transaction_date as posting_date
+ from
+ `tab{voucher_type}`
+ where
+ {party_type} = %s
+ and docstatus = 1
+ and company = %s
+ and ifnull(status, "") != "Closed"
+ and if({rounded_total_field}, {rounded_total_field}, {grand_total_field}) > advance_paid
+ and abs(100 - per_billed) > 0.01
+ {condition}
+ order by
+ transaction_date, name
+ """.format(
+ **{
+ "rounded_total_field": rounded_total_field,
+ "grand_total_field": grand_total_field,
+ "voucher_type": voucher_type,
+ "party_type": scrub(party_type),
+ "condition": condition,
+ }
+ ),
+ (party, company),
+ as_dict=True,
+ )
order_list = []
for d in orders:
@@ -1713,6 +1714,8 @@
cost_center=None,
condition=None,
):
+ if party_type not in ["Customer", "Supplier"]:
+ return []
voucher_type = "Sales Invoice" if party_type == "Customer" else "Purchase Invoice"
account = "debit_to" if voucher_type == "Sales Invoice" else "credit_to"
supplier_condition = ""
diff --git a/erpnext/accounts/doctype/shareholder/shareholder.js b/erpnext/accounts/doctype/shareholder/shareholder.js
index c6f101e..544d417 100644
--- a/erpnext/accounts/doctype/shareholder/shareholder.js
+++ b/erpnext/accounts/doctype/shareholder/shareholder.js
@@ -3,8 +3,6 @@
frappe.ui.form.on('Shareholder', {
refresh: function(frm) {
- frappe.dynamic_link = { doc: frm.doc, fieldname: 'name', doctype: 'Shareholder' };
-
frm.toggle_display(['contact_html'], !frm.doc.__islocal);
if (frm.doc.__islocal) {
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 31473db..8b44b22 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -850,7 +850,7 @@
if party_type == "Supplier":
held_invoices = frappe.db.sql(
- "select name from `tabPurchase Invoice` where release_date IS NOT NULL and release_date > CURDATE()",
+ "select name from `tabPurchase Invoice` where on_hold = 1 and release_date IS NOT NULL and release_date > CURDATE()",
as_dict=1,
)
held_invoices = set(d["name"] for d in held_invoices)
diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py
index 259568a..e1431ea 100644
--- a/erpnext/assets/doctype/asset/depreciation.py
+++ b/erpnext/assets/doctype/asset/depreciation.py
@@ -40,6 +40,7 @@
date = today()
failed_asset_names = []
+ error_log_names = []
for asset_name in get_depreciable_assets(date):
asset_doc = frappe.get_doc("Asset", asset_name)
@@ -50,10 +51,12 @@
except Exception as e:
frappe.db.rollback()
failed_asset_names.append(asset_name)
+ error_log = frappe.log_error(e)
+ error_log_names.append(error_log.name)
if failed_asset_names:
set_depr_entry_posting_status_for_failed_assets(failed_asset_names)
- notify_depr_entry_posting_error(failed_asset_names)
+ notify_depr_entry_posting_error(failed_asset_names, error_log_names)
frappe.db.commit()
@@ -239,7 +242,7 @@
frappe.db.set_value("Asset", asset_name, "depr_entry_posting_status", "Failed")
-def notify_depr_entry_posting_error(failed_asset_names):
+def notify_depr_entry_posting_error(failed_asset_names, error_log_names):
recipients = get_users_with_role("Accounts Manager")
if not recipients:
@@ -247,7 +250,8 @@
subject = _("Error while posting depreciation entries")
- asset_links = get_comma_separated_asset_links(failed_asset_names)
+ asset_links = get_comma_separated_links(failed_asset_names, "Asset")
+ error_log_links = get_comma_separated_links(error_log_names, "Error Log")
message = (
_("Hello,")
@@ -257,23 +261,26 @@
)
+ "."
+ "<br><br>"
- + _(
- "Please raise a support ticket and share this email, or forward this email to your development team so that they can find the issue in the developer console by manually creating the depreciation entry via the asset's depreciation schedule table."
+ + _("Here are the error logs for the aforementioned failed depreciation entries: {0}").format(
+ error_log_links
)
+ + "."
+ + "<br><br>"
+ + _("Please share this email with your support team so that they can find and fix the issue.")
)
frappe.sendmail(recipients=recipients, subject=subject, message=message)
-def get_comma_separated_asset_links(asset_names):
- asset_links = []
+def get_comma_separated_links(names, doctype):
+ links = []
- for asset_name in asset_names:
- asset_links.append(get_link_to_form("Asset", asset_name))
+ for name in names:
+ links.append(get_link_to_form(doctype, name))
- asset_links = ", ".join(asset_links)
+ links = ", ".join(links)
- return asset_links
+ return links
@frappe.whitelist()
diff --git a/erpnext/assets/doctype/asset_movement/asset_movement.js b/erpnext/assets/doctype/asset_movement/asset_movement.js
index f9c6007..4ccc3f8 100644
--- a/erpnext/assets/doctype/asset_movement/asset_movement.js
+++ b/erpnext/assets/doctype/asset_movement/asset_movement.js
@@ -63,7 +63,7 @@
fieldnames_to_be_altered = {
target_location: { read_only: 0, reqd: 1 },
source_location: { read_only: 1, reqd: 0 },
- from_employee: { read_only: 0, reqd: 1 },
+ from_employee: { read_only: 0, reqd: 0 },
to_employee: { read_only: 1, reqd: 0 }
};
}
diff --git a/erpnext/assets/doctype/asset_movement/asset_movement.py b/erpnext/assets/doctype/asset_movement/asset_movement.py
index b58ca10..22055dc 100644
--- a/erpnext/assets/doctype/asset_movement/asset_movement.py
+++ b/erpnext/assets/doctype/asset_movement/asset_movement.py
@@ -62,29 +62,20 @@
frappe.throw(_("Source and Target Location cannot be same"))
if self.purpose == "Receipt":
- # only when asset is bought and first entry is made
- if not d.source_location and not (d.target_location or d.to_employee):
+ if not (d.source_location or d.from_employee) and not (d.target_location or d.to_employee):
frappe.throw(
_("Target Location or To Employee is required while receiving Asset {0}").format(d.asset)
)
- elif d.source_location:
- # when asset is received from an employee
- if d.target_location and not d.from_employee:
- frappe.throw(
- _("From employee is required while receiving Asset {0} to a target location").format(
- d.asset
- )
- )
- if d.from_employee and not d.target_location:
- frappe.throw(
- _("Target Location is required while receiving Asset {0} from an employee").format(d.asset)
- )
- if d.to_employee and d.target_location:
- frappe.throw(
- _(
- "Asset {0} cannot be received at a location and given to employee in a single movement"
- ).format(d.asset)
- )
+ elif d.from_employee and not d.target_location:
+ frappe.throw(
+ _("Target Location is required while receiving Asset {0} from an employee").format(d.asset)
+ )
+ elif d.to_employee and d.target_location:
+ frappe.throw(
+ _(
+ "Asset {0} cannot be received at a location and given to an employee in a single movement"
+ ).format(d.asset)
+ )
def validate_employee(self):
for d in self.assets:
diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js
index 5b95d0f..372ca56 100644
--- a/erpnext/buying/doctype/supplier/supplier.js
+++ b/erpnext/buying/doctype/supplier/supplier.js
@@ -66,8 +66,6 @@
},
refresh: function (frm) {
- frappe.dynamic_link = { doc: frm.doc, fieldname: 'name', doctype: 'Supplier' }
-
if (frappe.defaults.get_default("supp_master_name") != "Naming Series") {
frm.toggle_display("naming_series", false);
} else {
diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py
index 9546680..173e812 100644
--- a/erpnext/controllers/sales_and_purchase_return.py
+++ b/erpnext/controllers/sales_and_purchase_return.py
@@ -669,7 +669,11 @@
if reference_voucher_detail_no:
filters["voucher_detail_no"] = reference_voucher_detail_no
- if item_row and item_row.get("warehouse"):
+ if (
+ voucher_type in ["Purchase Receipt", "Purchase Invoice"]
+ and item_row
+ and item_row.get("warehouse")
+ ):
filters["warehouse"] = item_row.get("warehouse")
return filters
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index 5137e03..caf4b6f 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -201,6 +201,12 @@
warehouse_asset_account = warehouse_account[item_row.get("warehouse")]["account"]
expense_account = frappe.get_cached_value("Company", self.company, "default_expense_account")
+ if not expense_account:
+ frappe.throw(
+ _(
+ "Please set default cost of goods sold account in company {0} for booking rounding gain and loss during stock transfer"
+ ).format(frappe.bold(self.company))
+ )
gl_list.append(
self.get_gl_dict(
diff --git a/erpnext/crm/doctype/lead/lead.js b/erpnext/crm/doctype/lead/lead.js
index b98a27e..9ac5418 100644
--- a/erpnext/crm/doctype/lead/lead.js
+++ b/erpnext/crm/doctype/lead/lead.js
@@ -30,11 +30,6 @@
var me = this;
let doc = this.frm.doc;
erpnext.toggle_naming_series();
- frappe.dynamic_link = {
- doc: doc,
- fieldname: 'name',
- doctype: 'Lead'
- };
if (!this.frm.is_new() && doc.__onload && !doc.__onload.is_customer) {
this.frm.add_custom_button(__("Customer"), this.make_customer, __("Create"));
diff --git a/erpnext/crm/doctype/prospect/prospect.js b/erpnext/crm/doctype/prospect/prospect.js
index 495ed29..c1a7ff5 100644
--- a/erpnext/crm/doctype/prospect/prospect.js
+++ b/erpnext/crm/doctype/prospect/prospect.js
@@ -3,8 +3,6 @@
frappe.ui.form.on('Prospect', {
refresh (frm) {
- frappe.dynamic_link = { doc: frm.doc, fieldname: "name", doctype: frm.doctype };
-
if (!frm.is_new() && frappe.boot.user.can_create.includes("Customer")) {
frm.add_custom_button(__("Customer"), function() {
frappe.model.open_mapped_doc({
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index 6dc1ff6..5f957a5 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -697,10 +697,9 @@
material_request.flags.ignore_permissions = 1
material_request.run_method("set_missing_values")
+ material_request.save()
if self.get("submit_material_request"):
material_request.submit()
- else:
- material_request.save()
frappe.flags.mute_messages = False
diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js
index 540e767..60f0941 100644
--- a/erpnext/selling/doctype/customer/customer.js
+++ b/erpnext/selling/doctype/customer/customer.js
@@ -131,8 +131,6 @@
erpnext.toggle_naming_series();
}
- frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Customer'}
-
if(!frm.doc.__islocal) {
frappe.contacts.render_address_and_contact(frm);
diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js
index 3335387..f4682c1 100644
--- a/erpnext/setup/doctype/company/company.js
+++ b/erpnext/setup/doctype/company/company.js
@@ -81,8 +81,6 @@
disbale_coa_fields(frm);
frappe.contacts.render_address_and_contact(frm);
- frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Company'}
-
if (frappe.perm.has_perm("Cost Center", 0, 'read')) {
frm.add_custom_button(__('Cost Centers'), function() {
frappe.set_route('Tree', 'Cost Center', {'company': frm.doc.name});
diff --git a/erpnext/setup/doctype/sales_partner/sales_partner.js b/erpnext/setup/doctype/sales_partner/sales_partner.js
index 5656d43..f9e3770 100644
--- a/erpnext/setup/doctype/sales_partner/sales_partner.js
+++ b/erpnext/setup/doctype/sales_partner/sales_partner.js
@@ -3,8 +3,6 @@
frappe.ui.form.on('Sales Partner', {
refresh: function(frm) {
- frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Sales Partner'}
-
if(frm.doc.__islocal){
hide_field(['address_html', 'contact_html', 'address_contacts']);
frappe.contacts.clear_address_and_contact(frm);
diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
index 8baae8a..0ef3027 100644
--- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
@@ -318,6 +318,37 @@
self.assertEqual(dn.per_returned, 100)
self.assertEqual(dn.status, "Return Issued")
+ def test_delivery_note_return_valuation_on_different_warehuose(self):
+ from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
+
+ company = frappe.db.get_value("Warehouse", "Stores - TCP1", "company")
+ item_code = "Test Return Valuation For DN"
+ make_item("Test Return Valuation For DN", {"is_stock_item": 1})
+ return_warehouse = create_warehouse("Returned Test Warehouse", company=company)
+
+ make_stock_entry(item_code=item_code, target="Stores - TCP1", qty=5, basic_rate=150)
+
+ dn = create_delivery_note(
+ item_code=item_code,
+ qty=5,
+ rate=500,
+ warehouse="Stores - TCP1",
+ company=company,
+ expense_account="Cost of Goods Sold - TCP1",
+ cost_center="Main - TCP1",
+ )
+
+ dn.submit()
+ self.assertEqual(dn.items[0].incoming_rate, 150)
+
+ from erpnext.controllers.sales_and_purchase_return import make_return_doc
+
+ return_dn = make_return_doc(dn.doctype, dn.name)
+ return_dn.items[0].warehouse = return_warehouse
+ return_dn.save().submit()
+
+ self.assertEqual(return_dn.items[0].incoming_rate, 150)
+
def test_return_single_item_from_bundled_items(self):
company = frappe.db.get_value("Warehouse", "Stores - TCP1", "company")
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 93d799a..ef4155e 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -773,7 +773,7 @@
rows = ""
for docname, attr_list in not_included.items():
- link = "<a href='/app/Form/Item/{0}'>{0}</a>".format(frappe.bold(_(docname)))
+ link = f"<a href='/app/item/{docname}'>{frappe.bold(docname)}</a>"
rows += table_row(link, body(attr_list))
error_description = _(
diff --git a/erpnext/stock/doctype/manufacturer/manufacturer.js b/erpnext/stock/doctype/manufacturer/manufacturer.js
index bb7e314..5b4990f 100644
--- a/erpnext/stock/doctype/manufacturer/manufacturer.js
+++ b/erpnext/stock/doctype/manufacturer/manufacturer.js
@@ -3,7 +3,6 @@
frappe.ui.form.on('Manufacturer', {
refresh: function(frm) {
- frappe.dynamic_link = { doc: frm.doc, fieldname: 'name', doctype: 'Manufacturer' };
if (frm.doc.__islocal) {
hide_field(['address_html','contact_html']);
frappe.contacts.clear_address_and_contact(frm);
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index ced8946..6134bfa 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -1965,6 +1965,32 @@
ste5.reload()
self.assertEqual(ste5.items[0].valuation_rate, 275.00)
+ ste6 = make_stock_entry(
+ purpose="Material Transfer",
+ posting_date=add_days(today(), -3),
+ source=warehouse1,
+ target=warehouse,
+ item_code=item_code,
+ qty=20,
+ company=pr.company,
+ )
+
+ ste6.reload()
+ self.assertEqual(ste6.items[0].valuation_rate, 275.00)
+
+ ste7 = make_stock_entry(
+ purpose="Material Transfer",
+ posting_date=add_days(today(), -3),
+ source=warehouse,
+ target=warehouse1,
+ item_code=item_code,
+ qty=20,
+ company=pr.company,
+ )
+
+ ste7.reload()
+ self.assertEqual(ste7.items[0].valuation_rate, 275.00)
+
create_landed_cost_voucher("Purchase Receipt", pr.name, pr.company, charges=2500 * -1)
pr.reload()
@@ -1985,6 +2011,12 @@
ste5.reload()
self.assertEqual(ste5.items[0].valuation_rate, valuation_rate)
+ ste6.reload()
+ self.assertEqual(ste6.items[0].valuation_rate, valuation_rate)
+
+ ste7.reload()
+ self.assertEqual(ste7.items[0].valuation_rate, valuation_rate)
+
def prepare_data_for_internal_transfer():
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier
diff --git a/erpnext/stock/doctype/warehouse/warehouse.js b/erpnext/stock/doctype/warehouse/warehouse.js
index 746a1cb..3819c0b2 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.js
+++ b/erpnext/stock/doctype/warehouse/warehouse.js
@@ -83,12 +83,6 @@
}
frm.toggle_enable(["is_group", "company"], false);
-
- frappe.dynamic_link = {
- doc: frm.doc,
- fieldname: "name",
- doctype: "Warehouse",
- };
},
});
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index 7b1eae5..5abb8e8 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -645,7 +645,7 @@
def update_distinct_item_warehouses(self, dependant_sle):
key = (dependant_sle.item_code, dependant_sle.warehouse)
- val = frappe._dict({"sle": dependant_sle})
+ val = frappe._dict({"sle": dependant_sle, "dependent_voucher_detail_nos": []})
if key not in self.distinct_item_warehouses:
self.distinct_item_warehouses[key] = val
@@ -654,13 +654,26 @@
existing_sle_posting_date = (
self.distinct_item_warehouses[key].get("sle", {}).get("posting_date")
)
+
+ dependent_voucher_detail_nos = self.get_dependent_voucher_detail_nos(key)
+
if getdate(dependant_sle.posting_date) < getdate(existing_sle_posting_date):
val.sle_changed = True
self.distinct_item_warehouses[key] = val
self.new_items_found = True
- elif self.distinct_item_warehouses[key].get("reposting_status"):
- self.distinct_item_warehouses[key] = val
+ elif dependant_sle.voucher_detail_no not in set(dependent_voucher_detail_nos):
+ # Future dependent voucher needs to be repost to get the correct stock value
+ # If dependent voucher has not reposted, then add it to the list
+ dependent_voucher_detail_nos.append(dependant_sle.voucher_detail_no)
self.new_items_found = True
+ val.dependent_voucher_detail_nos = dependent_voucher_detail_nos
+ self.distinct_item_warehouses[key] = val
+
+ def get_dependent_voucher_detail_nos(self, key):
+ if "dependent_voucher_detail_nos" not in self.distinct_item_warehouses[key]:
+ self.distinct_item_warehouses[key].dependent_voucher_detail_nos = []
+
+ return self.distinct_item_warehouses[key].dependent_voucher_detail_nos
def process_sle(self, sle):
# previous sle data for this warehouse
@@ -1370,6 +1383,7 @@
"qty_after_transaction",
"posting_date",
"posting_time",
+ "voucher_detail_no",
"timestamp(posting_date, posting_time) as timestamp",
],
as_dict=1,