feat(Healthcare): Capacity for Service Unit, concurrent appointments based on capacity, Patient Appointments (#27219)
* feat(Healthcare): Capacity for Service Unit, concurrent appointments based on Capacity, Patient enhancements
* fix: appointment test
Co-authored-by: Anoop <3326959+akurungadam@users.noreply.github.com>
diff --git a/erpnext/healthcare/utils.py b/erpnext/healthcare/utils.py
index d3d22c8..ffecf4d 100644
--- a/erpnext/healthcare/utils.py
+++ b/erpnext/healthcare/utils.py
@@ -543,58 +543,43 @@
@frappe.whitelist()
-def get_children(doctype, parent, company, is_root=False):
- parent_fieldname = "parent_" + doctype.lower().replace(" ", "_")
+def get_children(doctype, parent=None, company=None, is_root=False):
+ parent_fieldname = 'parent_' + doctype.lower().replace(' ', '_')
fields = [
- "name as value",
- "is_group as expandable",
- "lft",
- "rgt"
+ 'name as value',
+ 'is_group as expandable',
+ 'lft',
+ 'rgt'
]
- # fields = [ "name", "is_group", "lft", "rgt" ]
- filters = [["ifnull(`{0}`,'')".format(parent_fieldname), "=", "" if is_root else parent]]
+
+ filters = [["ifnull(`{0}`,'')".format(parent_fieldname),
+ '=', '' if is_root else parent]]
if is_root:
- fields += ["service_unit_type"] if doctype == "Healthcare Service Unit" else []
- filters.append(["company", "=", company])
-
+ fields += ['service_unit_type'] if doctype == 'Healthcare Service Unit' else []
+ filters.append(['company', '=', company])
else:
- fields += ["service_unit_type", "allow_appointments", "inpatient_occupancy", "occupancy_status"] if doctype == "Healthcare Service Unit" else []
- fields += [parent_fieldname + " as parent"]
+ fields += ['service_unit_type', 'allow_appointments', 'inpatient_occupancy',
+ 'occupancy_status'] if doctype == 'Healthcare Service Unit' else []
+ fields += [parent_fieldname + ' as parent']
- hc_service_units = frappe.get_list(doctype, fields=fields, filters=filters)
+ service_units = frappe.get_list(doctype, fields=fields, filters=filters)
+ for each in service_units:
+ if each['expandable'] == 1: # group node
+ available_count = frappe.db.count('Healthcare Service Unit', filters={
+ 'parent_healthcare_service_unit': each['value'],
+ 'inpatient_occupancy': 1})
- if doctype == "Healthcare Service Unit":
- for each in hc_service_units:
- occupancy_msg = ""
- if each["expandable"] == 1:
- occupied = False
- vacant = False
- child_list = frappe.db.sql(
- '''
- SELECT
- name, occupancy_status
- FROM
- `tabHealthcare Service Unit`
- WHERE
- inpatient_occupancy = 1
- and lft > %s and rgt < %s
- ''', (each['lft'], each['rgt']))
+ if available_count > 0:
+ occupied_count = frappe.db.count('Healthcare Service Unit', {
+ 'parent_healthcare_service_unit': each['value'],
+ 'inpatient_occupancy': 1,
+ 'occupancy_status': 'Occupied'})
+ # set occupancy status of group node
+ each['occupied_of_available'] = str(
+ occupied_count) + ' Occupied of ' + str(available_count)
- for child in child_list:
- if not occupied:
- occupied = 0
- if child[1] == "Occupied":
- occupied += 1
- if not vacant:
- vacant = 0
- if child[1] == "Vacant":
- vacant += 1
- if vacant and occupied:
- occupancy_total = vacant + occupied
- occupancy_msg = str(occupied) + " Occupied out of " + str(occupancy_total)
- each["occupied_out_of_vacant"] = occupancy_msg
- return hc_service_units
+ return service_units
@frappe.whitelist()
@@ -717,3 +702,40 @@
doc_html = "<div class='small'><div class='col-md-12 text-right'><a class='btn btn-default btn-xs' href='/app/Form/%s/%s'></a></div>" %(doctype, docname) + doc_html + '</div>'
return {'html': doc_html}
+
+
+def update_address_links(address, method):
+ '''
+ Hook validate Address
+ If Patient is linked in Address, also link the associated Customer
+ '''
+ if 'Healthcare' not in frappe.get_active_domains():
+ return
+
+ patient_links = list(filter(lambda link: link.get('link_doctype') == 'Patient', address.links))
+
+ for link in patient_links:
+ customer = frappe.db.get_value('Patient', link.get('link_name'), 'customer')
+ if customer and not address.has_link('Customer', customer):
+ address.append('links', dict(link_doctype = 'Customer', link_name = customer))
+
+
+def update_patient_email_and_phone_numbers(contact, method):
+ '''
+ Hook validate Contact
+ Update linked Patients' primary mobile and phone numbers
+ '''
+ if 'Healthcare' not in frappe.get_active_domains():
+ return
+
+ if contact.is_primary_contact and (contact.email_id or contact.mobile_no or contact.phone):
+ patient_links = list(filter(lambda link: link.get('link_doctype') == 'Patient', contact.links))
+
+ for link in patient_links:
+ contact_details = frappe.db.get_value('Patient', link.get('link_name'), ['email', 'mobile', 'phone'], as_dict=1)
+ if contact.email_id and contact.email_id != contact_details.get('email'):
+ frappe.db.set_value('Patient', link.get('link_name'), 'email', contact.email_id)
+ if contact.mobile_no and contact.mobile_no != contact_details.get('mobile'):
+ frappe.db.set_value('Patient', link.get('link_name'), 'mobile', contact.mobile_no)
+ if contact.phone and contact.phone != contact_details.get('phone'):
+ frappe.db.set_value('Patient', link.get('link_name'), 'phone', contact.phone)