Merge pull request #24446 from deepeshgarg007/patch-fix-1-new

fix: Project Template patch
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 38d8a62..5a5c448 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -132,16 +132,10 @@
 
 	return caller
 
-def get_last_membership():
+def get_last_membership(member):
 	'''Returns last membership if exists'''
 	last_membership = frappe.get_all('Membership', 'name,to_date,membership_type',
-		dict(member=frappe.session.user, paid=1), order_by='to_date desc', limit=1)
+		dict(member=member, paid=1), order_by='to_date desc', limit=1)
 
-	return last_membership and last_membership[0]
-
-def is_member():
-	'''Returns true if the user is still a member'''
-	last_membership = get_last_membership()
-	if last_membership and getdate(last_membership.to_date) > getdate():
-		return True
-	return False
+	if last_membership:
+		return last_membership[0]
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 5435d3b..3a6dbeb 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -1861,23 +1861,6 @@
 	def test_einvoice_json(self):
 		from erpnext.regional.india.e_invoice.utils import make_einvoice
 
-		customer_gstin = '27AACCM7806M1Z3'
-		customer_gstin_dtls = {
-			'LegalName': '_Test Customer', 'TradeName': '_Test Customer', 'AddrLoc': '_Test City',
-			'StateCode': '27', 'AddrPncd': '410038', 'AddrBno': '_Test Bldg',
-			'AddrBnm': '100', 'AddrFlno': '200', 'AddrSt': '_Test Street'
-		}
-		company_gstin = '27AAECE4835E1ZR'
-		company_gstin_dtls = {
-			'LegalName': '_Test Company', 'TradeName': '_Test Company', 'AddrLoc': '_Test City',
-			'StateCode': '27', 'AddrPncd': '401108', 'AddrBno': '_Test Bldg',
-			'AddrBnm': '100', 'AddrFlno': '200', 'AddrSt': '_Test Street'
-		}
-		# set cache gstin details to avoid fetching details which will require connection to GSP servers
-		frappe.local.gstin_cache = {}
-		frappe.local.gstin_cache[customer_gstin] = customer_gstin_dtls
-		frappe.local.gstin_cache[company_gstin] = company_gstin_dtls
-
 		si = make_sales_invoice_for_ewaybill()
 		si.naming_series = 'INV-2020-.#####'
 		si.items = []
@@ -1930,12 +1913,12 @@
 		self.assertEqual(value_details['SgstVal'], total_item_sgst_value)
 		self.assertEqual(value_details['IgstVal'], total_item_igst_value)
 
-		self.assertEqual(
-			value_details['TotInvVal'],
-			value_details['AssVal'] + value_details['CgstVal']
-			+ value_details['SgstVal'] + value_details['IgstVal']
+		calculated_invoice_value = \
+			value_details['AssVal'] + value_details['CgstVal'] \
+			+ value_details['SgstVal'] + value_details['IgstVal'] \
 			+ value_details['OthChrg'] - value_details['Discount']
-		)
+
+		self.assertTrue(value_details['TotInvVal'] - calculated_invoice_value < 0.1)
 
 		self.assertEqual(value_details['TotInvVal'], si.base_grand_total)
 		self.assertTrue(einvoice['EwbDtls'])
diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
index a36e7f8..eeb5140 100644
--- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
+++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
@@ -53,8 +53,8 @@
 
 		row = {
 			'item_code': d.item_code,
-			'item_name': item_record.item_name,
-			'item_group': item_record.item_group,
+			'item_name': item_record.item_name if item_record else d.item_name,
+			'item_group': item_record.item_group if item_record else d.item_group,
 			'description': d.description,
 			'invoice': d.parent,
 			'posting_date': d.posting_date,
@@ -316,6 +316,7 @@
 			`tabPurchase Invoice`.posting_date, `tabPurchase Invoice`.credit_to, `tabPurchase Invoice`.company,
 			`tabPurchase Invoice`.supplier, `tabPurchase Invoice`.remarks, `tabPurchase Invoice`.base_net_total,
 			`tabPurchase Invoice Item`.`item_code`, `tabPurchase Invoice Item`.description,
+			`tabPurchase Invoice Item`.`item_name`, `tabPurchase Invoice Item`.`item_group`,
 			`tabPurchase Invoice Item`.`project`, `tabPurchase Invoice Item`.`purchase_order`,
 			`tabPurchase Invoice Item`.`purchase_receipt`, `tabPurchase Invoice Item`.`po_detail`,
 			`tabPurchase Invoice Item`.`expense_account`, `tabPurchase Invoice Item`.`stock_qty`,
diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py
index e3aac9a..81f0ad3 100644
--- a/erpnext/controllers/queries.py
+++ b/erpnext/controllers/queries.py
@@ -657,6 +657,34 @@
 
 @frappe.whitelist()
 @frappe.validate_and_sanitize_search_inputs
+def get_healthcare_service_units(doctype, txt, searchfield, start, page_len, filters):
+	query = """
+		select name
+		from `tabHealthcare Service Unit`
+		where
+			is_group = 0
+			and company = {company}
+			and name like {txt}""".format(
+				company = frappe.db.escape(filters.get('company')), txt = frappe.db.escape('%{0}%'.format(txt)))
+
+	if filters and filters.get('inpatient_record'):
+		from erpnext.healthcare.doctype.inpatient_medication_entry.inpatient_medication_entry import get_current_healthcare_service_unit
+		service_unit = get_current_healthcare_service_unit(filters.get('inpatient_record'))
+
+		# if the patient is admitted, then appointments should be allowed against the admission service unit,
+		# inspite of it being an Inpatient Occupancy service unit
+		if service_unit:
+			query += " and (allow_appointments = 1 or name = {service_unit})".format(service_unit = frappe.db.escape(service_unit))
+		else:
+			query += " and allow_appointments = 1"
+	else:
+		query += " and allow_appointments = 1"
+
+	return frappe.db.sql(query, filters)
+
+
+@frappe.whitelist()
+@frappe.validate_and_sanitize_search_inputs
 def get_tax_template(doctype, txt, searchfield, start, page_len, filters):
 
 	item_doc = frappe.get_cached_doc('Item', filters.get('item_code'))
diff --git a/erpnext/crm/onboarding_step/create_opportunity/create_opportunity.json b/erpnext/crm/onboarding_step/create_opportunity/create_opportunity.json
index 9f996d9..0ee9317 100644
--- a/erpnext/crm/onboarding_step/create_opportunity/create_opportunity.json
+++ b/erpnext/crm/onboarding_step/create_opportunity/create_opportunity.json
@@ -8,12 +8,12 @@
  "is_mandatory": 0,
  "is_single": 0,
  "is_skipped": 0,
- "modified": "2020-05-14 17:38:27.496696",
+ "modified": "2021-01-21 15:28:52.483839",
  "modified_by": "Administrator",
  "name": "Create Opportunity",
  "owner": "Administrator",
  "reference_document": "Opportunity",
- "show_full_form": 0,
+ "show_full_form": 1,
  "title": "Create Opportunity",
  "validate_action": 1
 }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
index e55a143..c324228 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
@@ -100,7 +100,6 @@
 		allow_start = self.set_actual_qty()
 		if allow_start:
 			self.db_set('status', 'In Progress')
-			insert_clinical_procedure_to_medical_record(self)
 			return 'success'
 		return 'insufficient stock'
 
@@ -247,21 +246,3 @@
 		}, target_doc, set_missing_values)
 
 	return doc
-
-
-def insert_clinical_procedure_to_medical_record(doc):
-	subject = frappe.bold(_("Clinical Procedure conducted: ")) + cstr(doc.procedure_template) + "<br>"
-	if doc.practitioner:
-		subject += frappe.bold(_('Healthcare Practitioner: ')) + doc.practitioner
-	if subject and doc.notes:
-		subject += '<br/>' + doc.notes
-
-	medical_record = frappe.new_doc('Patient Medical Record')
-	medical_record.patient = doc.patient
-	medical_record.subject = subject
-	medical_record.status = 'Open'
-	medical_record.communication_date = doc.start_date
-	medical_record.reference_doctype = 'Clinical Procedure'
-	medical_record.reference_name = doc.name
-	medical_record.reference_owner = doc.owner
-	medical_record.save(ignore_permissions=True)
diff --git a/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry.py b/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry.py
index bba5213..e731908 100644
--- a/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry.py
+++ b/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry.py
@@ -264,7 +264,7 @@
 
 def get_current_healthcare_service_unit(inpatient_record):
 	ip_record = frappe.get_doc('Inpatient Record', inpatient_record)
-	if ip_record.inpatient_occupancies:
+	if ip_record.status in ['Admitted', 'Discharge Scheduled'] and ip_record.inpatient_occupancies:
 		return ip_record.inpatient_occupancies[-1].service_unit
 	return
 
diff --git a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
index 10990d4..8a918b0 100644
--- a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
+++ b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
@@ -142,11 +142,15 @@
 	return inpatient_record
 
 
-def get_healthcare_service_unit():
-	service_unit = get_random("Healthcare Service Unit", filters={"inpatient_occupancy": 1})
+def get_healthcare_service_unit(unit_name=None):
+	if not unit_name:
+		service_unit = get_random("Healthcare Service Unit", filters={"inpatient_occupancy": 1})
+	else:
+		service_unit = frappe.db.exists("Healthcare Service Unit", {"healthcare_service_unit_name": unit_name})
+
 	if not service_unit:
 		service_unit = frappe.new_doc("Healthcare Service Unit")
-		service_unit.healthcare_service_unit_name = "Test Service Unit Ip Occupancy"
+		service_unit.healthcare_service_unit_name = unit_name or "Test Service Unit Ip Occupancy"
 		service_unit.company = "_Test Company"
 		service_unit.service_unit_type = get_service_unit_type()
 		service_unit.inpatient_occupancy = 1
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.json b/erpnext/healthcare/doctype/lab_test/lab_test.json
index edf1d91..ac61fea 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.json
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.json
@@ -359,6 +359,7 @@
   {
    "fieldname": "normal_test_items",
    "fieldtype": "Table",
+   "label": "Normal Test Result",
    "options": "Normal Test Result",
    "print_hide": 1
   },
@@ -380,6 +381,7 @@
   {
    "fieldname": "sensitivity_test_items",
    "fieldtype": "Table",
+   "label": "Sensitivity Test Result",
    "options": "Sensitivity Test Result",
    "print_hide": 1,
    "report_hide": 1
@@ -529,6 +531,7 @@
   {
    "fieldname": "descriptive_test_items",
    "fieldtype": "Table",
+   "label": "Descriptive Test Result",
    "options": "Descriptive Test Result",
    "print_hide": 1,
    "report_hide": 1
@@ -549,13 +552,14 @@
   {
    "fieldname": "organism_test_items",
    "fieldtype": "Table",
+   "label": "Organism Test Result",
    "options": "Organism Test Result",
    "print_hide": 1
   }
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2020-07-30 18:18:38.516215",
+ "modified": "2020-11-30 11:04:17.195848",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Lab Test",
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.py b/erpnext/healthcare/doctype/lab_test/lab_test.py
index 2db7743..4b57cd0 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.py
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.py
@@ -17,11 +17,9 @@
 		self.validate_result_values()
 		self.db_set('submitted_date', getdate())
 		self.db_set('status', 'Completed')
-		insert_lab_test_to_medical_record(self)
 
 	def on_cancel(self):
 		self.db_set('status', 'Cancelled')
-		delete_lab_test_from_medical_record(self)
 		self.reload()
 
 	def on_update(self):
@@ -330,60 +328,6 @@
 		return frappe.get_doc('Employee', emp_id)
 	return None
 
-def insert_lab_test_to_medical_record(doc):
-	table_row = False
-	subject = cstr(doc.lab_test_name)
-	if doc.practitioner:
-		subject += frappe.bold(_('Healthcare Practitioner: '))+ doc.practitioner + '<br>'
-	if doc.normal_test_items:
-		item = doc.normal_test_items[0]
-		comment = ''
-		if item.lab_test_comment:
-			comment = str(item.lab_test_comment)
-		table_row = frappe.bold(_('Lab Test Conducted: ')) + item.lab_test_name
-
-		if item.lab_test_event:
-			table_row += frappe.bold(_('Lab Test Event: ')) + item.lab_test_event
-
-		if item.result_value:
-			table_row += ' ' + frappe.bold(_('Lab Test Result: ')) + item.result_value
-
-		if item.normal_range:
-			table_row += ' ' + _('Normal Range: ') + item.normal_range
-		table_row += ' ' + comment
-
-	elif doc.descriptive_test_items:
-		item = doc.descriptive_test_items[0]
-
-		if item.lab_test_particulars and item.result_value:
-			table_row = item.lab_test_particulars + ' ' + item.result_value
-
-	elif doc.sensitivity_test_items:
-		item = doc.sensitivity_test_items[0]
-
-		if item.antibiotic and item.antibiotic_sensitivity:
-			table_row = item.antibiotic + ' ' + item.antibiotic_sensitivity
-
-	if table_row:
-		subject += '<br>' + table_row
-	if doc.lab_test_comment:
-		subject += '<br>' + cstr(doc.lab_test_comment)
-
-	medical_record = frappe.new_doc('Patient Medical Record')
-	medical_record.patient = doc.patient
-	medical_record.subject = subject
-	medical_record.status = 'Open'
-	medical_record.communication_date = doc.result_date
-	medical_record.reference_doctype = 'Lab Test'
-	medical_record.reference_name = doc.name
-	medical_record.reference_owner = doc.owner
-	medical_record.save(ignore_permissions = True)
-
-def delete_lab_test_from_medical_record(self):
-	medical_record_id = frappe.db.sql('select name from `tabPatient Medical Record` where reference_name=%s', (self.name))
-
-	if medical_record_id and medical_record_id[0][0]:
-		frappe.delete_doc('Patient Medical Record', medical_record_id[0][0])
 
 @frappe.whitelist()
 def get_lab_test_prescribed(patient):
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
index 79e1775..3d5073b 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
@@ -31,12 +31,12 @@
 			};
 		});
 
-		frm.set_query('service_unit', function(){
+		frm.set_query('service_unit', function() {
 			return {
+				query: 'erpnext.controllers.queries.get_healthcare_service_units',
 				filters: {
-					'is_group': false,
-					'allow_appointments': true,
-					'company': frm.doc.company
+					company: frm.doc.company,
+					inpatient_record: frm.doc.inpatient_record
 				}
 			};
 		});
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
index dc820cb..b05c673 100755
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
@@ -18,6 +18,7 @@
 class PatientAppointment(Document):
 	def validate(self):
 		self.validate_overlaps()
+		self.validate_service_unit()
 		self.set_appointment_datetime()
 		self.validate_customer_created()
 		self.set_status()
@@ -68,6 +69,19 @@
 				overlaps[0][1], overlaps[0][2], overlaps[0][3], overlaps[0][4])
 			frappe.throw(overlapping_details, title=_('Appointments Overlapping'))
 
+	def validate_service_unit(self):
+		if self.inpatient_record and self.service_unit:
+			from erpnext.healthcare.doctype.inpatient_medication_entry.inpatient_medication_entry import get_current_healthcare_service_unit
+
+			is_inpatient_occupancy_unit = frappe.db.get_value('Healthcare Service Unit', self.service_unit,
+				'inpatient_occupancy')
+			service_unit = get_current_healthcare_service_unit(self.inpatient_record)
+			if is_inpatient_occupancy_unit and service_unit != self.service_unit:
+				msg = _('Patient {0} is not admitted in the service unit {1}').format(frappe.bold(self.patient), frappe.bold(self.service_unit)) + '<br>'
+				msg += _('Appointment for service units with Inpatient Occupancy can only be created against the unit where patient has been admitted.')
+				frappe.throw(msg, title=_('Invalid Healthcare Service Unit'))
+
+
 	def set_appointment_datetime(self):
 		self.appointment_datetime = "%s %s" % (self.appointment_date, self.appointment_time or "00:00:00")
 
diff --git a/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py
index b681ed1..f7ec6f5 100644
--- a/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py
+++ b/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py
@@ -5,7 +5,7 @@
 import unittest
 import frappe
 from erpnext.healthcare.doctype.patient_appointment.patient_appointment import update_status, make_encounter
-from frappe.utils import nowdate, add_days
+from frappe.utils import nowdate, add_days, now_datetime
 from frappe.utils.make_random import get_random
 from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profile
 
@@ -78,6 +78,59 @@
 		sales_invoice_name = frappe.db.get_value('Sales Invoice Item', {'reference_dn': appointment.name}, 'parent')
 		self.assertEqual(frappe.db.get_value('Sales Invoice', sales_invoice_name, 'status'), 'Cancelled')
 
+	def test_appointment_booking_for_admission_service_unit(self):
+		from erpnext.healthcare.doctype.inpatient_record.inpatient_record import admit_patient, discharge_patient, schedule_discharge
+		from erpnext.healthcare.doctype.inpatient_record.test_inpatient_record import \
+			create_inpatient, get_healthcare_service_unit, mark_invoiced_inpatient_occupancy
+
+		frappe.db.sql("""delete from `tabInpatient Record`""")
+		patient, medical_department, practitioner = create_healthcare_docs()
+		patient = create_patient()
+		# Schedule Admission
+		ip_record = create_inpatient(patient)
+		ip_record.expected_length_of_stay = 0
+		ip_record.save(ignore_permissions = True)
+
+		# Admit
+		service_unit = get_healthcare_service_unit('Test Service Unit Ip Occupancy')
+		admit_patient(ip_record, service_unit, now_datetime())
+
+		appointment = create_appointment(patient, practitioner, nowdate(), service_unit=service_unit)
+		self.assertEqual(appointment.service_unit, service_unit)
+
+		# Discharge
+		schedule_discharge(frappe.as_json({'patient': patient}))
+		ip_record1 = frappe.get_doc("Inpatient Record", ip_record.name)
+		mark_invoiced_inpatient_occupancy(ip_record1)
+		discharge_patient(ip_record1)
+
+	def test_invalid_healthcare_service_unit_validation(self):
+		from erpnext.healthcare.doctype.inpatient_record.inpatient_record import admit_patient, discharge_patient, schedule_discharge
+		from erpnext.healthcare.doctype.inpatient_record.test_inpatient_record import \
+			create_inpatient, get_healthcare_service_unit, mark_invoiced_inpatient_occupancy
+
+		frappe.db.sql("""delete from `tabInpatient Record`""")
+		patient, medical_department, practitioner = create_healthcare_docs()
+		patient = create_patient()
+		# Schedule Admission
+		ip_record = create_inpatient(patient)
+		ip_record.expected_length_of_stay = 0
+		ip_record.save(ignore_permissions = True)
+
+		# Admit
+		service_unit = get_healthcare_service_unit('Test Service Unit Ip Occupancy')
+		admit_patient(ip_record, service_unit, now_datetime())
+
+		appointment_service_unit = get_healthcare_service_unit('Test Service Unit Ip Occupancy for Appointment')
+		appointment = create_appointment(patient, practitioner, nowdate(), service_unit=appointment_service_unit, save=0)
+		self.assertRaises(frappe.exceptions.ValidationError, appointment.save)
+
+		# Discharge
+		schedule_discharge(frappe.as_json({'patient': patient}))
+		ip_record1 = frappe.get_doc("Inpatient Record", ip_record.name)
+		mark_invoiced_inpatient_occupancy(ip_record1)
+		discharge_patient(ip_record1)
+
 
 def create_healthcare_docs():
 	patient = create_patient()
@@ -125,7 +178,7 @@
 		encounter.submit()
 		return encounter
 
-def create_appointment(patient, practitioner, appointment_date, invoice=0, procedure_template=0):
+def create_appointment(patient, practitioner, appointment_date, invoice=0, procedure_template=0, service_unit=None, save=1):
 	item = create_healthcare_service_items()
 	frappe.db.set_value('Healthcare Settings', None, 'inpatient_visit_charge_item', item)
 	frappe.db.set_value('Healthcare Settings', None, 'op_consulting_charge_item', item)
@@ -136,12 +189,15 @@
 	appointment.appointment_date = appointment_date
 	appointment.company = '_Test Company'
 	appointment.duration = 15
+	if service_unit:
+		appointment.service_unit = service_unit
 	if invoice:
 		appointment.mode_of_payment = 'Cash'
 		appointment.paid_amount = 500
 	if procedure_template:
 		appointment.procedure_template = create_clinical_procedure_template().get('name')
-	appointment.save(ignore_permissions=True)
+	if save:
+		appointment.save(ignore_permissions=True)
 	return appointment
 
 def create_healthcare_service_items():
@@ -152,6 +208,7 @@
 	item.item_name = 'Consulting Charges'
 	item.item_group = 'Services'
 	item.is_stock_item = 0
+	item.stock_uom = 'Nos'
 	item.save()
 	return item.name
 
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
index 15675f4..b646ff9 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
@@ -210,7 +210,7 @@
   {
    "fieldname": "drug_prescription",
    "fieldtype": "Table",
-   "label": "Items",
+   "label": "Drug Prescription",
    "options": "Drug Prescription"
   },
   {
@@ -328,7 +328,7 @@
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2020-05-16 21:00:08.644531",
+ "modified": "2020-11-30 10:39:00.783119",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Patient Encounter",
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
index 87f4249..cc21417 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
@@ -17,10 +17,6 @@
 	def on_update(self):
 		if self.appointment:
 			frappe.db.set_value('Patient Appointment', self.appointment, 'status', 'Closed')
-		update_encounter_medical_record(self)
-
-	def after_insert(self):
-		insert_encounter_to_medical_record(self)
 
 	def on_submit(self):
 		if self.therapies:
@@ -33,8 +29,6 @@
 		if self.inpatient_record and self.drug_prescription:
 			delete_ip_medication_order(self)
 
-		delete_medical_record(self)
-
 	def set_title(self):
 		self.title = _('{0} with {1}').format(self.patient_name or self.patient,
 			self.practitioner_name or self.practitioner)[:100]
@@ -102,61 +96,7 @@
 			frappe.msgprint(_('Therapy Plan {0} created successfully.').format(frappe.bold(doc.name)), alert=True)
 
 
-def insert_encounter_to_medical_record(doc):
-	subject = set_subject_field(doc)
-	medical_record = frappe.new_doc('Patient Medical Record')
-	medical_record.patient = doc.patient
-	medical_record.subject = subject
-	medical_record.status = 'Open'
-	medical_record.communication_date = doc.encounter_date
-	medical_record.reference_doctype = 'Patient Encounter'
-	medical_record.reference_name = doc.name
-	medical_record.reference_owner = doc.owner
-	medical_record.save(ignore_permissions=True)
-
-
-def update_encounter_medical_record(encounter):
-	medical_record_id = frappe.db.exists('Patient Medical Record', {'reference_name': encounter.name})
-
-	if medical_record_id and medical_record_id[0][0]:
-		subject = set_subject_field(encounter)
-		frappe.db.set_value('Patient Medical Record', medical_record_id[0][0], 'subject', subject)
-	else:
-		insert_encounter_to_medical_record(encounter)
-
-
-def delete_medical_record(encounter):
-	record = frappe.db.exists('Patient Medical Record', {'reference_name', encounter.name})
-	if record:
-		frappe.delete_doc('Patient Medical Record', record, force=1)
-
 def delete_ip_medication_order(encounter):
 	record = frappe.db.exists('Inpatient Medication Order', {'patient_encounter': encounter.name})
 	if record:
-		frappe.delete_doc('Inpatient Medication Order', record, force=1)
-
-
-def set_subject_field(encounter):
-	subject = frappe.bold(_('Healthcare Practitioner: ')) + encounter.practitioner + '<br>'
-	if encounter.symptoms:
-		subject += frappe.bold(_('Symptoms: ')) + '<br>'
-		for entry in encounter.symptoms:
-			subject += cstr(entry.complaint) + '<br>'
-	else:
-		subject += frappe.bold(_('No Symptoms')) + '<br>'
-
-	if encounter.diagnosis:
-		subject += frappe.bold(_('Diagnosis: ')) + '<br>'
-		for entry in encounter.diagnosis:
-			subject += cstr(entry.diagnosis) + '<br>'
-	else:
-		subject += frappe.bold(_('No Diagnosis')) + '<br>'
-
-	if encounter.drug_prescription:
-		subject += '<br>' + _('Drug(s) Prescribed.')
-	if encounter.lab_test_prescription:
-		subject += '<br>' + _('Test(s) Prescribed.')
-	if encounter.procedure_prescription:
-		subject += '<br>' + _('Procedure(s) Prescribed.')
-
-	return subject
+		frappe.delete_doc('Inpatient Medication Order', record, force=1)
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_history_custom_document_type/__init__.py b/erpnext/healthcare/doctype/patient_history_custom_document_type/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_history_custom_document_type/__init__.py
diff --git a/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.json b/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.json
new file mode 100644
index 0000000..3025c7b
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.json
@@ -0,0 +1,55 @@
+{
+ "actions": [],
+ "creation": "2020-11-25 13:40:23.054469",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "document_type",
+  "date_fieldname",
+  "add_edit_fields",
+  "selected_fields"
+ ],
+ "fields": [
+  {
+   "fieldname": "document_type",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Document Type",
+   "options": "DocType",
+   "reqd": 1
+  },
+  {
+   "fieldname": "selected_fields",
+   "fieldtype": "Code",
+   "label": "Selected Fields",
+   "read_only": 1
+  },
+  {
+   "fieldname": "add_edit_fields",
+   "fieldtype": "Button",
+   "in_list_view": 1,
+   "label": "Add / Edit Fields"
+  },
+  {
+   "fieldname": "date_fieldname",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Date Fieldname",
+   "reqd": 1
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2020-11-30 13:54:37.474671",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient History Custom Document Type",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.py b/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.py
new file mode 100644
index 0000000..f0a1f92
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_history_custom_document_type/patient_history_custom_document_type.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class PatientHistoryCustomDocumentType(Document):
+	pass
diff --git a/erpnext/healthcare/doctype/patient_history_settings/__init__.py b/erpnext/healthcare/doctype/patient_history_settings/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_history_settings/__init__.py
diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js
new file mode 100644
index 0000000..453da6a
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.js
@@ -0,0 +1,133 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Patient History Settings', {
+	refresh: function(frm) {
+		frm.set_query('document_type', 'custom_doctypes', () => {
+			return {
+				filters: {
+					custom: 1,
+					is_submittable: 1,
+					module: 'Healthcare',
+				}
+			};
+		});
+	},
+
+	field_selector: function(frm, doc, standard=1) {
+		let document_fields = [];
+		if (doc.selected_fields)
+			document_fields = (JSON.parse(doc.selected_fields)).map(f => f.fieldname);
+
+		frm.call({
+			method: 'get_doctype_fields',
+			doc: frm.doc,
+			args: {
+				document_type: doc.document_type,
+				fields: document_fields
+			},
+			freeze: true,
+			callback: function(r) {
+				if (r.message) {
+					let doctype = 'Patient History Custom Document Type';
+					if (standard)
+						doctype = 'Patient History Standard Document Type';
+
+					frm.events.show_field_selector_dialog(frm, doc, doctype, r.message);
+				}
+			}
+		});
+	},
+
+	show_field_selector_dialog: function(frm, doc, doctype, doc_fields) {
+		let d = new frappe.ui.Dialog({
+			title: __('{0} Fields', [__(doc.document_type)]),
+			fields: [
+				{
+					label: __('Select Fields'),
+					fieldtype: 'MultiCheck',
+					fieldname: 'fields',
+					options: doc_fields,
+					columns: 2
+				}
+			]
+		});
+
+		d.$body.prepend(`
+			<div class="columns-search">
+				<input type="text" placeholder="${__('Search')}" data-element="search" class="form-control input-xs">
+			</div>`
+		);
+
+		frappe.utils.setup_search(d.$body, '.unit-checkbox', '.label-area');
+
+		d.set_primary_action(__('Save'), () => {
+			let values = d.get_values().fields;
+
+			let selected_fields = [];
+
+			frappe.model.with_doctype(doc.document_type, function() {
+				for (let idx in values) {
+					let value = values[idx];
+
+					let field = frappe.get_meta(doc.document_type).fields.filter((df) => df.fieldname == value)[0];
+					if (field) {
+						selected_fields.push({
+							label: field.label,
+							fieldname: field.fieldname,
+							fieldtype: field.fieldtype
+						});
+					}
+				}
+
+				d.refresh();
+				frappe.model.set_value(doctype, doc.name, 'selected_fields', JSON.stringify(selected_fields));
+			});
+
+			d.hide();
+		});
+
+		d.show();
+	},
+
+	get_date_field_for_dt: function(frm, row) {
+		frm.call({
+			method: 'get_date_field_for_dt',
+			doc: frm.doc,
+			args: {
+				document_type: row.document_type
+			},
+			callback: function(data) {
+				if (data.message) {
+					frappe.model.set_value('Patient History Custom Document Type',
+						row.name, 'date_fieldname', data.message);
+				}
+			}
+		});
+	}
+});
+
+frappe.ui.form.on('Patient History Custom Document Type', {
+	document_type: function(frm, cdt, cdn) {
+		let row = locals[cdt][cdn];
+		if (row.document_type) {
+			frm.events.get_date_field_for_dt(frm, row);
+		}
+	},
+
+	add_edit_fields: function(frm, cdt, cdn) {
+		let row = locals[cdt][cdn];
+		if (row.document_type) {
+			frm.events.field_selector(frm, row, 0);
+		}
+	}
+});
+
+frappe.ui.form.on('Patient History Standard Document Type', {
+	add_edit_fields: function(frm, cdt, cdn) {
+		let row = locals[cdt][cdn];
+		if (row.document_type) {
+			frm.events.field_selector(frm, row);
+		}
+	}
+});
diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.json b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.json
new file mode 100644
index 0000000..143e2c9
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.json
@@ -0,0 +1,55 @@
+{
+ "actions": [],
+ "creation": "2020-11-25 13:41:37.675518",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "standard_doctypes",
+  "section_break_2",
+  "custom_doctypes"
+ ],
+ "fields": [
+  {
+   "fieldname": "section_break_2",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "custom_doctypes",
+   "fieldtype": "Table",
+   "label": "Custom Document Types",
+   "options": "Patient History Custom Document Type"
+  },
+  {
+   "fieldname": "standard_doctypes",
+   "fieldtype": "Table",
+   "label": "Standard Document Types",
+   "options": "Patient History Standard Document Type",
+   "read_only": 1
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "issingle": 1,
+ "links": [],
+ "modified": "2020-11-25 13:43:38.511771",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient History Settings",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "print": 1,
+   "read": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py
new file mode 100644
index 0000000..2e8c994
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py
@@ -0,0 +1,188 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+import json
+from frappe import _
+from frappe.utils import cstr, cint
+from frappe.model.document import Document
+from erpnext.healthcare.page.patient_history.patient_history import get_patient_history_doctypes
+
+class PatientHistorySettings(Document):
+	def validate(self):
+		self.validate_submittable_doctypes()
+		self.validate_date_fieldnames()
+
+	def validate_submittable_doctypes(self):
+		for entry in self.custom_doctypes:
+			if not cint(frappe.db.get_value('DocType', entry.document_type, 'is_submittable')):
+				msg = _('Row #{0}: Document Type {1} is not submittable. ').format(
+					entry.idx, frappe.bold(entry.document_type))
+				msg += _('Patient Medical Record can only be created for submittable document types.')
+				frappe.throw(msg)
+
+	def validate_date_fieldnames(self):
+		for entry in self.custom_doctypes:
+			field = frappe.get_meta(entry.document_type).get_field(entry.date_fieldname)
+			if not field:
+				frappe.throw(_('Row #{0}: No such Field named {1} found in the Document Type {2}.').format(
+					entry.idx, frappe.bold(entry.date_fieldname), frappe.bold(entry.document_type)))
+
+			if field.fieldtype not in ['Date', 'Datetime']:
+				frappe.throw(_('Row #{0}: Field {1} in Document Type {2} is not a Date / Datetime field.').format(
+					entry.idx, frappe.bold(entry.date_fieldname), frappe.bold(entry.document_type)))
+
+	def get_doctype_fields(self, document_type, fields):
+		multicheck_fields = []
+		doc_fields = frappe.get_meta(document_type).fields
+
+		for field in doc_fields:
+			if field.fieldtype not in frappe.model.no_value_fields or \
+				field.fieldtype in frappe.model.table_fields and not field.hidden:
+				multicheck_fields.append({
+					'label': field.label,
+					'value': field.fieldname,
+					'checked': 1 if field.fieldname in fields else 0
+				})
+
+		return multicheck_fields
+
+	def get_date_field_for_dt(self, document_type):
+		meta = frappe.get_meta(document_type)
+		date_fields = meta.get('fields', {
+			'fieldtype': ['in', ['Date', 'Datetime']]
+		})
+
+		if date_fields:
+			return date_fields[0].get('fieldname')
+
+def create_medical_record(doc, method=None):
+	medical_record_required = validate_medical_record_required(doc)
+	if not medical_record_required:
+		return
+
+	if frappe.db.exists('Patient Medical Record', { 'reference_name': doc.name }):
+		return
+
+	subject = set_subject_field(doc)
+	date_field = get_date_field(doc.doctype)
+	medical_record = frappe.new_doc('Patient Medical Record')
+	medical_record.patient = doc.patient
+	medical_record.subject = subject
+	medical_record.status = 'Open'
+	medical_record.communication_date = doc.get(date_field)
+	medical_record.reference_doctype = doc.doctype
+	medical_record.reference_name = doc.name
+	medical_record.reference_owner = doc.owner
+	medical_record.save(ignore_permissions=True)
+
+
+def update_medical_record(doc, method=None):
+	medical_record_required = validate_medical_record_required(doc)
+	if not medical_record_required:
+		return
+
+	medical_record_id = frappe.db.exists('Patient Medical Record', { 'reference_name': doc.name })
+
+	if medical_record_id:
+		subject = set_subject_field(doc)
+		frappe.db.set_value('Patient Medical Record', medical_record_id[0][0], 'subject', subject)
+	else:
+		create_medical_record(doc)
+
+
+def delete_medical_record(doc, method=None):
+	medical_record_required = validate_medical_record_required(doc)
+	if not medical_record_required:
+		return
+
+	record = frappe.db.exists('Patient Medical Record', { 'reference_name': doc.name })
+	if record:
+		frappe.delete_doc('Patient Medical Record', record, force=1)
+
+
+def set_subject_field(doc):
+	from frappe.utils.formatters import format_value
+
+	meta = frappe.get_meta(doc.doctype)
+	subject = ''
+	patient_history_fields = get_patient_history_fields(doc)
+
+	for entry in patient_history_fields:
+		fieldname = entry.get('fieldname')
+		if entry.get('fieldtype') == 'Table' and doc.get(fieldname):
+			formatted_value = get_formatted_value_for_table_field(doc.get(fieldname), meta.get_field(fieldname))
+			subject += frappe.bold(_(entry.get('label')) + ': ') + '<br>' + cstr(formatted_value) + '<br>'
+
+		else:
+			if doc.get(fieldname):
+				formatted_value = format_value(doc.get(fieldname), meta.get_field(fieldname), doc)
+				subject += frappe.bold(_(entry.get('label')) + ': ') + cstr(formatted_value) + '<br>'
+
+	return subject
+
+
+def get_date_field(doctype):
+	dt = get_patient_history_config_dt(doctype)
+
+	return frappe.db.get_value(dt, { 'document_type': doctype }, 'date_fieldname')
+
+
+def get_patient_history_fields(doc):
+	dt = get_patient_history_config_dt(doc.doctype)
+	patient_history_fields = frappe.db.get_value(dt, { 'document_type': doc.doctype }, 'selected_fields')
+
+	if patient_history_fields:
+		return json.loads(patient_history_fields)
+
+
+def get_formatted_value_for_table_field(items, df):
+	child_meta = frappe.get_meta(df.options)
+
+	table_head = ''
+	table_row = ''
+	html = ''
+	create_head = True
+	for item in items:
+		table_row += '<tr>'
+		for cdf in child_meta.fields:
+			if cdf.in_list_view:
+				if create_head:
+					table_head += '<td>' + cdf.label + '</td>'
+				if item.get(cdf.fieldname):
+					table_row += '<td>' + str(item.get(cdf.fieldname)) + '</td>'
+				else:
+					table_row += '<td></td>'
+		create_head = False
+		table_row += '</tr>'
+
+	html += "<table class='table table-condensed table-bordered'>" + table_head +  table_row + "</table>"
+
+	return html
+
+
+def get_patient_history_config_dt(doctype):
+	if frappe.db.get_value('DocType', doctype, 'custom'):
+		return 'Patient History Custom Document Type'
+	else:
+		return 'Patient History Standard Document Type'
+
+
+def validate_medical_record_required(doc):
+	if frappe.flags.in_patch or frappe.flags.in_install or frappe.flags.in_setup_wizard \
+		or get_module(doc) != 'Healthcare':
+		return False
+
+	if doc.doctype not in get_patient_history_doctypes():
+		return False
+
+	return True
+
+def get_module(doc):
+	module = doc.meta.module
+	if not module:
+		module = frappe.db.get_value('DocType', doc.doctype, 'module')
+
+	return module
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_history_settings/test_patient_history_settings.py b/erpnext/healthcare/doctype/patient_history_settings/test_patient_history_settings.py
new file mode 100644
index 0000000..c93b788
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_history_settings/test_patient_history_settings.py
@@ -0,0 +1,104 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+import json
+from frappe.utils import getdate
+from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import create_patient
+
+class TestPatientHistorySettings(unittest.TestCase):
+	def setUp(self):
+		dt = create_custom_doctype()
+		settings = frappe.get_single("Patient History Settings")
+		settings.append("custom_doctypes", {
+			"document_type": dt.name,
+			"date_fieldname": "date",
+			"selected_fields": json.dumps([{
+				"label": "Date",
+				"fieldname": "date",
+				"fieldtype": "Date"
+			},
+			{
+				"label": "Rating",
+				"fieldname": "rating",
+				"fieldtype": "Rating"
+			},
+			{
+				"label": "Feedback",
+				"fieldname": "feedback",
+				"fieldtype": "Small Text"
+			}])
+		})
+		settings.save()
+
+	def test_custom_doctype_medical_record(self):
+		# tests for medical record creation of standard doctypes in test_patient_medical_record.py
+		patient = create_patient()
+		doc = create_doc(patient)
+
+		# check for medical record
+		medical_rec = frappe.db.exists("Patient Medical Record", {"status": "Open", "reference_name": doc.name})
+		self.assertTrue(medical_rec)
+
+		medical_rec = frappe.get_doc("Patient Medical Record", medical_rec)
+		expected_subject = "<b>Date: </b>{0}<br><b>Rating: </b>3<br><b>Feedback: </b>Test Patient History Settings<br>".format(
+			frappe.utils.format_date(getdate()))
+		self.assertEqual(medical_rec.subject, expected_subject)
+		self.assertEqual(medical_rec.patient, patient)
+		self.assertEqual(medical_rec.communication_date, getdate())
+
+
+def create_custom_doctype():
+	if not frappe.db.exists("DocType", "Test Patient Feedback"):
+		doc = frappe.get_doc({
+				"doctype": "DocType",
+				"module": "Healthcare",
+				"custom": 1,
+				"is_submittable": 1,
+				"fields": [{
+					"label": "Date",
+					"fieldname": "date",
+					"fieldtype": "Date"
+				},
+				{
+					"label": "Patient",
+					"fieldname": "patient",
+					"fieldtype": "Link",
+					"options": "Patient"
+				},
+				{
+					"label": "Rating",
+					"fieldname": "rating",
+					"fieldtype": "Rating"
+				},
+				{
+					"label": "Feedback",
+					"fieldname": "feedback",
+					"fieldtype": "Small Text"
+				}],
+				"permissions": [{
+					"role": "System Manager",
+					"read": 1
+				}],
+				"name": "Test Patient Feedback",
+			})
+		doc.insert()
+		return doc
+	else:
+		return frappe.get_doc("DocType", "Test Patient Feedback")
+
+
+def create_doc(patient):
+	doc = frappe.get_doc({
+		"doctype": "Test Patient Feedback",
+		"patient": patient,
+		"date": getdate(),
+		"rating": 3,
+		"feedback": "Test Patient History Settings"
+	}).insert()
+	doc.submit()
+
+	return doc
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_history_standard_document_type/__init__.py b/erpnext/healthcare/doctype/patient_history_standard_document_type/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_history_standard_document_type/__init__.py
diff --git a/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json b/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json
new file mode 100644
index 0000000..b43099c
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.json
@@ -0,0 +1,57 @@
+{
+ "actions": [],
+ "creation": "2020-11-25 13:39:36.014814",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "document_type",
+  "date_fieldname",
+  "add_edit_fields",
+  "selected_fields"
+ ],
+ "fields": [
+  {
+   "fieldname": "document_type",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Document Type",
+   "options": "DocType",
+   "read_only": 1,
+   "reqd": 1
+  },
+  {
+   "fieldname": "selected_fields",
+   "fieldtype": "Code",
+   "label": "Selected Fields",
+   "read_only": 1
+  },
+  {
+   "fieldname": "add_edit_fields",
+   "fieldtype": "Button",
+   "in_list_view": 1,
+   "label": "Add / Edit Fields"
+  },
+  {
+   "fieldname": "date_fieldname",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Date Fieldname",
+   "read_only": 1,
+   "reqd": 1
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2020-11-30 13:54:56.773325",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient History Standard Document Type",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.py b/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.py
new file mode 100644
index 0000000..2d94911
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_history_standard_document_type/patient_history_standard_document_type.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class PatientHistoryStandardDocumentType(Document):
+	pass
diff --git a/erpnext/healthcare/doctype/patient_medical_record/test_patient_medical_record.py b/erpnext/healthcare/doctype/patient_medical_record/test_patient_medical_record.py
index 419d956..c1d9872 100644
--- a/erpnext/healthcare/doctype/patient_medical_record/test_patient_medical_record.py
+++ b/erpnext/healthcare/doctype/patient_medical_record/test_patient_medical_record.py
@@ -18,6 +18,7 @@
 		patient, medical_department, practitioner = create_healthcare_docs()
 		appointment = create_appointment(patient, practitioner, nowdate(), invoice=1)
 		encounter = create_encounter(appointment)
+
 		# check for encounter
 		medical_rec = frappe.db.exists('Patient Medical Record', {'status': 'Open', 'reference_name': encounter.name})
 		self.assertTrue(medical_rec)
diff --git a/erpnext/healthcare/doctype/therapy_session/therapy_session.py b/erpnext/healthcare/doctype/therapy_session/therapy_session.py
index c000544..51f267f 100644
--- a/erpnext/healthcare/doctype/therapy_session/therapy_session.py
+++ b/erpnext/healthcare/doctype/therapy_session/therapy_session.py
@@ -41,7 +41,6 @@
 
 	def on_submit(self):
 		self.update_sessions_count_in_therapy_plan()
-		insert_session_medical_record(self)
 
 	def on_update(self):
 		if self.appointment:
@@ -142,23 +141,3 @@
 	item.reference_dt = 'Therapy Session'
 	item.reference_dn = therapy.name
 	return item
-
-
-def insert_session_medical_record(doc):
-	subject = frappe.bold(_('Therapy: ')) + cstr(doc.therapy_type) + '<br>'
-	if doc.therapy_plan:
-		subject += frappe.bold(_('Therapy Plan: ')) + cstr(doc.therapy_plan) + '<br>'
-	if doc.practitioner:
-		subject += frappe.bold(_('Healthcare Practitioner: ')) + doc.practitioner
-	subject += frappe.bold(_('Total Counts Targeted: ')) + cstr(doc.total_counts_targeted) + '<br>'
-	subject += frappe.bold(_('Total Counts Completed: ')) + cstr(doc.total_counts_completed) + '<br>'
-
-	medical_record = frappe.new_doc('Patient Medical Record')
-	medical_record.patient = doc.patient
-	medical_record.subject = subject
-	medical_record.status = 'Open'
-	medical_record.communication_date = doc.start_date
-	medical_record.reference_doctype = 'Therapy Session'
-	medical_record.reference_name = doc.name
-	medical_record.reference_owner = doc.owner
-	medical_record.save(ignore_permissions=True)
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/vital_signs/vital_signs.py b/erpnext/healthcare/doctype/vital_signs/vital_signs.py
index 69d81ff..35c823d 100644
--- a/erpnext/healthcare/doctype/vital_signs/vital_signs.py
+++ b/erpnext/healthcare/doctype/vital_signs/vital_signs.py
@@ -12,47 +12,7 @@
 	def validate(self):
 		self.set_title()
 
-	def on_submit(self):
-		insert_vital_signs_to_medical_record(self)
-
-	def on_cancel(self):
-		delete_vital_signs_from_medical_record(self)
-
 	def set_title(self):
 		self.title = _('{0} on {1}').format(self.patient_name or self.patient,
 			frappe.utils.format_date(self.signs_date))[:100]
 
-def insert_vital_signs_to_medical_record(doc):
-	subject = set_subject_field(doc)
-	medical_record = frappe.new_doc('Patient Medical Record')
-	medical_record.patient = doc.patient
-	medical_record.subject = subject
-	medical_record.status = 'Open'
-	medical_record.communication_date = doc.signs_date
-	medical_record.reference_doctype = 'Vital Signs'
-	medical_record.reference_name = doc.name
-	medical_record.reference_owner = doc.owner
-	medical_record.flags.ignore_mandatory = True
-	medical_record.save(ignore_permissions=True)
-
-def delete_vital_signs_from_medical_record(doc):
-	medical_record = frappe.db.get_value('Patient Medical Record', {'reference_name': doc.name})
-	if medical_record:
-		frappe.delete_doc('Patient Medical Record', medical_record)
-
-def set_subject_field(doc):
-	subject = ''
-	if doc.temperature:
-		subject += frappe.bold(_('Temperature: ')) + cstr(doc.temperature) + '<br>'
-	if doc.pulse:
-		subject += frappe.bold(_('Pulse: ')) + cstr(doc.pulse) + '<br>'
-	if doc.respiratory_rate:
-		subject += frappe.bold(_('Respiratory Rate: ')) + cstr(doc.respiratory_rate) + '<br>'
-	if doc.bp:
-		subject += frappe.bold(_('BP: ')) + cstr(doc.bp) + '<br>'
-	if doc.bmi:
-		subject += frappe.bold(_('BMI: ')) + cstr(doc.bmi) + '<br>'
-	if doc.nutrition_note:
-		subject += frappe.bold(_('Note: ')) + cstr(doc.nutrition_note) + '<br>'
-
-	return subject
diff --git a/erpnext/healthcare/page/patient_history/patient_history.css b/erpnext/healthcare/page/patient_history/patient_history.css
index 865d6ab..1bb5891 100644
--- a/erpnext/healthcare/page/patient_history/patient_history.css
+++ b/erpnext/healthcare/page/patient_history/patient_history.css
@@ -109,6 +109,11 @@
 	padding-right: 0px;
 }
 
+.patient-history-filter {
+	margin-left: 35px;
+	width: 25%;
+}
+
 #page-medical_record .plot-wrapper {
 	padding: 20px 15px;
 	border-bottom: 1px solid #d1d8dd;
diff --git a/erpnext/healthcare/page/patient_history/patient_history.html b/erpnext/healthcare/page/patient_history/patient_history.html
index 7a9446d..be486c6 100644
--- a/erpnext/healthcare/page/patient_history/patient_history.html
+++ b/erpnext/healthcare/page/patient_history/patient_history.html
@@ -1,6 +1,5 @@
 <div class="col-sm-12">
 	<div class="col-sm-3">
-	<p class="text-center">{%= __("Select Patient") %}</p>
 	<p class="patient" style="margin: auto; max-width: 300px; margin-bottom: 20px;"></p>
 	<div class="patient_details" style="z-index=0"></div>
 	</div>
@@ -11,6 +10,13 @@
 			<div id="chart" class="col-sm-12 patient_vital_charts">
 			</div>
 		</div>
+		<div class="header-separator col-sm-12 d-flex border-bottom py-3" style="display:none"></div>
+		<div class="row">
+			<div class="col-sm-12 d-flex">
+				<div class="patient-history-filter doctype-filter"></div>
+				<div class="patient-history-filter date-filter"></div>
+			</div>
+		</div>
 		<div class="col-sm-12 patient_documents_list">
 		</div>
 		<div class="col-sm-12 text-center py-3">
diff --git a/erpnext/healthcare/page/patient_history/patient_history.js b/erpnext/healthcare/page/patient_history/patient_history.js
index fe5b7bc..54343aa 100644
--- a/erpnext/healthcare/page/patient_history/patient_history.js
+++ b/erpnext/healthcare/page/patient_history/patient_history.js
@@ -1,141 +1,225 @@
-frappe.provide("frappe.patient_history");
+frappe.provide('frappe.patient_history');
 frappe.pages['patient_history'].on_page_load = function(wrapper) {
-	var me = this;
-	var page = frappe.ui.make_app_page({
+	let me = this;
+	let page = frappe.ui.make_app_page({
 		parent: wrapper,
 		title: 'Patient History',
 		single_column: true
 	});
 
-	frappe.breadcrumbs.add("Healthcare");
+	frappe.breadcrumbs.add('Healthcare');
 	let pid = '';
-	page.main.html(frappe.render_template("patient_history", {}));
-	var patient = frappe.ui.form.make_control({
-		parent: page.main.find(".patient"),
+	page.main.html(frappe.render_template('patient_history', {}));
+	page.main.find('.header-separator').hide();
+
+	let patient = frappe.ui.form.make_control({
+		parent: page.main.find('.patient'),
 		df: {
-			fieldtype: "Link",
-			options: "Patient",
-			fieldname: "patient",
-			change: function(){
-				if(pid != patient.get_value() && patient.get_value()){
+			fieldtype: 'Link',
+			options: 'Patient',
+			fieldname: 'patient',
+			placeholder: __('Select Patient'),
+			only_select: true,
+			change: function() {
+				let patient_id = patient.get_value();
+				if (pid != patient_id && patient_id) {
 					me.start = 0;
-					me.page.main.find(".patient_documents_list").html("");
-					get_documents(patient.get_value(), me);
-					show_patient_info(patient.get_value(), me);
-					show_patient_vital_charts(patient.get_value(), me, "bp", "mmHg", "Blood Pressure");
+					me.page.main.find('.patient_documents_list').html('');
+					setup_filters(patient_id, me);
+					get_documents(patient_id, me);
+					show_patient_info(patient_id, me);
+					show_patient_vital_charts(patient_id, me, 'bp', 'mmHg', 'Blood Pressure');
 				}
-				pid = patient.get_value();
+				pid = patient_id;
 			}
 		},
-		only_input: true,
 	});
 	patient.refresh();
 
-	if (frappe.route_options){
+	if (frappe.route_options) {
 		patient.set_value(frappe.route_options.patient);
 	}
 
-	this.page.main.on("click", ".btn-show-chart", function() {
-		var	btn_show_id = $(this).attr("data-show-chart-id"), pts = $(this).attr("data-pts");
-		var title = $(this).attr("data-title");
+	this.page.main.on('click', '.btn-show-chart', function() {
+		let	btn_show_id = $(this).attr('data-show-chart-id'), pts = $(this).attr('data-pts');
+		let title = $(this).attr('data-title');
 		show_patient_vital_charts(patient.get_value(), me, btn_show_id, pts, title);
 	});
 
-	this.page.main.on("click", ".btn-more", function() {
-		var	doctype = $(this).attr("data-doctype"), docname = $(this).attr("data-docname");
-		if(me.page.main.find("."+docname).parent().find('.document-html').attr('data-fetched') == "1"){
-			me.page.main.find("."+docname).hide();
-			me.page.main.find("."+docname).parent().find('.document-html').show();
-		}else{
-			if(doctype && docname){
-				let exclude = ["patient", "patient_name", 'patient_sex', "encounter_date"];
+	this.page.main.on('click', '.btn-more', function() {
+		let	doctype = $(this).attr('data-doctype'), docname = $(this).attr('data-docname');
+		if (me.page.main.find('.'+docname).parent().find('.document-html').attr('data-fetched') == '1') {
+			me.page.main.find('.'+docname).hide();
+			me.page.main.find('.'+docname).parent().find('.document-html').show();
+		} else {
+			if (doctype && docname) {
+				let exclude = ['patient', 'patient_name', 'patient_sex', 'encounter_date'];
 				frappe.call({
-					method: "erpnext.healthcare.utils.render_doc_as_html",
+					method: 'erpnext.healthcare.utils.render_doc_as_html',
 					args:{
 						doctype: doctype,
 						docname: docname,
 						exclude_fields: exclude
 					},
+					freeze: true,
 					callback: function(r) {
-						if (r.message){
-							me.page.main.find("."+docname).hide();
-							me.page.main.find("."+docname).parent().find('.document-html').html(r.message.html+"\
-							<div align='center'><a class='btn octicon octicon-chevron-up btn-default btn-xs\
-							btn-less' data-doctype='"+doctype+"' data-docname='"+docname+"'></a></div>");
-							me.page.main.find("."+docname).parent().find('.document-html').show();
-							me.page.main.find("."+docname).parent().find('.document-html').attr('data-fetched', "1");
+						if (r.message) {
+							me.page.main.find('.' + docname).hide();
+
+							me.page.main.find('.' + docname).parent().find('.document-html').html(
+								`${r.message.html}
+									<div align='center'>
+										<a class='btn octicon octicon-chevron-up btn-default btn-xs btn-less'
+											data-doctype='${doctype}'
+											data-docname='${docname}'>
+										</a>
+									</div>
+								`);
+
+							me.page.main.find('.' + docname).parent().find('.document-html').show();
+							me.page.main.find('.' + docname).parent().find('.document-html').attr('data-fetched', '1');
 						}
-					},
-					freeze: true
+					}
 				});
 			}
 		}
 	});
 
-	this.page.main.on("click", ".btn-less", function() {
-		var docname = $(this).attr("data-docname");
-		me.page.main.find("."+docname).parent().find('.document-id').show();
-		me.page.main.find("."+docname).parent().find('.document-html').hide();
+	this.page.main.on('click', '.btn-less', function() {
+		let docname = $(this).attr('data-docname');
+		me.page.main.find('.' + docname).parent().find('.document-id').show();
+		me.page.main.find('.' + docname).parent().find('.document-html').hide();
 	});
 	me.start = 0;
-	me.page.main.on("click", ".btn-get-records", function(){
+	me.page.main.on('click', '.btn-get-records', function() {
 		get_documents(patient.get_value(), me);
 	});
 };
 
-var get_documents = function(patient, me){
+let setup_filters = function(patient, me) {
+	$('.doctype-filter').empty();
+	frappe.xcall(
+		'erpnext.healthcare.page.patient_history.patient_history.get_patient_history_doctypes'
+	).then(document_types => {
+		let doctype_filter = frappe.ui.form.make_control({
+			parent: $('.doctype-filter'),
+			df: {
+				fieldtype: 'MultiSelectList',
+				fieldname: 'document_type',
+				placeholder: __('Select Document Type'),
+				input_class: 'input-xs',
+				change: () => {
+					me.start = 0;
+					me.page.main.find('.patient_documents_list').html('');
+					get_documents(patient, me, doctype_filter.get_value(), date_range_field.get_value());
+				},
+				get_data: () => {
+					return document_types.map(document_type => {
+						return {
+							description: document_type,
+							value: document_type
+						};
+					});
+				},
+			}
+		});
+		doctype_filter.refresh();
+
+		$('.date-filter').empty();
+		let date_range_field = frappe.ui.form.make_control({
+			df: {
+				fieldtype: 'DateRange',
+				fieldname: 'date_range',
+				placeholder: __('Date Range'),
+				input_class: 'input-xs',
+				change: () => {
+					let selected_date_range = date_range_field.get_value();
+					if (selected_date_range && selected_date_range.length === 2) {
+						me.start = 0;
+						me.page.main.find('.patient_documents_list').html('');
+						get_documents(patient, me, doctype_filter.get_value(), selected_date_range);
+					}
+				}
+			},
+			parent: $('.date-filter')
+		});
+		date_range_field.refresh();
+	});
+};
+
+let get_documents = function(patient, me, document_types="", selected_date_range="") {
+	let filters = {
+		name: patient,
+		start: me.start,
+		page_length: 20
+	};
+	if (document_types)
+		filters['document_types'] = document_types;
+	if (selected_date_range)
+		filters['date_range'] = selected_date_range;
+
 	frappe.call({
-		"method": "erpnext.healthcare.page.patient_history.patient_history.get_feed",
-		args: {
-			name: patient,
-			start: me.start,
-			page_length: 20
-		},
-		callback: function (r) {
-			var data = r.message;
-			if(data.length){
+		'method': 'erpnext.healthcare.page.patient_history.patient_history.get_feed',
+		args: filters,
+		callback: function(r) {
+			let data = r.message;
+			if (data.length) {
 				add_to_records(me, data);
-			}else{
-				me.page.main.find(".patient_documents_list").append("<div class='text-muted' align='center'><br><br>No more records..<br><br></div>");
-				me.page.main.find(".btn-get-records").hide();
+			} else {
+				me.page.main.find('.patient_documents_list').append(`
+					<div class='text-muted' align='center'>
+						<br><br>${__('No more records..')}<br><br>
+					</div>`);
+				me.page.main.find('.btn-get-records').hide();
 			}
 		}
 	});
 };
 
-var add_to_records = function(me, data){
-	var details = "<ul class='nav nav-pills nav-stacked'>";
-	var i;
-	for(i=0; i<data.length; i++){
-		if(data[i].reference_doctype){
+let add_to_records = function(me, data) {
+	let details = "<ul class='nav nav-pills nav-stacked'>";
+	let i;
+	for (i=0; i<data.length; i++) {
+		if (data[i].reference_doctype) {
 			let label = '';
-			if(data[i].subject){
-				label += "<br/>"+data[i].subject;
+			if (data[i].subject) {
+				label += "<br/>" + data[i].subject;
 			}
 			data[i] = add_date_separator(data[i]);
-			if(frappe.user_info(data[i].owner).image){
+
+			if (frappe.user_info(data[i].owner).image) {
 				data[i].imgsrc = frappe.utils.get_file_link(frappe.user_info(data[i].owner).image);
-			}
-			else{
+			} else {
 				data[i].imgsrc = false;
 			}
-			var time_line_heading = data[i].practitioner ? `${data[i].practitioner} ` : ``;
-			time_line_heading += data[i].reference_doctype + " - "+ data[i].reference_name;
-			details += `<li data-toggle='pill' class='patient_doc_menu'
-			data-doctype='${data[i].reference_doctype}' data-docname='${data[i].reference_name}'>
-			<div class='col-sm-12 d-flex border-bottom py-3'>`;
-			if (data[i].imgsrc){
-				details += `<span class='mr-3'>
-					<img class='avtar' src='${data[i].imgsrc}' width='32' height='32'>
-					</img>
-			</span>`;
-			}else{
-				details += `<span class='mr-3 avatar avatar-small' style='width:32px; height:32px;'><div align='center' class='standard-image'
-					style='background-color: #fafbfc;'>${data[i].practitioner ? data[i].practitioner.charAt(0) : "U"}</div></span>`;
+
+			let time_line_heading = data[i].practitioner ? `${data[i].practitioner} ` : ``;
+			time_line_heading += data[i].reference_doctype + " - " +
+				`<a onclick="frappe.set_route('Form', '${data[i].reference_doctype}', '${data[i].reference_name}');">
+					${data[i].reference_name}
+				</a>`;
+
+			details += `
+				<li data-toggle='pill' class='patient_doc_menu'
+					data-doctype='${data[i].reference_doctype}' data-docname='${data[i].reference_name}'>
+					<div class='col-sm-12 d-flex border-bottom py-3'>`;
+
+			if (data[i].imgsrc) {
+				details += `
+					<span class='mr-3'>
+						<img class='avtar' src='${data[i].imgsrc}' width='32' height='32'></img>
+					</span>`;
+			} else {
+				details += `<span class='mr-3 avatar avatar-small' style='width:32px; height:32px;'>
+					<div align='center' class='standard-image' style='background-color: #fafbfc;'>
+						${data[i].practitioner ? data[i].practitioner.charAt(0) : 'U'}
+					</div>
+				</span>`;
 			}
+
 			details += `<div class='d-flex flex-column width-full'>
 					<div>
-						`+time_line_heading+` on
+						`+time_line_heading+`
 							<span>
 								${data[i].date_sep}
 							</span>
@@ -156,133 +240,150 @@
 			</li>`;
 		}
 	}
-	details += "</ul>";
-	me.page.main.find(".patient_documents_list").append(details);
+
+	details += '</ul>';
+	me.page.main.find('.patient_documents_list').append(details);
 	me.start += data.length;
-	if(data.length===20){
+
+	if (data.length === 20) {
 		me.page.main.find(".btn-get-records").show();
-	}else{
+	} else {
 		me.page.main.find(".btn-get-records").hide();
-		me.page.main.find(".patient_documents_list").append("<div class='text-muted' align='center'><br><br>No more records..<br><br></div>");
+		me.page.main.find(".patient_documents_list").append(`
+			<div class='text-muted' align='center'>
+				<br><br>${__('No more records..')}<br><br>
+			</div>`);
 	}
 };
 
-var add_date_separator = function(data) {
-	var date = frappe.datetime.str_to_obj(data.creation);
+let add_date_separator = function(data) {
+	let date = frappe.datetime.str_to_obj(data.communication_date);
+	let pdate = '';
+	let diff = frappe.datetime.get_day_diff(frappe.datetime.get_today(), frappe.datetime.obj_to_str(date));
 
-	var diff = frappe.datetime.get_day_diff(frappe.datetime.get_today(), frappe.datetime.obj_to_str(date));
-	if(diff < 1) {
-		var pdate = 'Today';
-	} else if(diff < 2) {
-		pdate = 'Yesterday';
+	if (diff < 1) {
+		pdate = __('Today');
+	} else if (diff < 2) {
+		pdate = __('Yesterday');
 	} else {
-		pdate = frappe.datetime.global_date_format(date);
+		pdate = __('on ') + frappe.datetime.global_date_format(date);
 	}
 	data.date_sep = pdate;
 	return data;
 };
 
-var show_patient_info = function(patient, me){
+let show_patient_info = function(patient, me) {
 	frappe.call({
-		"method": "erpnext.healthcare.doctype.patient.patient.get_patient_detail",
+		'method': 'erpnext.healthcare.doctype.patient.patient.get_patient_detail',
 		args: {
 			patient: patient
 		},
-		callback: function (r) {
-			var data = r.message;
-			var details = "";
-			if(data.image){
-				details += "<div><img class='thumbnail' width=75% src='"+data.image+"'></div>";
+		callback: function(r) {
+			let data = r.message;
+			let details = '';
+			if (data.image) {
+				details += `<div><img class='thumbnail' width=75% src='${data.image}'></div>`;
 			}
-			details += "<b>" + data.patient_name +"</b><br>" + data.sex;
-			if(data.email) details += "<br>" + data.email;
-			if(data.mobile) details += "<br>" + data.mobile;
-			if(data.occupation) details += "<br><br><b>Occupation :</b> " + data.occupation;
-			if(data.blood_group) details += "<br><b>Blood group : </b> " + data.blood_group;
-			if(data.allergies) details +=  "<br><br><b>Allergies : </b> "+  data.allergies.replace("\n", "<br>");
-			if(data.medication) details +=  "<br><b>Medication : </b> "+  data.medication.replace("\n", "<br>");
-			if(data.alcohol_current_use) details +=  "<br><br><b>Alcohol use : </b> "+  data.alcohol_current_use;
-			if(data.alcohol_past_use) details +=  "<br><b>Alcohol past use : </b> "+  data.alcohol_past_use;
-			if(data.tobacco_current_use) details +=  "<br><b>Tobacco use : </b> "+  data.tobacco_current_use;
-			if(data.tobacco_past_use) details +=  "<br><b>Tobacco past use : </b> "+  data.tobacco_past_use;
-			if(data.medical_history) details +=  "<br><br><b>Medical history : </b> "+  data.medical_history.replace("\n", "<br>");
-			if(data.surgical_history) details +=  "<br><b>Surgical history : </b> "+  data.surgical_history.replace("\n", "<br>");
-			if(data.surrounding_factors) details +=  "<br><br><b>Occupational hazards : </b> "+  data.surrounding_factors.replace("\n", "<br>");
-			if(data.other_risk_factors) details += "<br><b>Other risk factors : </b> " + data.other_risk_factors.replace("\n", "<br>");
-			if(data.patient_details) details += "<br><br><b>More info : </b> " + data.patient_details.replace("\n", "<br>");
 
-			if(details){
-				details = "<div style='padding-left:10px; font-size:13px;' align='center'>" + details + "</div>";
+			details += `<b> ${data.patient_name} </b><br> ${data.sex}`;
+			if (data.email) details += `<br> ${data.email}`;
+			if (data.mobile) details += `<br> ${data.mobile}`;
+			if (data.occupation) details += `<br><br><b> ${__('Occupation')} : </b> ${data.occupation}`;
+			if (data.blood_group) details += `<br><b> ${__('Blood Group')} : </b> ${data.blood_group}`;
+			if (data.allergies) details +=  `<br><br><b> ${__('Allerigies')} : </b> ${data.allergies.replace("\n", ", ")}`;
+			if (data.medication) details +=  `<br><b> ${__('Medication')} : </b> ${data.medication.replace("\n", ", ")}`;
+			if (data.alcohol_current_use) details +=  `<br><br><b> ${__('Alcohol use')} : </b> ${data.alcohol_current_use}`;
+			if (data.alcohol_past_use) details +=  `<br><b> ${__('Alcohol past use')} : </b> ${data.alcohol_past_use}`;
+			if (data.tobacco_current_use) details +=  `<br><b> ${__('Tobacco use')} : </b> ${data.tobacco_current_use}`;
+			if (data.tobacco_past_use) details +=  `<br><b> ${__('Tobacco past use')} : </b> ${data.tobacco_past_use}`;
+			if (data.medical_history) details +=  `<br><br><b> ${__('Medical history')} : </b> ${data.medical_history.replace("\n", ", ")}`;
+			if (data.surgical_history) details +=  `<br><b> ${__('Surgical history')} : </b> ${data.surgical_history.replace("\n", ", ")}`;
+			if (data.surrounding_factors) details +=  `<br><br><b> ${__('Occupational hazards')} : </b> ${data.surrounding_factors.replace("\n", ", ")}`;
+			if (data.other_risk_factors) details += `<br><b> ${__('Other risk factors')} : </b> ${data.other_risk_factors.replace("\n", ", ")}`;
+			if (data.patient_details) details += `<br><br><b> ${__('More info')} : </b> ${data.patient_details.replace("\n", ", ")}`;
+
+			if (details) {
+				details = `<div style='padding-left:10px; font-size:13px;' align='left'>` + details + `</div>`;
 			}
-			me.page.main.find(".patient_details").html(details);
+			me.page.main.find('.patient_details').html(details);
 		}
 	});
 };
 
-var show_patient_vital_charts = function(patient, me, btn_show_id, pts, title) {
+let show_patient_vital_charts = function(patient, me, btn_show_id, pts, title) {
 	frappe.call({
-		method: "erpnext.healthcare.utils.get_patient_vitals",
+		method: 'erpnext.healthcare.utils.get_patient_vitals',
 		args:{
 			patient: patient
 		},
 		callback: function(r) {
-			if (r.message){
-				var show_chart_btns_html = "<div style='padding-top:5px;'><a class='btn btn-default btn-xs btn-show-chart' \
-				data-show-chart-id='bp' data-pts='mmHg' data-title='Blood Pressure'>Blood Pressure</a>\
-				<a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='pulse_rate' \
-				data-pts='per Minutes' data-title='Respiratory/Pulse Rate'>Respiratory/Pulse Rate</a>\
-				<a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='temperature' \
-				data-pts='°C or °F' data-title='Temperature'>Temperature</a>\
-				<a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='bmi' \
-				data-pts='' data-title='BMI'>BMI</a></div>";
-				me.page.main.find(".show_chart_btns").html(show_chart_btns_html);
-				var data = r.message;
+			if (r.message) {
+				let show_chart_btns_html = `
+					<div style='padding-top:10px;'>
+						<a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='bp' data-pts='mmHg' data-title='Blood Pressure'>
+							${__('Blood Pressure')}
+						</a>
+						<a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='pulse_rate' data-pts='per Minutes' data-title='Respiratory/Pulse Rate'>
+							${__('Respiratory/Pulse Rate')}
+						</a>
+						<a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='temperature' data-pts='°C or °F' data-title='Temperature'>
+							${__('Temperature')}
+						</a>
+						<a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='bmi' data-pts='' data-title='BMI'>
+							${__('BMI')}
+						</a>
+					</div>`;
+
+				me.page.main.find('.show_chart_btns').html(show_chart_btns_html);
+				let data = r.message;
 				let labels = [], datasets = [];
 				let bp_systolic = [], bp_diastolic = [], temperature = [];
 				let pulse = [], respiratory_rate = [], bmi = [], height = [], weight = [];
-				for(var i=0; i<data.length; i++){
-					labels.push(data[i].signs_date+"||"+data[i].signs_time);
-					if(btn_show_id=="bp"){
+
+				for (let i=0; i<data.length; i++) {
+					labels.push(data[i].signs_date+'||'+data[i].signs_time);
+
+					if (btn_show_id === 'bp') {
 						bp_systolic.push(data[i].bp_systolic);
 						bp_diastolic.push(data[i].bp_diastolic);
 					}
-					if(btn_show_id=="temperature"){
+					if (btn_show_id === 'temperature') {
 						temperature.push(data[i].temperature);
 					}
-					if(btn_show_id=="pulse_rate"){
+					if (btn_show_id === 'pulse_rate') {
 						pulse.push(data[i].pulse);
 						respiratory_rate.push(data[i].respiratory_rate);
 					}
-					if(btn_show_id=="bmi"){
+					if (btn_show_id === 'bmi') {
 						bmi.push(data[i].bmi);
 						height.push(data[i].height);
 						weight.push(data[i].weight);
 					}
 				}
-				if(btn_show_id=="temperature"){
-					datasets.push({name: "Temperature", values: temperature, chartType:'line'});
+				if (btn_show_id === 'temperature') {
+					datasets.push({name: 'Temperature', values: temperature, chartType: 'line'});
 				}
-				if(btn_show_id=="bmi"){
-					datasets.push({name: "BMI", values: bmi, chartType:'line'});
-					datasets.push({name: "Height", values: height, chartType:'line'});
-					datasets.push({name: "Weight", values: weight, chartType:'line'});
+				if (btn_show_id === 'bmi') {
+					datasets.push({name: 'BMI', values: bmi, chartType: 'line'});
+					datasets.push({name: 'Height', values: height, chartType: 'line'});
+					datasets.push({name: 'Weight', values: weight, chartType: 'line'});
 				}
-				if(btn_show_id=="bp"){
-					datasets.push({name: "BP Systolic", values: bp_systolic, chartType:'line'});
-					datasets.push({name: "BP Diastolic", values: bp_diastolic, chartType:'line'});
+				if (btn_show_id === 'bp') {
+					datasets.push({name: 'BP Systolic', values: bp_systolic, chartType: 'line'});
+					datasets.push({name: 'BP Diastolic', values: bp_diastolic, chartType: 'line'});
 				}
-				if(btn_show_id=="pulse_rate"){
-					datasets.push({name: "Heart Rate / Pulse", values: pulse, chartType:'line'});
-					datasets.push({name: "Respiratory Rate", values: respiratory_rate, chartType:'line'});
+				if (btn_show_id === 'pulse_rate') {
+					datasets.push({name: 'Heart Rate / Pulse', values: pulse, chartType: 'line'});
+					datasets.push({name: 'Respiratory Rate', values: respiratory_rate, chartType: 'line'});
 				}
-				new frappe.Chart( ".patient_vital_charts", {
+				new frappe.Chart('.patient_vital_charts', {
 					data: {
 						labels: labels,
 						datasets: datasets
 					},
 
 					title: title,
-					type: 'axis-mixed', // 'axis-mixed', 'bar', 'line', 'pie', 'percentage'
+					type: 'axis-mixed',
 					height: 200,
 					colors: ['purple', '#ffa3ef', 'light-blue'],
 
@@ -291,9 +392,11 @@
 						formatTooltipY: d => d + ' ' + pts,
 					}
 				});
-			}else{
-				me.page.main.find(".patient_vital_charts").html("");
-				me.page.main.find(".show_chart_btns").html("");
+				me.page.main.find('.header-separator').show();
+			} else {
+				me.page.main.find('.patient_vital_charts').html('');
+				me.page.main.find('.show_chart_btns').html('');
+				me.page.main.find('.header-separator').hide();
 			}
 		}
 	});
diff --git a/erpnext/healthcare/page/patient_history/patient_history.py b/erpnext/healthcare/page/patient_history/patient_history.py
index 772aa4e..4cdfd64 100644
--- a/erpnext/healthcare/page/patient_history/patient_history.py
+++ b/erpnext/healthcare/page/patient_history/patient_history.py
@@ -4,36 +4,70 @@
 
 from __future__ import unicode_literals
 import frappe
+import json
 from frappe.utils import cint
 from erpnext.healthcare.utils import render_docs_as_html
 
 @frappe.whitelist()
-def get_feed(name, start=0, page_length=20):
+def get_feed(name, document_types=None, date_range=None, start=0, page_length=20):
 	"""get feed"""
-	result = frappe.db.sql("""select name, owner, creation,
-		reference_doctype, reference_name, subject
-		from `tabPatient Medical Record`
-		where patient=%(patient)s
-		order by creation desc
-		limit %(start)s, %(page_length)s""",
-		{
-			"patient": name,
-			"start": cint(start),
-			"page_length": cint(page_length)
-		}, as_dict=True)
+	filters = get_filters(name, document_types, date_range)
+
+	result = frappe.db.get_all('Patient Medical Record',
+		fields=['name', 'owner', 'communication_date',
+			'reference_doctype', 'reference_name', 'subject'],
+		filters=filters,
+		order_by='communication_date DESC',
+		limit=cint(page_length),
+		start=cint(start)
+	)
+
 	return result
 
+
+def get_filters(name, document_types=None, date_range=None):
+	filters = {'patient': name}
+	if document_types:
+		document_types = json.loads(document_types)
+		if len(document_types):
+			filters['reference_doctype'] = ['IN', document_types]
+
+	if date_range:
+		try:
+			date_range = json.loads(date_range)
+			if date_range:
+				filters['communication_date'] = ['between', [date_range[0], date_range[1]]]
+		except json.decoder.JSONDecodeError:
+			pass
+
+	return filters
+
+
 @frappe.whitelist()
 def get_feed_for_dt(doctype, docname):
 	"""get feed"""
-	result = frappe.db.sql("""select name, owner, modified, creation,
-			reference_doctype, reference_name, subject
-		from `tabPatient Medical Record`
-		where reference_name=%(docname)s and reference_doctype=%(doctype)s
-		order by creation desc""",
-		{
-			"docname": docname,
-			"doctype": doctype
-		}, as_dict=True)
+	result = frappe.db.get_all('Patient Medical Record',
+		fields=['name', 'owner', 'communication_date',
+			'reference_doctype', 'reference_name', 'subject'],
+		filters={
+			'reference_doctype': doctype,
+			'reference_name': docname
+		},
+		order_by='communication_date DESC'
+	)
 
 	return result
+
+
+@frappe.whitelist()
+def get_patient_history_doctypes():
+	document_types = []
+	settings = frappe.get_single("Patient History Settings")
+
+	for entry in settings.standard_doctypes:
+		document_types.append(entry.document_type)
+
+	for entry in settings.custom_doctypes:
+		document_types.append(entry.document_type)
+
+	return document_types
diff --git a/erpnext/healthcare/setup.py b/erpnext/healthcare/setup.py
index 0684080..bf4df7e 100644
--- a/erpnext/healthcare/setup.py
+++ b/erpnext/healthcare/setup.py
@@ -16,6 +16,7 @@
 	create_healthcare_item_groups()
 	create_sensitivity()
 	add_healthcare_service_unit_tree_root()
+	setup_patient_history_settings()
 
 def create_medical_departments():
 	departments = [
@@ -213,3 +214,82 @@
 		if company:
 			return company[0].name
 	return None
+
+def setup_patient_history_settings():
+	import json
+
+	settings = frappe.get_single('Patient History Settings')
+	configuration = get_patient_history_config()
+	for dt, config in configuration.items():
+		settings.append("standard_doctypes", {
+			"document_type": dt,
+			"date_fieldname": config[0],
+			"selected_fields": json.dumps(config[1])
+		})
+	settings.save()
+
+def get_patient_history_config():
+	return {
+		"Patient Encounter": ("encounter_date", [
+			{"label": "Healthcare Practitioner", "fieldname": "practitioner", "fieldtype": "Link"},
+			{"label": "Symptoms", "fieldname": "symptoms", "fieldtype": "Table Multiselect"},
+			{"label": "Diagnosis", "fieldname": "diagnosis", "fieldtype": "Table Multiselect"},
+			{"label": "Drug Prescription", "fieldname": "drug_prescription", "fieldtype": "Table"},
+			{"label": "Lab Tests", "fieldname": "lab_test_prescription", "fieldtype": "Table"},
+			{"label": "Clinical Procedures", "fieldname": "procedure_prescription", "fieldtype": "Table"},
+			{"label": "Therapies", "fieldname": "therapies", "fieldtype": "Table"},
+			{"label": "Review Details", "fieldname": "encounter_comment", "fieldtype": "Small Text"}
+		]),
+		"Clinical Procedure": ("start_date", [
+			{"label": "Procedure Template", "fieldname": "procedure_template", "fieldtype": "Link"},
+			{"label": "Healthcare Practitioner", "fieldname": "practitioner", "fieldtype": "Link"},
+			{"label": "Notes", "fieldname": "notes", "fieldtype": "Small Text"},
+			{"label": "Service Unit", "fieldname": "service_unit", "fieldtype": "Healthcare Service Unit"},
+			{"label": "Start Time", "fieldname": "start_time", "fieldtype": "Time"},
+			{"label": "Sample", "fieldname": "sample", "fieldtype": "Link"}
+		]),
+		"Lab Test": ("result_date", [
+			{"label": "Test Template", "fieldname": "template", "fieldtype": "Link"},
+			{"label": "Healthcare Practitioner", "fieldname": "practitioner", "fieldtype": "Link"},
+			{"label": "Test Name", "fieldname": "lab_test_name", "fieldtype": "Data"},
+			{"label": "Lab Technician Name", "fieldname": "employee_name", "fieldtype": "Data"},
+			{"label": "Sample ID", "fieldname": "sample", "fieldtype": "Link"},
+			{"label": "Normal Test Result", "fieldname": "normal_test_items", "fieldtype": "Table"},
+			{"label": "Descriptive Test Result", "fieldname": "descriptive_test_items", "fieldtype": "Table"},
+			{"label": "Organism Test Result", "fieldname": "organism_test_items", "fieldtype": "Table"},
+			{"label": "Sensitivity Test Result", "fieldname": "sensitivity_test_items", "fieldtype": "Table"},
+			{"label": "Comments", "fieldname": "lab_test_comment", "fieldtype": "Table"}
+		]),
+		"Therapy Session": ("start_date", [
+			{"label": "Therapy Type", "fieldname": "therapy_type", "fieldtype": "Link"},
+			{"label": "Healthcare Practitioner", "fieldname": "practitioner", "fieldtype": "Link"},
+			{"label": "Therapy Plan", "fieldname": "therapy_plan", "fieldtype": "Link"},
+			{"label": "Duration", "fieldname": "duration", "fieldtype": "Int"},
+			{"label": "Location", "fieldname": "location", "fieldtype": "Link"},
+			{"label": "Healthcare Service Unit", "fieldname": "service_unit", "fieldtype": "Link"},
+			{"label": "Start Time", "fieldname": "start_time", "fieldtype": "Time"},
+			{"label": "Exercises", "fieldname": "exercises", "fieldtype": "Table"},
+			{"label": "Total Counts Targeted", "fieldname": "total_counts_targeted", "fieldtype": "Int"},
+			{"label": "Total Counts Completed", "fieldname": "total_counts_completed", "fieldtype": "Int"}
+		]),
+		"Vital Signs": ("signs_date", [
+			{"label": "Body Temperature", "fieldname": "temperature", "fieldtype": "Data"},
+			{"label": "Heart Rate / Pulse", "fieldname": "pulse", "fieldtype": "Data"},
+			{"label": "Respiratory rate", "fieldname": "respiratory_rate", "fieldtype": "Data"},
+			{"label": "Tongue", "fieldname": "tongue", "fieldtype": "Select"},
+			{"label": "Abdomen", "fieldname": "abdomen", "fieldtype": "Select"},
+			{"label": "Reflexes", "fieldname": "reflexes", "fieldtype": "Select"},
+			{"label": "Blood Pressure", "fieldname": "bp", "fieldtype": "Data"},
+			{"label": "Notes", "fieldname": "vital_signs_note", "fieldtype": "Small Text"},
+			{"label": "Height (In Meter)", "fieldname": "height", "fieldtype": "Float"},
+			{"label": "Weight (In Kilogram)", "fieldname": "weight", "fieldtype": "Float"},
+			{"label": "BMI", "fieldname": "bmi", "fieldtype": "Float"}
+		]),
+		"Inpatient Medication Order": ("start_date", [
+			{"label": "Healthcare Practitioner", "fieldname": "practitioner", "fieldtype": "Link"},
+			{"label": "Start Date", "fieldname": "start_date", "fieldtype": "Date"},
+			{"label": "End Date", "fieldname": "end_date", "fieldtype": "Date"},
+			{"label": "Medication Orders", "fieldname": "medication_orders", "fieldtype": "Table"},
+			{"label": "Total Orders", "fieldname": "total_orders", "fieldtype": "Float"}
+		])
+	}
\ No newline at end of file
diff --git a/erpnext/healthcare/utils.py b/erpnext/healthcare/utils.py
index 6a499aa..40f7f9c 100644
--- a/erpnext/healthcare/utils.py
+++ b/erpnext/healthcare/utils.py
@@ -6,6 +6,7 @@
 import math
 import frappe
 from frappe import _
+from frappe.utils.formatters import format_value
 from frappe.utils import time_diff_in_hours, rounded
 from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_income_account
 from erpnext.healthcare.doctype.fee_validity.fee_validity import create_fee_validity
@@ -648,11 +649,15 @@
 				html += "<table class='table table-condensed table-bordered'>" \
 				+ table_head +  table_row + "</table>"
 			continue
+
 		#on other field types add label and value to html
 		if not df.hidden and not df.print_hide and doc.get(df.fieldname) and df.fieldname not in exclude_fields:
-			html +=  '<br>{0} : {1}'.format(df.label or df.fieldname, \
-			doc.get(df.fieldname))
+			if doc.get(df.fieldname):
+				formatted_value = format_value(doc.get(df.fieldname), meta.get_field(df.fieldname), doc)
+				html +=  '<br>{0} : {1}'.format(df.label or df.fieldname, formatted_value)
+
 			if not has_data : has_data = True
+
 	if sec_on and col_on and has_data:
 		doc_html += section_html + html + '</div></div>'
 	elif sec_on and not col_on and has_data:
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index a2d9d86..14377e1 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -221,6 +221,11 @@
 }
 
 doc_events = {
+	"*": {
+		"on_submit": "erpnext.healthcare.doctype.patient_history_settings.patient_history_settings.create_medical_record",
+		"on_update_after_submit": "erpnext.healthcare.doctype.patient_history_settings.patient_history_settings.update_medical_record",
+		"on_cancel": "erpnext.healthcare.doctype.patient_history_settings.patient_history_settings.delete_medical_record"
+	},
 	"Stock Entry": {
 		"on_submit": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty",
 		"on_cancel": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty"
@@ -341,7 +346,8 @@
 		"erpnext.selling.doctype.quotation.quotation.set_expired_status",
 		"erpnext.healthcare.doctype.patient_appointment.patient_appointment.update_appointment_status",
 		"erpnext.buying.doctype.supplier_quotation.supplier_quotation.set_expired_status",
-		"erpnext.accounts.doctype.process_statement_of_accounts.process_statement_of_accounts.send_auto_email"
+		"erpnext.accounts.doctype.process_statement_of_accounts.process_statement_of_accounts.send_auto_email",
+		"erpnext.non_profit.doctype.membership.membership.set_expired_status"
 	],
 	"daily_long": [
 		"erpnext.setup.doctype.email_digest.email_digest.send",
diff --git a/erpnext/loan_management/report/applicant_wise_loan_security_exposure/applicant_wise_loan_security_exposure.py b/erpnext/loan_management/report/applicant_wise_loan_security_exposure/applicant_wise_loan_security_exposure.py
index 6d7c3b7..f280402 100644
--- a/erpnext/loan_management/report/applicant_wise_loan_security_exposure/applicant_wise_loan_security_exposure.py
+++ b/erpnext/loan_management/report/applicant_wise_loan_security_exposure/applicant_wise_loan_security_exposure.py
@@ -26,6 +26,7 @@
 		{"label": _("Disabled"), "fieldname": "disabled", "fieldtype": "Check", "width": 80},
 		{"label": _("Total Qty"), "fieldname": "total_qty", "fieldtype": "Float", "width": 100},
 		{"label": _("Latest Price"), "fieldname": "latest_price", "fieldtype": "Currency", "options": "currency", "width": 100},
+		{"label": _("Price Valid Upto"), "fieldname": "price_valid_upto", "fieldtype": "Datetime", "width": 100},
 		{"label": _("Current Value"), "fieldname": "current_value", "fieldtype": "Currency", "options": "currency", "width": 100},
 		{"label": _("% Of Applicant Portfolio"), "fieldname": "portfolio_percent", "fieldtype": "Percentage", "width": 100},
 		{"label": _("Currency"), "fieldname": "currency", "fieldtype": "Currency", "options": "Currency", "hidden": 1, "width": 100},
@@ -43,13 +44,16 @@
 
 	for key, qty in iteritems(pledge_values):
 		row = {}
-		current_value = flt(qty * loan_security_details.get(key[1])['latest_price'])
+		current_value = flt(qty * loan_security_details.get(key[1], {}).get('latest_price', 0))
+		valid_upto = loan_security_details.get(key[1], {}).get('valid_upto')
+
 		row.update(loan_security_details.get(key[1]))
 		row.update({
 			'applicant_type': applicant_type_map.get(key[0]),
 			'applicant_name': key[0],
 			'total_qty': qty,
 			'current_value': current_value,
+			'price_valid_upto': valid_upto,
 			'portfolio_percent': flt(current_value * 100 / total_value_map.get(key[0]), 2),
 			'currency': currency
 		})
@@ -60,20 +64,30 @@
 
 def get_loan_security_details(filters):
 	security_detail_map = {}
+	loan_security_price_map = {}
+	lsp_validity_map = {}
 
-	loan_security_price_map = frappe._dict(frappe.db.sql("""
-		SELECT loan_security, loan_security_price
+	loan_security_prices = frappe.db.sql("""
+		SELECT loan_security, loan_security_price, valid_upto
 		FROM `tabLoan Security Price` t1
 		WHERE valid_from >= (SELECT MAX(valid_from) FROM `tabLoan Security Price` t2
 		WHERE t1.loan_security = t2.loan_security)
-	""", as_list=1))
+	""", as_dict=1)
+
+	for security in loan_security_prices:
+		loan_security_price_map.setdefault(security.loan_security, security.loan_security_price)
+		lsp_validity_map.setdefault(security.loan_security, security.valid_upto)
 
 	loan_security_details = frappe.get_all('Loan Security', fields=['name as loan_security',
 		'loan_security_code', 'loan_security_name', 'haircut', 'loan_security_type',
 		'disabled'])
 
 	for security in loan_security_details:
-		security.update({'latest_price': flt(loan_security_price_map.get(security.loan_security))})
+		security.update({
+			'latest_price': flt(loan_security_price_map.get(security.loan_security)),
+			'valid_upto': lsp_validity_map.get(security.loan_security)
+		})
+
 		security_detail_map.setdefault(security.loan_security, security)
 
 	return security_detail_map
@@ -118,6 +132,6 @@
 			applicant_wise_unpledges.get((security.applicant, security.loan_security), 0.0)
 
 		total_value_map[security.applicant] += current_pledges.get((security.applicant, security.loan_security)) \
-			* loan_security_details.get(security.loan_security)['latest_price']
+			* loan_security_details.get(security.loan_security, {}).get('latest_price', 0)
 
 	return current_pledges, total_value_map, applicant_type_map
\ No newline at end of file
diff --git a/erpnext/loan_management/report/loan_interest_report/loan_interest_report.py b/erpnext/loan_management/report/loan_interest_report/loan_interest_report.py
index aa0325e..2bfe6d3 100644
--- a/erpnext/loan_management/report/loan_interest_report/loan_interest_report.py
+++ b/erpnext/loan_management/report/loan_interest_report/loan_interest_report.py
@@ -6,6 +6,8 @@
 import erpnext
 from frappe import _
 from frappe.utils import flt, getdate, add_days
+from erpnext.loan_management.report.applicant_wise_loan_security_exposure.applicant_wise_loan_security_exposure \
+	 import get_loan_security_details
 
 
 def execute(filters=None):
@@ -31,6 +33,7 @@
 		{"label": _("Undue Booked Interest"), "fieldname": "undue_interest", "fieldtype": "Currency", "options": "currency", "width": 120},
 		{"label": _("Interest %"), "fieldname": "rate_of_interest", "fieldtype": "Percent", "width": 100},
 		{"label": _("Penalty Interest %"), "fieldname": "penalty_interest", "fieldtype": "Percent", "width": 100},
+		{"label": _("Loan To Value Ratio"), "fieldname": "loan_to_value", "fieldtype": "Percent", "width": 100},
 		{"label": _("Currency"), "fieldname": "currency", "fieldtype": "Currency", "options": "Currency", "hidden": 1, "width": 100},
 	]
 
@@ -50,6 +53,9 @@
 
 	loan_list = [d.loan for d in loan_details]
 
+	current_pledges = get_loan_wise_pledges(filters)
+	loan_wise_security_value = get_loan_wise_security_value(filters, current_pledges)
+
 	sanctioned_amount_map = get_sanctioned_amount_map()
 	penal_interest_rate_map = get_penal_interest_rate_map()
 	payments = get_payments(loan_list)
@@ -67,12 +73,16 @@
 			"penalty": flt(accrual_map.get(loan.loan, {}).get("penalty")),
 			"penalty_interest": penal_interest_rate_map.get(loan.loan_type),
 			"undue_interest": flt(accrual_map.get(loan.loan, {}).get("undue_interest")),
+			"loan_to_value": 0.0,
 			"currency": currency
 		})
 
 		loan['total_outstanding'] = loan['principal_outstanding'] + loan['interest_outstanding'] \
 			+ loan['penalty']
 
+		if loan_wise_security_value.get(loan.loan):
+			loan['loan_to_value'] = (loan['principal_outstanding'] * 100) / loan_wise_security_value.get(loan.loan)
+
 	return loan_details
 
 def get_sanctioned_amount_map():
@@ -121,4 +131,53 @@
 	return accrual_map
 
 def get_penal_interest_rate_map():
-	return frappe._dict(frappe.get_all("Loan Type", fields=["name", "penalty_interest_rate"], as_list=1))
\ No newline at end of file
+	return frappe._dict(frappe.get_all("Loan Type", fields=["name", "penalty_interest_rate"], as_list=1))
+
+def get_loan_wise_pledges(filters):
+	loan_wise_unpledges = {}
+	current_pledges = {}
+
+	conditions = ""
+
+	if filters.get('company'):
+		conditions = "AND company = %(company)s"
+
+	unpledges = frappe.db.sql("""
+		SELECT up.loan, u.loan_security, sum(u.qty) as qty
+		FROM `tabLoan Security Unpledge` up, `tabUnpledge` u
+		WHERE u.parent = up.name
+		AND up.status = 'Approved'
+		{conditions}
+		GROUP BY up.loan
+	""".format(conditions=conditions), filters, as_dict=1)
+
+	for unpledge in unpledges:
+		loan_wise_unpledges.setdefault((unpledge.loan, unpledge.loan_security), unpledge.qty)
+
+	pledges = frappe.db.sql("""
+		SELECT lp.loan, p.loan_security, sum(p.qty) as qty
+		FROM `tabLoan Security Pledge` lp, `tabPledge`p
+		WHERE p.parent = lp.name
+		AND lp.status = 'Pledged'
+		{conditions}
+		GROUP BY lp.loan
+	""".format(conditions=conditions), filters, as_dict=1)
+
+	for security in pledges:
+		current_pledges.setdefault((security.loan, security.loan_security), security.qty)
+		current_pledges[(security.loan, security.loan_security)] -= \
+			loan_wise_unpledges.get((security.loan, security.loan_security), 0.0)
+
+	return current_pledges
+
+def get_loan_wise_security_value(filters, current_pledges):
+	loan_security_details = get_loan_security_details(filters)
+	loan_wise_security_value = {}
+
+	for key in current_pledges:
+		qty = current_pledges.get(key)
+		loan_wise_security_value.setdefault(key[0], 0.0)
+		loan_wise_security_value[key[0]] += \
+			flt(qty * loan_security_details.get(key[1], {}).get('latest_price', 0))
+
+	return loan_wise_security_value
\ No newline at end of file
diff --git a/erpnext/loan_management/report/loan_security_exposure/loan_security_exposure.py b/erpnext/loan_management/report/loan_security_exposure/loan_security_exposure.py
index 3ef10c0..ff88052 100644
--- a/erpnext/loan_management/report/loan_security_exposure/loan_security_exposure.py
+++ b/erpnext/loan_management/report/loan_security_exposure/loan_security_exposure.py
@@ -24,6 +24,7 @@
 		{"label": _("Disabled"), "fieldname": "disabled", "fieldtype": "Check", "width": 80},
 		{"label": _("Total Qty"), "fieldname": "total_qty", "fieldtype": "Float", "width": 100},
 		{"label": _("Latest Price"), "fieldname": "latest_price", "fieldtype": "Currency", "options": "currency", "width": 100},
+		{"label": _("Price Valid Upto"), "fieldname": "price_valid_upto", "fieldtype": "Datetime", "width": 100},
 		{"label": _("Current Value"), "fieldname": "current_value", "fieldtype": "Currency", "options": "currency", "width": 100},
 		{"label": _("% Of Total Portfolio"), "fieldname": "portfolio_percent", "fieldtype": "Percentage", "width": 100},
 		{"label": _("Pledged Applicant Count"), "fieldname": "pledged_applicant_count", "fieldtype": "Percentage", "width": 100},
@@ -40,13 +41,16 @@
 
 	for security, value in iteritems(current_pledges):
 		row = {}
-		current_value = flt(value['qty'] * loan_security_details.get(security)['latest_price'])
+		current_value = flt(value.get('qty', 0) * loan_security_details.get(security, {}).get('latest_price', 0))
+		valid_upto = loan_security_details.get(security, {}).get('valid_upto')
+
 		row.update(loan_security_details.get(security))
 		row.update({
-			'total_qty': value['qty'],
+			'total_qty': value.get('qty'),
 			'current_value': current_value,
+			'price_valid_upto': valid_upto,
 			'portfolio_percent': flt(current_value * 100 / total_portfolio_value, 2),
-			'pledged_applicant_count': value['applicant_count'],
+			'pledged_applicant_count': value.get('applicant_count'),
 			'currency': currency
 		})
 
diff --git a/erpnext/non_profit/doctype/member/member.json b/erpnext/non_profit/doctype/member/member.json
index 992ef16..f190cfa 100644
--- a/erpnext/non_profit/doctype/member/member.json
+++ b/erpnext/non_profit/doctype/member/member.json
@@ -12,7 +12,6 @@
   "membership_expiry_date",
   "column_break_5",
   "membership_type",
-  "email",
   "email_id",
   "image",
   "customer_section",
@@ -65,13 +64,6 @@
    "reqd": 1
   },
   {
-   "fieldname": "email",
-   "fieldtype": "Link",
-   "in_list_view": 1,
-   "label": "User",
-   "options": "User"
-  },
-  {
    "fieldname": "image",
    "fieldtype": "Attach Image",
    "hidden": 1,
@@ -178,7 +170,7 @@
  ],
  "image_field": "image",
  "links": [],
- "modified": "2020-09-16 23:44:13.596948",
+ "modified": "2020-11-09 12:12:10.174647",
  "modified_by": "Administrator",
  "module": "Non Profit",
  "name": "Member",
diff --git a/erpnext/non_profit/doctype/member/member.py b/erpnext/non_profit/doctype/member/member.py
index 25d6b53..04b99f9 100644
--- a/erpnext/non_profit/doctype/member/member.py
+++ b/erpnext/non_profit/doctype/member/member.py
@@ -18,8 +18,6 @@
 
 
 	def validate(self):
-		if self.email:
-			self.validate_email_type(self.email)
 		if self.email_id:
 			self.validate_email_type(self.email_id)
 
@@ -57,14 +55,16 @@
 	def make_customer_and_link(self):
 		if self.customer:
 			frappe.msgprint(_("A customer is already linked to this Member"))
-		cust = create_customer(frappe._dict({
+
+		customer = create_customer(frappe._dict({
 			'fullname': self.member_name,
-			'email': self.email_id or self.email,
+			'email': self.email_id,
 			'phone': None
 		}))
 
-		self.customer = cust
+		self.customer = customer
 		self.save()
+		frappe.msgprint(_("Customer {0} has been created succesfully.").format(self.customer))
 
 
 def get_or_create_member(user_details):
diff --git a/erpnext/non_profit/doctype/membership/membership.js b/erpnext/non_profit/doctype/membership/membership.js
index ee8a8c0..573ac33 100644
--- a/erpnext/non_profit/doctype/membership/membership.js
+++ b/erpnext/non_profit/doctype/membership/membership.js
@@ -4,16 +4,25 @@
 frappe.ui.form.on('Membership', {
 	setup: function(frm) {
 		frappe.db.get_single_value("Membership Settings", "enable_razorpay").then(val => {
-			if (val) frm.set_df_property('razorpay_details_section', 'hidden', false);
+			if (val) frm.set_df_property("razorpay_details_section", "hidden", false);
 		})
 	},
 
 	refresh: function(frm) {
+		if (frm.doc.__islocal)
+			return;
+
 		!frm.doc.invoice && frm.add_custom_button("Generate Invoice", () => {
-			frm.call("generate_invoice", {
-				save: true
-			}).then(() => {
-				frm.reload_doc();
+			frm.call({
+				doc: frm.doc,
+				method: "generate_invoice",
+				args: {save: true},
+				freeze: true,
+				freeze_message: __("Creating Membership Invoice"),
+				callback: function(r) {
+					if (r.invoice)
+						frm.reload_doc();
+				}
 			});
 		});
 
@@ -27,6 +36,6 @@
 	},
 
 	onload: function(frm) {
-		frm.add_fetch('membership_type', 'amount', 'amount');
+		frm.add_fetch("membership_type", "amount", "amount");
 	}
 });
diff --git a/erpnext/non_profit/doctype/membership/membership.json b/erpnext/non_profit/doctype/membership/membership.json
index 7f21896..6da053f 100644
--- a/erpnext/non_profit/doctype/membership/membership.json
+++ b/erpnext/non_profit/doctype/membership/membership.json
@@ -7,6 +7,7 @@
  "engine": "InnoDB",
  "field_order": [
   "member",
+  "member_name",
   "membership_type",
   "column_break_3",
   "membership_status",
@@ -46,6 +47,8 @@
   {
    "fieldname": "membership_status",
    "fieldtype": "Select",
+   "in_list_view": 1,
+   "in_standard_filter": 1,
    "label": "Membership Status",
    "options": "New\nCurrent\nExpired\nPending\nCancelled"
   },
@@ -122,11 +125,18 @@
    "fieldtype": "Link",
    "label": "Invoice",
    "options": "Sales Invoice"
+  },
+  {
+   "fetch_from": "member.member_name",
+   "fieldname": "member_name",
+   "fieldtype": "Data",
+   "label": "Member Name",
+   "read_only": 1
   }
  ],
  "index_web_pages_for_search": 1,
  "links": [],
- "modified": "2020-09-19 14:28:11.532696",
+ "modified": "2021-01-21 16:31:20.032656",
  "modified_by": "Administrator",
  "module": "Non Profit",
  "name": "Membership",
@@ -158,7 +168,9 @@
   }
  ],
  "restrict_to_domain": "Non Profit",
+ "search_fields": "member, member_name",
  "sort_field": "modified",
  "sort_order": "DESC",
+ "title_field": "member_name",
  "track_changes": 1
-}
+}
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py
index 7d15aba..c113b80 100644
--- a/erpnext/non_profit/doctype/membership/membership.py
+++ b/erpnext/non_profit/doctype/membership/membership.py
@@ -14,33 +14,43 @@
 from frappe import _
 import erpnext
 
-
 class Membership(Document):
 	def validate(self):
 		if not self.member or not frappe.db.exists("Member", self.member):
-			member_name = frappe.get_value('Member', dict(email=frappe.session.user))
+			# for web forms
+			user_type = frappe.db.get_value("User", frappe.session.user, "user_type")
+			if user_type == "Website User":
+				self.create_member_from_website_user()
+			else:
+				frappe.throw(_("Please select a Member"))
 
-			if not member_name:
-				user = frappe.get_doc('User', frappe.session.user)
-				member = frappe.get_doc(dict(
-					doctype='Member',
-					email=frappe.session.user,
-					membership_type=self.membership_type,
-					member_name=user.get_fullname()
-				)).insert(ignore_permissions=True)
-				member_name = member.name
+		self.validate_membership_period()
 
-			if self.get("__islocal"):
-				self.member = member_name
+	def create_member_from_website_user(self):
+		member_name = frappe.get_value("Member", dict(email_id=frappe.session.user))
 
+		if not member_name:
+			user = frappe.get_doc("User", frappe.session.user)
+			member = frappe.get_doc(dict(
+				doctype="Member",
+				email_id=frappe.session.user,
+				membership_type=self.membership_type,
+				member_name=user.get_fullname()
+			)).insert(ignore_permissions=True)
+			member_name = member.name
+
+		if self.get("__islocal"):
+			self.member = member_name
+
+	def validate_membership_period(self):
 		# get last membership (if active)
-		last_membership = erpnext.get_last_membership()
+		last_membership = erpnext.get_last_membership(self.member)
 
 		# if person applied for offline membership
 		if last_membership and not frappe.session.user == "Administrator":
 			# if last membership does not expire in 30 days, then do not allow to renew
 			if getdate(add_days(last_membership.to_date, -30)) > getdate(nowdate()) :
-				frappe.throw(_('You can only renew if your membership expires within 30 days'))
+				frappe.throw(_("You can only renew if your membership expires within 30 days"))
 
 			self.from_date = add_days(last_membership.to_date, 1)
 		elif frappe.session.user == "Administrator":
@@ -54,11 +64,16 @@
 			self.to_date = add_months(self.from_date, 1)
 
 	def on_payment_authorized(self, status_changed_to=None):
-		if status_changed_to in ("Completed", "Authorized"):
-			self.load_from_db()
-			self.db_set('paid', 1)
+		if status_changed_to not in ("Completed", "Authorized"):
+			return
+		self.load_from_db()
+		self.db_set("paid", 1)
+		settings = frappe.get_doc("Membership Settings")
+		if settings.enable_invoicing and settings.create_for_web_forms:
+			self.generate_invoice(with_payment_entry=settings.make_payment_entry, save=True)
 
-	def generate_invoice(self, save=True):
+
+	def generate_invoice(self, save=True, with_payment_entry=False):
 		if not (self.paid or self.currency or self.amount):
 			frappe.throw(_("The payment for this membership is not paid. To generate invoice fill the payment details"))
 
@@ -66,34 +81,64 @@
 			frappe.throw(_("An invoice is already linked to this document"))
 
 		member = frappe.get_doc("Member", self.member)
-		plan = frappe.get_doc("Membership Type", self.membership_type)
-		settings = frappe.get_doc("Membership Settings")
-
 		if not member.customer:
 			frappe.throw(_("No customer linked to member {0}").format(frappe.bold(self.member)))
 
-		if not settings.debit_account:
-			frappe.throw(_("You need to set <b>Debit Account</b> in Membership Settings"))
-
-		if not settings.company:
-			frappe.throw(_("You need to set <b>Default Company</b> for invoicing in Membership Settings"))
+		plan = frappe.get_doc("Membership Type", self.membership_type)
+		settings = frappe.get_doc("Membership Settings")
+		self.validate_membership_type_and_settings(plan, settings)
 
 		invoice = make_invoice(self, member, plan, settings)
 		self.invoice = invoice.name
 
+		if with_payment_entry:
+			self.make_payment_entry(settings, invoice)
+
 		if save:
 			self.save()
 
 		return invoice
 
+	def validate_membership_type_and_settings(self, plan, settings):
+		settings_link = get_link_to_form("Membership Type", self.membership_type)
+
+		if not settings.debit_account:
+			frappe.throw(_("You need to set <b>Debit Account</b> in {0}").format(settings_link))
+
+		if not settings.company:
+			frappe.throw(_("You need to set <b>Default Company</b> for invoicing in {0}").format(settings_link))
+
+		if not plan.linked_item:
+			frappe.throw(_("Please set a Linked Item for the Membership Type {0}").format(
+				get_link_to_form("Membership Type", self.membership_type)))
+
+	def make_payment_entry(self, settings, invoice):
+		if not settings.payment_account:
+			frappe.throw(_("You need to set <b>Payment Account</b> in {0}").format(
+				get_link_to_form("Membership Type", self.membership_type)))
+
+		from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
+		frappe.flags.ignore_account_permission = True
+		pe = get_payment_entry(dt="Sales Invoice", dn=invoice.name, bank_amount=invoice.grand_total)
+		frappe.flags.ignore_account_permission=False
+		pe.paid_to = settings.payment_account
+		pe.reference_no = self.name
+		pe.reference_date = getdate()
+		pe.save(ignore_permissions=True)
+		pe.submit()
+
 	def send_acknowlement(self):
 		settings = frappe.get_doc("Membership Settings")
 		if not settings.send_email:
-			frappe.throw(_("You need to enable <b>Send Acknowledge Email</b> in Membership Settings"))
+			frappe.throw(_("You need to enable <b>Send Acknowledge Email</b> in {0}").format(
+				get_link_to_form("Membership Settings", "Membership Settings")))
 
 		member = frappe.get_doc("Member", self.member)
+		if not member.email_id:
+			frappe.throw(_("Email address of member {0} is missing").format(frappe.utils.get_link_to_form("Member", self.member)))
+
 		plan = frappe.get_doc("Membership Type", self.membership_type)
-		email = member.email_id if member.email_id else member.email
+		email = member.email_id
 		attachments = [frappe.attach_print("Membership", self.name, print_format=settings.membership_print_format)]
 
 		if self.invoice and settings.send_invoice:
@@ -112,48 +157,56 @@
 		}
 
 		if not frappe.flags.in_test:
-			frappe.enqueue(method=frappe.sendmail, queue='short', timeout=300, is_async=True, **email_args)
+			frappe.enqueue(method=frappe.sendmail, queue="short", timeout=300, is_async=True, **email_args)
 		else:
 			frappe.sendmail(**email_args)
 
 	def generate_and_send_invoice(self):
-		invoice = self.generate_invoice(False)
+		self.generate_invoice(save=False)
 		self.send_acknowlement()
 
+
 def make_invoice(membership, member, plan, settings):
 	invoice = frappe.get_doc({
-		'doctype': 'Sales Invoice',
-		'customer': member.customer,
-		'debit_to': settings.debit_account,
-		'currency': membership.currency,
-		'is_pos': 0,
-		'items': [
+		"doctype": "Sales Invoice",
+		"customer": member.customer,
+		"debit_to": settings.debit_account,
+		"currency": membership.currency,
+		"company": settings.company,
+		"is_pos": 0,
+		"items": [
 			{
-				'item_code': plan.linked_item,
-				'rate': membership.amount,
-				'qty': 1
+				"item_code": plan.linked_item,
+				"rate": membership.amount,
+				"qty": 1
 			}
 		]
 	})
-
+	invoice.set_missing_values()
 	invoice.insert(ignore_permissions=True)
 	invoice.submit()
 
+	frappe.msgprint(_("Sales Invoice created successfully"))
+
 	return invoice
 
+
 def get_member_based_on_subscription(subscription_id, email):
 	members = frappe.get_all("Member", filters={
-					'subscription_id': subscription_id,
-					'email_id': email
+					"subscription_id": subscription_id,
+					"email_id": email
 				}, order_by="creation desc")
 
 	try:
-		return frappe.get_doc("Member", members[0]['name'])
+		return frappe.get_doc("Member", members[0]["name"])
 	except:
 		return None
 
+
 def verify_signature(data):
-	signature = frappe.request.headers.get('X-Razorpay-Signature')
+	if frappe.flags.in_test:
+		return True
+	signature = frappe.request.headers.get("X-Razorpay-Signature")
 
 	settings = frappe.get_doc("Membership Settings")
 	key = settings.get_webhook_secret()
@@ -162,6 +215,7 @@
 
 	controller.verify_signature(data, signature, key)
 
+
 @frappe.whitelist(allow_guest=True)
 def trigger_razorpay_subscription(*args, **kwargs):
 	data = frappe.request.get_data(as_text=True)
@@ -170,16 +224,16 @@
 	except Exception as e:
 		log = frappe.log_error(e, "Webhook Verification Error")
 		notify_failure(log)
-		return { 'status': 'Failed', 'reason': e}
+		return { "status": "Failed", "reason": e}
 
 	if isinstance(data, six.string_types):
 		data = json.loads(data)
 	data = frappe._dict(data)
 
-	subscription = data.payload.get("subscription", {}).get('entity', {})
+	subscription = data.payload.get("subscription", {}).get("entity", {})
 	subscription = frappe._dict(subscription)
 
-	payment = data.payload.get("payment", {}).get('entity', {})
+	payment = data.payload.get("payment", {}).get("entity", {})
 	payment = frappe._dict(payment)
 
 	try:
@@ -189,15 +243,15 @@
 		member = get_member_based_on_subscription(subscription.id, payment.email)
 		if not member:
 			member = create_member(frappe._dict({
-				'fullname': payment.email,
-				'email': payment.email,
-				'plan_id': get_plan_from_razorpay_id(subscription.plan_id)
+				"fullname": payment.email,
+				"email": payment.email,
+				"plan_id": get_plan_from_razorpay_id(subscription.plan_id)
 			}))
 
 			member.subscription_id = subscription.id
 			member.customer_id = payment.customer_id
 			if subscription.notes and type(subscription.notes) == dict:
-				notes = '\n'.join("{}: {}".format(k, v) for k, v in subscription.notes.items())
+				notes = "\n".join("{}: {}".format(k, v) for k, v in subscription.notes.items())
 				member.add_comment("Comment", notes)
 			elif subscription.notes and type(subscription.notes) == str:
 				member.add_comment("Comment", subscription.notes)
@@ -227,28 +281,39 @@
 		message = "{0}\n\n{1}\n\n{2}: {3}".format(e, frappe.get_traceback(), __("Payment ID"), payment.id)
 		log = frappe.log_error(message, _("Error creating membership entry for {0}").format(member.name))
 		notify_failure(log)
-		return { 'status': 'Failed', 'reason': e}
+		return { "status": "Failed", "reason": e}
 
-	return { 'status': 'Success' }
+	return { "status": "Success" }
 
 
 def notify_failure(log):
 	try:
-		content = """Dear System Manager,
-Razorpay webhook for creating renewing membership subscription failed due to some reason. Please check the following error log linked below
+		content = """
+			Dear System Manager,
+			Razorpay webhook for creating renewing membership subscription failed due to some reason.
+			Please check the following error log linked below
+			Error Log: {0}
+			Regards, Administrator
+		""".format(get_link_to_form("Error Log", log.name))
 
-Error Log: {0}
-
-Regards,
-Administrator""".format(get_link_to_form("Error Log", log.name))
 		sendmail_to_system_managers("[Important] [ERPNext] Razorpay membership webhook failed , please check.", content)
 	except:
 		pass
 
+
 def get_plan_from_razorpay_id(plan_id):
-	plan = frappe.get_all("Membership Type", filters={'razorpay_plan_id': plan_id}, order_by="creation desc")
+	plan = frappe.get_all("Membership Type", filters={"razorpay_plan_id": plan_id}, order_by="creation desc")
 
 	try:
-		return plan[0]['name']
+		return plan[0]["name"]
 	except:
 		return None
+
+
+def set_expired_status():
+	frappe.db.sql("""
+		UPDATE
+			`tabMembership` SET `status` = 'Expired'
+		WHERE
+			`status` not in ('Cancelled') AND `to_date` < %s
+		""", (nowdate()))
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/membership/membership_list.js b/erpnext/non_profit/doctype/membership/membership_list.js
new file mode 100644
index 0000000..a959159
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership/membership_list.js
@@ -0,0 +1,15 @@
+frappe.listview_settings['Membership'] = {
+	get_indicator: function(doc) {
+		if (doc.membership_status == 'New') {
+			return [__('New'), 'blue', 'membership_status,=,New'];
+		} else if (doc.membership_status === 'Current') {
+			return [__('Current'), 'green', 'membership_status,=,Current'];
+		} else if (doc.membership_status === 'Pending') {
+			return [__('Pending'), 'yellow', 'membership_status,=,Pending'];
+		} else if (doc.membership_status === 'Expired') {
+			return [__('Expired'), 'grey', 'membership_status,=,Expired'];
+		} else {
+			return [__('Cancelled'), 'red', 'membership_status,=,Cancelled'];
+		}
+	}
+};
diff --git a/erpnext/non_profit/doctype/membership/test_membership.py b/erpnext/non_profit/doctype/membership/test_membership.py
index b23f406..ff7e6c4 100644
--- a/erpnext/non_profit/doctype/membership/test_membership.py
+++ b/erpnext/non_profit/doctype/membership/test_membership.py
@@ -2,8 +2,110 @@
 # Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
 # See license.txt
 from __future__ import unicode_literals
-
 import unittest
+import frappe
+import erpnext
+from erpnext.non_profit.doctype.member.member import create_member
+from frappe.utils import nowdate, add_months
 
 class TestMembership(unittest.TestCase):
-	pass
+	def setUp(self):
+		# Get default company
+		company = frappe.get_doc("Company", erpnext.get_default_company())
+
+		# update membership settings
+		settings = frappe.get_doc("Membership Settings")
+		# Enable razorpay
+		settings.enable_razorpay = 1
+		settings.billing_cycle = "Monthly"
+		settings.billing_frequency = 24
+		# Enable invoicing
+		settings.enable_invoicing = 1
+		settings.make_payment_entry = 1
+		settings.company = company.name
+		settings.payment_account = company.default_cash_account
+		settings.debit_account = company.default_receivable_account
+		settings.save()
+
+		# make test plan
+		if not frappe.db.exists("Membership Type", "_rzpy_test_milythm"):
+			plan = frappe.new_doc("Membership Type")
+			plan.membership_type = "_rzpy_test_milythm"
+			plan.amount = 100
+			plan.razorpay_plan_id = "_rzpy_test_milythm"
+			plan.linked_item = create_item("_Test Item for Non Profit Membership").name
+			plan.insert()
+		else:
+			plan = frappe.get_doc("Membership Type", "_rzpy_test_milythm")
+
+		# make test member
+		self.member_doc = create_member(frappe._dict({
+				'fullname': "_Test_Member",
+				'email': "_test_member_erpnext@example.com",
+				'plan_id': plan.name
+		}))
+		self.member_doc.make_customer_and_link()
+		self.member = self.member_doc.name
+
+	def test_auto_generate_invoice_and_payment_entry(self):
+		entry = make_membership(self.member)
+
+		# Naive test to see if at all invoice was generated and attached to member
+		# In any case if details were missing, the invoicing would throw an error
+		invoice = entry.generate_invoice(save=True)
+		self.assertEqual(invoice.name, entry.invoice)
+
+	def test_renew_within_30_days(self):
+		# create a membership for two months
+		# Should work fine
+		make_membership(self.member, { "from_date": nowdate() })
+		make_membership(self.member, { "from_date": add_months(nowdate(), 1) })
+
+		from frappe.utils.user import add_role
+		add_role("test@example.com", "Non Profit Manager")
+		frappe.set_user("test@example.com")
+
+		# create next membership with expiry not within 30 days
+		self.assertRaises(frappe.ValidationError, make_membership, self.member, {
+			"from_date": add_months(nowdate(), 2),
+		})
+
+		frappe.set_user("Administrator")
+		# create the same membership but as administrator
+		make_membership(self.member, {
+			"from_date": add_months(nowdate(), 2),
+			"to_date": add_months(nowdate(), 3),
+		})
+
+def set_config(key, value):
+	frappe.db.set_value("Membership Settings", None, key, value)
+
+def make_membership(member, payload={}):
+	data = {
+		"doctype": "Membership",
+		"member": member,
+		"membership_status": "Current",
+		"membership_type": "_rzpy_test_milythm",
+		"currency": "INR",
+		"paid": 1,
+		"from_date": nowdate(),
+		"amount": 100
+	}
+	data.update(payload)
+	membership = frappe.get_doc(data)
+	membership.insert(ignore_permissions=True, ignore_if_duplicate=True)
+	return membership
+
+def create_item(item_code):
+	if not frappe.db.exists("Item", item_code):
+		item = frappe.new_doc("Item")
+		item.item_code = item_code
+		item.item_name = item_code
+		item.stock_uom = "Nos"
+		item.description = item_code
+		item.item_group = "All Item Groups"
+		item.is_stock_item = 0
+		item.save()
+	else:
+		item = frappe.get_doc("Item", item_code)
+	return item
diff --git a/erpnext/non_profit/doctype/membership_settings/membership_settings.js b/erpnext/non_profit/doctype/membership_settings/membership_settings.js
index 1d89402..c95aab2 100644
--- a/erpnext/non_profit/doctype/membership_settings/membership_settings.js
+++ b/erpnext/non_profit/doctype/membership_settings/membership_settings.js
@@ -11,7 +11,7 @@
 			});
 		}
 
-		frm.set_query('inv_print_format', function(doc) {
+		frm.set_query("inv_print_format", function() {
 			return {
 				filters: {
 					"doc_type": "Sales Invoice"
@@ -19,7 +19,7 @@
 			};
 		});
 
-		frm.set_query('membership_print_format', function(doc) {
+		frm.set_query("membership_print_format", function() {
 			return {
 				filters: {
 					"doc_type": "Membership"
@@ -27,12 +27,23 @@
 			};
 		});
 
-		frm.set_query('debit_account', function(doc) {
+		frm.set_query("debit_account", function() {
 			return {
 				filters: {
-					'account_type': 'Receivable',
-					'is_group': 0,
-					'company': frm.doc.company
+					"account_type": "Receivable",
+					"is_group": 0,
+					"company": frm.doc.company
+				}
+			};
+		});
+
+		frm.set_query("payment_account", function () {
+			var account_types = ["Bank", "Cash"];
+			return {
+				filters: {
+					"account_type": ["in", account_types],
+					"is_group": 0,
+					"company": frm.doc.company
 				}
 			};
 		});
diff --git a/erpnext/non_profit/doctype/membership_settings/membership_settings.json b/erpnext/non_profit/doctype/membership_settings/membership_settings.json
index 5b6bab5..3887b0a 100644
--- a/erpnext/non_profit/doctype/membership_settings/membership_settings.json
+++ b/erpnext/non_profit/doctype/membership_settings/membership_settings.json
@@ -11,9 +11,12 @@
   "billing_frequency",
   "webhook_secret",
   "column_break_6",
-  "enable_auto_invoicing",
+  "enable_invoicing",
+  "create_for_web_forms",
+  "make_payment_entry",
   "company",
   "debit_account",
+  "payment_account",
   "column_break_9",
   "send_email",
   "send_invoice",
@@ -58,14 +61,7 @@
    "label": "Invoicing"
   },
   {
-   "default": "0",
-   "fieldname": "enable_auto_invoicing",
-   "fieldtype": "Check",
-   "label": "Enable Auto Invoicing",
-   "mandatory_depends_on": "eval:doc.send_invoice"
-  },
-  {
-   "depends_on": "eval:doc.enable_auto_invoicing",
+   "depends_on": "eval:doc.enable_invoicing",
    "fieldname": "debit_account",
    "fieldtype": "Link",
    "label": "Debit Account",
@@ -77,7 +73,7 @@
    "fieldtype": "Column Break"
   },
   {
-   "depends_on": "eval:doc.enable_auto_invoicing",
+   "depends_on": "eval:doc.enable_invoicing",
    "fieldname": "company",
    "fieldtype": "Link",
    "label": "Company",
@@ -86,7 +82,7 @@
   },
   {
    "default": "0",
-   "depends_on": "eval:doc.enable_auto_invoicing && doc.send_email",
+   "depends_on": "eval:doc.enable_invoicing && doc.send_email",
    "fieldname": "send_invoice",
    "fieldtype": "Check",
    "label": "Send Invoice with Email"
@@ -119,11 +115,43 @@
    "label": "Email Template",
    "mandatory_depends_on": "eval:doc.send_email",
    "options": "Email Template"
+  },
+  {
+   "default": "0",
+   "fieldname": "enable_invoicing",
+   "fieldtype": "Check",
+   "label": "Enable Invoicing",
+   "mandatory_depends_on": "eval:doc.send_invoice || doc.make_payment_entry"
+  },
+  {
+   "default": "0",
+   "depends_on": "eval:doc.enable_invoicing",
+   "description": "Auto creates Payment Entry for Sales Invoices created for Membership from web forms.",
+   "fieldname": "make_payment_entry",
+   "fieldtype": "Check",
+   "label": "Make Payment Entry"
+  },
+  {
+   "depends_on": "eval:doc.make_payment_entry",
+   "fieldname": "payment_account",
+   "fieldtype": "Link",
+   "label": "Payment To",
+   "mandatory_depends_on": "eval:doc.make_payment_entry",
+   "options": "Account"
+  },
+  {
+   "default": "0",
+   "depends_on": "eval:doc.enable_invoicing",
+   "description": "Automatically create an invoice when payment is authorized from a web form entry",
+   "fieldname": "create_for_web_forms",
+   "fieldtype": "Check",
+   "label": "Auto Create Invoice for Web Forms"
   }
  ],
+ "index_web_pages_for_search": 1,
  "issingle": 1,
  "links": [],
- "modified": "2020-08-05 17:26:37.287395",
+ "modified": "2021-01-21 19:57:53.213286",
  "modified_by": "Administrator",
  "module": "Non Profit",
  "name": "Membership Settings",
diff --git a/erpnext/non_profit/doctype/membership_type/membership_type.js b/erpnext/non_profit/doctype/membership_type/membership_type.js
index 43311a2..91a5cb7 100644
--- a/erpnext/non_profit/doctype/membership_type/membership_type.js
+++ b/erpnext/non_profit/doctype/membership_type/membership_type.js
@@ -2,13 +2,21 @@
 // For license information, please see license.txt
 
 frappe.ui.form.on('Membership Type', {
-	refresh: function(frm) {
-		frappe.db.get_single_value("Membership Settings", "enable_razorpay").then(val => {
+	refresh: function (frm) {
+		frappe.db.get_single_value('Membership Settings', 'enable_razorpay').then(val => {
 			if (val) frm.set_df_property('razorpay_plan_id', 'hidden', false);
 		});
 
-		frappe.db.get_single_value("Membership Settings", "enable_auto_invoicing").then(val => {
+		frappe.db.get_single_value('Membership Settings', 'enable_invoicing').then(val => {
 			if (val) frm.set_df_property('linked_item', 'hidden', false);
 		});
+
+		frm.set_query('linked_item', () => {
+			return {
+				filters: {
+					is_stock_item: 0
+				}
+			};
+		});
 	}
 });
diff --git a/erpnext/non_profit/doctype/membership_type/membership_type.py b/erpnext/non_profit/doctype/membership_type/membership_type.py
index b95b043..022829b 100644
--- a/erpnext/non_profit/doctype/membership_type/membership_type.py
+++ b/erpnext/non_profit/doctype/membership_type/membership_type.py
@@ -5,9 +5,14 @@
 from __future__ import unicode_literals
 from frappe.model.document import Document
 import frappe
+from frappe import _
 
 class MembershipType(Document):
-	pass
+	def validate(self):
+		if self.linked_item:
+			is_stock_item = frappe.db.get_value("Item", self.linked_item, "is_stock_item")
+			if is_stock_item:
+				frappe.throw(_("The Linked Item should be a service item"))
 
 def get_membership_type(razorpay_id):
 	return frappe.db.exists("Membership Type", {"razorpay_plan_id": razorpay_id})
\ No newline at end of file
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 7b2428e..da52ae9 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -736,8 +736,9 @@
 erpnext.patches.v12_0.setup_einvoice_fields #2020-12-02
 erpnext.patches.v13_0.updates_for_multi_currency_payroll
 erpnext.patches.v13_0.update_reason_for_resignation_in_employee
-erpnext.patches.v13_0.update_custom_fields_for_shopify
 execute:frappe.delete_doc("Report", "Quoted Item Comparison")
+erpnext.patches.v13_0.update_member_email_address
+erpnext.patches.v13_0.update_custom_fields_for_shopify
 erpnext.patches.v13_0.updates_for_multi_currency_payroll
 erpnext.patches.v13_0.create_leave_policy_assignment_based_on_employee_current_leave_policy
 erpnext.patches.v13_0.add_po_to_global_search
@@ -745,3 +746,4 @@
 erpnext.patches.v13_0.update_project_template_tasks
 erpnext.patches.v13_0.set_company_in_leave_ledger_entry
 erpnext.patches.v13_0.convert_qi_parameter_to_link_field
+erpnext.patches.v13_0.setup_patient_history_settings_for_standard_doctypes
diff --git a/erpnext/patches/v13_0/setup_patient_history_settings_for_standard_doctypes.py b/erpnext/patches/v13_0/setup_patient_history_settings_for_standard_doctypes.py
new file mode 100644
index 0000000..de08aa2
--- /dev/null
+++ b/erpnext/patches/v13_0/setup_patient_history_settings_for_standard_doctypes.py
@@ -0,0 +1,13 @@
+from __future__ import unicode_literals
+import frappe
+from erpnext.healthcare.setup import setup_patient_history_settings
+
+def execute():
+	if "Healthcare" not in frappe.get_active_domains():
+		return
+
+	frappe.reload_doc("healthcare", "doctype", "Patient History Settings")
+	frappe.reload_doc("healthcare", "doctype", "Patient History Standard Document Type")
+	frappe.reload_doc("healthcare", "doctype", "Patient History Custom Document Type")
+
+	setup_patient_history_settings()
\ No newline at end of file
diff --git a/erpnext/patches/v13_0/update_member_email_address.py b/erpnext/patches/v13_0/update_member_email_address.py
new file mode 100644
index 0000000..4056f84
--- /dev/null
+++ b/erpnext/patches/v13_0/update_member_email_address.py
@@ -0,0 +1,23 @@
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.utils.rename_field import rename_field
+
+def execute():
+	"""add value to email_id column from email"""
+
+	if frappe.db.has_column("Member", "email"):
+		# Get all members
+		for member in frappe.db.get_all("Member", pluck="name"):
+			# Check if email_id already exists
+			if not frappe.db.get_value("Member", member, "email_id"):
+				# fetch email id from the user linked field email
+				email = frappe.db.get_value("Member", member, "email")
+
+				# Set the value for it
+				frappe.db.set_value("Member", member, "email_id", email)
+
+	if frappe.db.exists("DocType", "Membership Settings"):
+		rename_field("Membership Settings", "enable_auto_invoicing", "enable_invoicing")
diff --git a/erpnext/payroll/doctype/additional_salary/additional_salary.js b/erpnext/payroll/doctype/additional_salary/additional_salary.js
index 7737e6c..d20c98c 100644
--- a/erpnext/payroll/doctype/additional_salary/additional_salary.js
+++ b/erpnext/payroll/doctype/additional_salary/additional_salary.js
@@ -12,6 +12,8 @@
 				}
 			};
 		});
+
+		frm.trigger('set_earning_component');
 	},
 
 	employee: function(frm) {
@@ -43,6 +45,20 @@
 		});
 	},
 
+	company: function(frm) {
+		frm.trigger('set_earning_component');
+	},
+
+	set_earning_component: function(frm) {
+		if (!frm.doc.company) return;
+		frm.set_query("salary_component", function() {
+			return {
+				query: "erpnext.payroll.doctype.salary_structure.salary_structure.get_earning_deduction_components",
+				filters: {type: "earning", company: frm.doc.company}
+			};
+		});
+	},
+
 	get_employee_currency: function(frm) {
 		frappe.call({
 			method: "erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment.get_employee_currency",
diff --git a/erpnext/payroll/doctype/salary_structure/salary_structure.js b/erpnext/payroll/doctype/salary_structure/salary_structure.js
index ba824c5..6c7b382 100755
--- a/erpnext/payroll/doctype/salary_structure/salary_structure.js
+++ b/erpnext/payroll/doctype/salary_structure/salary_structure.js
@@ -70,6 +70,9 @@
 		});
 	},
 
+	company: function(frm) {
+		frm.trigger('set_earning_deduction_component');
+	},
 
 	currency: function(frm) {
 		calculate_totals(frm.doc);
@@ -117,6 +120,7 @@
 		fields_read_only.forEach(function(field) {
 			frappe.meta.get_docfield("Salary Detail", field, frm.doc.name).read_only = 1;
 		});
+		frm.trigger('set_earning_deduction_component');
 	},
 
 	assign_to_employees:function (frm) {
diff --git a/erpnext/payroll/doctype/salary_structure/salary_structure.py b/erpnext/payroll/doctype/salary_structure/salary_structure.py
index 77914bb..e718031 100644
--- a/erpnext/payroll/doctype/salary_structure/salary_structure.py
+++ b/erpnext/payroll/doctype/salary_structure/salary_structure.py
@@ -216,8 +216,13 @@
 	return frappe.db.sql("""
 		select t1.salary_component
 		from `tabSalary Component` t1, `tabSalary Component Account` t2
-		where t1.salary_component = t2.parent
-		and t1.type = %s 
-		and t2.company = %s
+		where (t1.name = t2.parent
+		and t1.type = %(type)s
+		and t2.company = %(company)s)
+		or (t1.type = %(type)s
+		and t1.statistical_component = 1)
 		order by salary_component
-	""", (filters['type'], filters['company']) )
+	""",{
+		"type": filters['type'],
+		"company": filters['company']
+	})
diff --git a/erpnext/regional/india/e_invoice/einvoice.js b/erpnext/regional/india/e_invoice/einvoice.js
index 9c86cc8..9fa94c4 100644
--- a/erpnext/regional/india/e_invoice/einvoice.js
+++ b/erpnext/regional/india/e_invoice/einvoice.js
@@ -18,6 +18,9 @@
 
 			if (!irn && !__unsaved) {
 				const action = () => {
+					if (frm.doc.__unsaved) {
+						frappe.throw(__('Please save the document to generate IRN.'));
+					}
 					frappe.call({
 						method: 'erpnext.regional.india.e_invoice.utils.get_einvoice',
 						args: { doctype, docname: name },
diff --git a/erpnext/regional/india/e_invoice/utils.py b/erpnext/regional/india/e_invoice/utils.py
index d0cac90..2366fcb 100644
--- a/erpnext/regional/india/e_invoice/utils.py
+++ b/erpnext/regional/india/e_invoice/utils.py
@@ -11,6 +11,7 @@
 import base64
 import frappe
 import traceback
+import io
 from frappe import _, bold
 from pyqrcode import create as qrcreate
 from frappe.integrations.utils import make_post_request, make_get_request
@@ -161,9 +162,9 @@
 
 		item.qty = abs(item.qty)
 		item.discount_amount = abs(item.discount_amount * item.qty)
-		item.unit_rate = abs(item.base_amount / item.qty)
-		item.gross_amount = abs(item.base_amount)
-		item.taxable_value = abs(item.base_amount)
+		item.unit_rate = abs(item.base_net_amount / item.qty)
+		item.gross_amount = abs(item.base_net_amount)
+		item.taxable_value = abs(item.base_net_amount)
 
 		item.batch_expiry_date = frappe.db.get_value('Batch', d.batch_no, 'expiry_date') if d.batch_no else None
 		item.batch_expiry_date = format_date(item.batch_expiry_date, 'dd/mm/yyyy') if item.batch_expiry_date else None
@@ -198,7 +199,7 @@
 		if t.account_head in gst_accounts_list:
 			item_tax_rate = item_tax_detail[0]
 			# item tax amount excluding discount amount
-			item_tax_amount = (item_tax_rate / 100) * item.base_amount
+			item_tax_amount = (item_tax_rate / 100) * item.base_net_amount
 
 			if t.account_head in gst_accounts.cess_account:
 				item_tax_amount_after_discount = item_tax_detail[1]
@@ -217,8 +218,14 @@
 
 def get_invoice_value_details(invoice):
 	invoice_value_details = frappe._dict(dict())
-	invoice_value_details.base_total = abs(invoice.base_total)
-	invoice_value_details.invoice_discount_amt = invoice.base_discount_amount
+
+	if invoice.apply_discount_on == 'Net Total' and invoice.discount_amount:
+		invoice_value_details.base_total = abs(invoice.base_total)
+	else:
+		invoice_value_details.base_total = abs(invoice.base_net_total)
+
+	# since tax already considers discount amount
+	invoice_value_details.invoice_discount_amt = 0 # invoice.base_discount_amount
 	invoice_value_details.round_off = invoice.base_rounding_adjustment
 	invoice_value_details.base_grand_total = abs(invoice.base_rounded_total) or abs(invoice.base_grand_total)
 	invoice_value_details.grand_total = abs(invoice.rounded_total) or abs(invoice.grand_total)
@@ -244,9 +251,9 @@
 			
 			for tax_type in ['igst', 'cgst', 'sgst']:
 				if t.account_head in gst_accounts[f'{tax_type}_account']:
-					invoice_value_details[f'total_{tax_type}_amt'] += abs(t.base_tax_amount)
+					invoice_value_details[f'total_{tax_type}_amt'] += abs(t.base_tax_amount_after_discount_amount)
 		else:
-			invoice_value_details.total_other_charges += abs(t.base_tax_amount)
+			invoice_value_details.total_other_charges += abs(t.base_tax_amount_after_discount_amount)
 	
 	return invoice_value_details
 
@@ -430,7 +437,7 @@
 		self.irn_details_url = self.base_url + '/enriched/ei/api/invoice/irn'
 		self.generate_irn_url = self.base_url + '/enriched/ei/api/invoice'
 		self.gstin_details_url = self.base_url + '/enriched/ei/api/master/gstin'
-		self.cancel_ewaybill_url = self.base_url + '/enriched/ei/api/ewayapi'
+		self.cancel_ewaybill_url = self.base_url + '/enriched/ewb/ewayapi?action=CANEWB'
 		self.generate_ewaybill_url = self.base_url + '/enriched/ei/api/ewaybill'
 
 	def get_credentials(self):
@@ -473,7 +480,7 @@
 			"data": json.dumps(data, indent=4) if isinstance(data, dict) else data,
 			"response": json.dumps(res, indent=4) if res else None
 		})
-		request_log.insert(ignore_permissions=True)
+		request_log.save(ignore_permissions=True)
 		frappe.db.commit()
 
 	def fetch_auth_token(self):
@@ -486,7 +493,8 @@
 			res = self.make_request('post', self.authenticate_url, headers)
 			self.e_invoice_settings.auth_token = "{} {}".format(res.get('token_type'), res.get('access_token'))
 			self.e_invoice_settings.token_expiry = add_to_date(None, seconds=res.get('expires_in'))
-			self.e_invoice_settings.save()
+			self.e_invoice_settings.save(ignore_permissions=True)
+			self.e_invoice_settings.reload()
 
 		except Exception:
 			self.log_error(res)
@@ -520,7 +528,7 @@
 		except Exception:
 			self.log_error()
 			self.raise_error(True)
-	
+
 	@staticmethod
 	def get_gstin_details(gstin):
 		'''fetch and cache GSTIN details'''
@@ -615,7 +623,7 @@
 		except Exception:
 			self.log_error(data)
 			self.raise_error(True)
-	
+
 	def generate_eway_bill(self, **kwargs):
 		args = frappe._dict(kwargs)
 
@@ -664,7 +672,8 @@
 			'cancelRsnCode': reason,
 			'cancelRmrk': remark
 		}, indent=4)
-
+		headers["username"] = headers["user_name"]
+		del headers["user_name"]
 		try:
 			res = self.make_request('post', self.cancel_ewaybill_url, headers, data)
 			if res.get('success'):
@@ -757,26 +766,26 @@
 			'label': _('IRN Generated')
 		}
 		self.update_invoice()
-	
+
 	def attach_qrcode_image(self):
 		qrcode = self.invoice.signed_qr_code
 		doctype = self.invoice.doctype
 		docname = self.invoice.name
+		filename = 'QRCode_{}.png'.format(docname).replace(os.path.sep, "__")
 
-		_file = frappe.new_doc('File')
-		_file.update({
-			'file_name': 'QRCode_{}.png'.format(docname.replace('/', '-')),
-			'attached_to_doctype': doctype,
-			'attached_to_name': docname,
-			'content': 'qrcode',
-			'is_private': 1
-		})
-		_file.insert()
-		frappe.db.commit()
+		qr_image = io.BytesIO()
 		url = qrcreate(qrcode, error='L')
-		abs_file_path = os.path.abspath(_file.get_full_path())
-		url.png(abs_file_path, scale=2, quiet_zone=1)
-
+		url.png(qr_image, scale=2, quiet_zone=1)
+		_file = frappe.get_doc({
+			"doctype": "File",
+			"file_name": filename,
+			"attached_to_doctype": doctype,
+			"attached_to_name": docname,
+			"attached_to_field": "qrcode_image",
+			"is_private": 1,
+			"content": qr_image.getvalue()})
+		_file.save()
+		frappe.db.commit()
 		self.invoice.qrcode_image = _file.file_url
 	
 	def update_invoice(self):
diff --git a/erpnext/regional/print_format/irs_1099_form/irs_1099_form.json b/erpnext/regional/print_format/irs_1099_form/irs_1099_form.json
index ce8c44a..e59700f 100644
--- a/erpnext/regional/print_format/irs_1099_form/irs_1099_form.json
+++ b/erpnext/regional/print_format/irs_1099_form/irs_1099_form.json
@@ -1,23 +1,26 @@
-[
- {
-	"align_labels_right": 0,
-	"css": "",
-	"custom_format": 1,
-	"default_print_language": "en",
-	"disabled": 0,
-	"doc_type": "Supplier",
-	"docstatus": 0,
-	"doctype": "Print Format",
-	"font": "Default",
-	"format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"Custom HTML\", \"options\": \"<div class=\\\"print-heading\\\">\\t\\t\\t\\t<h2>TAX Invoice<br><small>{{ doc.name }}</small>\\t\\t\\t\\t</h2></div>\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"customer_name\", \"label\": \"Customer Name\"}, {\"print_hide\": 0, \"fieldname\": \"customer_name_in_arabic\", \"label\": \"Customer Name in Arabic\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"posting_date\", \"label\": \"Date\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Address\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"company\", \"label\": \"Company\"}, {\"print_hide\": 0, \"fieldname\": \"company_trn\", \"label\": \"Company TRN\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"company_address_display\", \"label\": \"Company Address\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"item_code\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"description\", \"print_width\": \"200px\"}, {\"print_hide\": 0, \"fieldname\": \"uom\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"tax_code\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"items\", \"label\": \"Items\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"total\", \"label\": \"Total\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"charge_type\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"row_id\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"account_head\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"cost_center\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"description\", \"print_width\": \"300px\"}, {\"print_hide\": 0, \"fieldname\": \"rate\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"tax_amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"total\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"tax_amount_after_discount_amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"base_tax_amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"base_total\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"base_tax_amount_after_discount_amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"item_wise_tax_detail\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"taxes\", \"label\": \"Sales Taxes and Charges\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"grand_total\", \"label\": \"Grand Total\"}, {\"print_hide\": 0, \"fieldname\": \"rounded_total\", \"label\": \"Rounded Total\"}, {\"print_hide\": 0, \"fieldname\": \"in_words\", \"align\": \"left\", \"label\": \"In Words\"}]",
-	"html": "<div id=\"copy_a\" style=\"position: relative; top:0cm; width:17cm;height:28.0cm;\">\n  <table>\n  <tbody>\n    <tr style=\"height:12mm\">\n      <td class=\"tbs rbs lbs bbs\" style=\"width:86mm\" colspan=\"4\"; rowspan=\"3\">PAYER'S name, street address, city or town, state or province, country, ZIP<br>or foreign postal code, and telephone no.<br>\n\t{{company if company else \"\"}}<br>\n\t{{payer_street_address if payer_street_address else \"\"}}\n</td>\n      <td class=\"tbs rbs lbs bbs\" style=\"width:35mm\">1 Rents</td>\n      <td class=\"tbs rbs lbs bbs\" style=\"width:25mm\" rowspan=\"2\">OMB No. 1545-0115<br><yone>20</yone><ytwo>18</ytwo><br>Form 1099-MISC</td>\n      <td class=\"lbs bbs\" style=\"width:38mm\" colspan=\"2\" rowspan=\"2\">Miscellaneous Income</td>\n    </tr>\n    <tr style=\"height:12mm\">\n      <td class=\"tbs rbs lbs bbs\" style=\"width:35mm\">2 Royalties</td>\n    </tr>\n    <tr style=\"height:9mm\">\n      <td class=\"tbs rbs lbs bbs\" >3 Other Income<br>\n\t{{payments if payments else \"\"}}\n\t</td>\n      <td class=\"tbs rbs lbs bbs\" colspan=\"2\">4 Federal Income tax withheld</td>\n      <td class=\"tbs lbs bbs\" style=\"width:29mm\" rowspan=\"2\">Copy A<br>For<br>Internal Revenue<br>Service Center<br><br>File with Form 1096</td>\n    </tr>\n    <tr style=\"height:16mm\">\n      <td class=\"tbs rbs lbs bbs\" style=\"width:43mm\">PAYER'S TIN<br>\n\t{{company_tin if company_tin else \"\"}}\n\t</td>\n      \n      <td class=\"tbs rbs lbs bbs\" colspan=\"3\">RECIPIENT'S TIN<br><br>\n      {{tax_id if tax_id else \"None\"}}\n</td>\n      <td class=\"tbs rbs lbs bbs\" >Fishing boat proceeds</td>\n      <td class=\"tbs rbs lbs bbs\" colspan=\"2\">6 Medical and health care payments</td>\n    </tr>\n    <tr style=\"height:12mm\">\n      <td class=\"tbs rbs lbs bbs\" colspan=\"4\">RECIPIENT'S name <br>\n         {{supplier if supplier else \"\"}}\n      </td>\n      <td class=\"tbs rbs lbs bbs\" >7 Nonemployee compensation<br>\n\t</td> \n      <td class=\"tbs rbs lbs bbs\" colspan=\"2\">Substitute payments in lieu of dividends or interest</td>\n      <td class=\"tbs lbs bbs\" rowspan=\"6\">For Privacy Act<br>and Paperwork<br>Reduction Act<br>Notice, see the<br>2018 General<br>Instructions for<br>Certain<br>Information<br>Returns.</td>\n    </tr>\n    <tr style=\"height:6mm\">\n      <td class=\"tbs rbs lbs bbs\" colspan=\"4\" rowspan=\"2\">Street address (including apt. no.)<br>\n\t{{recipient_street_address if recipient_street_address else \"\"}}\n\t</td>\n      <td class=\"tbs rbs lbs bbs\" >$___________</td>\n      <td class=\"tbs rbs lbs bbs\" colspan=\"2\">$___________</td>\n    </tr>\n    <tr style=\"height:7mm\">\n      <td class=\"tbs rbs lbs bbs\" rowspan=\"2\">9 Payer made direct sales of<br>$5,000 or more of consumer products<br>to a buyer<br>(recipient) for resale</td>\n      <td class=\"tbs rbs lbs\" colspan=\"2\">10 Crop insurance proceeds</td>\n    </tr>\n    <tr style=\"height:5mm\">\n      <td class=\"tbs rbs lbs bbs\" colspan=\"4\" rowspan=\"2\">City or town, state or province, country, and ZIP or foreign postal code<br>\n\t{{recipient_city_state if recipient_city_state else \"\"}}\n</td>\n      <td style=\"vertical-align:bottom\" class=\" rbs lbs bbs\" colspan=\"2\">$___________</td>\n    </tr>\n    <tr style=\"height:9mm\">\n      <td class=\"tbs rbs lbs bbs\" >11</td>\n      <td class=\"tbs rbs lbs bbs\" colspan=2>12</td>\n    </tr>\n    <tr style=\"height:13mm\">\n      <td class=\"tbs rbs lbs bbs\" colspan=\"2\">Account number (see instructions)</td>\n      <td class=\"tbs rbs lbs bbs\" style=\"width:16mm\">FACTA filing<br>requirement</td>\n      <td class=\"tbs rbs lbs bbs\" style=\"width:14mm\">2nd TIN not.</td>\n      <td class=\"tbs rbs lbs bbs\" >13 Excess golden parachute payments<br>$___________</td>\n      <td class=\"tbs rbs lbs bbs\" colspan=\"2\">14 Gross proceeds paid to an<br>attorney<br>$___________</td>\n    </tr>\n    <tr style=\"height:12mm\">\n      <td class=\"tbs rbs lbs \" >15a Section 409A deferrals</td>\n      <td class=\"tbs rbs lbs \" colspan=\"3\">15b Section 409 income</td>\n      <td class=\"tbs rbs lbs \" >16 State tax withheld</td>\n      <td class=\"tbs rbs lbs \" colspan=\"2\">17 State/Payer's state no.</td>\n      <td class=\"tbs lbs\" >18 State income</td>\n    </tr>\n    <tr>\n      <td class=\"lbs rbs bbs\">$</td>\n      <td class=\"lbs rbs bbs\" colspan=\"3\">$</td>\n      <td class=\"lbs rbs bbs tbd\">$</td>\n      <td class=\"lbs rbs bbs tbd\" colspan=\"2\"></td>\n      <td class=\"lbs bbs tbd\">$</td>\n    </tr>\n\n    <tr style=\"height:8mm\">\n      <td class=\"tbs\" colspan=\"8\">Form 1099-MISC Cat. No. 14425J www.irs.gov/Form1099MISC Department of the Treasury - Internal Revenue Service</td>\n    </tr>\n\n  </tbody>\n</table>\n</div>\n<div id=\"copy_1\" style=\"position: relative; top:0cm; width:17cm;height:28.0cm;\">\n  <table>\n  <tbody>\n    <tr style=\"height:12mm\">\n      <td class=\"tbs rbs lbs bbs\" style=\"width:86mm\" colspan=\"4\"; rowspan=\"3\">PAYER'S name, street address, city or town, state or province, country, ZIP<br>or foreign postal code, and telephone no.<br>\n      {{company if company else \"\"}}<br>\n    \t{{payer_street_address if payer_street_address else \"\"}}</td>\n      <td class=\"tbs rbs lbs bbs\" style=\"width:35mm\">1 Rents</td>\n      <td class=\"tbs rbs lbs bbs\" style=\"width:25mm\" rowspan=\"2\">OMB No. 1545-0115<br><yone>20</yone><ytwo>18</ytwo><br>Form 1099-MISC</td>\n      <td class=\"lbs bbs\" style=\"width:38mm\" colspan=\"2\" rowspan=\"2\">Miscellaneous Income</td>\n    </tr>\n    <tr style=\"height:12mm\">\n      <td class=\"tbs rbs lbs bbs\" style=\"width:35mm\">2 Royalties</td>\n    </tr>\n    <tr style=\"height:9mm\">\n      <td class=\"tbs rbs lbs bbs\" >3 Other Income<br>\n\t{{payments if payments else \"\"}}\n\t</td>\n      <td class=\"tbs rbs lbs bbs\" colspan=\"2\">4 Federal Income tax withheld</td>\n      <td class=\"tbs lbs bbs\" style=\"width:29mm\" rowspan=\"2\">Copy 1<br>For State Tax<br>Department</td>\n    </tr>\n    <tr style=\"height:16mm\">\n      <td class=\"tbs rbs lbs bbs\" style=\"width:43mm\">PAYER'S TIN<br>\n\t{{company_tin if company_tin else \"\"}}\n\t</td>\n      <td class=\"tbs rbs lbs bbs\" colspan=\"3\">RECIPIENT'S TIN<br>\n\t{{tax_id if tax_id else \"\"}}\n\t</td>\n      <td class=\"tbs rbs lbs bbs\" >Fishing boat proceeds</td>\n      <td class=\"tbs rbs lbs bbs\" colspan=\"2\">6 Medical and health care payments</td>\n    </tr>\n    <tr style=\"height:12mm\">\n      <td class=\"tbs rbs lbs bbs\" colspan=\"4\">RECIPIENT'S name</td>\n      {{supplier if supplier else \"\"}}\n      <td class=\"tbs rbs lbs bbs\" >7 Nonemployee compensation<br>\n\t</td>\n      <td class=\"tbs rbs lbs bbs\" colspan=\"2\">Substitute payments in lieu of dividends or interest</td>\n      <td class=\"tbs lbs bbs\" rowspan=\"6\"></td>\n    </tr>\n    <tr style=\"height:6mm\">\n      <td class=\"tbs rbs lbs bbs\" colspan=\"4\" rowspan=\"2\">Street address (including apt. no.)<br>\n\t{{recipient_street_address if recipient_street_address else \"\"}}\n\t</td>\n      <td class=\"tbs rbs lbs bbs\" >$___________</td>\n      <td class=\"tbs rbs lbs bbs\" colspan=\"2\">$___________</td>\n    </tr>\n    <tr style=\"height:7mm\">\n      <td class=\"tbs rbs lbs bbs\" rowspan=\"2\">9 Payer made direct sales of<br>$5,000 or more of consumer products<br>to a buyer<br>(recipient) for resale</td>\n      <td class=\"tbs rbs lbs\" colspan=\"2\">10 Crop insurance proceeds</td>\n    </tr>\n    <tr style=\"height:5mm\">\n      <td class=\"tbs rbs lbs bbs\" colspan=\"4\" rowspan=\"2\">City or town, state or province, country, and ZIP or foreign postal code<br>\n\t{{recipient_city_state if recipient_city_state else \"\"}}\n\t</td>\n      <td style=\"vertical-align:bottom\" class=\" rbs lbs bbs\" colspan=\"2\">$___________</td>\n    </tr>\n    <tr style=\"height:9mm\">\n      <td class=\"tbs rbs lbs bbs\" >11</td>\n      <td class=\"tbs rbs lbs bbs\" colspan=2>12</td>\n    </tr>\n    <tr style=\"height:13mm\">\n      <td class=\"tbs rbs lbs bbs\" colspan=\"2\">Account number (see instructions)</td>\n      <td class=\"tbs rbs lbs bbs\" style=\"width:16mm\">FACTA filing<br>requirement</td>\n      <td class=\"tbs rbs lbs bbs\" style=\"width:14mm\">2nd TIN not.</td>\n      <td class=\"tbs rbs lbs bbs\" >13 Excess golden parachute payments<br>$___________</td>\n      <td class=\"tbs rbs lbs bbs\" colspan=\"2\">14 Gross proceeds paid to an<br>attorney<br>$___________</td>\n    </tr>\n    <tr style=\"height:12mm\">\n      <td class=\"tbs rbs lbs \" >15a Section 409A deferrals</td>\n      <td class=\"tbs rbs lbs \" colspan=\"3\">15b Section 409 income</td>\n      <td class=\"tbs rbs lbs \" >16 State tax withheld</td>\n      <td class=\"tbs rbs lbs \" colspan=\"2\">17 State/Payer's state no.</td>\n      <td class=\"tbs lbs\" >18 State income</td>\n    </tr>\n    <tr>\n      <td class=\"lbs rbs bbs\">$</td>\n      <td class=\"lbs rbs bbs\" colspan=\"3\">$</td>\n      <td class=\"lbs rbs bbs tbd\">$</td>\n      <td class=\"lbs rbs bbs tbd\" colspan=\"2\"></td>\n      <td class=\"lbs bbs tbd\">$</td>\n    </tr>\n\n    <tr style=\"height:8mm\">\n      <td class=\"tbs\" colspan=\"8\">Form 1099-MISC Cat. No. 14425J www.irs.gov/Form1099MISC Department of the Treasury - Internal Revenue Service</td>\n    </tr>\n\n  </tbody>\n</table>\n</div>\n<style>\nbody {\n  font-family: 'Helvetica', sans-serif;\n  font-size: 5.66pt;\n}\nyone {\n  font-family: 'Helvetica', sans-serif;\n  font-size: 14pt;\n  color: black;\n  -webkit-text-fill-color: white; /* Will override color (regardless of order) */\n  -webkit-text-stroke-width: 1px;\n  -webkit-text-stroke-color: black;\n}\nytwo {\n  font-family: 'Helvetica', sans-serif;\n  font-size: 14pt;\n  color: black;\n  -webkit-text-stroke-width: 1px;\n  -webkit-text-stroke-color: black;\n}\n\ntable, th, td {\n font-family: 'Helvetica', sans-serif;\n  font-size: 5.66pt;\n    border: none;\n}\n\n.tbs {\n    border-top: 1px solid black;\n}\n\n.bbs {\n    border-bottom: 1px solid black;\n}\n.lbs {\n    border-left: 1px solid black;\n}\n.rbs {\n    border-right: 1px solid black;\n}\n.allBorder {\n    border-top: 1px solid black;\n    border-right: 1px solid black;\n    border-left: 1px solid black;\n    borter-bottom: 1px solid black;\n}\n.bottomBorderOnlyDashed {\n\tborder-bottom: 1px dashed black;\n}\n.tbd {\n\tborder-top: 1px dashed black;\n}\n.address {\n\tvertical-align: bottom;\n}\n</style>",
-	"line_breaks": 0,
-	"modified": "2018-10-08 14:56:56.912851",
-	"module": "Regional",
-	"name": "IRS 1099 Form",
-	"print_format_builder": 1,
-	"print_format_type": "Server",
-	"show_section_headings": 0,
-	"standard": "No"
- }
-]
+{
+ "align_labels_right": 0,
+ "creation": "2020-11-09 16:01:26.096002",
+ "css": "",
+ "custom_format": 1,
+ "default_print_language": "en",
+ "disabled": 0,
+ "doc_type": "Supplier",
+ "docstatus": 0,
+ "doctype": "Print Format",
+ "font": "Default",
+ "format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"Custom HTML\", \"options\": \"<div class=\\\"print-heading\\\">\\t\\t\\t\\t<h2>TAX Invoice<br><small>{{ doc.name }}</small>\\t\\t\\t\\t</h2></div>\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"customer_name\", \"label\": \"Customer Name\"}, {\"print_hide\": 0, \"fieldname\": \"customer_name_in_arabic\", \"label\": \"Customer Name in Arabic\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"posting_date\", \"label\": \"Date\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Address\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"company\", \"label\": \"Company\"}, {\"print_hide\": 0, \"fieldname\": \"company_trn\", \"label\": \"Company TRN\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"company_address_display\", \"label\": \"Company Address\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"item_code\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"description\", \"print_width\": \"200px\"}, {\"print_hide\": 0, \"fieldname\": \"uom\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"tax_code\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"items\", \"label\": \"Items\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"total\", \"label\": \"Total\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"charge_type\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"row_id\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"account_head\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"cost_center\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"description\", \"print_width\": \"300px\"}, {\"print_hide\": 0, \"fieldname\": \"rate\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"tax_amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"total\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"tax_amount_after_discount_amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"base_tax_amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"base_total\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"base_tax_amount_after_discount_amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"item_wise_tax_detail\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"taxes\", \"label\": \"Sales Taxes and Charges\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"grand_total\", \"label\": \"Grand Total\"}, {\"print_hide\": 0, \"fieldname\": \"rounded_total\", \"label\": \"Rounded Total\"}, {\"print_hide\": 0, \"fieldname\": \"in_words\", \"align\": \"left\", \"label\": \"In Words\"}]",
+ "html": "<div id=\"copy_a\" style=\"position: relative; top:0cm; width:17cm;height:28.0cm;\">\n  <table>\n    <tbody>\n      <tr style=\"height:12mm\">\n        <td class=\"tbs rbs lbs bbs\" style=\"width:86mm\" colspan=\"4\" ; rowspan=\"3\">PAYER'S name, street address,\n          city or town, state or province, country, ZIP<br>or foreign postal code, and telephone no.<br>\n          {{ company or \"\" }}<br>\n          {{ payer_street_address or \"\" }}\n        </td>\n        <td class=\"tbs rbs lbs bbs\" style=\"width:35mm\">1 Rents</td>\n        <td class=\"tbs rbs lbs bbs\" style=\"width:25mm\" rowspan=\"2\">OMB No. 1545-0115<br>\n          <yone>{{ fiscal_year[:2] }}</yone>\n          <ytwo>{{ fiscal_year[-2:] }}</ytwo><br>Form 1099-MISC\n        </td>\n        <td class=\"lbs bbs\" style=\"width:38mm\" colspan=\"2\" rowspan=\"2\">Miscellaneous Income</td>\n      </tr>\n      <tr style=\"height:12mm\">\n        <td class=\"tbs rbs lbs bbs\" style=\"width:35mm\">2 Royalties</td>\n      </tr>\n      <tr style=\"height:9mm\">\n        <td class=\"tbs rbs lbs bbs\">3 Other Income<br>{{ payments or \"\" }}</td>\n        <td class=\"tbs rbs lbs bbs\" colspan=\"2\">4 Federal Income tax withheld</td>\n        <td class=\"tbs lbs bbs\" style=\"width:29mm\" rowspan=\"2\">Copy A<br>For<br>Internal Revenue<br>Service\n          Center<br><br>File with Form 1096</td>\n      </tr>\n      <tr style=\"height:16mm\">\n        <td class=\"tbs rbs lbs bbs\" style=\"width:43mm\">PAYER'S TIN<br>{{ company_tin or \"\" }}</td>\n\n        <td class=\"tbs rbs lbs bbs\" colspan=\"3\">RECIPIENT'S TIN<br><br>{{ tax_id or \"None\" }}</td>\n        <td class=\"tbs rbs lbs bbs\">Fishing boat proceeds</td>\n        <td class=\"tbs rbs lbs bbs\" colspan=\"2\">6 Medical and health care payments</td>\n      </tr>\n      <tr style=\"height:12mm\">\n        <td class=\"tbs rbs lbs bbs\" colspan=\"4\">RECIPIENT'S name <br>{{ supplier or \"\" }}</td>\n        <td class=\"tbs rbs lbs bbs\">7 Nonemployee compensation<br>\n        </td>\n        <td class=\"tbs rbs lbs bbs\" colspan=\"2\">Substitute payments in lieu of dividends or interest</td>\n        <td class=\"tbs lbs bbs\" rowspan=\"6\">For Privacy Act<br>and Paperwork<br>Reduction Act<br>Notice, see\n          the<br>2018 General<br>Instructions for<br>Certain<br>Information<br>Returns.</td>\n      </tr>\n      <tr style=\"height:6mm\">\n        <td class=\"tbs rbs lbs bbs\" colspan=\"4\" rowspan=\"2\">Street address (including apt. no.)<br>\n          {{ recipient_street_address or \"\" }}\n        </td>\n        <td class=\"tbs rbs lbs bbs\">$___________</td>\n        <td class=\"tbs rbs lbs bbs\" colspan=\"2\">$___________</td>\n      </tr>\n      <tr style=\"height:7mm\">\n        <td class=\"tbs rbs lbs bbs\" rowspan=\"2\">9 Payer made direct sales of<br>$5,000 or more of consumer\n          products<br>to a buyer<br>(recipient) for resale</td>\n        <td class=\"tbs rbs lbs\" colspan=\"2\">10 Crop insurance proceeds</td>\n      </tr>\n      <tr style=\"height:5mm\">\n        <td class=\"tbs rbs lbs bbs\" colspan=\"4\" rowspan=\"2\">City or town, state or province, country, and ZIP or\n          foreign postal code<br>\n          {{ recipient_city_state or \"\" }}\n        </td>\n        <td style=\"vertical-align:bottom\" class=\" rbs lbs bbs\" colspan=\"2\">$___________</td>\n      </tr>\n      <tr style=\"height:9mm\">\n        <td class=\"tbs rbs lbs bbs\">11</td>\n        <td class=\"tbs rbs lbs bbs\" colspan=2>12</td>\n      </tr>\n      <tr style=\"height:13mm\">\n        <td class=\"tbs rbs lbs bbs\" colspan=\"2\">Account number (see instructions)</td>\n        <td class=\"tbs rbs lbs bbs\" style=\"width:16mm\">FACTA filing<br>requirement</td>\n        <td class=\"tbs rbs lbs bbs\" style=\"width:14mm\">2nd TIN not.</td>\n        <td class=\"tbs rbs lbs bbs\">13 Excess golden parachute payments<br>$___________</td>\n        <td class=\"tbs rbs lbs bbs\" colspan=\"2\">14 Gross proceeds paid to an<br>attorney<br>$___________</td>\n      </tr>\n      <tr style=\"height:12mm\">\n        <td class=\"tbs rbs lbs \">15a Section 409A deferrals</td>\n        <td class=\"tbs rbs lbs \" colspan=\"3\">15b Section 409 income</td>\n        <td class=\"tbs rbs lbs \">16 State tax withheld</td>\n        <td class=\"tbs rbs lbs \" colspan=\"2\">17 State/Payer's state no.</td>\n        <td class=\"tbs lbs\">18 State income</td>\n      </tr>\n      <tr>\n        <td class=\"lbs rbs bbs\">$</td>\n        <td class=\"lbs rbs bbs\" colspan=\"3\">$</td>\n        <td class=\"lbs rbs bbs tbd\">$</td>\n        <td class=\"lbs rbs bbs tbd\" colspan=\"2\"></td>\n        <td class=\"lbs bbs tbd\">$</td>\n      </tr>\n\n      <tr style=\"height:8mm\">\n        <td class=\"tbs\" colspan=\"8\">Form 1099-MISC Cat. No. 14425J www.irs.gov/Form1099MISC Department of the\n          Treasury - Internal Revenue Service</td>\n      </tr>\n\n    </tbody>\n  </table>\n</div>\n<div id=\"copy_1\" style=\"position: relative; top:0cm; width:17cm;height:28.0cm;\">\n  <table>\n    <tbody>\n      <tr style=\"height:12mm\">\n        <td class=\"tbs rbs lbs bbs\" style=\"width:86mm\" colspan=\"4\" ; rowspan=\"3\">PAYER'S name, street address,\n          city or town, state or province, country, ZIP<br>or foreign postal code, and telephone no.<br>\n          {{ company or \"\"}}<b r>\n          {{ payer_street_address or \"\" }}\n        </td>\n        <td class=\"tbs rbs lbs bbs\" style=\"width:35mm\">1 Rents</td>\n        <td class=\"tbs rbs lbs bbs\" style=\"width:25mm\" rowspan=\"2\">OMB No. 1545-0115<br>\n          <yone>{{ fiscal_year[:2] }}</yone>\n          <ytwo>{{ fiscal_year[-2:] }}</ytwo><br>Form 1099-MISC\n        </td>\n        <td class=\"lbs bbs\" style=\"width:38mm\" colspan=\"2\" rowspan=\"2\">Miscellaneous Income</td>\n      </tr>\n      <tr style=\"height:12mm\">\n        <td class=\"tbs rbs lbs bbs\" style=\"width:35mm\">2 Royalties</td>\n      </tr>\n      <tr style=\"height:9mm\">\n        <td class=\"tbs rbs lbs bbs\">3 Other Income<br>\n          {{ payments or \"\" }}\n        </td>\n        <td class=\"tbs rbs lbs bbs\" colspan=\"2\">4 Federal Income tax withheld</td>\n        <td class=\"tbs lbs bbs\" style=\"width:29mm\" rowspan=\"2\">Copy 1<br>For State Tax<br>Department</td>\n      </tr>\n      <tr style=\"height:16mm\">\n        <td class=\"tbs rbs lbs bbs\" style=\"width:43mm\">PAYER'S TIN<br>\n          {{ company_tin or \"\" }}\n        </td>\n        <td class=\"tbs rbs lbs bbs\" colspan=\"3\">RECIPIENT'S TIN<br>\n          {{ tax_id or \"\" }}\n        </td>\n        <td class=\"tbs rbs lbs bbs\">Fishing boat proceeds</td>\n        <td class=\"tbs rbs lbs bbs\" colspan=\"2\">6 Medical and health care payments</td>\n      </tr>\n      <tr style=\"height:12mm\">\n        <td class=\"tbs rbs lbs bbs\" colspan=\"4\">RECIPIENT'S name</td>\n        {{ supplier or \"\" }}\n        <td class=\"tbs rbs lbs bbs\">7 Nonemployee compensation<br>\n        </td>\n        <td class=\"tbs rbs lbs bbs\" colspan=\"2\">Substitute payments in lieu of dividends or interest</td>\n        <td class=\"tbs lbs bbs\" rowspan=\"6\"></td>\n      </tr>\n      <tr style=\"height:6mm\">\n        <td class=\"tbs rbs lbs bbs\" colspan=\"4\" rowspan=\"2\">Street address (including apt. no.)<br>\n          {{ recipient_street_address or \"\" }}\n        </td>\n        <td class=\"tbs rbs lbs bbs\">$___________</td>\n        <td class=\"tbs rbs lbs bbs\" colspan=\"2\">$___________</td>\n      </tr>\n      <tr style=\"height:7mm\">\n        <td class=\"tbs rbs lbs bbs\" rowspan=\"2\">9 Payer made direct sales of<br>$5,000 or more of consumer\n          products<br>to a buyer<br>(recipient) for resale</td>\n        <td class=\"tbs rbs lbs\" colspan=\"2\">10 Crop insurance proceeds</td>\n      </tr>\n      <tr style=\"height:5mm\">\n        <td class=\"tbs rbs lbs bbs\" colspan=\"4\" rowspan=\"2\">City or town, state or province, country, and ZIP or\n          foreign postal code<br>\n          {{ recipient_city_state or \"\" }}\n        </td>\n        <td style=\"vertical-align:bottom\" class=\" rbs lbs bbs\" colspan=\"2\">$___________</td>\n      </tr>\n      <tr style=\"height:9mm\">\n        <td class=\"tbs rbs lbs bbs\">11</td>\n        <td class=\"tbs rbs lbs bbs\" colspan=2>12</td>\n      </tr>\n      <tr style=\"height:13mm\">\n        <td class=\"tbs rbs lbs bbs\" colspan=\"2\">Account number (see instructions)</td>\n        <td class=\"tbs rbs lbs bbs\" style=\"width:16mm\">FACTA filing<br>requirement</td>\n        <td class=\"tbs rbs lbs bbs\" style=\"width:14mm\">2nd TIN not.</td>\n        <td class=\"tbs rbs lbs bbs\">13 Excess golden parachute payments<br>$___________</td>\n        <td class=\"tbs rbs lbs bbs\" colspan=\"2\">14 Gross proceeds paid to an<br>attorney<br>$___________</td>\n      </tr>\n      <tr style=\"height:12mm\">\n        <td class=\"tbs rbs lbs \">15a Section 409A deferrals</td>\n        <td class=\"tbs rbs lbs \" colspan=\"3\">15b Section 409 income</td>\n        <td class=\"tbs rbs lbs \">16 State tax withheld</td>\n        <td class=\"tbs rbs lbs \" colspan=\"2\">17 State/Payer's state no.</td>\n        <td class=\"tbs lbs\">18 State income</td>\n      </tr>\n      <tr>\n        <td class=\"lbs rbs bbs\">$</td>\n        <td class=\"lbs rbs bbs\" colspan=\"3\">$</td>\n        <td class=\"lbs rbs bbs tbd\">$</td>\n        <td class=\"lbs rbs bbs tbd\" colspan=\"2\"></td>\n        <td class=\"lbs bbs tbd\">$</td>\n      </tr>\n\n      <tr style=\"height:8mm\">\n        <td class=\"tbs\" colspan=\"8\">Form 1099-MISC Cat. No. 14425J www.irs.gov/Form1099MISC Department of the\n          Treasury - Internal Revenue Service</td>\n      </tr>\n\n    </tbody>\n  </table>\n</div>\n<style>\n  body {\n    font-family: 'Helvetica', sans-serif;\n    font-size: 5.66pt;\n  }\n\n  yone {\n    font-family: 'Helvetica', sans-serif;\n    font-size: 14pt;\n    color: black;\n    -webkit-text-fill-color: white;\n    /* Will override color (regardless of order) */\n    -webkit-text-stroke-width: 1px;\n    -webkit-text-stroke-color: black;\n  }\n\n  ytwo {\n    font-family: 'Helvetica', sans-serif;\n    font-size: 14pt;\n    color: black;\n    -webkit-text-stroke-width: 1px;\n    -webkit-text-stroke-color: black;\n  }\n\n  table,\n  th,\n  td {\n    font-family: 'Helvetica', sans-serif;\n    font-size: 5.66pt;\n    border: none;\n  }\n\n  .tbs {\n    border-top: 1px solid black;\n  }\n\n  .bbs {\n    border-bottom: 1px solid black;\n  }\n\n  .lbs {\n    border-left: 1px solid black;\n  }\n\n  .rbs {\n    border-right: 1px solid black;\n  }\n\n  .allBorder {\n    border-top: 1px solid black;\n    border-right: 1px solid black;\n    border-left: 1px solid black;\n    border-bottom: 1px solid black;\n  }\n\n  .bottomBorderOnlyDashed {\n    border-bottom: 1px dashed black;\n  }\n\n  .tbd {\n    border-top: 1px dashed black;\n  }\n\n  .address {\n    vertical-align: bottom;\n  }\n</style>",
+ "idx": 0,
+ "line_breaks": 0,
+ "modified": "2021-01-19 07:25:16.333666",
+ "modified_by": "Administrator",
+ "module": "Regional",
+ "name": "IRS 1099 Form",
+ "owner": "Administrator",
+ "print_format_builder": 1,
+ "print_format_type": "Jinja",
+ "raw_printing": 0,
+ "show_section_headings": 0,
+ "standard": "No"
+}
\ No newline at end of file
diff --git a/erpnext/regional/report/irs_1099/irs_1099.js b/erpnext/regional/report/irs_1099/irs_1099.js
index 2d74652..070ff43 100644
--- a/erpnext/regional/report/irs_1099/irs_1099.js
+++ b/erpnext/regional/report/irs_1099/irs_1099.js
@@ -4,7 +4,7 @@
 frappe.query_reports["IRS 1099"] = {
 	"filters": [
 		{
-			"fieldname":"company",
+			"fieldname": "company",
 			"label": __("Company"),
 			"fieldtype": "Link",
 			"options": "Company",
@@ -13,7 +13,7 @@
 			"width": 80,
 		},
 		{
-			"fieldname":"fiscal_year",
+			"fieldname": "fiscal_year",
 			"label": __("Fiscal Year"),
 			"fieldtype": "Link",
 			"options": "Fiscal Year",
@@ -22,7 +22,7 @@
 			"width": 80,
 		},
 		{
-			"fieldname":"supplier_group",
+			"fieldname": "supplier_group",
 			"label": __("Supplier Group"),
 			"fieldtype": "Link",
 			"options": "Supplier Group",
@@ -32,16 +32,16 @@
 		},
 	],
 
-	onload: function(query_report) {
+	onload: function (query_report) {
 		query_report.page.add_inner_button(__("Print IRS 1099 Forms"), () => {
 			build_1099_print(query_report);
 		});
 	}
 };
 
-function build_1099_print(query_report){
+function build_1099_print(query_report) {
 	let filters = JSON.stringify(query_report.get_values());
 	let w = window.open('/api/method/erpnext.regional.report.irs_1099.irs_1099.irs_1099_print?' +
-								'&filters=' + encodeURIComponent(filters));
+		'&filters=' + encodeURIComponent(filters));
 	// w.print();
 }
diff --git a/erpnext/regional/report/irs_1099/irs_1099.py b/erpnext/regional/report/irs_1099/irs_1099.py
index d3509e5..c1c8aed 100644
--- a/erpnext/regional/report/irs_1099/irs_1099.py
+++ b/erpnext/regional/report/irs_1099/irs_1099.py
@@ -1,29 +1,34 @@
 # Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
 # For license information, please see license.txt
 
-from __future__ import unicode_literals
-import frappe
 import json
-from frappe import _, _dict
-from frappe.utils import nowdate
-from frappe.utils.data import fmt_money
-from erpnext.accounts.utils import get_fiscal_year
+
 from PyPDF2 import PdfFileWriter
+
+import frappe
+from erpnext.accounts.utils import get_fiscal_year
+from frappe import _
+from frappe.utils import cstr, nowdate
+from frappe.utils.data import fmt_money
+from frappe.utils.jinja import render_template
 from frappe.utils.pdf import get_pdf
 from frappe.utils.print_format import read_multi_pdf
-from frappe.utils.jinja import render_template
+
+IRS_1099_FORMS_FILE_EXTENSION = ".pdf"
 
 
 def execute(filters=None):
-	filters = filters if isinstance(filters, _dict) else _dict(filters)
-
+	filters = filters if isinstance(filters, frappe._dict) else frappe._dict(filters)
 	if not filters:
 		filters.setdefault('fiscal_year', get_fiscal_year(nowdate())[0])
 		filters.setdefault('company', frappe.db.get_default("company"))
 
-	region = frappe.db.get_value("Company", fieldname = ["country"], filters = { "name": filters.company })
+	region = frappe.db.get_value("Company",
+		filters={"name": filters.company},
+		fieldname=["country"])
+
 	if region != 'United States':
-		return [],[]
+		return [], []
 
 	data = []
 	columns = get_columns()
@@ -34,20 +39,23 @@
 			s.tax_id as "tax_id",
 			SUM(gl.debit_in_account_currency) AS "payments"
 		FROM
-			`tabGL Entry` gl INNER JOIN `tabSupplier` s
+			`tabGL Entry` gl
+				INNER JOIN `tabSupplier` s
 		WHERE
 			s.name = gl.party
-		AND	s.irs_1099 = 1
-		AND gl.fiscal_year = %(fiscal_year)s
-		AND gl.party_type = "Supplier"
-
+				AND s.irs_1099 = 1
+				AND gl.fiscal_year = %(fiscal_year)s
+				AND gl.party_type = "Supplier"
 		GROUP BY
 			gl.party
-
 		ORDER BY
-			gl.party DESC""", {"fiscal_year": filters.fiscal_year,
+			gl.party DESC
+	""", {
+		"fiscal_year": filters.fiscal_year,
 		"supplier_group": filters.supplier_group,
-		"company": filters.company}, as_dict=True)
+		"company": filters.company
+	}, as_dict=True)
+
 	return columns, data
 
 
@@ -74,7 +82,6 @@
 			"width": 120
 		},
 		{
-
 			"fieldname": "payments",
 			"label": _("Total Payments"),
 			"fieldtype": "Currency",
@@ -88,23 +95,32 @@
 	if not filters:
 		frappe._dict({
 			"company": frappe.db.get_default("Company"),
-			"fiscal_year": frappe.db.get_default("fiscal_year")})
+			"fiscal_year": frappe.db.get_default("Fiscal Year")
+		})
 	else:
 		filters = frappe._dict(json.loads(filters))
+
+	fiscal_year_doc = get_fiscal_year(fiscal_year=filters.fiscal_year, as_dict=True)
+	fiscal_year = cstr(fiscal_year_doc.year_start_date.year)
+
 	company_address = get_payer_address_html(filters.company)
 	company_tin = frappe.db.get_value("Company", filters.company, "tax_id")
+
 	columns, data = execute(filters)
 	template = frappe.get_doc("Print Format", "IRS 1099 Form").html
 	output = PdfFileWriter()
+
 	for row in data:
+		row["fiscal_year"] = fiscal_year
 		row["company"] = filters.company
 		row["company_tin"] = company_tin
 		row["payer_street_address"] = company_address
-		row["recipient_street_address"], row["recipient_city_state"] = get_street_address_html("Supplier", row.supplier)
+		row["recipient_street_address"], row["recipient_city_state"] = get_street_address_html(
+			"Supplier", row.supplier)
 		row["payments"] = fmt_money(row["payments"], precision=0, currency="USD")
-		frappe._dict(row)
 		pdf = get_pdf(render_template(template, row), output=output if output else None)
-	frappe.local.response.filename = filters.fiscal_year + " " + filters.company + " IRS 1099 Forms"
+
+	frappe.local.response.filename = f"{filters.fiscal_year} {filters.company} IRS 1099 Forms{IRS_1099_FORMS_FILE_EXTENSION}"
 	frappe.local.response.filecontent = read_multi_pdf(output)
 	frappe.local.response.type = "download"
 
@@ -120,36 +136,45 @@
 		ORDER BY
 			address_type="Postal" DESC, address_type="Billing" DESC
 		LIMIT 1
-		""", {"company": company}, as_dict=True)
+	""", {"company": company}, as_dict=True)
+
+	address_display = ""
 	if address_list:
 		company_address = address_list[0]["name"]
-		return frappe.get_doc("Address", company_address).get_display()
-	else:
-		return ""
+		address_display = frappe.get_doc("Address", company_address).get_display()
+
+	return address_display
 
 
 def get_street_address_html(party_type, party):
 	address_list = frappe.db.sql("""
 		SELECT
 			link.parent
-		FROM `tabDynamic Link` link, `tabAddress` address
-		WHERE link.parenttype = "Address"
-		AND link.link_name = %(party)s
-		ORDER BY address.address_type="Postal" DESC,
+		FROM
+			`tabDynamic Link` link,
+			`tabAddress` address
+		WHERE
+			link.parenttype = "Address"
+				AND link.link_name = %(party)s
+		ORDER BY
+			address.address_type="Postal" DESC,
 			address.address_type="Billing" DESC
 		LIMIT 1
-		""", {"party": party}, as_dict=True)
+	""", {"party": party}, as_dict=True)
+
+	street_address = city_state = ""
 	if address_list:
 		supplier_address = address_list[0]["parent"]
 		doc = frappe.get_doc("Address", supplier_address)
+
 		if doc.address_line2:
-			street = doc.address_line1 + "<br>\n" + doc.address_line2 + "<br>\n"
+			street_address = doc.address_line1 + "<br>\n" + doc.address_line2 + "<br>\n"
 		else:
-			street = doc.address_line1 + "<br>\n"
-		city = doc.city + ", " if doc.city else ""
-		city = city + doc.state + " " if doc.state else city
-		city = city + doc.pincode if doc.pincode else city
-		city += "<br>\n"
-		return street, city
-	else:
-		return "", ""
+			street_address = doc.address_line1 + "<br>\n"
+
+		city_state = doc.city + ", " if doc.city else ""
+		city_state = city_state + doc.state + " " if doc.state else city_state
+		city_state = city_state + doc.pincode if doc.pincode else city_state
+		city_state += "<br>\n"
+
+	return street_address, city_state
diff --git a/erpnext/stock/report/stock_ageing/stock_ageing.py b/erpnext/stock/report/stock_ageing/stock_ageing.py
index 8aaf7ab..ff603fc 100644
--- a/erpnext/stock/report/stock_ageing/stock_ageing.py
+++ b/erpnext/stock/report/stock_ageing/stock_ageing.py
@@ -233,7 +233,8 @@
 				from `tabItem` {item_conditions}) item
 		where item_code = item.name and
 			company = %(company)s and
-			posting_date <= %(to_date)s
+			posting_date <= %(to_date)s and
+			is_cancelled != 1
 			{sle_conditions}
 			order by posting_date, posting_time, sle.creation, actual_qty""" #nosec
 		.format(item_conditions=get_item_conditions(filters),
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index 02d10a4..1ac2959 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -214,7 +214,10 @@
 
 	def before_insert(self):
 		if frappe.db.get_single_value("Support Settings", "track_service_level_agreement"):
-			self.set_response_and_resolution_time(priority=self.priority, service_level_agreement=self.service_level_agreement)
+			if frappe.flags.in_test:
+				self.set_response_and_resolution_time(priority=self.priority, service_level_agreement=self.service_level_agreement)
+			else:
+				self.set_response_and_resolution_time()
 
 	def set_response_and_resolution_time(self, priority=None, service_level_agreement=None):
 		service_level_agreement = get_active_service_level_agreement_for(priority=priority,