Merge branch 'develop' into fix-payment-entry-wrong-bank-account-fetch-develop
diff --git a/erpnext/accounts/doctype/coupon_code/test_coupon_code.py b/erpnext/accounts/doctype/coupon_code/test_coupon_code.py
index 990b896..3a0d416 100644
--- a/erpnext/accounts/doctype/coupon_code/test_coupon_code.py
+++ b/erpnext/accounts/doctype/coupon_code/test_coupon_code.py
@@ -26,22 +26,22 @@
 		"item_group": "_Test Item Group",
 		"item_name": "_Test Tesla Car",
 		"apply_warehouse_wise_reorder_level": 0,
-		"warehouse":"_Test Warehouse - _TC",
+		"warehouse":"Stores - TCP1",
 		"gst_hsn_code": "999800",
 		"valuation_rate": 5000,
 		"standard_rate":5000,
 		"item_defaults": [{
-		"company": "_Test Company",
-		"default_warehouse": "_Test Warehouse - _TC",
+		"company": "_Test Company with perpetual inventory",
+		"default_warehouse": "Stores - TCP1",
 		"default_price_list":"_Test Price List",
-		"expense_account": "_Test Account Cost for Goods Sold - _TC",
-		"buying_cost_center": "_Test Cost Center - _TC",
-		"selling_cost_center": "_Test Cost Center - _TC",
-		"income_account": "Sales - _TC"
+		"expense_account": "Cost of Goods Sold - TCP1",
+		"buying_cost_center": "Main - TCP1",
+		"selling_cost_center": "Main - TCP1",
+		"income_account": "Sales - TCP1"
 		}],
 		"show_in_website": 1,
 		"route":"-test-tesla-car",
-		"website_warehouse": "_Test Warehouse - _TC"
+		"website_warehouse": "Stores - TCP1"
 		})
 		item.insert()
 	# create test item price
@@ -63,12 +63,12 @@
 		"items": [{
 			"item_code": "_Test Tesla Car"
 		}],
-		"warehouse":"_Test Warehouse - _TC",
+		"warehouse":"Stores - TCP1",
 		"coupon_code_based":1,
 		"selling": 1,
 		"rate_or_discount": "Discount Percentage",
 		"discount_percentage": 30,
-		"company": "_Test Company",
+		"company": "_Test Company with perpetual inventory",
 		"currency":"INR",
 		"for_price_list":"_Test Price List"
 		})
@@ -112,7 +112,10 @@
 		self.assertEqual(coupon_code.get("used"),0)
 
 	def test_2_sales_order_with_coupon_code(self):
-		so = make_sales_order(customer="_Test Customer",selling_price_list="_Test Price List",item_code="_Test Tesla Car", rate=5000,qty=1, do_not_submit=True)
+		so = make_sales_order(company='_Test Company with perpetual inventory', warehouse='Stores - TCP1',
+			customer="_Test Customer", selling_price_list="_Test Price List", item_code="_Test Tesla Car", rate=5000,qty=1,
+			do_not_submit=True)
+
 		so = frappe.get_doc('Sales Order', so.name)
 		# check item price before coupon code is applied
 		self.assertEqual(so.items[0].rate, 5000)
@@ -120,7 +123,7 @@
 		so.sales_partner='_Test Coupon Partner'
 		so.save()
 		# check item price after coupon code is applied
-		self.assertEqual(so.items[0].rate, 3500)	
+		self.assertEqual(so.items[0].rate, 3500)
 		so.submit()
 
 	def test_3_check_coupon_code_used_after_so(self):
diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
index 23ad1ee..479d4b6 100644
--- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
@@ -6,6 +6,7 @@
 from frappe.utils import flt, nowdate
 from erpnext.accounts.doctype.account.test_account import get_inventory_account
 from erpnext.exceptions import InvalidAccountCurrency
+from erpnext.accounts.general_ledger import StockAccountInvalidTransaction
 
 class TestJournalEntry(unittest.TestCase):
 	def test_journal_entry_with_against_jv(self):
@@ -81,19 +82,46 @@
 		from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
 		set_perpetual_inventory()
 
-		jv = frappe.copy_doc(test_records[0])
+		jv = frappe.copy_doc({
+			"cheque_date": nowdate(),
+			"cheque_no": "33",
+			"company": "_Test Company with perpetual inventory",
+			"doctype": "Journal Entry",
+			"accounts": [
+			{
+				"account": "Debtors - TCP1",
+				"party_type": "Customer",
+				"party": "_Test Customer",
+				"credit_in_account_currency": 400.0,
+				"debit_in_account_currency": 0.0,
+				"doctype": "Journal Entry Account",
+				"parentfield": "accounts",
+				"cost_center": "Main - TCP1"
+			},
+			{
+				"account": "_Test Bank - TCP1",
+				"credit_in_account_currency": 0.0,
+				"debit_in_account_currency": 400.0,
+				"doctype": "Journal Entry Account",
+				"parentfield": "accounts",
+				"cost_center": "Main - TCP1"
+			}
+			],
+			"naming_series": "_T-Journal Entry-",
+			"posting_date": nowdate(),
+			"user_remark": "test",
+			"voucher_type": "Bank Entry"
+			})
+
 		jv.get("accounts")[0].update({
-			"account": get_inventory_account('_Test Company'),
-			"company": "_Test Company",
+			"account": get_inventory_account('_Test Company with perpetual inventory'),
+			"company": "_Test Company with perpetual inventory",
 			"party_type": None,
 			"party": None
 		})
 
-		jv.insert()
-
-		from erpnext.accounts.general_ledger import StockAccountInvalidTransaction
 		self.assertRaises(StockAccountInvalidTransaction, jv.submit)
-
+		jv.cancel()
 		set_perpetual_inventory(0)
 
 	def test_multi_currency(self):
diff --git a/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py
index f295725..9c62a87 100644
--- a/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py
+++ b/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py
@@ -23,13 +23,13 @@
 		import time
 		time.sleep(1)
 		self.assertRaises(frappe.TimestampMismatchError, w2.save)
-	
+
 	def test_change_naming_series(self):
 		inv = create_pos_invoice(do_not_submit=1)
 		inv.naming_series = 'TEST-'
 
 		self.assertRaises(frappe.CannotChangeConstantError, inv.save)
-	
+
 	def test_discount_and_inclusive_tax(self):
 		inv = create_pos_invoice(qty=100, rate=50, do_not_save=1)
 		inv.append("taxes", {
@@ -66,7 +66,7 @@
 
 		self.assertEqual(inv.net_total, 4298.25)
 		self.assertEqual(inv.grand_total, 4900.00)
-	
+
 	def test_tax_calculation_with_multiple_items(self):
 		inv = create_pos_invoice(qty=84, rate=4.6, do_not_save=True)
 		item_row = inv.get("items")[0]
@@ -148,7 +148,7 @@
 		self.assertEqual(inv.grand_total, 5675.57)
 		self.assertEqual(inv.rounding_adjustment, 0.43)
 		self.assertEqual(inv.rounded_total, 5676.0)
-	
+
 	def test_tax_calculation_with_multiple_items_and_discount(self):
 		inv = create_pos_invoice(qty=1, rate=75, do_not_save=True)
 		item_row = inv.get("items")[0]
@@ -194,7 +194,7 @@
 
 		self.assertEqual(pos_return.get('payments')[0].amount, -500)
 		self.assertEqual(pos_return.get('payments')[1].amount, -500)
-	
+
 	def test_pos_change_amount(self):
 		pos = create_pos_invoice(company= "_Test Company", debit_to="Debtors - _TC",
 			income_account = "Sales - _TC", expense_account = "Cost of Goods Sold - _TC", rate=105,
@@ -208,33 +208,43 @@
 
 		self.assertEqual(pos.grand_total, 105.0)
 		self.assertEqual(pos.change_amount, 5.0)
-	
+
 	def test_without_payment(self):
 		inv = create_pos_invoice(do_not_save=1)
 		# Check that the invoice cannot be submitted without payments
 		inv.payments = []
 		self.assertRaises(frappe.ValidationError, inv.insert)
-	
+
 	def test_serialized_item_transaction(self):
 		from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item
 		from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
 
-		se = make_serialized_item(target_warehouse="_Test Warehouse - _TC")
+		se = make_serialized_item(company='_Test Company with perpetual inventory',
+			target_warehouse="Stores - TCP1", cost_center='Main - TCP1', expense_account='Cost of Goods Sold - TCP1')
+
 		serial_nos = get_serial_nos(se.get("items")[0].serial_no)
 
-		pos = create_pos_invoice(item=se.get("items")[0].item_code, rate=1000, do_not_save=1)
+		pos = create_pos_invoice(company='_Test Company with perpetual inventory', debit_to='Debtors - TCP1',
+			account_for_change_amount='Cash - TCP1', warehouse='Stores - TCP1', income_account='Sales - TCP1',
+			expense_account='Cost of Goods Sold - TCP1', cost_center='Main - TCP1',
+			item=se.get("items")[0].item_code, rate=1000, do_not_save=1)
+
 		pos.get("items")[0].serial_no = serial_nos[0]
-		pos.append("payments", {'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - _TC', 'amount': 1000})
+		pos.append("payments", {'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - TCP1', 'amount': 1000})
 
 		pos.insert()
 		pos.submit()
 
-		pos2 = create_pos_invoice(item=se.get("items")[0].item_code, rate=1000, do_not_save=1)
+		pos2 = create_pos_invoice(company='_Test Company with perpetual inventory', debit_to='Debtors - TCP1',
+			account_for_change_amount='Cash - TCP1', warehouse='Stores - TCP1', income_account='Sales - TCP1',
+			expense_account='Cost of Goods Sold - TCP1', cost_center='Main - TCP1',
+			item=se.get("items")[0].item_code, rate=1000, do_not_save=1)
+
 		pos2.get("items")[0].serial_no = serial_nos[0]
-		pos2.append("payments", {'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - _TC', 'amount': 1000})
-		
+		pos2.append("payments", {'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - TCP1', 'amount': 1000})
+
 		self.assertRaises(frappe.ValidationError, pos2.insert)
-	
+
 	def test_loyalty_points(self):
 		from erpnext.accounts.doctype.loyalty_program.test_loyalty_program import create_records
 		from erpnext.accounts.doctype.loyalty_program.loyalty_program import get_loyalty_program_details_with_points
@@ -255,14 +265,14 @@
 		inv.cancel()
 		after_cancel_lp_details = get_loyalty_program_details_with_points(inv.customer, company=inv.company, loyalty_program=inv.loyalty_program)
 		self.assertEqual(after_cancel_lp_details.loyalty_points, before_lp_details.loyalty_points)
-	
+
 	def test_loyalty_points_redeemption(self):
 		from erpnext.accounts.doctype.loyalty_program.loyalty_program import get_loyalty_program_details_with_points
 		# add 10 loyalty points
 		create_pos_invoice(customer="Test Loyalty Customer", rate=10000)
 
 		before_lp_details = get_loyalty_program_details_with_points("Test Loyalty Customer", company="_Test Company", loyalty_program="Test Single Loyalty")
-		
+
 		inv = create_pos_invoice(customer="Test Loyalty Customer", rate=10000, do_not_save=1)
 		inv.redeem_loyalty_points = 1
 		inv.loyalty_points = before_lp_details.loyalty_points
@@ -299,7 +309,7 @@
 	pos_inv.return_against = args.return_against
 	pos_inv.currency=args.currency or "INR"
 	pos_inv.conversion_rate = args.conversion_rate or 1
-	pos_inv.account_for_change_amount = "Cash - _TC"
+	pos_inv.account_for_change_amount = args.account_for_change_amount or "Cash - _TC"
 
 	pos_inv.append("items", {
 		"item_code": args.item or args.item_code or "_Test Item",
diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py
index a245d63..cf3deb8 100644
--- a/erpnext/accounts/general_ledger.py
+++ b/erpnext/accounts/general_ledger.py
@@ -158,8 +158,10 @@
 			if account not in aii_accounts:
 				continue
 
+			# Always use current date to get stock and account balance as there can future entries for
+			# other items
 			account_bal, stock_bal, warehouse_list = get_stock_and_account_balance(account,
-				gl_map[0].posting_date, gl_map[0].company)
+				getdate(), gl_map[0].company)
 
 			if gl_map[0].voucher_type=="Journal Entry":
 				# In case of Journal Entry, there are no corresponding SL entries,
@@ -169,7 +171,6 @@
 					frappe.throw(_("Account: {0} can only be updated via Stock Transactions")
 						.format(account), StockAccountInvalidTransaction)
 
-			# This has been comment for a temporary, will add this code again on release of immutable ledger
 			elif account_bal != stock_bal:
 				precision = get_field_precision(frappe.get_meta("GL Entry").get_field("debit"),
 					currency=frappe.get_cached_value('Company',  gl_map[0].company,  "default_currency"))
diff --git a/erpnext/education/doctype/student_attendance_tool/student_attendance_tool.js b/erpnext/education/doctype/student_attendance_tool/student_attendance_tool.js
index cc9607d..0384505 100644
--- a/erpnext/education/doctype/student_attendance_tool/student_attendance_tool.js
+++ b/erpnext/education/doctype/student_attendance_tool/student_attendance_tool.js
@@ -140,7 +140,7 @@
 							frappe.call({
 								method: "erpnext.education.api.mark_attendance",
 								freeze: true,
-								freeze_message: "Marking attendance",
+								freeze_message: __("Marking attendance"),
 								args: {
 									"students_present": students_present,
 									"students_absent": students_absent,
@@ -180,4 +180,4 @@
 			</div>`
 		);
 	}
-});
\ No newline at end of file
+});
diff --git a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py
index ce58148..1043e5b 100644
--- a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py
+++ b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py
@@ -42,7 +42,7 @@
 				# create the list of possible grades
 				if student_row[scrub_criteria] not in grades:
 					grades.append(student_row[scrub_criteria])
-				
+
 				# create the dict of for gradewise analysis
 				if student_row[scrub_criteria] not in grade_wise_analysis[criteria]:
 					grade_wise_analysis[criteria][student_row[scrub_criteria]] = 1
@@ -101,7 +101,7 @@
 
 	# create the nested dictionary structure as given below:
 	# <variable_name>.<student_name>.<course>.<assessment_group>.<assessment_criteria>.<grade/score/max_score>
-	# "Total Score" -> assessment criteria used for totaling and args.assessment_group -> for totaling all the assesments
+	# "Final Grade" -> assessment criteria used for totaling and args.assessment_group -> for totaling all the assesments
 
 	student_details = {}
 	formatted_assessment_result = defaultdict(dict)
@@ -123,13 +123,13 @@
 		formatted_assessment_result[result.student][result.course][assessment_group]\
 			[assessment_criteria]["grade"] = tmp_grade
 
-	# create the assessment criteria "Total Score" with the sum of all the scores of the assessment criteria in a given assessment group
+	# create the assessment criteria "Final Grade" with the sum of all the scores of the assessment criteria in a given assessment group
 	def add_total_score(result, assessment_group):
-		if "Total Score" not in formatted_assessment_result[result.student][result.course][assessment_group]:
-			formatted_assessment_result[result.student][result.course][assessment_group]["Total Score"] = frappe._dict({
-				"assessment_criteria": "Total Score", "maximum_score": result.maximum_score, "score": result.score, "grade": result.grade})
+		if "Final Grade" not in formatted_assessment_result[result.student][result.course][assessment_group]:
+			formatted_assessment_result[result.student][result.course][assessment_group]["Final Grade"] = frappe._dict({
+				"assessment_criteria": "Final Grade", "maximum_score": result.maximum_score, "score": result.score, "grade": result.grade})
 		else:
-			add_score_and_recalculate_grade(result, assessment_group, "Total Score")
+			add_score_and_recalculate_grade(result, assessment_group, "Final Grade")
 
 	for result in assessment_result:
 		if result.student not in student_details:
@@ -152,7 +152,7 @@
 		elif create_total_dict:
 			if get_all_assessment_groups:
 				formatted_assessment_result[result.student][result.course][result.assessment_group]\
-					[result.assessment_criteria] = assessment_criteria_details				
+					[result.assessment_criteria] = assessment_criteria_details
 			if not formatted_assessment_result[result.student][result.course][args.assessment_group]:
 				formatted_assessment_result[result.student][result.course][args.assessment_group] = defaultdict(dict)
 				formatted_assessment_result[result.student][result.course][args.assessment_group]\
@@ -166,7 +166,7 @@
 			add_total_score(result, args.assessment_group)
 
 		total_maximum_score = formatted_assessment_result[result.student][result.course][args.assessment_group]\
-			["Total Score"]["maximum_score"]
+			["Final Grade"]["maximum_score"]
 		if get_assessment_criteria:
 			assessment_criteria_dict[result.assessment_criteria] = formatted_assessment_result[result.student][result.course]\
 				[args.assessment_group][result.assessment_criteria]["maximum_score"]
@@ -174,7 +174,7 @@
 			course_dict[result.course] = total_maximum_score
 
 	if get_assessment_criteria and total_maximum_score:
-		assessment_criteria_dict["Total Score"] = total_maximum_score
+		assessment_criteria_dict["Final Grade"] = total_maximum_score
 
 	return {
 		"student_details": student_details,
@@ -220,7 +220,7 @@
 	datasets = []
 
 	for grade in grades:
-		tmp = frappe._dict({"values":[], "title": grade})
+		tmp = frappe._dict({"name": grade, "values":[]})
 		for criteria in criteria_list:
 			if grade in kounter[criteria]:
 				tmp["values"].append(kounter[criteria][grade])
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test_list.js b/erpnext/healthcare/doctype/lab_test/lab_test_list.js
index 6783bb3..b7f157c 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test_list.js
+++ b/erpnext/healthcare/doctype/lab_test/lab_test_list.js
@@ -58,7 +58,7 @@
 					}
 				},
 				freeze: true,
-				freeze_message: 'Creating Lab Tests...'
+				freeze_message: __('Creating Lab Tests...')
 			});
 			dialog.hide();
 		}
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
index edcee99..6353d19 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
@@ -220,7 +220,7 @@
 					}
 				},
 				freeze: true,
-				freeze_message: 'Scheduling Patient Admission'
+				freeze_message: __('Scheduling Patient Admission')
 			});
 			frm.refresh_fields();
 			dialog.hide();
diff --git a/erpnext/hr/doctype/holiday_list/holiday_list_calendar.js b/erpnext/hr/doctype/holiday_list/holiday_list_calendar.js
index 3cc8dd5..4e188ad 100644
--- a/erpnext/hr/doctype/holiday_list/holiday_list_calendar.js
+++ b/erpnext/hr/doctype/holiday_list/holiday_list_calendar.js
@@ -9,6 +9,7 @@
 		"title": "description",
 		"allDay": "allDay"
 	},
+	order_by: `from_date`,
 	get_events_method: "erpnext.hr.doctype.holiday_list.holiday_list.get_events",
 	filters: [
 		{
diff --git a/erpnext/non_profit/doctype/member/member.js b/erpnext/non_profit/doctype/member/member.js
index 3e9d0ba..199dcfc 100644
--- a/erpnext/non_profit/doctype/member/member.js
+++ b/erpnext/non_profit/doctype/member/member.js
@@ -29,6 +29,14 @@
 				frappe.set_route('query-report', 'Accounts Receivable', {member:frm.doc.name});
 			});
 
+			if (!frm.doc.customer) {
+				frm.add_custom_button(__('Create Customer'), () => {
+					frm.call('make_customer_and_link').then(() => {
+						frm.reload_doc();
+					});
+				});
+			}
+
 			// indicator
 			erpnext.utils.set_party_dashboard_indicators(frm);
 
diff --git a/erpnext/non_profit/doctype/member/member.py b/erpnext/non_profit/doctype/member/member.py
index d1294cc..c52082c 100644
--- a/erpnext/non_profit/doctype/member/member.py
+++ b/erpnext/non_profit/doctype/member/member.py
@@ -53,6 +53,19 @@
 
 		return subscription
 
+	def make_customer_and_link(self):
+		if self.customer:
+			frappe.msgprint(_("A customer is already linked to this Member"))
+		cust = create_customer(frappe._dict({
+			'fullname': self.member_name,
+			'email': self.email_id or self.user,
+			'phone': None
+		}))
+
+		self.customer = cust
+		self.save()
+
+
 def get_or_create_member(user_details):
 	member_list = frappe.get_all("Member", filters={'email': user_details.email, 'membership_type': user_details.plan_id})
 	if member_list and member_list[0]:
@@ -83,8 +96,10 @@
 	try:
 		contact = frappe.new_doc("Contact")
 		contact.first_name = user_details.fullname
-		contact.add_phone(user_details.mobile, is_primary_phone=1, is_primary_mobile_no=1)
-		contact.add_email(user_details.email, is_primary=1)
+		if user_details.mobile:
+			contact.add_phone(user_details.mobile, is_primary_phone=1, is_primary_mobile_no=1)
+		if user_details.email:
+			contact.add_email(user_details.email, is_primary=1)
 		contact.insert(ignore_permissions=True)
 
 		contact.append("links", {
@@ -121,7 +136,7 @@
 			'subscription_id': 'sub_EZycCvXFvqnC6p'
 		}
 	"""
-	# {"plan_id":"IFF Starter","fullname":"Shivam Mishra","mobile":"7506056962","email":"shivam@shivam.dev","pan":"Testing123"}
+
 	user_details = frappe._dict(user_details)
 	member = get_or_create_member(user_details)
 	if not member:
diff --git a/erpnext/non_profit/doctype/membership/membership.json b/erpnext/non_profit/doctype/membership/membership.json
index 9f10d0c..238f4c3 100644
--- a/erpnext/non_profit/doctype/membership/membership.json
+++ b/erpnext/non_profit/doctype/membership/membership.json
@@ -120,13 +120,15 @@
   {
    "fieldname": "webhook_payload",
    "fieldtype": "Code",
+   "hidden": 1,
    "label": "Webhook Payload",
    "options": "JSON",
    "read_only": 1
   }
  ],
+ "index_web_pages_for_search": 1,
  "links": [],
- "modified": "2020-04-06 14:29:33.856060",
+ "modified": "2020-07-27 14:28:11.532696",
  "modified_by": "Administrator",
  "module": "Non Profit",
  "name": "Membership",
diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py
index 7a0caed..729e111 100644
--- a/erpnext/non_profit/doctype/membership/membership.py
+++ b/erpnext/non_profit/doctype/membership/membership.py
@@ -81,7 +81,12 @@
 @frappe.whitelist(allow_guest=True)
 def trigger_razorpay_subscription(*args, **kwargs):
 	data = frappe.request.get_data(as_text=True)
-	verify_signature(data)
+	try:
+		verify_signature(data)
+	except Exception as e:
+		signature = frappe.request.headers.get('X-Razorpay-Signature')
+		log = "{0} \n\n {1} \n\n {2} \n\n {3}".format(e, frappe.get_traceback(), signature, data)
+		frappe.log_error(e, "Webhook Verification Error")
 
 	if isinstance(data, six.string_types):
 		data = json.loads(data)
@@ -99,36 +104,40 @@
 	except Exception as e:
 		error_log = frappe.log_error(frappe.get_traceback() + '\n' + data_json , _("Membership Webhook Failed"))
 		notify_failure(error_log)
-		return False
+		return { status: 'Failed' }
 
 	if not member:
-		return False
+		return { status: 'Failed' }
+	try:
+		if data.event == "subscription.activated":
+			member.customer_id = payment.customer_id
+		elif data.event == "subscription.charged":
+			membership = frappe.new_doc("Membership")
+			membership.update({
+				"member": member.name,
+				"membership_status": "Current",
+				"membership_type": member.membership_type,
+				"currency": "INR",
+				"paid": 1,
+				"payment_id": payment.id,
+				"webhook_payload": data_json,
+				"from_date": datetime.fromtimestamp(subscription.current_start),
+				"to_date": datetime.fromtimestamp(subscription.current_end),
+				"amount": payment.amount / 100 # Convert to rupees from paise
+			})
+			membership.insert(ignore_permissions=True)
 
-	if data.event == "subscription.activated":
-		member.customer_id = payment.customer_id
-	elif data.event == "subscription.charged":
-		membership = frappe.new_doc("Membership")
-		membership.update({
-			"member": member.name,
-			"membership_status": "Current",
-			"membership_type": member.membership_type,
-			"currency": "INR",
-			"paid": 1,
-			"payment_id": payment.id,
-			"webhook_payload": data_json,
-			"from_date": datetime.fromtimestamp(subscription.current_start),
-			"to_date": datetime.fromtimestamp(subscription.current_end),
-			"amount": payment.amount / 100 # Convert to rupees from paise
-		})
-		membership.insert(ignore_permissions=True)
+		# Update these values anyway
+		member.subscription_start = datetime.fromtimestamp(subscription.start_at)
+		member.subscription_end = datetime.fromtimestamp(subscription.end_at)
+		member.subscription_activated = 1
+		member.save(ignore_permissions=True)
+	except Exception as e:
+		log = frappe.log_error(e, "Error creating membership entry")
+		notify_failure(log)
+		return { status: 'Failed' }
 
-	# Update these values anyway
-	member.subscription_start = datetime.fromtimestamp(subscription.start_at)
-	member.subscription_end = datetime.fromtimestamp(subscription.end_at)
-	member.subscription_activated = 1
-	member.save(ignore_permissions=True)
-
-	return True
+	return { status: 'Success' }
 
 
 def notify_failure(log):
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index a24f5f7..3bd4169 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -15,7 +15,7 @@
 erpnext.patches.v4_0.global_defaults_to_system_settings
 erpnext.patches.v4_0.update_incharge_name_to_sales_person_in_maintenance_schedule
 execute:frappe.reload_doc("accounts", "doctype", "POS Payment Method") #2020-05-28
-execute:frappe.reload_doc("HR", "doctype", "HR Settings") #2020-01-16
+execute:frappe.reload_doc("HR", "doctype", "HR Settings") #2020-01-16 #2020-07-24
 execute:frappe.reload_doc('stock', 'doctype', 'warehouse') # 2017-04-24
 execute:frappe.reload_doc('accounts', 'doctype', 'sales_invoice') # 2016-08-31
 execute:frappe.reload_doc('selling', 'doctype', 'sales_order') # 2014-01-29
diff --git a/erpnext/patches/v12_0/rename_pos_closing_doctype.py b/erpnext/patches/v12_0/rename_pos_closing_doctype.py
index 8ca92ef..0577f81 100644
--- a/erpnext/patches/v12_0/rename_pos_closing_doctype.py
+++ b/erpnext/patches/v12_0/rename_pos_closing_doctype.py
@@ -12,11 +12,11 @@
 			frappe.rename_doc('DocType', 'POS Closing Voucher Taxes', 'POS Closing Entry Taxes', force=True)
 		
 		if not frappe.db.exists('DocType', 'POS Closing Voucher Details'):
-			frappe.rename_doc('DocType', 'POS Closing Voucher Details', 'POS Closing Entry Details', force=True)
+			frappe.rename_doc('DocType', 'POS Closing Voucher Details', 'POS Closing Entry Detail', force=True)
 
 		frappe.reload_doc('Accounts', 'doctype', 'POS Closing Entry')
 		frappe.reload_doc('Accounts', 'doctype', 'POS Closing Entry Taxes')
-		frappe.reload_doc('Accounts', 'doctype', 'POS Closing Entry Details')
+		frappe.reload_doc('Accounts', 'doctype', 'POS Closing Entry Detail')
 
 	if frappe.db.exists("DocType", "POS Closing Voucher"):
 		frappe.delete_doc("DocType", "POS Closing Voucher")
diff --git a/erpnext/patches/v13_0/replace_pos_payment_mode_table.py b/erpnext/patches/v13_0/replace_pos_payment_mode_table.py
index 4a621b6..1ca211b 100644
--- a/erpnext/patches/v13_0/replace_pos_payment_mode_table.py
+++ b/erpnext/patches/v13_0/replace_pos_payment_mode_table.py
@@ -6,7 +6,7 @@
 import frappe
 
 def execute():
-	frappe.reload_doc("Selling", "doctype", "POS Payment Method")
+	frappe.reload_doc("accounts", "doctype", "POS Payment Method")
 	pos_profiles = frappe.get_all("POS Profile")
 
 	for pos_profile in pos_profiles:
diff --git a/erpnext/payroll/doctype/payroll_entry/payroll_entry.js b/erpnext/payroll/doctype/payroll_entry/payroll_entry.js
index 8d35a7b..1abc869 100644
--- a/erpnext/payroll/doctype/payroll_entry/payroll_entry.js
+++ b/erpnext/payroll/doctype/payroll_entry/payroll_entry.js
@@ -213,7 +213,7 @@
 				},
 				doc: frm.doc,
 				freeze: true,
-				freeze_message: 'Validating Employee Attendance...'
+				freeze_message: __('Validating Employee Attendance...')
 			});
 		}else{
 			frm.fields_dict.attendance_detail_html.html("");
@@ -237,7 +237,7 @@
 				callback: function() {frm.events.refresh(frm);},
 				doc: frm.doc,
 				freeze: true,
-				freeze_message: 'Submitting Salary Slips and creating Journal Entry...'
+				freeze_message: __('Submitting Salary Slips and creating Journal Entry...')
 			});
 		},
 		function() {
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index d5f479f..d7b43bf 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -13,7 +13,7 @@
 from erpnext.setup.doctype.item_group.item_group import (get_parent_item_groups, invalidate_cache_for)
 from frappe import _, msgprint
 from frappe.utils import (cint, cstr, flt, formatdate, get_timestamp, getdate,
-						  now_datetime, random_string, strip, get_link_to_form)
+		now_datetime, random_string, strip, get_link_to_form, nowtime)
 from frappe.utils.html_utils import clean_html
 from frappe.website.doctype.website_slideshow.website_slideshow import \
 	get_slideshow
@@ -194,7 +194,7 @@
 
 			if default_warehouse:
 				stock_entry = make_stock_entry(item_code=self.name, target=default_warehouse, qty=self.opening_stock,
-					rate=self.valuation_rate, company=default.company)
+					rate=self.valuation_rate, company=default.company, posting_date=getdate(), posting_time=nowtime())
 
 				stock_entry.add_comment("Comment", _("Opening Stock"))
 
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index 0fbc631..8e25804 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -413,7 +413,7 @@
 	def test_serial_item_error(self):
 		se, serial_nos = self.test_serial_by_series()
 		if not frappe.db.exists('Serial No', 'ABCD'):
-			make_serialized_item("_Test Serialized Item", "ABCD\nEFGH")
+			make_serialized_item(item_code="_Test Serialized Item", serial_no="ABCD\nEFGH")
 
 		se = frappe.copy_doc(test_records[0])
 		se.purpose = "Material Transfer"
@@ -823,15 +823,29 @@
 			])
 		)
 
-def make_serialized_item(item_code=None, serial_no=None, target_warehouse=None):
+def make_serialized_item(**args):
+	args = frappe._dict(args)
 	se = frappe.copy_doc(test_records[0])
-	se.get("items")[0].item_code = item_code or "_Test Serialized Item With Series"
-	se.get("items")[0].serial_no = serial_no
+
+	if args.company:
+		se.company = args.company
+
+	se.get("items")[0].item_code = args.item_code or "_Test Serialized Item With Series"
+
+	if args.serial_no:
+		se.get("items")[0].serial_no = args.serial_no
+
+	if args.cost_center:
+		se.get("items")[0].cost_center = args.cost_center
+
+	if args.expense_account:
+		se.get("items")[0].expense_account = args.expense_account
+
 	se.get("items")[0].qty = 2
 	se.get("items")[0].transfer_qty = 2
 
-	if target_warehouse:
-		se.get("items")[0].t_warehouse = target_warehouse
+	if args.target_warehouse:
+		se.get("items")[0].t_warehouse = args.target_warehouse
 
 	se.set_stock_entry_type()
 	se.insert()