Merge pull request #39282 from ruthra-kumar/type_error_on_transaction_js
fix: possible typeerror on transaction.js
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index 82af85d..651599d 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -91,8 +91,8 @@
super(Account, self).on_update()
def onload(self):
- frozen_accounts_modifier = frappe.db.get_value(
- "Accounts Settings", "Accounts Settings", "frozen_accounts_modifier"
+ frozen_accounts_modifier = frappe.db.get_single_value(
+ "Accounts Settings", "frozen_accounts_modifier"
)
if not frozen_accounts_modifier or frozen_accounts_modifier in frappe.get_roles():
self.set_onload("can_freeze_account", True)
diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py
index 8d82123..1d6cb8e 100644
--- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py
+++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py
@@ -91,6 +91,7 @@
self.validate_duplicate_references()
self.allocate_payment_entries()
self.update_allocated_amount()
+ self.set_status()
def on_cancel(self):
for payment_entry in self.payment_entries:
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py
index 139f526..777a5bb 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.py
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py
@@ -435,8 +435,8 @@
def validate_frozen_account(account, adv_adj=None):
frozen_account = frappe.get_cached_value("Account", account, "freeze_account")
if frozen_account == "Yes" and not adv_adj:
- frozen_accounts_modifier = frappe.db.get_value(
- "Accounts Settings", None, "frozen_accounts_modifier"
+ frozen_accounts_modifier = frappe.db.get_single_value(
+ "Accounts Settings", "frozen_accounts_modifier"
)
if not frozen_accounts_modifier:
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index 18aa682..17293ad 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -527,7 +527,7 @@
values.extend(warehouses)
if items:
- condition = " and `tab{child_doc}`.{apply_on} in ({items})".format(
+ condition += " and `tab{child_doc}`.{apply_on} in ({items})".format(
child_doc=child_doctype, apply_on=apply_on, items=",".join(["%s"] * len(items))
)
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index e676560..5338054 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -552,7 +552,7 @@
self.against_expense_account = ",".join(against_accounts)
def po_required(self):
- if frappe.db.get_value("Buying Settings", None, "po_required") == "Yes":
+ if frappe.db.get_single_value("Buying Settings", "po_required") == "Yes":
if frappe.get_value(
"Supplier", self.supplier, "allow_purchase_invoice_creation_without_purchase_order"
@@ -572,7 +572,7 @@
def pr_required(self):
stock_items = self.get_stock_items()
- if frappe.db.get_value("Buying Settings", None, "pr_required") == "Yes":
+ if frappe.db.get_single_value("Buying Settings", "pr_required") == "Yes":
if frappe.get_value(
"Supplier", self.supplier, "allow_purchase_invoice_creation_without_purchase_receipt"
@@ -1104,17 +1104,6 @@
item=item,
)
)
-
- # update gross amount of asset bought through this document
- assets = frappe.db.get_all(
- "Asset", filters={"purchase_invoice": self.name, "item_code": item.item_code}
- )
- for asset in assets:
- frappe.db.set_value("Asset", asset.name, "gross_purchase_amount", flt(item.valuation_rate))
- frappe.db.set_value(
- "Asset", asset.name, "purchase_receipt_amount", flt(item.valuation_rate)
- )
-
if (
self.auto_accounting_for_stock
and self.is_opening == "No"
@@ -1156,17 +1145,24 @@
item.item_tax_amount, item.precision("item_tax_amount")
)
+ if item.is_fixed_asset and item.landed_cost_voucher_amount:
+ self.update_gross_purchase_amount_for_linked_assets(item)
+
+ def update_gross_purchase_amount_for_linked_assets(self, item):
assets = frappe.db.get_all(
"Asset",
filters={"purchase_invoice": self.name, "item_code": item.item_code},
fields=["name", "asset_quantity"],
)
for asset in assets:
+ purchase_amount = flt(item.valuation_rate) * asset.asset_quantity
frappe.db.set_value(
- "Asset", asset.name, "gross_purchase_amount", flt(item.valuation_rate) * asset.asset_quantity
- )
- frappe.db.set_value(
- "Asset", asset.name, "purchase_receipt_amount", flt(item.valuation_rate) * asset.asset_quantity
+ "Asset",
+ asset.name,
+ {
+ "gross_purchase_amount": purchase_amount,
+ "purchase_receipt_amount": purchase_amount,
+ },
)
def make_stock_adjustment_entry(
diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
index 8aa95bf..5acd8b0 100644
--- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -1237,8 +1237,8 @@
@change_settings("Accounts Settings", {"unlink_payment_on_cancellation_of_invoice": 1})
def test_gain_loss_with_advance_entry(self):
- unlink_enabled = frappe.db.get_value(
- "Accounts Settings", "Accounts Settings", "unlink_payment_on_cancel_of_invoice"
+ unlink_enabled = frappe.db.get_single_value(
+ "Accounts Settings", "unlink_payment_on_cancel_of_invoice"
)
frappe.db.set_single_value("Accounts Settings", "unlink_payment_on_cancel_of_invoice", 1)
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index c8d92d0..ba2cd82 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -898,8 +898,8 @@
frm.events.append_time_log(frm, timesheet, 1.0);
}
});
- frm.refresh_field("timesheets");
frm.trigger("calculate_timesheet_totals");
+ frm.refresh();
},
async get_exchange_rate(frm, from_currency, to_currency) {
diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py
index 91ba239..b48a8e6 100644
--- a/erpnext/accounts/general_ledger.py
+++ b/erpnext/accounts/general_ledger.py
@@ -654,10 +654,10 @@
Hence stop admin to bypass if accounts are freezed
"""
if not adv_adj:
- acc_frozen_upto = frappe.db.get_value("Accounts Settings", None, "acc_frozen_upto")
+ acc_frozen_upto = frappe.db.get_single_value("Accounts Settings", "acc_frozen_upto")
if acc_frozen_upto:
- frozen_accounts_modifier = frappe.db.get_value(
- "Accounts Settings", None, "frozen_accounts_modifier"
+ frozen_accounts_modifier = frappe.db.get_single_value(
+ "Accounts Settings", "frozen_accounts_modifier"
)
if getdate(posting_date) <= getdate(acc_frozen_upto) and (
frozen_accounts_modifier not in frappe.get_roles() or frappe.session.user == "Administrator"
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index 9feda11..3a70afc 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -55,8 +55,8 @@
def run(self, args):
self.filters.update(args)
self.set_defaults()
- self.party_naming_by = frappe.db.get_value(
- args.get("naming_by")[0], None, args.get("naming_by")[1]
+ self.party_naming_by = frappe.db.get_single_value(
+ args.get("naming_by")[0], args.get("naming_by")[1]
)
self.get_columns()
self.get_data()
diff --git a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
index 22b5c6b..0947cff 100644
--- a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
+++ b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
@@ -24,8 +24,8 @@
def run(self, args):
self.account_type = args.get("account_type")
self.party_type = get_party_types_from_account_type(self.account_type)
- self.party_naming_by = frappe.db.get_value(
- args.get("naming_by")[0], None, args.get("naming_by")[1]
+ self.party_naming_by = frappe.db.get_single_value(
+ args.get("naming_by")[0], args.get("naming_by")[1]
)
self.get_columns()
self.get_data(args)
diff --git a/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py b/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py
index 0464f99..a2c0f86 100644
--- a/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py
+++ b/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py
@@ -21,8 +21,8 @@
frappe.throw(_("From Date must be before To Date"))
self.filters.party_type = args.get("party_type")
- self.party_naming_by = frappe.db.get_value(
- args.get("naming_by")[0], None, args.get("naming_by")[1]
+ self.party_naming_by = frappe.db.get_single_value(
+ args.get("naming_by")[0], args.get("naming_by")[1]
)
self.get_gl_entries()
diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js
index 58fd6d4..02e7a9b 100644
--- a/erpnext/assets/doctype/asset/asset.js
+++ b/erpnext/assets/doctype/asset/asset.js
@@ -571,10 +571,16 @@
indicator: 'red'
});
}
- frm.set_value('gross_purchase_amount', item.base_net_rate + item.item_tax_amount);
- frm.set_value('purchase_receipt_amount', item.base_net_rate + item.item_tax_amount);
- item.asset_location && frm.set_value('location', item.asset_location);
+ var is_grouped_asset = frappe.db.get_value('Item', item.item_code, 'is_grouped_asset');
+ var asset_quantity = is_grouped_asset ? item.qty : 1;
+ var purchase_amount = flt(item.valuation_rate * asset_quantity, precision('gross_purchase_amount'));
+
+ frm.set_value('gross_purchase_amount', purchase_amount);
+ frm.set_value('purchase_receipt_amount', purchase_amount);
+ frm.set_value('asset_quantity', asset_quantity);
frm.set_value('cost_center', item.cost_center || purchase_doc.cost_center);
+ if(item.asset_location) { frm.set_value('location', item.asset_location); }
+
},
set_depreciation_rate: function(frm, row) {
diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py
index 66930c0..017df90 100644
--- a/erpnext/assets/doctype/asset/depreciation.py
+++ b/erpnext/assets/doctype/asset/depreciation.py
@@ -35,7 +35,7 @@
def post_depreciation_entries(date=None):
# Return if automatic booking of asset depreciation is disabled
if not cint(
- frappe.db.get_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically")
+ frappe.db.get_single_value("Accounts Settings", "book_asset_depreciation_entry_automatically")
):
return
diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.json b/erpnext/buying/doctype/buying_settings/buying_settings.json
index 3f8559e..b05de7d 100644
--- a/erpnext/buying/doctype/buying_settings/buying_settings.json
+++ b/erpnext/buying/doctype/buying_settings/buying_settings.json
@@ -214,7 +214,7 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
- "modified": "2023-11-28 13:01:18.403492",
+ "modified": "2024-01-05 15:26:02.320942",
"modified_by": "Administrator",
"module": "Buying",
"name": "Buying Settings",
@@ -238,6 +238,41 @@
"role": "Purchase Manager",
"share": 1,
"write": 1
+ },
+ {
+ "email": 1,
+ "print": 1,
+ "read": 1,
+ "role": "Accounts User",
+ "share": 1
+ },
+ {
+ "email": 1,
+ "print": 1,
+ "read": 1,
+ "role": "Accounts Manager",
+ "share": 1
+ },
+ {
+ "email": 1,
+ "print": 1,
+ "read": 1,
+ "role": "Stock Manager",
+ "share": 1
+ },
+ {
+ "email": 1,
+ "print": 1,
+ "read": 1,
+ "role": "Stock User",
+ "share": 1
+ },
+ {
+ "email": 1,
+ "print": 1,
+ "read": 1,
+ "role": "Purchase User",
+ "share": 1
}
],
"sort_field": "modified",
diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
index 9aaf86b..eec996c 100644
--- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
+++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
@@ -358,8 +358,8 @@
target_doc.currency = args.currency or get_party_account_currency(
"Supplier", for_supplier, source.company
)
- target_doc.buying_price_list = args.buying_price_list or frappe.db.get_value(
- "Buying Settings", None, "buying_price_list"
+ target_doc.buying_price_list = args.buying_price_list or frappe.db.get_single_value(
+ "Buying Settings", "buying_price_list"
)
set_missing_values(source, target_doc)
@@ -399,7 +399,7 @@
"currency": doc.get("currency")
or get_party_account_currency("Supplier", doc.get("supplier"), doc.get("company")),
"buying_price_list": doc.get("buying_price_list")
- or frappe.db.get_value("Buying Settings", None, "buying_price_list"),
+ or frappe.db.get_single_value("Buying Settings", "buying_price_list"),
}
)
add_items(sq_doc, doc.get("supplier"), doc.get("items"))
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 572fa51..fb68010 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -744,11 +744,8 @@
item_data = frappe.db.get_value(
"Item", row.item_code, ["asset_naming_series", "asset_category"], as_dict=1
)
-
- if is_grouped_asset:
- purchase_amount = flt(row.base_amount + row.item_tax_amount)
- else:
- purchase_amount = flt(row.base_rate + row.item_tax_amount)
+ asset_quantity = row.qty if is_grouped_asset else 1
+ purchase_amount = flt(row.valuation_rate) * asset_quantity
asset = frappe.get_doc(
{
@@ -764,7 +761,7 @@
"calculate_depreciation": 0,
"purchase_receipt_amount": purchase_amount,
"gross_purchase_amount": purchase_amount,
- "asset_quantity": row.qty if is_grouped_asset else 1,
+ "asset_quantity": asset_quantity,
"purchase_receipt": self.name if self.doctype == "Purchase Receipt" else None,
"purchase_invoice": self.name if self.doctype == "Purchase Invoice" else None,
}
diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py
index e7bd2a7..6e50279 100644
--- a/erpnext/controllers/sales_and_purchase_return.py
+++ b/erpnext/controllers/sales_and_purchase_return.py
@@ -10,7 +10,7 @@
import erpnext
from erpnext.stock.serial_batch_bundle import get_batches_from_bundle
from erpnext.stock.serial_batch_bundle import get_serial_nos as get_serial_nos_from_bundle
-from erpnext.stock.utils import get_incoming_rate
+from erpnext.stock.utils import get_incoming_rate, get_valuation_method
class StockOverReturnError(frappe.ValidationError):
@@ -116,7 +116,12 @@
ref = valid_items.get(d.item_code, frappe._dict())
validate_quantity(doc, d, ref, valid_items, already_returned_items)
- if ref.rate and doc.doctype in ("Delivery Note", "Sales Invoice") and flt(d.rate) > ref.rate:
+ if (
+ ref.rate
+ and flt(d.rate) > ref.rate
+ and doc.doctype in ("Delivery Note", "Sales Invoice")
+ and get_valuation_method(ref.item_code) != "Moving Average"
+ ):
frappe.throw(
_("Row # {0}: Rate cannot be greater than the rate used in {1} {2}").format(
d.idx, doc.doctype, doc.return_against
diff --git a/erpnext/crm/doctype/appointment/appointment.py b/erpnext/crm/doctype/appointment/appointment.py
index a735510..541f77b 100644
--- a/erpnext/crm/doctype/appointment/appointment.py
+++ b/erpnext/crm/doctype/appointment/appointment.py
@@ -76,7 +76,7 @@
self.create_calendar_event()
else:
# Set status to unverified
- self.status = "Unverified"
+ self.db_set("status", "Unverified")
# Send email to confirm
self.send_confirmation_email()
diff --git a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py
index 8ebca54..ba1fae9 100644
--- a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py
+++ b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py
@@ -129,9 +129,7 @@
self.default_cost_center, self.default_round_off_account = frappe.db.get_value(
"Company", self.erpnext_company, ["cost_center", "round_off_account"]
)
- self.default_warehouse = frappe.db.get_value(
- "Stock Settings", "Stock Settings", "default_warehouse"
- )
+ self.default_warehouse = frappe.db.get_single_value("Stock Settings", "default_warehouse")
def _process_master_data(self):
def get_company_name(collection):
diff --git a/erpnext/manufacturing/doctype/bom_update_log/bom_updation_utils.py b/erpnext/manufacturing/doctype/bom_update_log/bom_updation_utils.py
index a2919b7..f013b88 100644
--- a/erpnext/manufacturing/doctype/bom_update_log/bom_updation_utils.py
+++ b/erpnext/manufacturing/doctype/bom_update_log/bom_updation_utils.py
@@ -86,10 +86,12 @@
if new_bom == d.parent:
frappe.throw(_("BOM recursion: {0} cannot be child of {1}").format(new_bom, d.parent))
- bom_list.append(d.parent)
+ if d.parent not in tuple(bom_list):
+ bom_list.append(d.parent)
+
get_ancestor_boms(d.parent, bom_list)
- return list(set(bom_list))
+ return bom_list
def update_new_bom_in_bom_items(unit_cost: float, current_bom: str, new_bom: str) -> None:
diff --git a/erpnext/manufacturing/doctype/bom_update_log/test_bom_update_log.py b/erpnext/manufacturing/doctype/bom_update_log/test_bom_update_log.py
index b38fc89..30e6f5e 100644
--- a/erpnext/manufacturing/doctype/bom_update_log/test_bom_update_log.py
+++ b/erpnext/manufacturing/doctype/bom_update_log/test_bom_update_log.py
@@ -57,6 +57,68 @@
log.reload()
self.assertEqual(log.status, "Completed")
+ def test_bom_replace_for_root_bom(self):
+ """
+ - B-Item A (Root Item)
+ - B-Item B
+ - B-Item C
+ - B-Item D
+ - B-Item E
+ - B-Item F
+
+ Create New BOM for B-Item E with B-Item G and replace it in the above BOM.
+ """
+
+ from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
+ from erpnext.stock.doctype.item.test_item import make_item
+
+ items = ["B-Item A", "B-Item B", "B-Item C", "B-Item D", "B-Item E", "B-Item F", "B-Item G"]
+
+ for item_code in items:
+ if not frappe.db.exists("Item", item_code):
+ make_item(item_code)
+
+ for item_code in items:
+ remove_bom(item_code)
+
+ bom_tree = {
+ "B-Item A": {"B-Item B": {"B-Item C": {}}, "B-Item D": {"B-Item E": {"B-Item F": {}}}}
+ }
+
+ root_bom = create_nested_bom(bom_tree, prefix="")
+
+ exploded_items = frappe.get_all(
+ "BOM Explosion Item", filters={"parent": root_bom.name}, fields=["item_code"]
+ )
+
+ exploded_items = [item.item_code for item in exploded_items]
+ expected_exploded_items = ["B-Item C", "B-Item F"]
+ self.assertEqual(sorted(exploded_items), sorted(expected_exploded_items))
+
+ old_bom = frappe.db.get_value("BOM", {"item": "B-Item E"}, "name")
+ bom_tree = {"B-Item E": {"B-Item G": {}}}
+
+ new_bom = create_nested_bom(bom_tree, prefix="")
+ enqueue_replace_bom(boms=frappe._dict(current_bom=old_bom, new_bom=new_bom.name))
+
+ exploded_items = frappe.get_all(
+ "BOM Explosion Item", filters={"parent": root_bom.name}, fields=["item_code"]
+ )
+
+ exploded_items = [item.item_code for item in exploded_items]
+ expected_exploded_items = ["B-Item C", "B-Item G"]
+ self.assertEqual(sorted(exploded_items), sorted(expected_exploded_items))
+
+
+def remove_bom(item_code):
+ boms = frappe.get_all("BOM", fields=["docstatus", "name"], filters={"item": item_code})
+
+ for row in boms:
+ if row.docstatus == 1:
+ frappe.get_doc("BOM", row.name).cancel()
+
+ frappe.delete_doc("BOM", row.name)
+
def update_cost_in_all_boms_in_test():
"""
diff --git a/erpnext/manufacturing/doctype/workstation/workstation.py b/erpnext/manufacturing/doctype/workstation/workstation.py
index 0a247fc..0f05eaa 100644
--- a/erpnext/manufacturing/doctype/workstation/workstation.py
+++ b/erpnext/manufacturing/doctype/workstation/workstation.py
@@ -156,7 +156,7 @@
if not frappe.db.get_single_value("Manufacturing Settings", "allow_production_on_holidays"):
check_workstation_for_holiday(workstation, from_datetime, to_datetime)
- if not cint(frappe.db.get_value("Manufacturing Settings", None, "allow_overtime")):
+ if not cint(frappe.db.get_single_value("Manufacturing Settings", "allow_overtime")):
is_within_operating_hours(workstation, operation, from_datetime, to_datetime)
diff --git a/erpnext/patches/v13_0/modify_invalid_gain_loss_gl_entries.py b/erpnext/patches/v13_0/modify_invalid_gain_loss_gl_entries.py
index 0f77afd..8e58d79 100644
--- a/erpnext/patches/v13_0/modify_invalid_gain_loss_gl_entries.py
+++ b/erpnext/patches/v13_0/modify_invalid_gain_loss_gl_entries.py
@@ -45,7 +45,7 @@
message=json.dumps(purchase_invoices + sales_invoices, indent=2),
)
- acc_frozen_upto = frappe.db.get_value("Accounts Settings", None, "acc_frozen_upto")
+ acc_frozen_upto = frappe.db.get_single_value("Accounts Settings", "acc_frozen_upto")
if acc_frozen_upto:
frappe.db.set_single_value("Accounts Settings", "acc_frozen_upto", None)
diff --git a/erpnext/patches/v14_0/migrate_crm_settings.py b/erpnext/patches/v14_0/migrate_crm_settings.py
index 2477255..d093bc3 100644
--- a/erpnext/patches/v14_0/migrate_crm_settings.py
+++ b/erpnext/patches/v14_0/migrate_crm_settings.py
@@ -2,8 +2,7 @@
def execute():
- settings = frappe.db.get_value(
- "Selling Settings",
+ settings = frappe.db.get_single_value(
"Selling Settings",
["campaign_naming_by", "close_opportunity_after_days", "default_valid_till"],
as_dict=True,
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index d17d21c..382437f 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -370,18 +370,16 @@
def get_project_list(
doctype, txt, filters, limit_start, limit_page_length=20, order_by="modified"
):
- user = frappe.session.user
customers, suppliers = get_customers_suppliers("Project", frappe.session.user)
ignore_permissions = False
- if is_website_user():
+ if is_website_user() and frappe.session.user != "Guest":
if not filters:
filters = []
if customers:
filters.append([doctype, "customer", "in", customers])
-
- ignore_permissions = True
+ ignore_permissions = True
meta = frappe.get_meta(doctype)
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 09941ea..9542361 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -582,17 +582,17 @@
def set_indicator(self):
"""Set indicator for portal"""
- if self.per_billed < 100 and self.per_delivered < 100:
- self.indicator_color = "orange"
- self.indicator_title = _("Not Paid and Not Delivered")
+ self.indicator_color = {
+ "Draft": "red",
+ "On Hold": "orange",
+ "To Deliver and Bill": "orange",
+ "To Bill": "orange",
+ "To Deliver": "orange",
+ "Completed": "green",
+ "Cancelled": "red",
+ }.get(self.status, "blue")
- elif self.per_billed == 100 and self.per_delivered < 100:
- self.indicator_color = "orange"
- self.indicator_title = _("Paid and Not Delivered")
-
- else:
- self.indicator_color = "green"
- self.indicator_title = _("Paid")
+ self.indicator_title = _(self.status)
def on_recurring(self, reference_doc, auto_repeat_doc):
def _get_delivery_date(ref_doc_delivery_date, red_doc_transaction_date, transaction_date):
diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py
index a6c86a6..ac7fdb1 100644
--- a/erpnext/selling/doctype/sales_order/test_sales_order.py
+++ b/erpnext/selling/doctype/sales_order/test_sales_order.py
@@ -35,8 +35,8 @@
def setUpClass(cls):
super().setUpClass()
cls.unlink_setting = int(
- frappe.db.get_value(
- "Accounts Settings", "Accounts Settings", "unlink_advance_payment_on_cancelation_of_order"
+ frappe.db.get_single_value(
+ "Accounts Settings", "unlink_advance_payment_on_cancelation_of_order"
)
)
diff --git a/erpnext/selling/report/customer_credit_balance/customer_credit_balance.py b/erpnext/selling/report/customer_credit_balance/customer_credit_balance.py
index 98633cb..a584d3a 100644
--- a/erpnext/selling/report/customer_credit_balance/customer_credit_balance.py
+++ b/erpnext/selling/report/customer_credit_balance/customer_credit_balance.py
@@ -13,7 +13,7 @@
if not filters:
filters = {}
# Check if customer id is according to naming series or customer name
- customer_naming_type = frappe.db.get_value("Selling Settings", None, "cust_master_name")
+ customer_naming_type = frappe.db.get_single_value("Selling Settings", "cust_master_name")
columns = get_columns(customer_naming_type)
data = []
diff --git a/erpnext/startup/boot.py b/erpnext/startup/boot.py
index 4b4d14f..d2be1a0 100644
--- a/erpnext/startup/boot.py
+++ b/erpnext/startup/boot.py
@@ -9,8 +9,6 @@
def boot_session(bootinfo):
"""boot session - send website info if guest"""
- bootinfo.custom_css = frappe.db.get_value("Style Settings", None, "custom_css") or ""
-
if frappe.session["user"] != "Guest":
update_page_info(bootinfo)
diff --git a/erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.py b/erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.py
index f71d21d..1c70183 100644
--- a/erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.py
+++ b/erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.py
@@ -65,7 +65,7 @@
& (
(table.from_date.between(self.from_date, self.to_date))
| (table.to_date.between(self.from_date, self.to_date))
- | (table.from_date >= self.from_date and table.to_date <= self.to_date)
+ | (table.from_date >= self.from_date and table.to_date >= self.to_date)
)
)
)
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 2d9e11a..feb4583 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -635,8 +635,8 @@
def recalculate_bin_qty(self, new_name):
from erpnext.stock.stock_balance import repost_stock
- existing_allow_negative_stock = frappe.db.get_value(
- "Stock Settings", None, "allow_negative_stock"
+ existing_allow_negative_stock = frappe.db.get_single_value(
+ "Stock Settings", "allow_negative_stock"
)
frappe.db.set_single_value("Stock Settings", "allow_negative_stock", 1)
diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
index 30b26a0..b4f7708 100644
--- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
+++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
@@ -194,7 +194,8 @@
for d in self.get("purchase_receipts"):
doc = frappe.get_doc(d.receipt_document_type, d.receipt_document)
# check if there are {qty} assets created and linked to this receipt document
- self.validate_asset_qty_and_status(d.receipt_document_type, doc)
+ if self.docstatus != 2:
+ self.validate_asset_qty_and_status(d.receipt_document_type, doc)
# set landed cost voucher amount in pr item
doc.set_landed_cost_voucher_amount()
@@ -239,20 +240,20 @@
},
fields=["name", "docstatus"],
)
- if not docs or len(docs) != item.qty:
+ if not docs or len(docs) < item.qty:
frappe.throw(
_(
- "There are not enough asset created or linked to {0}. Please create or link {1} Assets with respective document."
- ).format(item.receipt_document, item.qty)
+ "There are only {0} asset created or linked to {1}. Please create or link {2} Assets with respective document."
+ ).format(len(docs), item.receipt_document, item.qty)
)
if docs:
for d in docs:
if d.docstatus == 1:
frappe.throw(
_(
- "{2} <b>{0}</b> has submitted Assets. Remove Item <b>{1}</b> from table to continue."
+ "{0} <b>{1}</b> has submitted Assets. Remove Item <b>{2}</b> from table to continue."
).format(
- item.receipt_document, item.item_code, item.receipt_document_type
+ item.receipt_document_type, item.receipt_document, item.item_code
)
)
diff --git a/erpnext/stock/doctype/price_list/price_list.py b/erpnext/stock/doctype/price_list/price_list.py
index 580c7c0..882c3f5 100644
--- a/erpnext/stock/doctype/price_list/price_list.py
+++ b/erpnext/stock/doctype/price_list/price_list.py
@@ -39,11 +39,11 @@
def set_default_if_missing(self):
if cint(self.selling):
- if not frappe.db.get_value("Selling Settings", None, "selling_price_list"):
+ if not frappe.db.get_single_value("Selling Settings", "selling_price_list"):
frappe.set_value("Selling Settings", "Selling Settings", "selling_price_list", self.name)
elif cint(self.buying):
- if not frappe.db.get_value("Buying Settings", None, "buying_price_list"):
+ if not frappe.db.get_single_value("Buying Settings", "buying_price_list"):
frappe.set_value("Buying Settings", "Buying Settings", "buying_price_list", self.name)
def update_item_price(self):
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index c7e36e9..6a92988 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -13,6 +13,7 @@
import erpnext
from erpnext.accounts.utils import get_account_currency
from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_enabled
+from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
from erpnext.buying.utils import check_on_hold_or_closed_status
from erpnext.controllers.buying_controller import BuyingController
from erpnext.stock.doctype.delivery_note.delivery_note import make_inter_company_transaction
@@ -302,7 +303,7 @@
)
def po_required(self):
- if frappe.db.get_value("Buying Settings", None, "po_required") == "Yes":
+ if frappe.db.get_single_value("Buying Settings", "po_required") == "Yes":
for d in self.get("items"):
if not d.purchase_order:
frappe.throw(_("Purchase Order number required for Item {0}").format(d.item_code))
@@ -674,15 +675,16 @@
landed_cost_entries = get_item_account_wise_additional_cost(self.name)
if d.is_fixed_asset:
- account_type = (
- "capital_work_in_progress_account"
- if is_cwip_accounting_enabled(d.asset_category)
- else "fixed_asset_account"
- )
-
- stock_asset_account_name = get_asset_account(
- account_type, asset_category=d.asset_category, company=self.company
- )
+ if is_cwip_accounting_enabled(d.asset_category):
+ stock_asset_account_name = get_asset_account(
+ "capital_work_in_progress_account",
+ asset_category=d.asset_category,
+ company=self.company,
+ )
+ else:
+ stock_asset_account_name = get_asset_category_account(
+ "fixed_asset_account", asset_category=d.asset_category, company=self.company
+ )
stock_value_diff = (
flt(d.base_net_amount)
@@ -719,7 +721,7 @@
):
warehouse_with_no_account.append(d.warehouse or d.rejected_warehouse)
- if d.is_fixed_asset:
+ if d.is_fixed_asset and d.landed_cost_voucher_amount:
self.update_assets(d, d.valuation_rate)
if warehouse_with_no_account:
@@ -852,11 +854,14 @@
)
for asset in assets:
+ purchase_amount = flt(valuation_rate) * asset.asset_quantity
frappe.db.set_value(
- "Asset", asset.name, "gross_purchase_amount", flt(valuation_rate) * asset.asset_quantity
- )
- frappe.db.set_value(
- "Asset", asset.name, "purchase_receipt_amount", flt(valuation_rate) * asset.asset_quantity
+ "Asset",
+ asset.name,
+ {
+ "gross_purchase_amount": purchase_amount,
+ "purchase_receipt_amount": purchase_amount,
+ },
)
def update_status(self, status):
diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
index 79b8ee3..112c226 100644
--- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
+++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
@@ -140,12 +140,7 @@
return query[0][0] if query else None
def validate_accounts_freeze(self):
- acc_settings = frappe.db.get_value(
- "Accounts Settings",
- "Accounts Settings",
- ["acc_frozen_upto", "frozen_accounts_modifier"],
- as_dict=1,
- )
+ acc_settings = frappe.get_cached_doc("Account Settings")
if not acc_settings.acc_frozen_upto:
return
if getdate(self.posting_date) <= getdate(acc_settings.acc_frozen_upto):
@@ -224,7 +219,7 @@
transaction_status = frappe.db.get_value(self.voucher_type, self.voucher_no, "docstatus")
if transaction_status == 2:
- msg = _("Cannot cancel as processing of cancelled documents is pending.")
+ msg = _("Cannot cancel as processing of cancelled documents is pending.")
msg += "<br>" + _("Please try again in an hour.")
frappe.throw(msg, title=_("Pending processing"))
diff --git a/erpnext/stock/reorder_item.py b/erpnext/stock/reorder_item.py
index a6f52f3..4cd9cbb 100644
--- a/erpnext/stock/reorder_item.py
+++ b/erpnext/stock/reorder_item.py
@@ -18,7 +18,7 @@
if not (frappe.db.a_row_exists("Company") and frappe.db.a_row_exists("Fiscal Year")):
return
- if cint(frappe.db.get_value("Stock Settings", None, "auto_indent")):
+ if cint(frappe.db.get_single_value("Stock Settings", "auto_indent")):
return _reorder_item()
@@ -212,7 +212,7 @@
if mr_list:
if getattr(frappe.local, "reorder_email_notify", None) is None:
frappe.local.reorder_email_notify = cint(
- frappe.db.get_value("Stock Settings", None, "reorder_email_notify")
+ frappe.db.get_single_value("Stock Settings", "reorder_email_notify")
)
if frappe.local.reorder_email_notify:
diff --git a/erpnext/stock/stock_balance.py b/erpnext/stock/stock_balance.py
index a4fe2ee..ba03ff2 100644
--- a/erpnext/stock/stock_balance.py
+++ b/erpnext/stock/stock_balance.py
@@ -15,8 +15,8 @@
frappe.db.auto_commit_on_many_writes = 1
if allow_negative_stock:
- existing_allow_negative_stock = frappe.db.get_value(
- "Stock Settings", None, "allow_negative_stock"
+ existing_allow_negative_stock = frappe.db.get_single_value(
+ "Stock Settings", "allow_negative_stock"
)
frappe.db.set_single_value("Stock Settings", "allow_negative_stock", 1)
diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py
index 4b0e284..f29e7ea 100644
--- a/erpnext/stock/utils.py
+++ b/erpnext/stock/utils.py
@@ -338,7 +338,7 @@
val_method = frappe.db.get_value("Item", item_code, "valuation_method", cache=True)
if not val_method:
val_method = (
- frappe.db.get_value("Stock Settings", None, "valuation_method", cache=True) or "FIFO"
+ frappe.db.get_single_value("Stock Settings", "valuation_method", cache=True) or "FIFO"
)
return val_method
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index c03fb3e..dc1529b 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -230,7 +230,7 @@
def auto_close_tickets():
"""Auto-close replied support tickets after 7 days"""
auto_close_after_days = (
- frappe.db.get_value("Support Settings", "Support Settings", "close_issue_after_days") or 7
+ frappe.db.get_single_value("Support Settings", "close_issue_after_days") or 7
)
table = frappe.qb.DocType("Issue")
diff --git a/erpnext/utilities/doctype/video/video.py b/erpnext/utilities/doctype/video/video.py
index 1a9fe19..c3a653a 100644
--- a/erpnext/utilities/doctype/video/video.py
+++ b/erpnext/utilities/doctype/video/video.py
@@ -78,9 +78,8 @@
def update_youtube_data():
# Called every 30 minutes via hooks
- enable_youtube_tracking, frequency = frappe.db.get_value(
- "Video Settings", "Video Settings", ["enable_youtube_tracking", "frequency"]
- )
+ enable_youtube_tracking = frappe.db.get_single_value("Video Settings", "enable_youtube_tracking")
+ frequency = frappe.db.get_single_value("Video Settings", "frequency")
if not cint(enable_youtube_tracking):
return