Compare commits
28 Commits
v14.39.0
...
develop-ri
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e475a152c9 | ||
|
|
d070f48e44 | ||
|
|
1cb9d45823 | ||
|
|
46f94cf387 | ||
|
|
79321f56ca | ||
|
|
18702841af | ||
|
|
8b2328c6d3 | ||
|
|
13aaff30a5 | ||
|
|
a563fed6dc | ||
|
|
19a227a970 | ||
|
|
727dcc5034 | ||
|
|
89b570ecf5 | ||
|
|
b33db6c79a | ||
|
|
e5177a6e46 | ||
|
|
fffa13f22b | ||
|
|
f2395a9297 | ||
|
|
3ecdf028f2 | ||
|
|
8772e40bae | ||
|
|
b56c9b91f1 | ||
|
|
c2a0c1e989 | ||
|
|
461b607a6a | ||
|
|
9bc44a3b40 | ||
|
|
50cfc68d2c | ||
|
|
aa0a756111 | ||
|
|
413b40f5a7 | ||
|
|
b56e3b3f1a | ||
|
|
65a5eff6fd | ||
|
|
3b25ee4e6a |
@@ -3,7 +3,7 @@ import inspect
|
||||
|
||||
import frappe
|
||||
|
||||
__version__ = "14.39.0"
|
||||
__version__ = "14.34.3"
|
||||
|
||||
|
||||
def get_default_company(user=None):
|
||||
|
||||
@@ -56,36 +56,41 @@ frappe.treeview_settings["Account"] = {
|
||||
accounts = nodes;
|
||||
}
|
||||
|
||||
const get_balances = frappe.call({
|
||||
method: 'erpnext.accounts.utils.get_account_balances',
|
||||
args: {
|
||||
accounts: accounts,
|
||||
company: cur_tree.args.company
|
||||
},
|
||||
});
|
||||
frappe.db.get_single_value("Accounts Settings", "show_balance_in_coa").then((value) => {
|
||||
if(value) {
|
||||
|
||||
get_balances.then(r => {
|
||||
if (!r.message || r.message.length == 0) return;
|
||||
const get_balances = frappe.call({
|
||||
method: 'erpnext.accounts.utils.get_account_balances',
|
||||
args: {
|
||||
accounts: accounts,
|
||||
company: cur_tree.args.company
|
||||
},
|
||||
});
|
||||
|
||||
for (let account of r.message) {
|
||||
get_balances.then(r => {
|
||||
if (!r.message || r.message.length == 0) return;
|
||||
|
||||
const node = cur_tree.nodes && cur_tree.nodes[account.value];
|
||||
if (!node || node.is_root) continue;
|
||||
for (let account of r.message) {
|
||||
|
||||
// show Dr if positive since balance is calculated as debit - credit else show Cr
|
||||
const balance = account.balance_in_account_currency || account.balance;
|
||||
const dr_or_cr = balance > 0 ? "Dr": "Cr";
|
||||
const format = (value, currency) => format_currency(Math.abs(value), currency);
|
||||
const node = cur_tree.nodes && cur_tree.nodes[account.value];
|
||||
if (!node || node.is_root) continue;
|
||||
|
||||
if (account.balance!==undefined) {
|
||||
node.parent && node.parent.find('.balance-area').remove();
|
||||
$('<span class="balance-area pull-right">'
|
||||
+ (account.balance_in_account_currency ?
|
||||
(format(account.balance_in_account_currency, account.account_currency) + " / ") : "")
|
||||
+ format(account.balance, account.company_currency)
|
||||
+ " " + dr_or_cr
|
||||
+ '</span>').insertBefore(node.$ul);
|
||||
}
|
||||
// show Dr if positive since balance is calculated as debit - credit else show Cr
|
||||
const balance = account.balance_in_account_currency || account.balance;
|
||||
const dr_or_cr = balance > 0 ? "Dr": "Cr";
|
||||
const format = (value, currency) => format_currency(Math.abs(value), currency);
|
||||
|
||||
if (account.balance!==undefined) {
|
||||
node.parent && node.parent.find('.balance-area').remove();
|
||||
$('<span class="balance-area pull-right">'
|
||||
+ (account.balance_in_account_currency ?
|
||||
(format(account.balance_in_account_currency, account.account_currency) + " / ") : "")
|
||||
+ format(account.balance, account.company_currency)
|
||||
+ " " + dr_or_cr
|
||||
+ '</span>').insertBefore(node.$ul);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -66,7 +66,9 @@
|
||||
"report_settings_sb",
|
||||
"banking_tab",
|
||||
"enable_party_matching",
|
||||
"enable_fuzzy_matching"
|
||||
"enable_fuzzy_matching",
|
||||
"tab_break_dpet",
|
||||
"show_balance_in_coa"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -416,6 +418,17 @@
|
||||
"fieldname": "ignore_account_closing_balance",
|
||||
"fieldtype": "Check",
|
||||
"label": "Ignore Account Closing Balance"
|
||||
},
|
||||
{
|
||||
"fieldname": "tab_break_dpet",
|
||||
"fieldtype": "Tab Break",
|
||||
"label": "Chart Of Accounts"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "show_balance_in_coa",
|
||||
"fieldtype": "Check",
|
||||
"label": "Show Balances in Chart Of Accounts"
|
||||
}
|
||||
],
|
||||
"icon": "icon-cog",
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
import collections
|
||||
|
||||
import frappe
|
||||
@@ -43,7 +45,6 @@ class POSInvoice(SalesInvoice):
|
||||
self.validate_debit_to_acc()
|
||||
self.validate_write_off_account()
|
||||
self.validate_change_amount()
|
||||
self.validate_duplicate_serial_and_batch_no()
|
||||
self.validate_change_account()
|
||||
self.validate_item_cost_centers()
|
||||
self.validate_warehouse()
|
||||
@@ -56,6 +57,7 @@ class POSInvoice(SalesInvoice):
|
||||
self.validate_payment_amount()
|
||||
self.validate_loyalty_transaction()
|
||||
self.validate_company_with_pos_company()
|
||||
self.validate_duplicate_serial_no()
|
||||
if self.coupon_code:
|
||||
from erpnext.accounts.doctype.pricing_rule.utils import validate_coupon_code
|
||||
|
||||
@@ -156,27 +158,18 @@ class POSInvoice(SalesInvoice):
|
||||
title=_("Item Unavailable"),
|
||||
)
|
||||
|
||||
def validate_duplicate_serial_and_batch_no(self):
|
||||
def validate_duplicate_serial_no(self):
|
||||
serial_nos = []
|
||||
batch_nos = []
|
||||
|
||||
for row in self.get("items"):
|
||||
if row.serial_no:
|
||||
serial_nos = row.serial_no.split("\n")
|
||||
|
||||
if row.batch_no and not row.serial_no:
|
||||
batch_nos.append(row.batch_no)
|
||||
|
||||
if serial_nos:
|
||||
for key, value in collections.Counter(serial_nos).items():
|
||||
if value > 1:
|
||||
frappe.throw(_("Duplicate Serial No {0} found").format("key"))
|
||||
|
||||
if batch_nos:
|
||||
for key, value in collections.Counter(batch_nos).items():
|
||||
if value > 1:
|
||||
frappe.throw(_("Duplicate Batch No {0} found").format("key"))
|
||||
|
||||
def validate_pos_reserved_batch_qty(self, item):
|
||||
filters = {"item_code": item.item_code, "warehouse": item.warehouse, "batch_no": item.batch_no}
|
||||
|
||||
|
||||
@@ -464,6 +464,37 @@ class TestPOSInvoice(unittest.TestCase):
|
||||
pos2.insert()
|
||||
self.assertRaises(frappe.ValidationError, pos2.submit)
|
||||
|
||||
def test_pos_invoice_with_duplicate_serial_no(self):
|
||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item
|
||||
|
||||
se = make_serialized_item(
|
||||
company="_Test Company",
|
||||
target_warehouse="Stores - _TC",
|
||||
cost_center="Main - _TC",
|
||||
expense_account="Cost of Goods Sold - _TC",
|
||||
)
|
||||
|
||||
serial_nos = get_serial_nos(se.get("items")[0].serial_no)
|
||||
|
||||
pos = create_pos_invoice(
|
||||
company="_Test Company",
|
||||
debit_to="Debtors - _TC",
|
||||
account_for_change_amount="Cash - _TC",
|
||||
warehouse="Stores - _TC",
|
||||
income_account="Sales - _TC",
|
||||
expense_account="Cost of Goods Sold - _TC",
|
||||
cost_center="Main - _TC",
|
||||
item=se.get("items")[0].item_code,
|
||||
rate=1000,
|
||||
qty=2,
|
||||
do_not_save=1,
|
||||
)
|
||||
|
||||
pos.get("items")[0].has_serial_no = 1
|
||||
pos.get("items")[0].serial_no = serial_nos[0] + "\n" + serial_nos[0]
|
||||
self.assertRaises(frappe.ValidationError, pos.submit)
|
||||
|
||||
def test_invalid_serial_no_validation(self):
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item
|
||||
|
||||
|
||||
@@ -1153,7 +1153,7 @@ class TestPurchaseInvoice(unittest.TestCase, StockTestMixin):
|
||||
|
||||
item = create_item("_Test Item for Deferred Accounting", is_purchase_item=True)
|
||||
item.enable_deferred_expense = 1
|
||||
item.deferred_expense_account = deferred_account
|
||||
item.item_defaults[0].deferred_expense_account = deferred_account
|
||||
item.save()
|
||||
|
||||
pi = make_purchase_invoice(item=item.name, qty=1, rate=100, do_not_save=True)
|
||||
|
||||
@@ -15,9 +15,11 @@ def get_data():
|
||||
},
|
||||
"internal_links": {
|
||||
"Sales Order": ["items", "sales_order"],
|
||||
"Delivery Note": ["items", "delivery_note"],
|
||||
"Timesheet": ["timesheets", "time_sheet"],
|
||||
},
|
||||
"internal_and_external_links": {
|
||||
"Delivery Note": ["items", "delivery_note"],
|
||||
},
|
||||
"transactions": [
|
||||
{
|
||||
"label": _("Payment"),
|
||||
|
||||
@@ -2322,7 +2322,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
item = create_item("_Test Item for Deferred Accounting")
|
||||
item.enable_deferred_revenue = 1
|
||||
item.deferred_revenue_account = deferred_account
|
||||
item.item_defaults[0].deferred_revenue_account = deferred_account
|
||||
item.no_of_months = 12
|
||||
item.save()
|
||||
|
||||
@@ -3102,7 +3102,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
item = create_item("_Test Item for Deferred Accounting")
|
||||
item.enable_deferred_expense = 1
|
||||
item.deferred_revenue_account = deferred_account
|
||||
item.item_defaults[0].deferred_revenue_account = deferred_account
|
||||
item.save()
|
||||
|
||||
si = create_sales_invoice(
|
||||
|
||||
@@ -81,7 +81,7 @@ class TestDeferredRevenueAndExpense(FrappeTestCase, AccountsTestMixin):
|
||||
self.create_item("_Test Internet Subscription", 0, self.warehouse, self.company)
|
||||
item = frappe.get_doc("Item", self.item)
|
||||
item.enable_deferred_revenue = 1
|
||||
item.deferred_revenue_account = self.deferred_revenue_account
|
||||
item.item_defaults[0].deferred_revenue_account = self.deferred_revenue_account
|
||||
item.no_of_months = 3
|
||||
item.save()
|
||||
|
||||
@@ -150,7 +150,7 @@ class TestDeferredRevenueAndExpense(FrappeTestCase, AccountsTestMixin):
|
||||
self.create_item("_Test Office Desk", 0, self.warehouse, self.company)
|
||||
item = frappe.get_doc("Item", self.item)
|
||||
item.enable_deferred_expense = 1
|
||||
item.deferred_expense_account = self.deferred_expense_account
|
||||
item.item_defaults[0].deferred_expense_account = self.deferred_expense_account
|
||||
item.no_of_months_exp = 3
|
||||
item.save()
|
||||
|
||||
|
||||
@@ -272,20 +272,19 @@ def get_conditions(filters):
|
||||
if match_conditions:
|
||||
conditions.append(match_conditions)
|
||||
|
||||
if filters.get("include_dimensions"):
|
||||
accounting_dimensions = get_accounting_dimensions(as_list=False)
|
||||
accounting_dimensions = get_accounting_dimensions(as_list=False)
|
||||
|
||||
if accounting_dimensions:
|
||||
for dimension in accounting_dimensions:
|
||||
if not dimension.disabled:
|
||||
if filters.get(dimension.fieldname):
|
||||
if frappe.get_cached_value("DocType", dimension.document_type, "is_tree"):
|
||||
filters[dimension.fieldname] = get_dimension_with_children(
|
||||
dimension.document_type, filters.get(dimension.fieldname)
|
||||
)
|
||||
conditions.append("{0} in %({0})s".format(dimension.fieldname))
|
||||
else:
|
||||
conditions.append("{0} in %({0})s".format(dimension.fieldname))
|
||||
if accounting_dimensions:
|
||||
for dimension in accounting_dimensions:
|
||||
if not dimension.disabled:
|
||||
if filters.get(dimension.fieldname):
|
||||
if frappe.get_cached_value("DocType", dimension.document_type, "is_tree"):
|
||||
filters[dimension.fieldname] = get_dimension_with_children(
|
||||
dimension.document_type, filters.get(dimension.fieldname)
|
||||
)
|
||||
conditions.append("{0} in %({0})s".format(dimension.fieldname))
|
||||
else:
|
||||
conditions.append("{0} in %({0})s".format(dimension.fieldname))
|
||||
|
||||
return "and {}".format(" and ".join(conditions)) if conditions else ""
|
||||
|
||||
|
||||
@@ -1171,6 +1171,7 @@
|
||||
"depends_on": "is_internal_supplier",
|
||||
"fieldname": "set_from_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Set From Warehouse",
|
||||
"options": "Warehouse"
|
||||
},
|
||||
@@ -1271,7 +1272,7 @@
|
||||
"idx": 105,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2023-05-24 11:16:41.195340",
|
||||
"modified": "2023-09-13 16:21:07.361700",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order",
|
||||
|
||||
@@ -878,6 +878,7 @@
|
||||
"depends_on": "eval:parent.is_internal_supplier",
|
||||
"fieldname": "from_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "From Warehouse",
|
||||
"options": "Warehouse"
|
||||
},
|
||||
@@ -902,7 +903,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2022-11-29 16:47:41.364387",
|
||||
"modified": "2023-09-13 16:22:40.825092",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order Item",
|
||||
|
||||
@@ -195,6 +195,9 @@ class TestSupplier(FrappeTestCase):
|
||||
def create_supplier(**args):
|
||||
args = frappe._dict(args)
|
||||
|
||||
if not args.supplier_name:
|
||||
args.supplier_name = frappe.generate_hash()
|
||||
|
||||
if frappe.db.exists("Supplier", args.supplier_name):
|
||||
return frappe.get_doc("Supplier", args.supplier_name)
|
||||
|
||||
@@ -202,6 +205,7 @@ def create_supplier(**args):
|
||||
{
|
||||
"doctype": "Supplier",
|
||||
"supplier_name": args.supplier_name,
|
||||
"default_currency": args.default_currency,
|
||||
"supplier_group": args.supplier_group or "Services",
|
||||
"supplier_type": args.supplier_type or "Company",
|
||||
"tax_withholding_category": args.tax_withholding_category,
|
||||
|
||||
@@ -7,7 +7,7 @@ import copy
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.query_builder.functions import Coalesce, Sum
|
||||
from frappe.utils import date_diff, flt, getdate
|
||||
from frappe.utils import cint, date_diff, flt, getdate
|
||||
|
||||
|
||||
def execute(filters=None):
|
||||
@@ -47,8 +47,10 @@ def get_data(filters):
|
||||
mr.transaction_date.as_("date"),
|
||||
mr_item.schedule_date.as_("required_date"),
|
||||
mr_item.item_code.as_("item_code"),
|
||||
Sum(Coalesce(mr_item.stock_qty, 0)).as_("qty"),
|
||||
Coalesce(mr_item.stock_uom, "").as_("uom"),
|
||||
Sum(Coalesce(mr_item.qty, 0)).as_("qty"),
|
||||
Sum(Coalesce(mr_item.stock_qty, 0)).as_("stock_qty"),
|
||||
Coalesce(mr_item.uom, "").as_("uom"),
|
||||
Coalesce(mr_item.stock_uom, "").as_("stock_uom"),
|
||||
Sum(Coalesce(mr_item.ordered_qty, 0)).as_("ordered_qty"),
|
||||
Sum(Coalesce(mr_item.received_qty, 0)).as_("received_qty"),
|
||||
(Sum(Coalesce(mr_item.stock_qty, 0)) - Sum(Coalesce(mr_item.received_qty, 0))).as_(
|
||||
@@ -96,7 +98,7 @@ def get_conditions(filters, query, mr, mr_item):
|
||||
|
||||
|
||||
def update_qty_columns(row_to_update, data_row):
|
||||
fields = ["qty", "ordered_qty", "received_qty", "qty_to_receive", "qty_to_order"]
|
||||
fields = ["qty", "stock_qty", "ordered_qty", "received_qty", "qty_to_receive", "qty_to_order"]
|
||||
for field in fields:
|
||||
row_to_update[field] += flt(data_row[field])
|
||||
|
||||
@@ -104,16 +106,20 @@ def update_qty_columns(row_to_update, data_row):
|
||||
def prepare_data(data, filters):
|
||||
"""Prepare consolidated Report data and Chart data"""
|
||||
material_request_map, item_qty_map = {}, {}
|
||||
precision = cint(frappe.db.get_default("float_precision")) or 2
|
||||
|
||||
for row in data:
|
||||
# item wise map for charts
|
||||
if not row["item_code"] in item_qty_map:
|
||||
item_qty_map[row["item_code"]] = {
|
||||
"qty": row["qty"],
|
||||
"ordered_qty": row["ordered_qty"],
|
||||
"received_qty": row["received_qty"],
|
||||
"qty_to_receive": row["qty_to_receive"],
|
||||
"qty_to_order": row["qty_to_order"],
|
||||
"qty": flt(row["stock_qty"], precision),
|
||||
"stock_qty": flt(row["stock_qty"], precision),
|
||||
"stock_uom": row["stock_uom"],
|
||||
"uom": row["uom"],
|
||||
"ordered_qty": flt(row["ordered_qty"], precision),
|
||||
"received_qty": flt(row["received_qty"], precision),
|
||||
"qty_to_receive": flt(row["qty_to_receive"], precision),
|
||||
"qty_to_order": flt(row["qty_to_order"], precision),
|
||||
}
|
||||
else:
|
||||
item_entry = item_qty_map[row["item_code"]]
|
||||
@@ -200,21 +206,34 @@ def get_columns(filters):
|
||||
{"label": _("Item Name"), "fieldname": "item_name", "fieldtype": "Data", "width": 100},
|
||||
{"label": _("Description"), "fieldname": "description", "fieldtype": "Data", "width": 200},
|
||||
{
|
||||
"label": _("Stock UOM"),
|
||||
"label": _("UOM"),
|
||||
"fieldname": "uom",
|
||||
"fieldtype": "Data",
|
||||
"width": 100,
|
||||
},
|
||||
{
|
||||
"label": _("Stock UOM"),
|
||||
"fieldname": "stock_uom",
|
||||
"fieldtype": "Data",
|
||||
"width": 100,
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
columns.extend(
|
||||
[
|
||||
{
|
||||
"label": _("Stock Qty"),
|
||||
"label": _("Qty"),
|
||||
"fieldname": "qty",
|
||||
"fieldtype": "Float",
|
||||
"width": 120,
|
||||
"width": 140,
|
||||
"convertible": "qty",
|
||||
},
|
||||
{
|
||||
"label": _("Qty in Stock UOM"),
|
||||
"fieldname": "stock_qty",
|
||||
"fieldtype": "Float",
|
||||
"width": 140,
|
||||
"convertible": "qty",
|
||||
},
|
||||
{
|
||||
|
||||
@@ -162,10 +162,13 @@ class BuyingController(SubcontractingController):
|
||||
purchase_doc_field = (
|
||||
"purchase_receipt" if self.doctype == "Purchase Receipt" else "purchase_invoice"
|
||||
)
|
||||
not_cancelled_asset = [
|
||||
d.name
|
||||
for d in frappe.db.get_all("Asset", {purchase_doc_field: self.return_against, "docstatus": 1})
|
||||
]
|
||||
not_cancelled_asset = []
|
||||
if self.return_against:
|
||||
not_cancelled_asset = [
|
||||
d.name
|
||||
for d in frappe.db.get_all("Asset", {purchase_doc_field: self.return_against, "docstatus": 1})
|
||||
]
|
||||
|
||||
if self.is_return and len(not_cancelled_asset):
|
||||
frappe.throw(
|
||||
_(
|
||||
|
||||
@@ -634,7 +634,6 @@ def get_applicable_shipping_rules(party=None, quotation=None):
|
||||
shipping_rules = get_shipping_rules(quotation)
|
||||
|
||||
if shipping_rules:
|
||||
rule_label_map = frappe.db.get_values("Shipping Rule", shipping_rules, "label")
|
||||
# we need this in sorted order as per the position of the rule in the settings page
|
||||
return [[rule, rule] for rule in shipping_rules]
|
||||
|
||||
|
||||
@@ -339,5 +339,6 @@ erpnext.patches.v14_0.update_closing_balances #15-07-2023
|
||||
execute:frappe.defaults.clear_default("fiscal_year")
|
||||
execute:frappe.db.set_single_value('Selling Settings', 'allow_negative_rates_for_items', 0)
|
||||
erpnext.patches.v14_0.correct_asset_value_if_je_with_workflow
|
||||
erpnext.patches.v14_0.migrate_deferred_accounts_to_item_defaults
|
||||
# below migration patch should always run last
|
||||
erpnext.patches.v14_0.migrate_gl_to_payment_ledger
|
||||
|
||||
@@ -46,6 +46,17 @@ def execute():
|
||||
for doctype in doctypes:
|
||||
frappe.delete_doc("DocType", doctype, ignore_missing=True)
|
||||
|
||||
titles = [
|
||||
"Fees",
|
||||
"Student Admission",
|
||||
"Grant Application",
|
||||
"Chapter",
|
||||
"Certification Application",
|
||||
]
|
||||
items = frappe.get_all("Portal Menu Item", filters=[["title", "in", titles]], pluck="name")
|
||||
for item in items:
|
||||
frappe.delete_doc("Portal Menu Item", item, ignore_missing=True, force=True)
|
||||
|
||||
frappe.delete_doc("Module Def", "Education", ignore_missing=True, force=True)
|
||||
|
||||
click.secho(
|
||||
|
||||
@@ -41,7 +41,7 @@ def execute():
|
||||
for card in cards:
|
||||
frappe.delete_doc("Number Card", card, ignore_missing=True, force=True)
|
||||
|
||||
titles = ["Lab Test", "Prescription", "Patient Appointment"]
|
||||
titles = ["Lab Test", "Prescription", "Patient Appointment", "Patient"]
|
||||
items = frappe.get_all("Portal Menu Item", filters=[["title", "in", titles]], pluck="name")
|
||||
for item in items:
|
||||
frappe.delete_doc("Portal Menu Item", item, ignore_missing=True, force=True)
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import frappe
|
||||
|
||||
|
||||
def execute():
|
||||
try:
|
||||
item_dict = get_deferred_accounts()
|
||||
add_to_item_defaults(item_dict)
|
||||
except Exception:
|
||||
frappe.db.rollback()
|
||||
frappe.log_error("Failed to migrate deferred accounts in Item Defaults.")
|
||||
|
||||
|
||||
def get_deferred_accounts():
|
||||
item = frappe.qb.DocType("Item")
|
||||
return (
|
||||
frappe.qb.from_(item)
|
||||
.select(item.name, item.deferred_expense_account, item.deferred_revenue_account)
|
||||
.where((item.enable_deferred_expense == 1) | (item.enable_deferred_revenue == 1))
|
||||
.run(as_dict=True)
|
||||
)
|
||||
|
||||
|
||||
def add_to_item_defaults(item_dict):
|
||||
for item in item_dict:
|
||||
add_company_wise_item_default(item, "deferred_expense_account")
|
||||
add_company_wise_item_default(item, "deferred_revenue_account")
|
||||
|
||||
|
||||
def add_company_wise_item_default(item, account_type):
|
||||
company = frappe.get_cached_value("Account", item[account_type], "company")
|
||||
if company and item[account_type]:
|
||||
item_defaults = frappe.get_cached_value("Item", item["name"], "item_defaults")
|
||||
for item_row in item_defaults:
|
||||
if item_row.company == company:
|
||||
frappe.set_value("Item Default", item_row.name, account_type, item[account_type])
|
||||
break
|
||||
else:
|
||||
item_defaults.append({"company": company, account_type: item[account_type]})
|
||||
frappe.set_value("Item", item["name"], "item_defaults", item_defaults)
|
||||
@@ -119,19 +119,10 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
}
|
||||
});
|
||||
|
||||
if(this.frm.fields_dict["items"].grid.get_field('batch_no')) {
|
||||
this.frm.set_query("batch_no", "items", function(doc, cdt, cdn) {
|
||||
if(this.frm.fields_dict['items'].grid.get_field('batch_no')) {
|
||||
this.frm.set_query('batch_no', 'items', function(doc, cdt, cdn) {
|
||||
return me.set_query_for_batch(doc, cdt, cdn);
|
||||
});
|
||||
|
||||
let batch_field = this.frm.get_docfield('items', 'batch_no');
|
||||
if (batch_field) {
|
||||
batch_field.get_route_options_for_new_doc = (row) => {
|
||||
return {
|
||||
'item': row.doc.item_code
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if(
|
||||
@@ -196,14 +187,6 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
});
|
||||
}
|
||||
|
||||
let batch_no_field = this.frm.get_docfield("items", "batch_no");
|
||||
if (batch_no_field) {
|
||||
batch_no_field.get_route_options_for_new_doc = function(row) {
|
||||
return {
|
||||
"item": row.doc.item_code
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (this.frm.fields_dict["items"].grid.get_field('blanket_order')) {
|
||||
this.frm.set_query("blanket_order", "items", function(doc, cdt, cdn) {
|
||||
@@ -257,6 +240,17 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
if(this.frm.fields_dict['items'].grid.get_field('batch_no')) {
|
||||
let batch_field = this.frm.get_docfield('items', 'batch_no');
|
||||
if (batch_field) {
|
||||
batch_field.get_route_options_for_new_doc = (row) => {
|
||||
return {
|
||||
'item': row.doc.item_code
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is_return() {
|
||||
|
||||
@@ -1998,6 +1998,61 @@ class TestSalesOrder(FrappeTestCase):
|
||||
self.assertEqual(len(dn.packed_items), 1)
|
||||
self.assertEqual(dn.items[0].item_code, "_Test Product Bundle Item Partial 2")
|
||||
|
||||
@change_settings("Selling Settings", {"editable_bundle_item_rates": 1})
|
||||
def test_expired_rate_for_packed_item(self):
|
||||
bundle = "_Test Product Bundle 1"
|
||||
packed_item = "_Packed Item 1"
|
||||
|
||||
# test Update Items with product bundle
|
||||
for product_bundle in [bundle]:
|
||||
if not frappe.db.exists("Item", product_bundle):
|
||||
bundle_item = make_item(product_bundle, {"is_stock_item": 0})
|
||||
bundle_item.append(
|
||||
"item_defaults", {"company": "_Test Company", "default_warehouse": "_Test Warehouse - _TC"}
|
||||
)
|
||||
bundle_item.save(ignore_permissions=True)
|
||||
|
||||
for product_bundle in [packed_item]:
|
||||
if not frappe.db.exists("Item", product_bundle):
|
||||
make_item(product_bundle, {"is_stock_item": 0, "stock_uom": "Nos"})
|
||||
|
||||
make_product_bundle(bundle, [packed_item], 1)
|
||||
|
||||
for scenario in [
|
||||
{"valid_upto": add_days(nowdate(), -1), "expected_rate": 0.0},
|
||||
{"valid_upto": add_days(nowdate(), 1), "expected_rate": 111.0},
|
||||
]:
|
||||
with self.subTest(scenario=scenario):
|
||||
frappe.get_doc(
|
||||
{
|
||||
"doctype": "Item Price",
|
||||
"item_code": packed_item,
|
||||
"selling": 1,
|
||||
"price_list": "_Test Price List",
|
||||
"valid_from": add_days(nowdate(), -1),
|
||||
"valid_upto": scenario.get("valid_upto"),
|
||||
"price_list_rate": 111,
|
||||
}
|
||||
).save()
|
||||
|
||||
so = frappe.new_doc("Sales Order")
|
||||
so.transaction_date = nowdate()
|
||||
so.delivery_date = nowdate()
|
||||
so.set_warehouse = ""
|
||||
so.company = "_Test Company"
|
||||
so.customer = "_Test Customer"
|
||||
so.currency = "INR"
|
||||
so.selling_price_list = "_Test Price List"
|
||||
so.append("items", {"item_code": bundle, "qty": 1})
|
||||
so.save()
|
||||
|
||||
self.assertEqual(len(so.items), 1)
|
||||
self.assertEqual(len(so.packed_items), 1)
|
||||
self.assertEqual(so.items[0].item_code, bundle)
|
||||
self.assertEqual(so.packed_items[0].item_code, packed_item)
|
||||
self.assertEqual(so.items[0].rate, scenario.get("expected_rate"))
|
||||
self.assertEqual(so.packed_items[0].rate, scenario.get("expected_rate"))
|
||||
|
||||
|
||||
def automatically_fetch_payment_terms(enable=1):
|
||||
accounts_settings = frappe.get_doc("Accounts Settings")
|
||||
|
||||
@@ -138,6 +138,7 @@ class DeliveryNote(SellingController):
|
||||
self.validate_uom_is_integer("stock_uom", "stock_qty")
|
||||
self.validate_uom_is_integer("uom", "qty")
|
||||
self.validate_with_previous_doc()
|
||||
self.validate_duplicate_serial_nos()
|
||||
|
||||
from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
|
||||
|
||||
@@ -412,6 +413,21 @@ class DeliveryNote(SellingController):
|
||||
pluck="name",
|
||||
)
|
||||
|
||||
def validate_duplicate_serial_nos(self):
|
||||
serial_nos = []
|
||||
for item in self.items:
|
||||
if not item.serial_no:
|
||||
continue
|
||||
|
||||
for serial_no in item.serial_no.split("\n"):
|
||||
if serial_no in serial_nos:
|
||||
frappe.throw(
|
||||
_("Row #{0}: Serial No {1} is already selected.").format(item.idx, serial_no),
|
||||
title=_("Duplicate Serial No"),
|
||||
)
|
||||
else:
|
||||
serial_nos.append(serial_no)
|
||||
|
||||
|
||||
def update_billed_amount_based_on_so(so_detail, update_modified=True):
|
||||
from frappe.query_builder.functions import Sum
|
||||
|
||||
@@ -11,10 +11,12 @@ def get_data():
|
||||
},
|
||||
"internal_links": {
|
||||
"Sales Order": ["items", "against_sales_order"],
|
||||
"Sales Invoice": ["items", "against_sales_invoice"],
|
||||
"Material Request": ["items", "material_request"],
|
||||
"Purchase Order": ["items", "purchase_order"],
|
||||
},
|
||||
"internal_and_external_links": {
|
||||
"Sales Invoice": ["items", "against_sales_invoice"],
|
||||
},
|
||||
"transactions": [
|
||||
{"label": _("Related"), "items": ["Sales Invoice", "Packing Slip", "Delivery Trip"]},
|
||||
{"label": _("Reference"), "items": ["Sales Order", "Shipment", "Quality Inspection"]},
|
||||
|
||||
@@ -1211,6 +1211,38 @@ class TestDeliveryNote(FrappeTestCase):
|
||||
|
||||
self.assertTrue(return_dn.docstatus == 1)
|
||||
|
||||
def test_duplicate_serial_no_in_delivery_note(self):
|
||||
# Step - 1: Create Serial Item
|
||||
serial_item = make_item(
|
||||
properties={
|
||||
"is_stock_item": 1,
|
||||
"has_serial_no": 1,
|
||||
"serial_no_series": frappe.generate_hash("", 10) + ".###",
|
||||
}
|
||||
).name
|
||||
|
||||
# Step - 2: Inward Stock
|
||||
se = make_stock_entry(item_code=serial_item, target="_Test Warehouse - _TC", qty=4)
|
||||
|
||||
# Step - 3: Create Delivery Note with Duplicare Serial Nos
|
||||
serial_nos = se.items[0].serial_no.split("\n")
|
||||
dn = create_delivery_note(
|
||||
item_code=serial_item,
|
||||
warehouse="_Test Warehouse - _TC",
|
||||
qty=2,
|
||||
do_not_save=True,
|
||||
)
|
||||
dn.items[0].serial_no = "\n".join(serial_nos[:2])
|
||||
dn.append("items", dn.items[0].as_dict())
|
||||
|
||||
# Test - 1: ValidationError should be raised
|
||||
self.assertRaises(frappe.ValidationError, dn.save)
|
||||
|
||||
# Step - 4: Submit Delivery Note with unique Serial Nos
|
||||
dn.items[1].serial_no = "\n".join(serial_nos[2:])
|
||||
dn.save()
|
||||
dn.submit()
|
||||
|
||||
def tearDown(self):
|
||||
frappe.db.rollback()
|
||||
frappe.db.set_single_value("Selling Settings", "dont_reserve_sales_order_qty_on_sales_return", 0)
|
||||
|
||||
@@ -350,18 +350,20 @@ $.extend(erpnext.item, {
|
||||
}
|
||||
}
|
||||
|
||||
frm.fields_dict['deferred_revenue_account'].get_query = function() {
|
||||
frm.fields_dict["item_defaults"].grid.get_field("deferred_revenue_account").get_query = function(doc, cdt, cdn) {
|
||||
return {
|
||||
filters: {
|
||||
"company": locals[cdt][cdn].company,
|
||||
'root_type': 'Liability',
|
||||
"is_group": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frm.fields_dict['deferred_expense_account'].get_query = function() {
|
||||
frm.fields_dict["item_defaults"].grid.get_field("deferred_expense_account").get_query = function(doc, cdt, cdn) {
|
||||
return {
|
||||
filters: {
|
||||
"company": locals[cdt][cdn].company,
|
||||
'root_type': 'Asset',
|
||||
"is_group": 0
|
||||
}
|
||||
|
||||
@@ -70,6 +70,13 @@
|
||||
"variant_based_on",
|
||||
"attributes",
|
||||
"accounting",
|
||||
"deferred_accounting_section",
|
||||
"enable_deferred_expense",
|
||||
"no_of_months_exp",
|
||||
"column_break_9s9o",
|
||||
"enable_deferred_revenue",
|
||||
"no_of_months",
|
||||
"section_break_avcp",
|
||||
"item_defaults",
|
||||
"purchasing_tab",
|
||||
"purchase_uom",
|
||||
@@ -85,10 +92,6 @@
|
||||
"delivered_by_supplier",
|
||||
"column_break2",
|
||||
"supplier_items",
|
||||
"deferred_expense_section",
|
||||
"enable_deferred_expense",
|
||||
"deferred_expense_account",
|
||||
"no_of_months_exp",
|
||||
"foreign_trade_details",
|
||||
"country_of_origin",
|
||||
"column_break_59",
|
||||
@@ -99,10 +102,6 @@
|
||||
"is_sales_item",
|
||||
"column_break3",
|
||||
"max_discount",
|
||||
"deferred_revenue",
|
||||
"enable_deferred_revenue",
|
||||
"deferred_revenue_account",
|
||||
"no_of_months",
|
||||
"customer_details",
|
||||
"customer_items",
|
||||
"item_tax_section_break",
|
||||
@@ -657,20 +656,6 @@
|
||||
"oldfieldname": "max_discount",
|
||||
"oldfieldtype": "Currency"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "deferred_revenue",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Deferred Revenue"
|
||||
},
|
||||
{
|
||||
"depends_on": "enable_deferred_revenue",
|
||||
"fieldname": "deferred_revenue_account",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Deferred Revenue Account",
|
||||
"options": "Account"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "enable_deferred_revenue",
|
||||
@@ -681,21 +666,7 @@
|
||||
"depends_on": "enable_deferred_revenue",
|
||||
"fieldname": "no_of_months",
|
||||
"fieldtype": "Int",
|
||||
"label": "No of Months"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "deferred_expense_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Deferred Expense"
|
||||
},
|
||||
{
|
||||
"depends_on": "enable_deferred_expense",
|
||||
"fieldname": "deferred_expense_account",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Deferred Expense Account",
|
||||
"options": "Account"
|
||||
"label": "No of Months (Revenue)"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
@@ -904,6 +875,20 @@
|
||||
"fieldname": "accounting",
|
||||
"fieldtype": "Tab Break",
|
||||
"label": "Accounting"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_9s9o",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_avcp",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "deferred_accounting_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Deferred Accounting"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-tag",
|
||||
@@ -912,7 +897,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"make_attachments_public": 1,
|
||||
"modified": "2023-07-14 17:18:18.658942",
|
||||
"modified": "2023-09-11 13:46:32.688051",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Item",
|
||||
|
||||
@@ -19,7 +19,11 @@
|
||||
"selling_defaults",
|
||||
"selling_cost_center",
|
||||
"column_break_12",
|
||||
"income_account"
|
||||
"income_account",
|
||||
"deferred_accounting_defaults_section",
|
||||
"deferred_expense_account",
|
||||
"column_break_kwad",
|
||||
"deferred_revenue_account"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -108,11 +112,34 @@
|
||||
"fieldtype": "Link",
|
||||
"label": "Default Provisional Account",
|
||||
"options": "Account"
|
||||
},
|
||||
{
|
||||
"fieldname": "deferred_accounting_defaults_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Deferred Accounting Defaults"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: parent.enable_deferred_expense",
|
||||
"fieldname": "deferred_expense_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Deferred Expense Account",
|
||||
"options": "Account"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: parent.enable_deferred_revenue",
|
||||
"fieldname": "deferred_revenue_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Deferred Revenue Account",
|
||||
"options": "Account"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_kwad",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2022-04-10 20:18:54.148195",
|
||||
"modified": "2023-09-04 12:33:14.607267",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Item Default",
|
||||
|
||||
@@ -296,6 +296,7 @@
|
||||
"depends_on": "eval:doc.material_request_type == 'Material Transfer'",
|
||||
"fieldname": "set_from_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Set Source Warehouse",
|
||||
"options": "Warehouse"
|
||||
},
|
||||
@@ -356,7 +357,7 @@
|
||||
"idx": 70,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2023-07-25 17:19:31.662662",
|
||||
"modified": "2023-09-15 12:07:24.789471",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Material Request",
|
||||
|
||||
@@ -207,6 +207,9 @@ def update_packed_item_price_data(pi_row, item_data, doc):
|
||||
"conversion_rate": doc.get("conversion_rate"),
|
||||
}
|
||||
)
|
||||
if not row_data.get("transaction_date"):
|
||||
row_data.update({"transaction_date": doc.get("transaction_date")})
|
||||
|
||||
rate = get_price_list_rate(row_data, item_doc).get("price_list_rate")
|
||||
|
||||
pi_row.rate = rate or item_data.get("valuation_rate") or 0.0
|
||||
|
||||
@@ -605,7 +605,7 @@ class PurchaseReceipt(BuyingController):
|
||||
account=provisional_account,
|
||||
cost_center=item.cost_center,
|
||||
debit=0.0,
|
||||
credit=multiplication_factor * item.amount,
|
||||
credit=multiplication_factor * item.base_amount,
|
||||
remarks=remarks,
|
||||
against_account=expense_account,
|
||||
account_currency=credit_currency,
|
||||
@@ -619,7 +619,7 @@ class PurchaseReceipt(BuyingController):
|
||||
gl_entries=gl_entries,
|
||||
account=expense_account,
|
||||
cost_center=item.cost_center,
|
||||
debit=multiplication_factor * item.amount,
|
||||
debit=multiplication_factor * item.base_amount,
|
||||
credit=0.0,
|
||||
remarks=remarks,
|
||||
against_account=provisional_account,
|
||||
|
||||
@@ -2024,6 +2024,49 @@ class TestPurchaseReceipt(FrappeTestCase):
|
||||
ste7.reload()
|
||||
self.assertEqual(ste7.items[0].valuation_rate, valuation_rate)
|
||||
|
||||
def test_purchase_receipt_provisional_accounting(self):
|
||||
# Step - 1: Create Supplier with Default Currency as USD
|
||||
from erpnext.buying.doctype.supplier.test_supplier import create_supplier
|
||||
|
||||
supplier = create_supplier(default_currency="USD")
|
||||
|
||||
# Step - 2: Setup Company for Provisional Accounting
|
||||
from erpnext.accounts.doctype.account.test_account import create_account
|
||||
|
||||
provisional_account = create_account(
|
||||
account_name="Provision Account",
|
||||
parent_account="Current Liabilities - _TC",
|
||||
company="_Test Company",
|
||||
)
|
||||
company = frappe.get_doc("Company", "_Test Company")
|
||||
company.enable_provisional_accounting_for_non_stock_items = 1
|
||||
company.default_provisional_account = provisional_account
|
||||
company.save()
|
||||
|
||||
# Step - 3: Create Non-Stock Item
|
||||
item = make_item(properties={"is_stock_item": 0})
|
||||
|
||||
# Step - 4: Create Purchase Receipt
|
||||
pr = make_purchase_receipt(
|
||||
qty=2,
|
||||
item_code=item.name,
|
||||
company=company.name,
|
||||
supplier=supplier.name,
|
||||
currency=supplier.default_currency,
|
||||
)
|
||||
|
||||
# Test - 1: Total and Base Total should not be the same as the currency is different
|
||||
self.assertNotEqual(flt(pr.total, 2), flt(pr.base_total, 2))
|
||||
self.assertEqual(flt(pr.total * pr.conversion_rate, 2), flt(pr.base_total, 2))
|
||||
|
||||
# Test - 2: Sum of Debit or Credit should be equal to Purchase Receipt Base Total
|
||||
amount = frappe.db.get_value("GL Entry", {"docstatus": 1, "voucher_no": pr.name}, ["sum(debit)"])
|
||||
expected_amount = pr.base_total
|
||||
self.assertEqual(amount, expected_amount)
|
||||
|
||||
company.enable_provisional_accounting_for_non_stock_items = 0
|
||||
company.save()
|
||||
|
||||
|
||||
def prepare_data_for_internal_transfer():
|
||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier
|
||||
|
||||
@@ -101,15 +101,6 @@ frappe.ui.form.on('Stock Entry', {
|
||||
}
|
||||
});
|
||||
|
||||
let batch_field = frm.get_docfield('items', 'batch_no');
|
||||
if (batch_field) {
|
||||
batch_field.get_route_options_for_new_doc = (row) => {
|
||||
return {
|
||||
'item': row.doc.item_code
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
frm.add_fetch("bom_no", "inspection_required", "inspection_required");
|
||||
erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype);
|
||||
|
||||
@@ -345,6 +336,15 @@ frappe.ui.form.on('Stock Entry', {
|
||||
if(!check_should_not_attach_bom_items(frm.doc.bom_no)) {
|
||||
erpnext.accounts.dimensions.update_dimension(frm, frm.doctype);
|
||||
}
|
||||
|
||||
let batch_field = frm.get_docfield('items', 'batch_no');
|
||||
if (batch_field) {
|
||||
batch_field.get_route_options_for_new_doc = (row) => {
|
||||
return {
|
||||
'item': row.doc.item_code
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
get_items_from_transit_entry: function(frm) {
|
||||
|
||||
@@ -729,7 +729,11 @@ def get_default_discount_account(args, item):
|
||||
def get_default_deferred_account(args, item, fieldname=None):
|
||||
if item.get("enable_deferred_revenue") or item.get("enable_deferred_expense"):
|
||||
return (
|
||||
item.get(fieldname)
|
||||
frappe.get_cached_value(
|
||||
"Item Default",
|
||||
{"parent": args.item_code, "company": args.get("company")},
|
||||
fieldname,
|
||||
)
|
||||
or args.get(fieldname)
|
||||
or frappe.get_cached_value("Company", args.company, "default_" + fieldname)
|
||||
)
|
||||
|
||||
@@ -75,15 +75,6 @@ frappe.ui.form.on('Subcontracting Receipt', {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let batch_no_field = frm.get_docfield('items', 'batch_no');
|
||||
if (batch_no_field) {
|
||||
batch_no_field.get_route_options_for_new_doc = function(row) {
|
||||
return {
|
||||
'item': row.doc.item_code
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
refresh: (frm) => {
|
||||
@@ -148,6 +139,15 @@ frappe.ui.form.on('Subcontracting Receipt', {
|
||||
|
||||
frm.fields_dict.supplied_items.grid.update_docfield_property('consumed_qty', 'read_only', frm.doc.__onload && frm.doc.__onload.backflush_based_on === 'BOM');
|
||||
}
|
||||
|
||||
let batch_no_field = frm.get_docfield('items', 'batch_no');
|
||||
if (batch_no_field) {
|
||||
batch_no_field.get_route_options_for_new_doc = function(row) {
|
||||
return {
|
||||
'item': row.doc.item_code
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
set_warehouse: (frm) => {
|
||||
@@ -202,4 +202,4 @@ let set_missing_values = (frm) => {
|
||||
if (!r.exc) frm.refresh();
|
||||
},
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user