diff --git a/healthcare/healthcare/doctype/observation/observation.html b/healthcare/healthcare/doctype/observation/observation.html new file mode 100644 index 0000000000..178a767a94 --- /dev/null +++ b/healthcare/healthcare/doctype/observation/observation.html @@ -0,0 +1,360 @@ + + + +
+
+
+
Referred By:
+ {%- if doc.practitioner_name -%} +
{{ doc.practitioner_name.upper() }}
+ {% else %} +
Self
+ {% endif %} +
+ {%- if doc.sales_invoice -%} +
+
Invoice No.:
+
{{ doc.sales_invoice }}
+
+ {% endif %} +
+
+
+
+
+ + SAMPLE + +
+
+ Collected on +
+
+
+
+ + INVESTIGATION + +
+
+ Method +
+
+
+
+ + RESULT + +
+
+ Reported on +
+
+
+
+ + UNIT + +
+
+
+
+ + REFERENCE INTERVAL + +
+
+
+ +{% if doc.get("name") %} + {% set full_data = get_observations_for_medical_record(doc.name, doc.parent_observation) %} +
+ {% for data in full_data[0] %} + {% if not data.get("has_component") %} + {% if data.get("observation").get("preferred_display_name") %} + {% set observation_name = data.get("observation").get("preferred_display_name") %} + {% else %} + {% set observation_name = data.get("observation").get("observation_template") %} + {% endif %} + + {% if data.get("observation") or data.get("observation") %} + {% if data.get("observation").get("status")=="Approved" and (data.get("observation").get("result_data") or data.get("observation").get("result_text") or data.get("observation").get("result_select") not in [None, "", "Null"]) %} +
+
+ + {{observation_name}} + +
+
+
+
+ {% if data.get("observation").get("sample") %} +
+ {{data.get("observation").get("sample")}} +
+ {% else %} +
+ {{ frappe.db.get_value("Observation Template", data.get("observation").get("observation_template"), "sample") or "" }} +
+ {% endif %} + {% if data.get("observation").get("received_time") %} +
+ {{frappe.utils.format_datetime(data.get("observation").get("received_time"))[:-3]}} +
+ {% endif %} +
+
+
+ {{observation_name}} +
+ {% if data.get("observation").get("method") %} +
+ {{data.get("observation").get("method")}} +
+ {% endif %} +
+
+
+ {% if data.get("observation").get("result_data") or data.get("observation").get("result_select") %} + {{data.get("observation").get("result_data") + or data.get("observation").get("result_select")}} + {% elif data.get("observation").get("result_text") %} + {% if '
' in data.get("observation").get("result_text") %} + {% if data.get("observation").get("result_text")|length <= 60 %} + {{data.get("observation").get("result_text")}} + {% endif %} + {% elif data.get("observation").get("result_text")|length <= 24 %} + {{data.get("observation").get("result_text")}} + {% endif %} + {% endif %} +
+ {% if data.get("observation").get("time_of_result") %} +
+ {{frappe.utils.format_datetime(data.get("observation").get("time_of_result"))[:-3]}} +
+ {% endif %} +
+
+ {% if data.get("observation").get("permitted_unit") %} + {{data.get("observation").get("permitted_unit")}} + {% endif %} +
+
+ {% if data.get("observation").get("reference") %} + {{data.get("observation").get("reference")}} + {% endif %} +
+
+ {% if data.get("observation").get("result_text") %} + {% if '
' in data.get("observation").get("result_text") %} + {% if data.get("observation").get("result_text")|length > 60 %} +
+ {{data.get("observation").get("result_text")}} +
+ {% endif %} + {% elif data.get("observation").get("result_text")|length > 24 %} +
+ {{data.get("observation").get("result_text")}} +
+ {% endif %} + {% endif %} + {% if data.get("observation").get("result_interpretation") %} +
+ {{data.get("observation").get("result_interpretation")}} +
+ {% endif %} + {% if data.get("observation").get("note") %} +
+ {{data.get("observation").get("note")}} +
+ {% endif %} + {% if data.get("observation").get("description") %} +
+ {{data.get("observation").get("description")}} +
+ {% endif %} +
+ + {% endif %} + {% endif %} + {% else %} + {% if data["obs_approved"] and data[data.get("observation")] and data["has_result"] %} +
+
+
+
+
+ + {{data.get("display_name")}} + +
+ {% for comps in data[data.get("observation")] %} + {% if comps.get("observation").get("preferred_display_name") %} + {% set observation_name = comps.get("observation").get("preferred_display_name") %} + {% else %} + {% set observation_name = comps.get("observation").get("observation_template") %} + {% endif %} + {% if comps.get("observation").get("status")=="Approved" and comps.get("observation") %} + {% if comps.get("observation").get("result_data") or comps.get("observation").get("result_text") or comps.get("observation").get("result_select") not in [None, "", "Null"] %} +
+
+
+
+ {% if comps.get("observation").get("sample") %} +
+ {{comps.get("observation").get("sample")}} +
+ {% else %} +
+ {{ frappe.db.get_value("Observation Template", comps.get("observation").get("observation_template"), "sample") or ""}} +
+ {% endif %} + {% if comps.get("observation").get("received_time") %} +
+ {{frappe.utils.format_datetime(comps.get("observation").get("received_time"))[:-3]}} +
+ {% endif %} +
+
+
+ {{observation_name}} +
+ {% if comps.get("observation").get("method") %} +
+ {{comps.get("observation").get("method")}} +
+ {% endif %} +
+
+
+ {% if comps.get("observation").get("result_data") or comps.get("observation").get("result_select") %} + {{comps.get("observation").get("result_data") + or comps.get("observation").get("result_select")}} + {% elif comps.get("observation").get("result_text") %} + {% if '
' in comps.get("observation").get("result_text") %} + {% if comps.get("observation").get("result_text")|length <= 60 %} + {{comps.get("observation").get("result_text")}} + {% endif %} + {% elif comps.get("observation").get("result_text")|length <= 24 %} + {{comps.get("observation").get("result_text")}} + {% endif %} + {% endif %} +
+ {% if comps.get("observation").get("time_of_result") %} +
+ {{frappe.utils.format_datetime(comps.get("observation").get("time_of_result"))[:-3]}} +
+ {% endif %} +
+
+ {% if comps.get("observation").get("permitted_unit") %} + {{comps.get("observation").get("permitted_unit")}} + {% endif %} +
+
+ {% if comps.get("observation").get("reference") %} + {{comps.get("observation").get("reference")}} + {% endif %} +
+
+ {% if comps.get("observation").get("result_text") %} + {% if '
' in comps.get("observation").get("result_text") %} + {% if comps.get("observation").get("result_text")|length > 60 %} +
+ {{comps.get("observation").get("result_text")}} +
+ {% endif %} + {% elif comps.get("observation").get("result_text")|length > 24 %} +
+ {{comps.get("observation").get("result_text")}} +
+ {% endif %} + {% endif %} + {% if comps.get("observation").get("result_interpretation") %} +
+ {{comps.get("observation").get("result_interpretation")}} +
+ {% endif %} + {% if comps.get("observation").get("note") %} +
+ {{comps.get("observation").get("note")}} +
+ {% endif %} + {% if comps.get("observation").get("description") and not data.get("description") %} +
+ {{comps.get("observation").get("description")}} +
+ {% endif %} +
+
+ {% endif %} + {% endif %} + {% endfor %} +
+ {{data.get("description") or ""}} +
+
+
+ + + {% endif %} + {% endif %} + {% endfor %} + +{% endif %} \ No newline at end of file diff --git a/healthcare/healthcare/doctype/observation/observation.py b/healthcare/healthcare/doctype/observation/observation.py index ed8782c53d..ed5611a538 100644 --- a/healthcare/healthcare/doctype/observation/observation.py +++ b/healthcare/healthcare/doctype/observation/observation.py @@ -602,3 +602,17 @@ def eval_condition_and_formula(d, data):

Hint: {4}""" ).format(d.parenttype, get_link_to_form(d.parenttype, d.parent), d.idx, err, description) frappe.throw(message, title=_("Error in formula")) + + +def get_observations_for_medical_record(observation, parent_observation=None): + if not observation: + return + + if parent_observation: + obs_doc = frappe.get_doc("Observation", parent_observation) + else: + obs_doc = frappe.get_doc("Observation", observation) + + out_data, obs_length = aggregate_and_return_observation_data([obs_doc]) + + return out_data, obs_length diff --git a/healthcare/healthcare/doctype/patient_history_settings/patient_history_settings.py b/healthcare/healthcare/doctype/patient_history_settings/patient_history_settings.py index 3e33a42bed..ad31492780 100644 --- a/healthcare/healthcare/doctype/patient_history_settings/patient_history_settings.py +++ b/healthcare/healthcare/doctype/patient_history_settings/patient_history_settings.py @@ -9,6 +9,7 @@ from frappe import _ from frappe.model.document import Document from frappe.utils import cint, cstr +from frappe.utils.formatters import format_value from healthcare.healthcare.page.patient_history.patient_history import get_patient_history_doctypes @@ -79,7 +80,14 @@ def create_medical_record(doc, method=None): if not medical_record_required: return - if frappe.db.exists("Patient Medical Record", {"reference_name": doc.name}): + reference = doc.name + if doc.doctype == "Observation": + if doc.parent_observation: + reference = doc.parent_observation + + if frappe.db.exists("Patient Medical Record", {"reference_name": reference}): + if doc.doctype == "Observation" and reference: + update_medical_record(doc, reference=reference) return subject = set_subject_field(doc) @@ -90,17 +98,20 @@ def create_medical_record(doc, method=None): 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_name = reference medical_record.reference_owner = doc.owner medical_record.save(ignore_permissions=True) -def update_medical_record(doc, method=None): +def update_medical_record(doc, method=None, reference=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}) + medical_record_id = frappe.db.exists( + "Patient Medical Record", + {"reference_name": reference if doc.doctype == "Observation" else doc.name}, + ) if medical_record_id: subject = set_subject_field(doc) @@ -120,24 +131,25 @@ def delete_medical_record(doc, method=None): 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")) + ":") + "
" + cstr(formatted_value) + "
" - - 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) + "
" + if doc.doctype == "Observation": + subject = frappe.render_template( + "healthcare/healthcare/doctype/observation/observation.html", dict(doc=doc) + ) + else: + 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")) + ":") + "
" + cstr(formatted_value) + "
" + 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) + "
" return subject diff --git a/healthcare/hooks.py b/healthcare/hooks.py index 89db00624f..435d580b22 100644 --- a/healthcare/hooks.py +++ b/healthcare/hooks.py @@ -72,6 +72,7 @@ "methods": [ "healthcare.healthcare.doctype.diagnostic_report.diagnostic_report.diagnostic_report_print", "healthcare.healthcare.utils.generate_barcodes", + "healthcare.healthcare.doctype.observation.observation.get_observations_for_medical_record", ] } diff --git a/healthcare/patches.txt b/healthcare/patches.txt index 7c9f3b36ae..52d127f947 100644 --- a/healthcare/patches.txt +++ b/healthcare/patches.txt @@ -9,6 +9,8 @@ healthcare.patches.v15_0.rename_medical_code_standard_and_medical_code healthcare.patches.v15_0.setup_service_request healthcare.patches.v15_0.create_custom_field_in_payment_entry healthcare.patches.v15_0.create_custom_field_for_package_subscription +healthcare.patches.v15_0.add_observation_to_patient_history +healthcare.patches.v15_0.create_patient_medical_records_for_observations [post_model_sync] healthcare.patches.v15_0.rename_field_medical_department_in_appoitment_type_service_item diff --git a/healthcare/patches/v15_0/add_observation_to_patient_history.py b/healthcare/patches/v15_0/add_observation_to_patient_history.py new file mode 100644 index 0000000000..a7802e0144 --- /dev/null +++ b/healthcare/patches/v15_0/add_observation_to_patient_history.py @@ -0,0 +1,23 @@ +import json + +import frappe + + +def execute(): + settings = frappe.get_single("Patient History Settings") + selected_fields = [ + {"label": "Observation Template", "fieldname": "observation_template", "fieldtype": "Link"}, + {"label": "Posting Date", "fieldname": "posting_date", "fieldtype": "Date"}, + {"label": "Status", "fieldname": "status", "fieldtype": "Select"}, + {"label": "Time of Result", "fieldname": "time_of_result", "fieldtype": "Datetime"}, + ] + + settings.append( + "standard_doctypes", + { + "document_type": "Observation", + "date_fieldname": "posting_date", + "selected_fields": json.dumps(selected_fields), + }, + ) + settings.save() diff --git a/healthcare/patches/v15_0/create_patient_medical_records_for_observations.py b/healthcare/patches/v15_0/create_patient_medical_records_for_observations.py new file mode 100644 index 0000000000..2f4bf952b8 --- /dev/null +++ b/healthcare/patches/v15_0/create_patient_medical_records_for_observations.py @@ -0,0 +1,34 @@ +import frappe +from frappe.utils import getdate + + +def execute(): + observations = frappe.db.get_all("Observation", filters={"docstatus": 1}, pluck="name") + + for obs in observations: + obs_doc = frappe.get_doc("Observation", obs) + + subject = frappe.render_template( + "healthcare/healthcare/doctype/observation/observation.html", dict(doc=obs_doc) + ) + + reference = obs + if obs_doc.parent_observation: + reference = obs_doc.parent_observation + + exists = frappe.db.exists( + "Patient Medical Record", {"reference_doctype": "Observation", "reference_name": reference} + ) + + if exists: + frappe.db.set_value("Patient Medical Record", exists, "subject", subject) + else: + medical_record = frappe.new_doc("Patient Medical Record") + medical_record.patient = obs_doc.patient + medical_record.subject = subject + medical_record.status = "Open" + medical_record.communication_date = getdate(obs_doc.modified) + medical_record.reference_doctype = "Observation" + medical_record.reference_name = reference + medical_record.reference_owner = obs_doc.owner + medical_record.save(ignore_permissions=True) diff --git a/healthcare/setup.py b/healthcare/setup.py index a690c63b49..664c9837ae 100644 --- a/healthcare/setup.py +++ b/healthcare/setup.py @@ -992,6 +992,15 @@ def get_patient_history_config(): {"label": "Total Orders", "fieldname": "total_orders", "fieldtype": "Float"}, ], ), + "Observation": ( + "posting_date", + [ + {"label": "Observation Template", "fieldname": "observation_template", "fieldtype": "Link"}, + {"label": "Posting Date", "fieldname": "posting_date", "fieldtype": "Date"}, + {"label": "Status", "fieldname": "status", "fieldtype": "Select"}, + {"label": "Time of Result", "fieldname": "time_of_result", "fieldtype": "Datetime"}, + ], + ), }