Automate - Patient Apointment Invoicing
This commit is contained in:
parent
4371c7e492
commit
363deb67c3
@ -241,6 +241,40 @@
|
|||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"default": "0",
|
||||||
|
"description": "Manage Appointment Invoice submit and cancel automatically for Patient Encounter",
|
||||||
|
"fieldname": "manage_appointment_invoice_automatically",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Manage Appointment Invoice Automatically",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
@ -1293,7 +1327,7 @@
|
|||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-08-01 13:30:04.448397",
|
"modified": "2018-08-03 15:18:36.631441",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Healthcare",
|
"module": "Healthcare",
|
||||||
"name": "Healthcare Settings",
|
"name": "Healthcare Settings",
|
||||||
|
@ -6,11 +6,13 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
import json
|
import json
|
||||||
from frappe.utils import getdate
|
from frappe.utils import getdate, add_days
|
||||||
from frappe import _
|
from frappe import _
|
||||||
import datetime
|
import datetime
|
||||||
from frappe.core.doctype.sms_settings.sms_settings import send_sms
|
from frappe.core.doctype.sms_settings.sms_settings import send_sms
|
||||||
from erpnext.hr.doctype.employee.employee import is_holiday
|
from erpnext.hr.doctype.employee.employee import is_holiday
|
||||||
|
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account,get_income_account
|
||||||
|
from erpnext.healthcare.utils import validity_exists, service_item_and_practitioner_charge
|
||||||
|
|
||||||
class PatientAppointment(Document):
|
class PatientAppointment(Document):
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
@ -41,23 +43,108 @@ class PatientAppointment(Document):
|
|||||||
frappe.msgprint(_("{0} has fee validity till {1}").format(appointment.patient, fee_validity.valid_till))
|
frappe.msgprint(_("{0} has fee validity till {1}").format(appointment.patient, fee_validity.valid_till))
|
||||||
confirm_sms(self)
|
confirm_sms(self)
|
||||||
|
|
||||||
|
if frappe.db.get_value("Healthcare Settings", None, "manage_appointment_invoice_automatically") == '1' and \
|
||||||
|
frappe.db.get_value("Patient Appointment", self.name, "invoiced") != 1:
|
||||||
|
invoice_appointment(self)
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def invoice_appointment(appointment_doc):
|
||||||
|
if not appointment_doc.name:
|
||||||
|
return False
|
||||||
|
sales_invoice = frappe.new_doc("Sales Invoice")
|
||||||
|
sales_invoice.customer = frappe.get_value("Patient", appointment_doc.patient, "customer")
|
||||||
|
sales_invoice.appointment = appointment_doc.name
|
||||||
|
sales_invoice.due_date = getdate()
|
||||||
|
sales_invoice.is_pos = True
|
||||||
|
sales_invoice.company = appointment_doc.company
|
||||||
|
sales_invoice.debit_to = get_receivable_account(appointment_doc.company)
|
||||||
|
|
||||||
|
item_line = sales_invoice.append("items")
|
||||||
|
service_item, practitioner_charge = service_item_and_practitioner_charge(appointment_doc)
|
||||||
|
item_line.item_code = service_item
|
||||||
|
item_line.description = "Consulting Charges: " + appointment_doc.practitioner
|
||||||
|
item_line.income_account = get_income_account(appointment_doc.practitioner, appointment_doc.company)
|
||||||
|
item_line.rate = practitioner_charge
|
||||||
|
item_line.amount = practitioner_charge
|
||||||
|
item_line.qty = 1
|
||||||
|
item_line.reference_dt = "Patient Appointment"
|
||||||
|
item_line.reference_dn = appointment_doc.name
|
||||||
|
|
||||||
|
payments_line = sales_invoice.append("payments")
|
||||||
|
payments_line.mode_of_payment = "Cash"
|
||||||
|
payments_line.amount = practitioner_charge
|
||||||
|
|
||||||
|
sales_invoice.set_missing_values(for_validate = True)
|
||||||
|
|
||||||
|
sales_invoice.save(ignore_permissions=True)
|
||||||
|
sales_invoice.submit()
|
||||||
|
frappe.msgprint(_("Sales Invoice {0} created as paid".format(sales_invoice.name)), alert=True)
|
||||||
|
|
||||||
def appointment_cancel(appointment_id):
|
def appointment_cancel(appointment_id):
|
||||||
appointment = frappe.get_doc("Patient Appointment", appointment_id)
|
appointment = frappe.get_doc("Patient Appointment", appointment_id)
|
||||||
|
|
||||||
# If invoiced --> fee_validity update with -1 visit
|
# If invoiced --> fee_validity update with -1 visit
|
||||||
if appointment.invoiced:
|
if appointment.invoiced:
|
||||||
|
sales_invoice = exists_sales_invoice(appointment)
|
||||||
|
if sales_invoice and cancel_sales_invoice(sales_invoice):
|
||||||
|
frappe.msgprint(
|
||||||
|
_("Appointment {0} and Sales Invoice {1} cancelled".format(appointment.name, sales_invoice.name))
|
||||||
|
)
|
||||||
|
else:
|
||||||
validity = validity_exists(appointment.practitioner, appointment.patient)
|
validity = validity_exists(appointment.practitioner, appointment.patient)
|
||||||
if validity:
|
if validity:
|
||||||
fee_validity = frappe.get_doc("Fee Validity", validity[0][0])
|
fee_validity = frappe.get_doc("Fee Validity", validity[0][0])
|
||||||
|
if appointment_valid_in_fee_validity(appointment, fee_validity.valid_till, True, fee_validity.ref_invoice):
|
||||||
visited = fee_validity.visited - 1
|
visited = fee_validity.visited - 1
|
||||||
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
||||||
if visited <= 0:
|
|
||||||
frappe.msgprint(
|
frappe.msgprint(
|
||||||
_("Appointment cancelled, Please review and cancel the invoice {0}".format(fee_validity.ref_invoice))
|
_("Appointment cancelled, Please review and cancel the invoice {0}".format(fee_validity.ref_invoice))
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
frappe.msgprint(_("Appointment cancelled"))
|
frappe.msgprint(_("Appointment cancelled"))
|
||||||
|
else:
|
||||||
|
frappe.msgprint(_("Appointment cancelled"))
|
||||||
|
else:
|
||||||
|
frappe.msgprint(_("Appointment cancelled"))
|
||||||
|
|
||||||
|
def appointment_valid_in_fee_validity(appointment, valid_end_date, invoiced, ref_invoice):
|
||||||
|
valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
|
||||||
|
max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
|
||||||
|
valid_start_date = add_days(getdate(valid_end_date), -int(valid_days))
|
||||||
|
|
||||||
|
# Appointments which has same fee validity range with the appointment
|
||||||
|
appointments = frappe.get_list("Patient Appointment",{'patient': appointment.patient, 'invoiced': invoiced,
|
||||||
|
'appointment_date':("<=", getdate(valid_end_date)), 'appointment_date':(">=", getdate(valid_start_date)),
|
||||||
|
'practitioner': appointment.practitioner}, order_by="appointment_date desc", limit=int(max_visit))
|
||||||
|
|
||||||
|
if appointments and len(appointments) > 0:
|
||||||
|
appointment_obj = appointments[len(appointments)-1]
|
||||||
|
sales_invoice = exists_sales_invoice(appointment_obj)
|
||||||
|
if sales_invoice.name == ref_invoice:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def cancel_sales_invoice(sales_invoice):
|
||||||
|
if frappe.db.get_value("Healthcare Settings", None, "manage_appointment_invoice_automatically") == '1':
|
||||||
|
if len(sales_invoice.items) == 1:
|
||||||
|
sales_invoice.cancel()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def exists_sales_invoice_item(appointment):
|
||||||
|
return frappe.db.exists(
|
||||||
|
"Sales Invoice Item",
|
||||||
|
{
|
||||||
|
"reference_dt": "Patient Appointment",
|
||||||
|
"reference_dn": appointment.name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def exists_sales_invoice(appointment):
|
||||||
|
sales_item_exist = exists_sales_invoice_item(appointment)
|
||||||
|
if sales_item_exist:
|
||||||
|
sales_invoice = frappe.get_doc("Sales Invoice", frappe.db.get_value("Sales Invoice Item", sales_item_exist, "parent"))
|
||||||
|
return sales_invoice
|
||||||
|
return False
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_availability_data(date, practitioner):
|
def get_availability_data(date, practitioner):
|
||||||
@ -193,13 +280,6 @@ def confirm_sms(doc):
|
|||||||
message = frappe.db.get_value("Healthcare Settings", None, "app_con_msg")
|
message = frappe.db.get_value("Healthcare Settings", None, "app_con_msg")
|
||||||
send_message(doc, message)
|
send_message(doc, message)
|
||||||
|
|
||||||
|
|
||||||
def validity_exists(practitioner, patient):
|
|
||||||
return frappe.db.exists({
|
|
||||||
"doctype": "Fee Validity",
|
|
||||||
"practitioner": practitioner,
|
|
||||||
"patient": patient})
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def create_encounter(appointment):
|
def create_encounter(appointment):
|
||||||
appointment = frappe.get_doc("Patient Appointment", appointment)
|
appointment = frappe.get_doc("Patient Appointment", appointment)
|
||||||
|
@ -7,9 +7,8 @@ import frappe
|
|||||||
import datetime
|
import datetime
|
||||||
from frappe import _
|
from frappe import _
|
||||||
import math
|
import math
|
||||||
from frappe.utils import time_diff_in_hours, rounded
|
from frappe.utils import time_diff_in_hours, rounded, getdate, add_days
|
||||||
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_income_account
|
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_income_account
|
||||||
from erpnext.healthcare.doctype.patient_appointment.patient_appointment import validity_exists
|
|
||||||
from erpnext.healthcare.doctype.fee_validity.fee_validity import create_fee_validity, update_fee_validity
|
from erpnext.healthcare.doctype.fee_validity.fee_validity import create_fee_validity, update_fee_validity
|
||||||
from erpnext.healthcare.doctype.lab_test.lab_test import create_multiple
|
from erpnext.healthcare.doctype.lab_test.lab_test import create_multiple
|
||||||
|
|
||||||
@ -272,6 +271,12 @@ def manage_prescriptions(invoiced, ref_dt, ref_dn, dt, created_check_field):
|
|||||||
doc_created = frappe.db.get_value(dt, {'prescription': ref_dn})
|
doc_created = frappe.db.get_value(dt, {'prescription': ref_dn})
|
||||||
frappe.db.set_value(dt, doc_created, 'invoiced', invoiced)
|
frappe.db.set_value(dt, doc_created, 'invoiced', invoiced)
|
||||||
|
|
||||||
|
def validity_exists(practitioner, patient):
|
||||||
|
return frappe.db.exists({
|
||||||
|
"doctype": "Fee Validity",
|
||||||
|
"practitioner": practitioner,
|
||||||
|
"patient": patient})
|
||||||
|
|
||||||
def manage_fee_validity(appointment_name, method, ref_invoice=None):
|
def manage_fee_validity(appointment_name, method, ref_invoice=None):
|
||||||
appointment_doc = frappe.get_doc("Patient Appointment", appointment_name)
|
appointment_doc = frappe.get_doc("Patient Appointment", appointment_name)
|
||||||
validity_exist = validity_exists(appointment_doc.practitioner, appointment_doc.patient)
|
validity_exist = validity_exists(appointment_doc.practitioner, appointment_doc.patient)
|
||||||
@ -282,12 +287,13 @@ def manage_fee_validity(appointment_name, method, ref_invoice=None):
|
|||||||
# Check if the validity is valid
|
# Check if the validity is valid
|
||||||
if (fee_validity.valid_till >= appointment_doc.appointment_date):
|
if (fee_validity.valid_till >= appointment_doc.appointment_date):
|
||||||
if (method == "on_cancel" and appointment_doc.status != "Closed"):
|
if (method == "on_cancel" and appointment_doc.status != "Closed"):
|
||||||
|
if ref_invoice == fee_validity.ref_invoice:
|
||||||
visited = fee_validity.visited - 1
|
visited = fee_validity.visited - 1
|
||||||
if visited < 0:
|
if visited < 0:
|
||||||
visited = 0
|
visited = 0
|
||||||
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
||||||
do_not_update = True
|
do_not_update = True
|
||||||
elif (fee_validity.visited < fee_validity.max_visit):
|
elif (method == "on_submit" and fee_validity.visited < fee_validity.max_visit):
|
||||||
visited = fee_validity.visited + 1
|
visited = fee_validity.visited + 1
|
||||||
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
||||||
do_not_update = True
|
do_not_update = True
|
||||||
@ -301,30 +307,49 @@ def manage_fee_validity(appointment_name, method, ref_invoice=None):
|
|||||||
fee_validity = create_fee_validity(appointment_doc.practitioner, appointment_doc.patient, appointment_doc.appointment_date, ref_invoice)
|
fee_validity = create_fee_validity(appointment_doc.practitioner, appointment_doc.patient, appointment_doc.appointment_date, ref_invoice)
|
||||||
visited = fee_validity.visited
|
visited = fee_validity.visited
|
||||||
|
|
||||||
|
print "do_not_update: ", do_not_update
|
||||||
|
print "visited: ", visited
|
||||||
|
|
||||||
# Mark All Patient Appointment invoiced = True in the validity range do not cross the max visit
|
# Mark All Patient Appointment invoiced = True in the validity range do not cross the max visit
|
||||||
if (method == "on_cancel"):
|
if (method == "on_cancel"):
|
||||||
invoiced = True
|
invoiced = True
|
||||||
else:
|
else:
|
||||||
invoiced = False
|
invoiced = False
|
||||||
patient_appointments = frappe.get_list("Patient Appointment",{'patient': fee_validity.patient, 'invoiced': invoiced,
|
|
||||||
'appointment_date':("<=", fee_validity.valid_till), 'practitioner': fee_validity.practitioner}, order_by="appointment_date")
|
patient_appointments = appointments_valid_in_fee_validity(appointment_doc, invoiced)
|
||||||
if patient_appointments and fee_validity:
|
if patient_appointments and fee_validity:
|
||||||
visit = visited
|
visit = visited
|
||||||
for appointment in patient_appointments:
|
for appointment in patient_appointments:
|
||||||
if (method == "on_cancel" and appointment.status != "Closed"):
|
if (method == "on_cancel" and appointment.status != "Closed"):
|
||||||
|
if ref_invoice == fee_validity.ref_invoice:
|
||||||
visited = visited - 1
|
visited = visited - 1
|
||||||
if visited < 0:
|
if visited < 0:
|
||||||
visited = 0
|
visited = 0
|
||||||
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
||||||
frappe.db.set_value("Patient Appointment", appointment.name, "invoiced", False)
|
frappe.db.set_value("Patient Appointment", appointment.name, "invoiced", False)
|
||||||
manage_doc_for_appoitnment("Patient Encounter", appointment.name, False)
|
manage_doc_for_appoitnment("Patient Encounter", appointment.name, False)
|
||||||
elif int(fee_validity.max_visit) > visit:
|
elif method == "on_submit" and int(fee_validity.max_visit) > visit:
|
||||||
|
if ref_invoice == fee_validity.ref_invoice:
|
||||||
visited = visited + 1
|
visited = visited + 1
|
||||||
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
||||||
frappe.db.set_value("Patient Appointment", appointment.name, "invoiced", True)
|
frappe.db.set_value("Patient Appointment", appointment.name, "invoiced", True)
|
||||||
manage_doc_for_appoitnment("Patient Encounter", appointment.name, True)
|
manage_doc_for_appoitnment("Patient Encounter", appointment.name, True)
|
||||||
|
if ref_invoice == fee_validity.ref_invoice:
|
||||||
visit = visit + 1
|
visit = visit + 1
|
||||||
|
|
||||||
|
if method == "on_cancel":
|
||||||
|
ref_invoice_in_fee_validity = frappe.db.get_value("Fee Validity", fee_validity.name, 'ref_invoice')
|
||||||
|
if ref_invoice_in_fee_validity == ref_invoice:
|
||||||
|
frappe.delete_doc("Fee Validity", fee_validity.name)
|
||||||
|
|
||||||
|
def appointments_valid_in_fee_validity(appointment, invoiced):
|
||||||
|
valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
|
||||||
|
max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
|
||||||
|
valid_days_date = add_days(getdate(appointment.appointment_date), int(valid_days))
|
||||||
|
return frappe.get_list("Patient Appointment",{'patient': appointment.patient, 'invoiced': invoiced,
|
||||||
|
'appointment_date':("<=", valid_days_date), 'appointment_date':(">=", getdate(appointment.appointment_date)),
|
||||||
|
'practitioner': appointment.practitioner}, order_by="appointment_date", limit=int(max_visit)-1)
|
||||||
|
|
||||||
def manage_doc_for_appoitnment(dt_from_appointment, appointment, invoiced):
|
def manage_doc_for_appoitnment(dt_from_appointment, appointment, invoiced):
|
||||||
dn_from_appointment = frappe.db.exists(
|
dn_from_appointment = frappe.db.exists(
|
||||||
dt_from_appointment,
|
dt_from_appointment,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user