From 5100e11fb6d1aec3fd61a1cb3168c96d8e745f23 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Mon, 24 Feb 2020 22:08:45 +0530 Subject: [PATCH] fix: appointment reminders not working --- .../patient_appointment.json | 14 +++---- .../patient_appointment.py | 37 +++++++++++++------ erpnext/hooks.py | 3 +- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json index c2fba688a53..ea0075ce63f 100644 --- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json +++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json @@ -30,12 +30,12 @@ "appointment_datetime", "duration", "section_break_16", - "invoiced", - "ref_sales_invoice", - "column_break_2", "mode_of_payment", "paid_amount", "company", + "column_break_2", + "invoiced", + "ref_sales_invoice", "section_break_3", "notes", "referring_practitioner", @@ -83,7 +83,6 @@ "read_only": 1 }, { - "default": "Scheduled", "depends_on": "eval:!doc.__islocal", "fieldname": "status", "fieldtype": "Select", @@ -202,9 +201,9 @@ { "fieldname": "appointment_datetime", "fieldtype": "Datetime", - "hidden": 1, - "label": "Date TIme", + "label": "Appointment Datetime", "print_hide": 1, + "read_only": 1, "report_hide": 1, "search_index": 1 }, @@ -227,6 +226,7 @@ "default": "0", "fieldname": "invoiced", "fieldtype": "Check", + "in_filter": 1, "label": "Invoiced", "read_only": 1, "search_index": 1 @@ -279,7 +279,7 @@ } ], "links": [], - "modified": "2020-02-10 22:38:55.401247", + "modified": "2020-02-24 21:29:28.374886", "modified_by": "Administrator", "module": "Healthcare", "name": "Patient Appointment", diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py index 76feb22adac..4ae079af6d0 100755 --- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py +++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py @@ -18,6 +18,7 @@ from erpnext.healthcare.utils import check_validity_exists, get_service_item_and class PatientAppointment(Document): def validate(self): self.validate_overlaps() + self.set_appointment_datetime() def after_insert(self): invoice_appointment(self) @@ -59,6 +60,9 @@ class PatientAppointment(Document): overlaps[0][1], overlaps[0][2], overlaps[0][3], overlaps[0][4]) frappe.throw(_(overlapping_details)) + def set_appointment_datetime(self): + self.appointment_datetime = "%s %s" % (self.appointment_date, self.appointment_time or "00:00:00") + def update_prescription_details(self): if self.procedure_prescription: frappe.db.set_value('Procedure Prescription', self.procedure_prescription, 'appointment_booked', 1) @@ -151,6 +155,7 @@ def cancel_appointment(appointment_id): else: frappe.msgprint(_('Appointment Cancelled')) + def validate_appointment_in_fee_validity(appointment, valid_end_date, ref_invoice): valid_days = frappe.db.get_single_value('Healthcare Settings', 'valid_days') max_visit = frappe.db.get_single_value('Healthcare Settings', 'max_visit') @@ -172,6 +177,7 @@ def validate_appointment_in_fee_validity(appointment, valid_end_date, ref_invoic return True return False + def cancel_sales_invoice(sales_invoice): if frappe.db.get_single_value('Healthcare Settings', 'automate_appointment_invoicing'): if len(sales_invoice.items) == 1: @@ -179,6 +185,7 @@ def cancel_sales_invoice(sales_invoice): return True return False + def check_si_item_exists(appointment): return frappe.db.exists( 'Sales Invoice Item', @@ -188,6 +195,7 @@ def check_si_item_exists(appointment): } ) + def check_sales_invoice_exists(appointment): si_item = check_si_item_exists(appointment) if si_item: @@ -195,6 +203,7 @@ def check_sales_invoice_exists(appointment): return sales_invoice return False + @frappe.whitelist() def get_availability_data(date, practitioner): """ @@ -223,6 +232,7 @@ def get_availability_data(date, practitioner): return {'slot_details': slot_details} + def check_employee_wise_availability(date, practitioner_doc): employee = None if practitioner_doc.employee: @@ -245,6 +255,7 @@ def check_employee_wise_availability(date, practitioner_doc): else: frappe.throw(_('{0} is on Leave on {1}').format(practitioner_doc.name, date)) + def get_available_slots(practitioner_schedules, date): available_slots = [] slot_details = [] @@ -315,6 +326,7 @@ def send_confirmation_msg(doc): message = frappe.db.get_single_value('Healthcare Settings', 'appointment_confirmation_msg') send_message(doc, message) + @frappe.whitelist() def make_encounter(source_name, target_doc=None): doc = get_mapped_doc('Patient Appointment', source_name, { @@ -331,25 +343,26 @@ def make_encounter(source_name, target_doc=None): ] } }, target_doc) - return doc -def remind_appointment(): + +def send_appointment_reminder(): if frappe.db.get_single_value('Healthcare Settings', 'send_appointment_reminder'): - remind_before = datetime.datetime.strptime(frappe.get_single_value('Healthcare Settings', 'remind_before'), '%H:%M:%S') + remind_before = datetime.datetime.strptime(frappe.db.get_single_value('Healthcare Settings', 'remind_before'), '%H:%M:%S') reminder_dt = datetime.datetime.now() + datetime.timedelta( hours=remind_before.hour, minutes=remind_before.minute, seconds=remind_before.second) - appointment_list = frappe.db.sql( - 'select name from `tabPatient Appointment` where start_dt between %s and %s and reminded = 0 ', - (datetime.datetime.now(), reminder_dt) - ) + appointment_list = frappe.db.get_all('Patient Appointment', { + 'appointment_datetime': ['between', (datetime.datetime.now(), reminder_dt)], + 'reminded': 0, + 'status': ['!=', 'Cancelled'] + }) - for i in range(0, len(appointment_list)): - doc = frappe.get_doc('Patient Appointment', appointment_list[i][0]) + for appointment in appointment_list: + doc = frappe.get_doc('Patient Appointment', appointment.name) message = frappe.db.get_single_value('Healthcare Settings', 'appointment_reminder_msg') send_message(doc, message) - frappe.db.set_value('Patient Appointment', doc.name, 'reminded',1) + frappe.db.set_value('Patient Appointment', doc.name, 'reminded', 1) def send_message(doc, message): patient = frappe.get_doc('Patient', doc.patient) @@ -363,6 +376,7 @@ def send_message(doc, message): number = [patient.mobile] send_sms(number, message) + @frappe.whitelist() def get_events(start, end, filters=None): """Returns events for Gantt / Calendar view rendering. @@ -372,7 +386,7 @@ def get_events(start, end, filters=None): :param filters: Filters (JSON). """ from frappe.desk.calendar import get_event_conditions - conditions = get_event_conditions("Patient Appointment", filters) + conditions = get_event_conditions('Patient Appointment', filters) data = frappe.db.sql(""" select @@ -394,6 +408,7 @@ def get_events(start, end, filters=None): return data + @frappe.whitelist() def get_procedure_prescribed(patient): return frappe.db.sql("""select pp.name, pp.procedure, pp.parent, ct.practitioner, diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 774c917f682..bc3dffaf2d5 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -273,7 +273,8 @@ auto_cancel_exempted_doctypes= [ scheduler_events = { "all": [ - "erpnext.projects.doctype.project.project.project_status_update_reminder" + "erpnext.projects.doctype.project.project.project_status_update_reminder", + "erpnext.healthcare_healthcare.doctype.patient_appointment.patient_appointment.send_appointment_reminder" ], "hourly": [ 'erpnext.hr.doctype.daily_work_summary_group.daily_work_summary_group.trigger_emails',