Merge pull request #30361 from deepeshgarg007/tax_account_display
fix: GST account not showing up in tax templates
diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool_item/opening_invoice_creation_tool_item.json b/erpnext/accounts/doctype/opening_invoice_creation_tool_item/opening_invoice_creation_tool_item.json
index 5c19091..ed8ff7c 100644
--- a/erpnext/accounts/doctype/opening_invoice_creation_tool_item/opening_invoice_creation_tool_item.json
+++ b/erpnext/accounts/doctype/opening_invoice_creation_tool_item/opening_invoice_creation_tool_item.json
@@ -110,13 +110,12 @@
"description": "Reference number of the invoice from the previous system",
"fieldname": "invoice_number",
"fieldtype": "Data",
- "in_list_view": 1,
"label": "Invoice Number"
}
],
"istable": 1,
"links": [],
- "modified": "2021-12-17 19:25:06.053187",
+ "modified": "2022-03-21 19:31:45.382656",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Opening Invoice Creation Tool Item",
@@ -125,5 +124,6 @@
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
+ "states": [],
"track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
index 91c07ad..d782cc2 100644
--- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
+++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
@@ -485,16 +485,15 @@
"payment_account": pay.account,
}, ["name"])
- args = {
- 'doctype': 'Payment Request',
+ filters = {
'reference_doctype': 'POS Invoice',
'reference_name': self.name,
'payment_gateway_account': payment_gateway_account,
'email_to': self.contact_mobile
}
- pr = frappe.db.exists(args)
+ pr = frappe.db.get_value('Payment Request', filters=filters)
if pr:
- return frappe.get_doc('Payment Request', pr[0][0])
+ return frappe.get_doc('Payment Request', pr)
@frappe.whitelist()
def get_stock_availability(item_code, warehouse):
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index e107912..9433489 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -1711,6 +1711,7 @@
}
}, target_doc, set_missing_values)
+ doclist.set_onload('ignore_price_list', True)
return doclist
@frappe.whitelist()
diff --git a/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.py b/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.py
index d5483b5..904513c 100644
--- a/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.py
+++ b/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.py
@@ -200,9 +200,9 @@
invoice_list_names = ",".join('"' + invoice['name'] + '"' for invoice in invoice_list)
if invoice_list:
inv_mop_detail = frappe.db.sql("""
- select t.owner,
+ select t.owner,
t.posting_date,
- t.mode_of_payment,
+ t.mode_of_payment,
sum(t.paid_amount) as paid_amount
from (
select a.owner, a.posting_date,
@@ -230,7 +230,7 @@
and b.reference_type = "Sales Invoice"
and b.reference_name in ({invoice_list_names})
group by a.owner, a.posting_date, mode_of_payment
- ) t
+ ) t
group by t.owner, t.posting_date, t.mode_of_payment
""".format(invoice_list_names=invoice_list_names), as_dict=1)
@@ -252,4 +252,4 @@
for d in inv_mop_detail:
mode_of_payment_details.setdefault(d["owner"]+cstr(d["posting_date"]), []).append((d.mode_of_payment,d.paid_amount))
- return mode_of_payment_details
\ No newline at end of file
+ return mode_of_payment_details
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 2c66542..f93f9fe 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -442,6 +442,8 @@
}
}, target_doc, set_missing_values)
+ doc.set_onload('ignore_price_list', True)
+
return doc
@frappe.whitelist()
@@ -509,6 +511,7 @@
doc = get_mapped_doc("Purchase Order", source_name, fields,
target_doc, postprocess, ignore_permissions=ignore_permissions)
+ doc.set_onload('ignore_price_list', True)
return doc
diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
index 81fc324..d578863 100644
--- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
+++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
@@ -139,6 +139,7 @@
},
}, target_doc, set_missing_values)
+ doclist.set_onload('ignore_price_list', True)
return doclist
@frappe.whitelist()
diff --git a/erpnext/crm/doctype/appointment/appointment.py b/erpnext/crm/doctype/appointment/appointment.py
index 20fb987..88a9c10 100644
--- a/erpnext/crm/doctype/appointment/appointment.py
+++ b/erpnext/crm/doctype/appointment/appointment.py
@@ -225,9 +225,7 @@
def _get_employee_from_user(user):
- employee_docname = frappe.db.exists(
- {'doctype': 'Employee', 'user_id': user})
+ employee_docname = frappe.db.get_value('Employee', {'user_id': user})
if employee_docname:
- # frappe.db.exists returns a tuple of a tuple
- return frappe.get_doc('Employee', employee_docname[0][0])
+ return frappe.get_doc('Employee', employee_docname)
return None
diff --git a/erpnext/crm/doctype/appointment/test_appointment.py b/erpnext/crm/doctype/appointment/test_appointment.py
index f4086dc..776e604 100644
--- a/erpnext/crm/doctype/appointment/test_appointment.py
+++ b/erpnext/crm/doctype/appointment/test_appointment.py
@@ -8,50 +8,44 @@
def create_test_lead():
- test_lead = frappe.db.exists({'doctype': 'Lead', 'email_id':'test@example.com'})
- if test_lead:
- return frappe.get_doc('Lead', test_lead[0][0])
- test_lead = frappe.get_doc({
- 'doctype': 'Lead',
- 'lead_name': 'Test Lead',
- 'email_id': 'test@example.com'
- })
- test_lead.insert(ignore_permissions=True)
- return test_lead
+ test_lead = frappe.db.get_value("Lead", {"email_id": "test@example.com"})
+ if test_lead:
+ return frappe.get_doc("Lead", test_lead)
+ test_lead = frappe.get_doc(
+ {"doctype": "Lead", "lead_name": "Test Lead", "email_id": "test@example.com"}
+ )
+ test_lead.insert(ignore_permissions=True)
+ return test_lead
def create_test_appointments():
- test_appointment = frappe.db.exists(
- {'doctype': 'Appointment', 'scheduled_time':datetime.datetime.now(),'email':'test@example.com'})
- if test_appointment:
- return frappe.get_doc('Appointment', test_appointment[0][0])
- test_appointment = frappe.get_doc({
- 'doctype': 'Appointment',
- 'email': 'test@example.com',
- 'status': 'Open',
- 'customer_name': 'Test Lead',
- 'customer_phone_number': '666',
- 'customer_skype': 'test',
- 'customer_email': 'test@example.com',
- 'scheduled_time': datetime.datetime.now()
- })
- test_appointment.insert()
- return test_appointment
+ test_appointment = frappe.get_doc(
+ {
+ "doctype": "Appointment",
+ "email": "test@example.com",
+ "status": "Open",
+ "customer_name": "Test Lead",
+ "customer_phone_number": "666",
+ "customer_skype": "test",
+ "customer_email": "test@example.com",
+ "scheduled_time": datetime.datetime.now(),
+ }
+ )
+ test_appointment.insert()
+ return test_appointment
class TestAppointment(unittest.TestCase):
- test_appointment = test_lead = None
+ test_appointment = test_lead = None
- def setUp(self):
- self.test_lead = create_test_lead()
- self.test_appointment = create_test_appointments()
+ def setUp(self):
+ self.test_lead = create_test_lead()
+ self.test_appointment = create_test_appointments()
- def test_calendar_event_created(self):
- cal_event = frappe.get_doc(
- 'Event', self.test_appointment.calendar_event)
- self.assertEqual(cal_event.starts_on,
- self.test_appointment.scheduled_time)
+ def test_calendar_event_created(self):
+ cal_event = frappe.get_doc("Event", self.test_appointment.calendar_event)
+ self.assertEqual(cal_event.starts_on, self.test_appointment.scheduled_time)
- def test_lead_linked(self):
- lead = frappe.get_doc('Lead', self.test_lead.name)
- self.assertIsNotNone(lead)
+ def test_lead_linked(self):
+ lead = frappe.get_doc("Lead", self.test_lead.name)
+ self.assertIsNotNone(lead)
diff --git a/erpnext/e_commerce/product_ui/views.js b/erpnext/e_commerce/product_ui/views.js
index 6dce79d..fb63b21 100644
--- a/erpnext/e_commerce/product_ui/views.js
+++ b/erpnext/e_commerce/product_ui/views.js
@@ -418,6 +418,22 @@
me.change_route_with_filters();
});
+
+ // bind filter lookup input box
+ $('.filter-lookup-input').on('keydown', frappe.utils.debounce((e) => {
+ const $input = $(e.target);
+ const keyword = ($input.val() || '').toLowerCase();
+ const $filter_options = $input.next('.filter-options');
+
+ $filter_options.find('.filter-lookup-wrapper').show();
+ $filter_options.find('.filter-lookup-wrapper').each((i, el) => {
+ const $el = $(el);
+ const value = $el.data('value').toLowerCase();
+ if (!value.includes(keyword)) {
+ $el.hide();
+ }
+ });
+ }, 300));
}
change_route_with_filters() {
diff --git a/erpnext/education/setup.py b/erpnext/education/setup.py
index b716926..663f1ca 100644
--- a/erpnext/education/setup.py
+++ b/erpnext/education/setup.py
@@ -3,7 +3,6 @@
import frappe
-from erpnext.setup.utils import insert_record
def setup_education():
@@ -13,6 +12,21 @@
return
create_academic_sessions()
+
+def insert_record(records):
+ for r in records:
+ doc = frappe.new_doc(r.get("doctype"))
+ doc.update(r)
+ try:
+ doc.insert(ignore_permissions=True)
+ except frappe.DuplicateEntryError as e:
+ # pass DuplicateEntryError and continue
+ if e.args and e.args[0]==doc.doctype and e.args[1]==doc.name:
+ # make sure DuplicateEntryError is for the exact same doc and not a related doc
+ pass
+ else:
+ raise
+
def create_academic_sessions():
data = [
{"doctype": "Academic Year", "academic_year_name": "2015-16"},
diff --git a/erpnext/hr/doctype/leave_application/test_leave_application.py b/erpnext/hr/doctype/leave_application/test_leave_application.py
index 7d32fd8..3a30990 100644
--- a/erpnext/hr/doctype/leave_application/test_leave_application.py
+++ b/erpnext/hr/doctype/leave_application/test_leave_application.py
@@ -25,6 +25,7 @@
LeaveDayBlockedError,
NotAnOptionalHoliday,
OverlapError,
+ get_leave_allocation_records,
get_leave_balance_on,
get_leave_details,
)
@@ -882,6 +883,27 @@
self.assertEqual(leave_allocation['leaves_pending_approval'], 1)
self.assertEqual(leave_allocation['remaining_leaves'], 26)
+ @set_holiday_list('Salary Slip Test Holiday List', '_Test Company')
+ def test_get_leave_allocation_records(self):
+ employee = get_employee()
+ leave_type = create_leave_type(
+ leave_type_name="_Test_CF_leave_expiry",
+ is_carry_forward=1,
+ expire_carry_forwarded_leaves_after_days=90)
+ leave_type.insert()
+
+ leave_alloc = create_carry_forwarded_allocation(employee, leave_type)
+ details = get_leave_allocation_records(employee.name, getdate(), leave_type.name)
+ expected_data = {
+ "from_date": getdate(leave_alloc.from_date),
+ "to_date": getdate(leave_alloc.to_date),
+ "total_leaves_allocated": 30.0,
+ "unused_leaves": 15.0,
+ "new_leaves_allocated": 15.0,
+ "leave_type": leave_type.name
+ }
+ self.assertEqual(details.get(leave_type.name), expected_data)
+
def create_carry_forwarded_allocation(employee, leave_type):
# initial leave allocation
@@ -903,6 +925,8 @@
carry_forward=1)
leave_allocation.submit()
+ return leave_allocation
+
def make_allocation_record(employee=None, leave_type=None, from_date=None, to_date=None, carry_forward=False, leaves=None):
allocation = frappe.get_doc({
"doctype": "Leave Allocation",
@@ -931,12 +955,9 @@
dept_doc.save(ignore_permissions=True)
def get_leave_period():
- leave_period_name = frappe.db.exists({
- "doctype": "Leave Period",
- "company": "_Test Company"
- })
+ leave_period_name = frappe.db.get_value("Leave Period", {"company": "_Test Company"})
if leave_period_name:
- return frappe.get_doc("Leave Period", leave_period_name[0][0])
+ return frappe.get_doc("Leave Period", leave_period_name)
else:
return frappe.get_doc(dict(
name = 'Test Leave Period',
diff --git a/erpnext/payroll/doctype/payroll_entry/payroll_entry.py b/erpnext/payroll/doctype/payroll_entry/payroll_entry.py
index 32b0f0f..9061c5f 100644
--- a/erpnext/payroll/doctype/payroll_entry/payroll_entry.py
+++ b/erpnext/payroll/doctype/payroll_entry/payroll_entry.py
@@ -708,6 +708,8 @@
if not_submitted_ss:
frappe.msgprint(_("Could not submit some Salary Slips"))
+ frappe.flags.via_payroll_entry = False
+
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_payroll_entries_for_jv(doctype, txt, searchfield, start, page_len, filters):
diff --git a/erpnext/payroll/doctype/salary_slip/test_salary_slip.py b/erpnext/payroll/doctype/salary_slip/test_salary_slip.py
index 5e41b66..f072135 100644
--- a/erpnext/payroll/doctype/salary_slip/test_salary_slip.py
+++ b/erpnext/payroll/doctype/salary_slip/test_salary_slip.py
@@ -38,6 +38,8 @@
class TestSalarySlip(unittest.TestCase):
def setUp(self):
setup_test()
+ frappe.flags.pop("via_payroll_entry", None)
+
def tearDown(self):
frappe.db.rollback()
@@ -409,15 +411,17 @@
"email_salary_slip_to_employee": 1
})
def test_email_salary_slip(self):
- frappe.db.sql("delete from `tabEmail Queue`")
+ frappe.db.delete("Email Queue")
- make_employee("test_email_salary_slip@salary.com", company="_Test Company")
- ss = make_employee_salary_slip("test_email_salary_slip@salary.com", "Monthly", "Test Salary Slip Email")
+ user_id = "test_email_salary_slip@salary.com"
+
+ make_employee(user_id, company="_Test Company")
+ ss = make_employee_salary_slip(user_id, "Monthly", "Test Salary Slip Email")
ss.company = "_Test Company"
ss.save()
ss.submit()
- email_queue = frappe.db.sql("""select name from `tabEmail Queue`""")
+ email_queue = frappe.db.a_row_exists("Email Queue")
self.assertTrue(email_queue)
def test_loan_repayment_salary_slip(self):
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 00373a6..5543dfe 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -1070,7 +1070,7 @@
}
if(flt(this.frm.doc.conversion_rate)>0.0) {
- if(this.frm.doc.ignore_pricing_rule) {
+ if(this.frm.doc.__onload.ignore_price_list) {
this.calculate_taxes_and_totals();
} else if (!this.in_apply_price_list){
this.apply_price_list();
@@ -1884,6 +1884,7 @@
callback: function(r) {
if(!r.exc) {
item.item_tax_rate = r.message;
+ me.add_taxes_from_item_tax_template(item.item_tax_rate);
me.calculate_taxes_and_totals();
}
}
diff --git a/erpnext/public/scss/shopping_cart.scss b/erpnext/public/scss/shopping_cart.scss
index 019496d..6ae464d 100644
--- a/erpnext/public/scss/shopping_cart.scss
+++ b/erpnext/public/scss/shopping_cart.scss
@@ -264,6 +264,15 @@
font-size: 13px;
}
+ .filter-lookup-input {
+ background-color: white;
+ border: 1px solid var(--gray-300);
+
+ &:focus {
+ border: 1px solid var(--primary);
+ }
+ }
+
.filter-label {
font-size: 11px;
font-weight: 600;
diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py
index 06b4ff1..d602f0c 100644
--- a/erpnext/selling/doctype/quotation/quotation.py
+++ b/erpnext/selling/doctype/quotation/quotation.py
@@ -206,6 +206,7 @@
}, target_doc, set_missing_values, ignore_permissions=ignore_permissions)
# postprocess: fetch shipping address, set missing values
+ doclist.set_onload('ignore_price_list', True)
return doclist
@@ -269,6 +270,8 @@
}
}, target_doc, set_missing_values, ignore_permissions=ignore_permissions)
+ doclist.set_onload('ignore_price_list', True)
+
return doclist
def _make_customer(source_name, ignore_permissions=False):
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 73e3d19..b906ec0 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -584,6 +584,8 @@
target_doc = get_mapped_doc("Sales Order", source_name, mapper, target_doc, set_missing_values)
+ target_doc.set_onload('ignore_price_list', True)
+
return target_doc
@frappe.whitelist()
@@ -664,6 +666,8 @@
if automatically_fetch_payment_terms:
doclist.set_payment_schedule()
+ doclist.set_onload('ignore_price_list', True)
+
return doclist
@frappe.whitelist()
diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py
index 1d7bad2..1d95ddb 100644
--- a/erpnext/setup/install.py
+++ b/erpnext/setup/install.py
@@ -21,9 +21,7 @@
def after_install():
frappe.get_doc({'doctype': "Role", "role_name": "Analytics"}).insert()
set_single_defaults()
- create_compact_item_print_custom_field()
- create_print_uom_after_qty_custom_field()
- create_print_zero_amount_taxes_custom_field()
+ create_print_setting_custom_fields()
add_all_roles_to("Administrator")
create_default_cash_flow_mapper_templates()
create_default_success_action()
@@ -77,7 +75,7 @@
except frappe.ValidationError:
pass
-def create_compact_item_print_custom_field():
+def create_print_setting_custom_fields():
create_custom_field('Print Settings', {
'label': _('Compact Item Print'),
'fieldname': 'compact_item_print',
@@ -85,9 +83,6 @@
'default': 1,
'insert_after': 'with_letterhead'
})
-
-
-def create_print_uom_after_qty_custom_field():
create_custom_field('Print Settings', {
'label': _('Print UOM after Quantity'),
'fieldname': 'print_uom_after_quantity',
@@ -95,9 +90,6 @@
'default': 0,
'insert_after': 'compact_item_print'
})
-
-
-def create_print_zero_amount_taxes_custom_field():
create_custom_field('Print Settings', {
'label': _('Print taxes with zero amount'),
'fieldname': 'print_taxes_with_zero_amount',
diff --git a/erpnext/setup/setup_wizard/data/test_mfg.json b/erpnext/setup/setup_wizard/data/test_mfg.json
deleted file mode 100644
index efc5fa8..0000000
--- a/erpnext/setup/setup_wizard/data/test_mfg.json
+++ /dev/null
@@ -1,56 +0,0 @@
-{
- "add_sample_data": 1,
- "bank_account": "HDFC",
- "company_abbr": "FT",
- "company_name": "For Testing",
- "company_tagline": "Just for GST",
- "country": "India",
- "currency": "INR",
- "customer_1": "Test Customer 1",
- "customer_2": "Test Customer 2",
- "domains": ["Manufacturing"],
- "email": "great@example.com",
- "full_name": "Great Tester",
- "fy_end_date": "2018-03-31",
- "fy_start_date": "2017-04-01",
- "is_purchase_item_1": 1,
- "is_purchase_item_2": 1,
- "is_purchase_item_3": 0,
- "is_purchase_item_4": 0,
- "is_purchase_item_5": 0,
- "is_sales_item_1": 1,
- "is_sales_item_2": 1,
- "is_sales_item_3": 1,
- "is_sales_item_4": 1,
- "is_sales_item_5": 1,
- "item_1": "Test Item 1",
- "item_2": "Test Item 2",
- "item_group_1": "Products",
- "item_group_2": "Products",
- "item_group_3": "Products",
- "item_group_4": "Products",
- "item_group_5": "Products",
- "item_uom_1": "Unit",
- "item_uom_2": "Unit",
- "item_uom_3": "Unit",
- "item_uom_4": "Unit",
- "item_uom_5": "Unit",
- "language": "English (United States)",
- "password": "test",
- "setup_website": 1,
- "supplier_1": "Test Supplier 1",
- "supplier_2": "Test Supplier 2",
- "timezone": "Asia/Kolkata",
- "user_accountant_1": 1,
- "user_accountant_2": 1,
- "user_accountant_3": 1,
- "user_accountant_4": 1,
- "user_purchaser_1": 1,
- "user_purchaser_2": 1,
- "user_purchaser_3": 1,
- "user_purchaser_4": 1,
- "user_sales_1": 1,
- "user_sales_2": 1,
- "user_sales_3": 1,
- "user_sales_4": 1
-}
\ No newline at end of file
diff --git a/erpnext/setup/setup_wizard/operations/sample_data.py b/erpnext/setup/setup_wizard/operations/sample_data.py
deleted file mode 100644
index 1685994..0000000
--- a/erpnext/setup/setup_wizard/operations/sample_data.py
+++ /dev/null
@@ -1,179 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-
-import json
-import os
-import random
-
-import frappe
-import frappe.utils
-from frappe import _
-from frappe.utils.make_random import add_random_children
-
-
-def make_sample_data(domains, make_dependent = False):
- """Create a few opportunities, quotes, material requests, issues, todos, projects
- to help the user get started"""
-
- if make_dependent:
- items = frappe.get_all("Item", {'is_sales_item': 1})
- customers = frappe.get_all("Customer")
- warehouses = frappe.get_all("Warehouse")
-
- if items and customers:
- for i in range(3):
- customer = random.choice(customers).name
- make_opportunity(items, customer)
- make_quote(items, customer)
-
- if items and warehouses:
- make_material_request(frappe.get_all("Item"))
-
- make_projects(domains)
- import_notification()
-
-def make_opportunity(items, customer):
- b = frappe.get_doc({
- "doctype": "Opportunity",
- "opportunity_from": "Customer",
- "customer": customer,
- "opportunity_type": _("Sales"),
- "with_items": 1
- })
-
- add_random_children(b, "items", rows=len(items), randomize = {
- "qty": (1, 5),
- "item_code": ["Item"]
- }, unique="item_code")
-
- b.insert(ignore_permissions=True)
-
- b.add_comment('Comment', text="This is a dummy record")
-
-def make_quote(items, customer):
- qtn = frappe.get_doc({
- "doctype": "Quotation",
- "quotation_to": "Customer",
- "party_name": customer,
- "order_type": "Sales"
- })
-
- add_random_children(qtn, "items", rows=len(items), randomize = {
- "qty": (1, 5),
- "item_code": ["Item"]
- }, unique="item_code")
-
- qtn.insert(ignore_permissions=True)
-
- qtn.add_comment('Comment', text="This is a dummy record")
-
-def make_material_request(items):
- for i in items:
- mr = frappe.get_doc({
- "doctype": "Material Request",
- "material_request_type": "Purchase",
- "schedule_date": frappe.utils.add_days(frappe.utils.nowdate(), 7),
- "items": [{
- "schedule_date": frappe.utils.add_days(frappe.utils.nowdate(), 7),
- "item_code": i.name,
- "qty": 10
- }]
- })
- mr.insert()
- mr.submit()
-
- mr.add_comment('Comment', text="This is a dummy record")
-
-
-def make_issue():
- pass
-
-def make_projects(domains):
- current_date = frappe.utils.nowdate()
- project = frappe.get_doc({
- "doctype": "Project",
- "project_name": "ERPNext Implementation",
- })
-
- tasks = [
- {
- "title": "Explore ERPNext",
- "start_date": current_date,
- "end_date": current_date,
- "file": "explore.md"
- }]
-
- if 'Education' in domains:
- tasks += [
- {
- "title": _("Setup your Institute in ERPNext"),
- "start_date": current_date,
- "end_date": frappe.utils.add_days(current_date, 1),
- "file": "education_masters.md"
- },
- {
- "title": "Setup Master Data",
- "start_date": current_date,
- "end_date": frappe.utils.add_days(current_date, 1),
- "file": "education_masters.md"
- }]
-
- else:
- tasks += [
- {
- "title": "Setup Your Company",
- "start_date": current_date,
- "end_date": frappe.utils.add_days(current_date, 1),
- "file": "masters.md"
- },
- {
- "title": "Start Tracking your Sales",
- "start_date": current_date,
- "end_date": frappe.utils.add_days(current_date, 2),
- "file": "sales.md"
- },
- {
- "title": "Start Managing Purchases",
- "start_date": current_date,
- "end_date": frappe.utils.add_days(current_date, 3),
- "file": "purchase.md"
- },
- {
- "title": "Import Data",
- "start_date": current_date,
- "end_date": frappe.utils.add_days(current_date, 4),
- "file": "import_data.md"
- },
- {
- "title": "Go Live!",
- "start_date": current_date,
- "end_date": frappe.utils.add_days(current_date, 5),
- "file": "go_live.md"
- }]
-
- for t in tasks:
- with open (os.path.join(os.path.dirname(__file__), "tasks", t['file'])) as f:
- t['description'] = frappe.utils.md_to_html(f.read())
- del t['file']
-
- project.append('tasks', t)
-
- project.insert(ignore_permissions=True)
-
-def import_notification():
- '''Import notification for task start'''
- with open (os.path.join(os.path.dirname(__file__), "tasks/task_alert.json")) as f:
- notification = frappe.get_doc(json.loads(f.read())[0])
- notification.insert()
-
- # trigger the first message!
- from frappe.email.doctype.notification.notification import trigger_daily_alerts
- trigger_daily_alerts()
-
-def test_sample():
- frappe.db.sql('delete from `tabNotification`')
- frappe.db.sql('delete from tabProject')
- frappe.db.sql('delete from tabTask')
- make_projects('Education')
- import_notification()
diff --git a/erpnext/setup/setup_wizard/setup_wizard.py b/erpnext/setup/setup_wizard/setup_wizard.py
index c9ed184..239e145 100644
--- a/erpnext/setup/setup_wizard/setup_wizard.py
+++ b/erpnext/setup/setup_wizard/setup_wizard.py
@@ -7,7 +7,6 @@
from .operations import company_setup
from .operations import install_fixtures as fixtures
-from .operations import sample_data
def get_setup_stages(args=None):
@@ -103,16 +102,6 @@
frappe.local.message_log = []
login_as_first_user(args)
- make_sample_data(args.get('domains'))
-
-def make_sample_data(domains):
- try:
- sample_data.make_sample_data(domains)
- except Exception:
- # clear message
- if frappe.message_log:
- frappe.message_log.pop()
- pass
def login_as_first_user(args):
if args.get("email") and hasattr(frappe.local, "login_manager"):
diff --git a/erpnext/setup/setup_wizard/tasks/education_masters.md b/erpnext/setup/setup_wizard/tasks/education_masters.md
deleted file mode 100644
index d0887d2..0000000
--- a/erpnext/setup/setup_wizard/tasks/education_masters.md
+++ /dev/null
@@ -1,9 +0,0 @@
-Lets start making things in ERPNext that are representative of your institution.
-
-1. Make a list of **Programs** that you offer
-1. Add a few **Courses** that your programs cover
-1. Create **Academic Terms** and **Academic Years**
-1. Start adding **Students**
-1. Group your students into **Batches**
-
-Watch this video to learn more about ERPNext Education: https://www.youtube.com/watch?v=f6foQOyGzdA
diff --git a/erpnext/setup/setup_wizard/tasks/explore.md b/erpnext/setup/setup_wizard/tasks/explore.md
deleted file mode 100644
index ce6cb60..0000000
--- a/erpnext/setup/setup_wizard/tasks/explore.md
+++ /dev/null
@@ -1,7 +0,0 @@
-Thanks for checking this out! ❤️
-
-If you are evaluating an ERP system for the first time, this is going to be quite a task! But don't worry, ERPNext is awesome.
-
-First, get familiar with the surroundings. ERPNext covers a *lot of features*, go to the home page and click on the "Explore" icon.
-
-All the best!
\ No newline at end of file
diff --git a/erpnext/setup/setup_wizard/tasks/go_live.md b/erpnext/setup/setup_wizard/tasks/go_live.md
deleted file mode 100644
index 0a934a4..0000000
--- a/erpnext/setup/setup_wizard/tasks/go_live.md
+++ /dev/null
@@ -1,18 +0,0 @@
-Ready to go live with ERPNext? 🏁🏁🏁
-
-Here are the steps:
-
-1. Sync up your **Chart of Accounts**
-3. Add your opening stock using **Stock Reconciliation**
-4. Add your open invoices (both sales and purchase)
-3. Add your opening account balances by making a **Journal Entry**
-
-If you need help for going live, sign up for an account at erpnext.com or find a partner to help you with this.
-
-Or you can watch these videos 📺:
-
-Setup your chart of accounts: https://www.youtube.com/watch?v=AcfMCT7wLLo
-
-Add Open Stock: https://www.youtube.com/watch?v=nlHX0ZZ84Lw
-
-Add Opening Balances: https://www.youtube.com/watch?v=nlHX0ZZ84Lw
diff --git a/erpnext/setup/setup_wizard/tasks/import_data.md b/erpnext/setup/setup_wizard/tasks/import_data.md
deleted file mode 100644
index c5b85c9..0000000
--- a/erpnext/setup/setup_wizard/tasks/import_data.md
+++ /dev/null
@@ -1,5 +0,0 @@
-Lets import some data! 💪💪
-
-If you are already running a business, you most likely have your Items, Customers or Suppliers in some spreadsheet file somewhere, import it into ERPNext with the Data Import Tool.
-
-Watch this video to get started: https://www.youtube.com/watch?v=Ta2Xx3QoK3E
diff --git a/erpnext/setup/setup_wizard/tasks/masters.md b/erpnext/setup/setup_wizard/tasks/masters.md
deleted file mode 100644
index 6ade159..0000000
--- a/erpnext/setup/setup_wizard/tasks/masters.md
+++ /dev/null
@@ -1,7 +0,0 @@
-Start building a model of your business in ERPNext by adding your Items and Customers.
-
-These videos 📺 will help you get started:
-
-Adding Customers and Suppliers: https://www.youtube.com/watch?v=zsrrVDk6VBs
-
-Adding Items and Prices: https://www.youtube.com/watch?v=FcOsV-e8ymE
\ No newline at end of file
diff --git a/erpnext/setup/setup_wizard/tasks/purchase.md b/erpnext/setup/setup_wizard/tasks/purchase.md
deleted file mode 100644
index 3f3bc3b..0000000
--- a/erpnext/setup/setup_wizard/tasks/purchase.md
+++ /dev/null
@@ -1,10 +0,0 @@
-How to manage your purchasing in ERPNext 🛒🛒🛒:
-
-1. Add a few **Suppliers**
-2. Find out what you need by making **Material Requests**.
-3. Now start placing orders via **Purchase Order**.
-4. When your suppliers deliver, make **Purchase Receipts**
-
-Now never run out of stock again! 😎
-
-Watch this video 📺 to get an overview: https://www.youtube.com/watch?v=4TN9kPyfIqM
\ No newline at end of file
diff --git a/erpnext/setup/setup_wizard/tasks/sales.md b/erpnext/setup/setup_wizard/tasks/sales.md
deleted file mode 100644
index 15268fa..0000000
--- a/erpnext/setup/setup_wizard/tasks/sales.md
+++ /dev/null
@@ -1,8 +0,0 @@
-Start managing your sales with ERPNext 🔔🔔🔔:
-
-1. Add potential business contacts as **Leads**
-2. Udpate your deals in pipeline in **Opportunities**
-3. Send proposals to your leads or customers with **Quotations**
-4. Track confirmed orders with **Sales Orders**
-
-Watch this video 📺 to get an overview: https://www.youtube.com/watch?v=o9XCSZHJfpA
diff --git a/erpnext/setup/setup_wizard/tasks/school_import_data.md b/erpnext/setup/setup_wizard/tasks/school_import_data.md
deleted file mode 100644
index 1fbe049..0000000
--- a/erpnext/setup/setup_wizard/tasks/school_import_data.md
+++ /dev/null
@@ -1,5 +0,0 @@
-Lets import some data! 💪💪
-
-If you are already running a Institute, you most likely have your Students in some spreadsheet file somewhere. Import it into ERPNext with the Data Import Tool.
-
-Watch this video to get started: https://www.youtube.com/watch?v=Ta2Xx3QoK3E
\ No newline at end of file
diff --git a/erpnext/setup/setup_wizard/tasks/task_alert.json b/erpnext/setup/setup_wizard/tasks/task_alert.json
deleted file mode 100644
index cac868a..0000000
--- a/erpnext/setup/setup_wizard/tasks/task_alert.json
+++ /dev/null
@@ -1,28 +0,0 @@
-[
- {
- "attach_print": 0,
- "condition": "doc.status in ('Open', 'Overdue')",
- "date_changed": "exp_end_date",
- "days_in_advance": 0,
- "docstatus": 0,
- "doctype": "Notification",
- "document_type": "Task",
- "enabled": 1,
- "event": "Days After",
- "is_standard": 0,
- "message": "<p>Task due today:</p>\n\n<div>\n{{ doc.description }}\n</div>\n\n<hr>\n<p style=\"font-size: 85%\">\nThis is a notification for a task that is due today, and a sample <b>Notification</b>. In ERPNext you can setup notifications on anything, Invoices, Orders, Leads, Opportunities, so you never miss a thing.\n<br>To edit this, and setup other alerts, just type <b>Notification</b> in the search bar.</p>",
- "method": null,
- "modified": "2017-03-09 07:34:58.168370",
- "module": null,
- "name": "Task Due Alert",
- "recipients": [
- {
- "cc": null,
- "condition": null,
- "email_by_document_field": "owner"
- }
- ],
- "subject": "{{ doc.subject }}",
- "value_changed": null
- }
-]
\ No newline at end of file
diff --git a/erpnext/setup/setup_wizard/utils.py b/erpnext/setup/setup_wizard/utils.py
deleted file mode 100644
index f1ec50af..0000000
--- a/erpnext/setup/setup_wizard/utils.py
+++ /dev/null
@@ -1,12 +0,0 @@
-import json
-import os
-
-from frappe.desk.page.setup_wizard.setup_wizard import setup_complete
-
-
-def complete():
- with open(os.path.join(os.path.dirname(__file__),
- 'data', 'test_mfg.json'), 'r') as f:
- data = json.loads(f.read())
-
- setup_complete(data)
diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py
index a4f2207..6db1961 100644
--- a/erpnext/setup/utils.py
+++ b/erpnext/setup/utils.py
@@ -5,28 +5,17 @@
import frappe
from frappe import _
from frappe.utils import add_days, flt, get_datetime_str, nowdate
+from frappe.utils.data import now_datetime
+from frappe.utils.nestedset import get_ancestors_of, get_root_of # noqa
from erpnext import get_default_company
-def get_root_of(doctype):
- """Get root element of a DocType with a tree structure"""
- result = frappe.db.sql_list("""select name from `tab%s`
- where lft=1 and rgt=(select max(rgt) from `tab%s` where docstatus < 2)""" %
- (doctype, doctype))
- return result[0] if result else None
-
-def get_ancestors_of(doctype, name):
- """Get ancestor elements of a DocType with a tree structure"""
- lft, rgt = frappe.db.get_value(doctype, name, ["lft", "rgt"])
- result = frappe.db.sql_list("""select name from `tab%s`
- where lft<%s and rgt>%s order by lft desc""" % (doctype, "%s", "%s"), (lft, rgt))
- return result or []
-
def before_tests():
frappe.clear_cache()
# complete setup if missing
from frappe.desk.page.setup_wizard.setup_wizard import setup_complete
+ current_year = now_datetime().year
if not frappe.get_list("Company"):
setup_complete({
"currency" :"USD",
@@ -36,8 +25,8 @@
"company_abbr" :"WP",
"industry" :"Manufacturing",
"country" :"United States",
- "fy_start_date" :"2021-01-01",
- "fy_end_date" :"2021-12-31",
+ "fy_start_date" :f"{current_year}-01-01",
+ "fy_end_date" :f"{current_year}-12-31",
"language" :"english",
"company_tagline" :"Testing",
"email" :"test@erpnext.com",
@@ -51,7 +40,6 @@
frappe.db.sql("delete from `tabSalary Slip`")
frappe.db.sql("delete from `tabItem Price`")
- frappe.db.set_value("Stock Settings", None, "auto_insert_price_list_rate_if_missing", 0)
enable_all_roles_and_domains()
set_defaults_for_tests()
@@ -142,13 +130,13 @@
add_all_roles_to('Administrator')
def set_defaults_for_tests():
- from frappe.utils.nestedset import get_root_of
-
selling_settings = frappe.get_single("Selling Settings")
selling_settings.customer_group = get_root_of("Customer Group")
selling_settings.territory = get_root_of("Territory")
selling_settings.save()
+ frappe.db.set_single_value("Stock Settings", "auto_insert_price_list_rate_if_missing", 0)
+
def insert_record(records):
for r in records:
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index ffa2f93..492f90b 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -519,6 +519,8 @@
if automatically_fetch_payment_terms:
doc.set_payment_schedule()
+ doc.set_onload('ignore_price_list', True)
+
return doc
@frappe.whitelist()
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 5bb337e..4bf37fe 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -823,6 +823,7 @@
}
}, target_doc, set_missing_values)
+ doclist.set_onload('ignore_price_list', True)
return doclist
def get_invoiced_qty_map(purchase_receipt):
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index c77c6c3..4c06012 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -3,6 +3,7 @@
import json
+from typing import List, Optional, Union
import frappe
from frappe import ValidationError, _
@@ -574,22 +575,30 @@
return serial_nos
@frappe.whitelist()
-def auto_fetch_serial_number(qty, item_code, warehouse,
- posting_date=None, batch_nos=None, for_doctype=None, exclude_sr_nos=None):
+def auto_fetch_serial_number(
+ qty: float,
+ item_code: str,
+ warehouse: str,
+ posting_date: Optional[str] = None,
+ batch_nos: Optional[Union[str, List[str]]] = None,
+ for_doctype: Optional[str] = None,
+ exclude_sr_nos: Optional[List[str]] = None
+ ) -> List[str]:
filters = frappe._dict({"item_code": item_code, "warehouse": warehouse})
if exclude_sr_nos is None:
exclude_sr_nos = []
else:
+ exclude_sr_nos = safe_json_loads(exclude_sr_nos)
exclude_sr_nos = get_serial_nos(clean_serial_no_string("\n".join(exclude_sr_nos)))
if batch_nos:
batch_nos = safe_json_loads(batch_nos)
if isinstance(batch_nos, list):
filters.batch_no = batch_nos
- elif isinstance(batch_nos, str):
- filters.batch_no = [batch_nos]
+ else:
+ filters.batch_no = [str(batch_nos)]
if posting_date:
filters.expiry_date = posting_date
diff --git a/erpnext/stock/doctype/serial_no/test_serial_no.py b/erpnext/stock/doctype/serial_no/test_serial_no.py
index cca6307..7df0a56 100644
--- a/erpnext/stock/doctype/serial_no/test_serial_no.py
+++ b/erpnext/stock/doctype/serial_no/test_serial_no.py
@@ -274,7 +274,8 @@
msg=f"{partial_fetch} should be subset of {first_fetch}")
# exclusion
- remaining = auto_fetch_serial_number(3, item_code, warehouse, exclude_sr_nos=partial_fetch)
+ remaining = auto_fetch_serial_number(3, item_code, warehouse,
+ exclude_sr_nos=json.dumps(partial_fetch))
self.assertEqual(sorted(remaining + partial_fetch), first_fetch)
# batchwise
diff --git a/erpnext/templates/generators/item_group.html b/erpnext/templates/generators/item_group.html
index e099cdd..956c3c51 100644
--- a/erpnext/templates/generators/item_group.html
+++ b/erpnext/templates/generators/item_group.html
@@ -52,24 +52,6 @@
</div>
- <script>
- frappe.ready(() => {
- $('.product-filter-filter').on('keydown', frappe.utils.debounce((e) => {
- const $input = $(e.target);
- const keyword = ($input.val() || '').toLowerCase();
- const $filter_options = $input.next('.filter-options');
-
- $filter_options.find('.custom-control').show();
- $filter_options.find('.custom-control').each((i, el) => {
- const $el = $(el);
- const value = $el.data('value').toLowerCase();
- if (!value.includes(keyword)) {
- $el.hide();
- }
- });
- }, 300));
- })
- </script>
</div>
</div>
</div>
diff --git a/erpnext/templates/includes/macros.html b/erpnext/templates/includes/macros.html
index 4741307..fb4cecf 100644
--- a/erpnext/templates/includes/macros.html
+++ b/erpnext/templates/includes/macros.html
@@ -300,13 +300,13 @@
{% if values | len > 20 %}
<!-- show inline filter if values more than 20 -->
- <input type="text" class="form-control form-control-sm mb-2 product-filter-filter"/>
+ <input type="text" class="form-control form-control-sm mb-2 filter-lookup-input" placeholder="Search {{ item_field.label + 's' }}"/>
{% endif %}
{% if values %}
<div class="filter-options">
{% for value in values %}
- <div class="checkbox" data-value="{{ value }}">
+ <div class="filter-lookup-wrapper checkbox" data-value="{{ value }}">
<label for="{{value}}">
<input type="checkbox"
class="product-filter field-filter"
@@ -329,16 +329,16 @@
{%- macro attribute_filter_section(filters)-%}
{% for attribute in filters %}
<div class="mb-4 filter-block pb-5">
- <div class="filter-label mb-3">{{ attribute.name}}</div>
- {% if values | len > 20 %}
+ <div class="filter-label mb-3">{{ attribute.name }}</div>
+ {% if attribute.item_attribute_values | len > 20 %}
<!-- show inline filter if values more than 20 -->
- <input type="text" class="form-control form-control-sm mb-2 product-filter-filter"/>
+ <input type="text" class="form-control form-control-sm mb-2 filter-lookup-input" placeholder="Search {{ attribute.name + 's' }}"/>
{% endif %}
{% if attribute.item_attribute_values %}
<div class="filter-options">
{% for attr_value in attribute.item_attribute_values %}
- <div class="checkbox">
+ <div class="filter-lookup-wrapper checkbox" data-value="{{ attr_value }}">
<label data-value="{{ attr_value }}">
<input type="checkbox"
class="product-filter attribute-filter"
diff --git a/erpnext/www/all-products/index.html b/erpnext/www/all-products/index.html
index 3d5517c..04fc74c 100644
--- a/erpnext/www/all-products/index.html
+++ b/erpnext/www/all-products/index.html
@@ -31,24 +31,6 @@
{% endif %}
</div>
- <script>
- frappe.ready(() => {
- $('.product-filter-filter').on('keydown', frappe.utils.debounce((e) => {
- const $input = $(e.target);
- const keyword = ($input.val() || '').toLowerCase();
- const $filter_options = $input.next('.filter-options');
-
- $filter_options.find('.custom-control').show();
- $filter_options.find('.custom-control').each((i, el) => {
- const $el = $(el);
- const value = $el.data('value').toLowerCase();
- if (!value.includes(keyword)) {
- $el.hide();
- }
- });
- }, 300));
- })
- </script>
</div>
</div>