Automate - Patient Apointment Invoicing
This commit is contained in:
parent
4371c7e492
commit
363deb67c3
@ -241,6 +241,40 @@
|
||||
"translatable": 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_in_quick_entry": 0,
|
||||
@ -1293,7 +1327,7 @@
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-08-01 13:30:04.448397",
|
||||
"modified": "2018-08-03 15:18:36.631441",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Healthcare Settings",
|
||||
|
@ -6,11 +6,13 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
import json
|
||||
from frappe.utils import getdate
|
||||
from frappe.utils import getdate, add_days
|
||||
from frappe import _
|
||||
import datetime
|
||||
from frappe.core.doctype.sms_settings.sms_settings import send_sms
|
||||
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):
|
||||
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))
|
||||
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):
|
||||
appointment = frappe.get_doc("Patient Appointment", appointment_id)
|
||||
|
||||
# If invoiced --> fee_validity update with -1 visit
|
||||
if appointment.invoiced:
|
||||
validity = validity_exists(appointment.practitioner, appointment.patient)
|
||||
if validity:
|
||||
fee_validity = frappe.get_doc("Fee Validity", validity[0][0])
|
||||
visited = fee_validity.visited - 1
|
||||
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
||||
if visited <= 0:
|
||||
frappe.msgprint(
|
||||
_("Appointment cancelled, Please review and cancel the invoice {0}".format(fee_validity.ref_invoice))
|
||||
)
|
||||
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)
|
||||
if validity:
|
||||
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
|
||||
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
||||
frappe.msgprint(
|
||||
_("Appointment cancelled, Please review and cancel the invoice {0}".format(fee_validity.ref_invoice))
|
||||
)
|
||||
else:
|
||||
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()
|
||||
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")
|
||||
send_message(doc, message)
|
||||
|
||||
|
||||
def validity_exists(practitioner, patient):
|
||||
return frappe.db.exists({
|
||||
"doctype": "Fee Validity",
|
||||
"practitioner": practitioner,
|
||||
"patient": patient})
|
||||
|
||||
@frappe.whitelist()
|
||||
def create_encounter(appointment):
|
||||
appointment = frappe.get_doc("Patient Appointment", appointment)
|
||||
|
@ -7,9 +7,8 @@ import frappe
|
||||
import datetime
|
||||
from frappe import _
|
||||
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.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.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})
|
||||
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):
|
||||
appointment_doc = frappe.get_doc("Patient Appointment", appointment_name)
|
||||
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
|
||||
if (fee_validity.valid_till >= appointment_doc.appointment_date):
|
||||
if (method == "on_cancel" and appointment_doc.status != "Closed"):
|
||||
visited = fee_validity.visited - 1
|
||||
if visited < 0:
|
||||
visited = 0
|
||||
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
||||
if ref_invoice == fee_validity.ref_invoice:
|
||||
visited = fee_validity.visited - 1
|
||||
if visited < 0:
|
||||
visited = 0
|
||||
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
||||
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
|
||||
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
||||
do_not_update = True
|
||||
@ -301,29 +307,48 @@ 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)
|
||||
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
|
||||
if (method == "on_cancel"):
|
||||
invoiced = True
|
||||
else:
|
||||
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:
|
||||
visit = visited
|
||||
for appointment in patient_appointments:
|
||||
if (method == "on_cancel" and appointment.status != "Closed"):
|
||||
visited = visited - 1
|
||||
if visited < 0:
|
||||
visited = 0
|
||||
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
||||
if ref_invoice == fee_validity.ref_invoice:
|
||||
visited = visited - 1
|
||||
if visited < 0:
|
||||
visited = 0
|
||||
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
||||
frappe.db.set_value("Patient Appointment", appointment.name, "invoiced", False)
|
||||
manage_doc_for_appoitnment("Patient Encounter", appointment.name, False)
|
||||
elif int(fee_validity.max_visit) > visit:
|
||||
visited = visited + 1
|
||||
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
||||
elif method == "on_submit" and int(fee_validity.max_visit) > visit:
|
||||
if ref_invoice == fee_validity.ref_invoice:
|
||||
visited = visited + 1
|
||||
frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
|
||||
frappe.db.set_value("Patient Appointment", appointment.name, "invoiced", True)
|
||||
manage_doc_for_appoitnment("Patient Encounter", appointment.name, True)
|
||||
visit = visit + 1
|
||||
if ref_invoice == fee_validity.ref_invoice:
|
||||
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):
|
||||
dn_from_appointment = frappe.db.exists(
|
||||
|
Loading…
x
Reference in New Issue
Block a user