feat: multi-company billing
sales onvoice - filter get items based on company utils - company filters in all get item helper methods utils - refactor appointemnt items
This commit is contained in:
parent
f90ea8d622
commit
c01fb2a4d8
@ -919,7 +919,7 @@ var get_healthcare_services_to_invoice = function(frm) {
|
||||
if(patient && patient!=selected_patient){
|
||||
selected_patient = patient;
|
||||
var method = "erpnext.healthcare.utils.get_healthcare_services_to_invoice";
|
||||
var args = {patient: patient};
|
||||
var args = {patient: patient, company: frm.doc.company};
|
||||
var columns = (["service", "reference_name", "reference_type"]);
|
||||
get_healthcare_items(frm, true, $results, $placeholder, method, args, columns);
|
||||
}
|
||||
@ -1063,7 +1063,10 @@ var get_drugs_to_invoice = function(frm) {
|
||||
description:'Quantity will be calculated only for items which has "Nos" as UoM. You may change as required for each invoice item.',
|
||||
get_query: function(doc) {
|
||||
return {
|
||||
filters: { patient: dialog.get_value("patient"), docstatus: 1 }
|
||||
filters: { patient: dialog.get_value("patient"),
|
||||
company: frm.doc.company,
|
||||
docstatus: 1
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
|
@ -3,82 +3,84 @@
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import math
|
||||
import json
|
||||
import frappe
|
||||
from frappe import _
|
||||
import math
|
||||
from frappe.utils import time_diff_in_hours, rounded
|
||||
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_income_account
|
||||
from erpnext.healthcare.doctype.fee_validity.fee_validity import create_fee_validity
|
||||
from erpnext.healthcare.doctype.lab_test.lab_test import create_multiple
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_healthcare_services_to_invoice(patient):
|
||||
def get_healthcare_services_to_invoice(patient, company):
|
||||
patient = frappe.get_doc('Patient', patient)
|
||||
items_to_invoice = []
|
||||
if patient:
|
||||
validate_customer_created(patient)
|
||||
items_to_invoice = []
|
||||
patient_appointments = frappe.get_list(
|
||||
'Patient Appointment',
|
||||
fields='*',
|
||||
filters={'patient': patient.name, 'invoiced': 0},
|
||||
order_by='appointment_date'
|
||||
)
|
||||
if patient_appointments:
|
||||
items_to_invoice = get_fee_validity(patient_appointments)
|
||||
# Customer validated, build a list of billable services
|
||||
items_to_invoice += get_appointments_to_invoice(patient, company)
|
||||
items_to_invoice += get_encounters_to_invoice(patient, company)
|
||||
items_to_invoice += get_lab_tests_to_invoice(patient, company)
|
||||
items_to_invoice += get_clinical_procedures_to_invoice(patient, company)
|
||||
items_to_invoice += get_inpatient_services_to_invoice(patient, company)
|
||||
|
||||
encounters = get_encounters_to_invoice(patient)
|
||||
lab_tests = get_lab_tests_to_invoice(patient)
|
||||
clinical_procedures = get_clinical_procedures_to_invoice(patient)
|
||||
inpatient_services = get_inpatient_services_to_invoice(patient)
|
||||
|
||||
items_to_invoice += encounters + lab_tests + clinical_procedures + inpatient_services
|
||||
return items_to_invoice
|
||||
|
||||
|
||||
def validate_customer_created(patient):
|
||||
if not frappe.db.get_value('Patient', patient.name, 'customer'):
|
||||
msg = _("Please set a Customer linked to the Patient")
|
||||
msg += " <b><a href='#Form/Patient/{0}'>{0}</a></b>".format(patient.name)
|
||||
frappe.throw(msg, title=_('Customer Not Found'))
|
||||
|
||||
def get_fee_validity(patient_appointments):
|
||||
if not frappe.db.get_single_value('Healthcare Settings', 'enable_free_follow_ups'):
|
||||
return
|
||||
|
||||
items_to_invoice = []
|
||||
def get_appointments_to_invoice(patient, company):
|
||||
appointments_to_invoice = []
|
||||
patient_appointments = frappe.get_list(
|
||||
'Patient Appointment',
|
||||
fields = '*',
|
||||
filters = {'patient': patient.name, 'company': company, 'invoiced': 0},
|
||||
order_by = 'appointment_date'
|
||||
)
|
||||
|
||||
for appointment in patient_appointments:
|
||||
# Procedure Appointments
|
||||
if appointment.procedure_template:
|
||||
if frappe.db.get_value('Clinical Procedure Template', appointment.procedure_template, 'is_billable'):
|
||||
items_to_invoice.append({
|
||||
appointments_to_invoice.append({
|
||||
'reference_type': 'Patient Appointment',
|
||||
'reference_name': appointment.name,
|
||||
'service': appointment.procedure_template
|
||||
})
|
||||
# Consultation Appointments, should check fee validity
|
||||
else:
|
||||
fee_validity = frappe.db.exists('Fee Validity Reference', {'appointment': appointment.name})
|
||||
if not fee_validity:
|
||||
practitioner_charge = 0
|
||||
income_account = None
|
||||
service_item = None
|
||||
if appointment.practitioner:
|
||||
service_item, practitioner_charge = get_service_item_and_practitioner_charge(appointment)
|
||||
income_account = get_income_account(appointment.practitioner, appointment.company)
|
||||
items_to_invoice.append({
|
||||
'reference_type': 'Patient Appointment',
|
||||
'reference_name': appointment.name,
|
||||
'service': service_item,
|
||||
'rate': practitioner_charge,
|
||||
'income_account': income_account
|
||||
})
|
||||
if frappe.db.get_single_value('Healthcare Settings', 'enable_free_follow_ups') and \
|
||||
frappe.db.exists('Fee Validity Reference', {'appointment': appointment.name}):
|
||||
continue # Skip invoicing, fee validty present
|
||||
practitioner_charge = 0
|
||||
income_account = None
|
||||
service_item = None
|
||||
if appointment.practitioner:
|
||||
service_item, practitioner_charge = get_service_item_and_practitioner_charge(appointment)
|
||||
income_account = get_income_account(appointment.practitioner, appointment.company)
|
||||
appointments_to_invoice.append({
|
||||
'reference_type': 'Patient Appointment',
|
||||
'reference_name': appointment.name,
|
||||
'service': service_item,
|
||||
'rate': practitioner_charge,
|
||||
'income_account': income_account
|
||||
})
|
||||
|
||||
return items_to_invoice
|
||||
return appointments_to_invoice
|
||||
|
||||
|
||||
def get_encounters_to_invoice(patient):
|
||||
def get_encounters_to_invoice(patient, company):
|
||||
encounters_to_invoice = []
|
||||
encounters = frappe.get_list(
|
||||
'Patient Encounter',
|
||||
fields=['*'],
|
||||
filters={'patient': patient.name, 'invoiced': False, 'docstatus': 1}
|
||||
filters={'patient': patient.name, 'company': company, 'invoiced': False, 'docstatus': 1}
|
||||
)
|
||||
if encounters:
|
||||
for encounter in encounters:
|
||||
@ -101,12 +103,12 @@ def get_encounters_to_invoice(patient):
|
||||
return encounters_to_invoice
|
||||
|
||||
|
||||
def get_lab_tests_to_invoice(patient):
|
||||
def get_lab_tests_to_invoice(patient, company):
|
||||
lab_tests_to_invoice = []
|
||||
lab_tests = frappe.get_list(
|
||||
'Lab Test',
|
||||
fields=['name', 'template'],
|
||||
filters={'patient': patient.name, 'invoiced': False, 'docstatus': 1}
|
||||
filters={'patient': patient.name, 'company': company, 'invoiced': False, 'docstatus': 1}
|
||||
)
|
||||
for lab_test in lab_tests:
|
||||
item, is_billable = frappe.get_cached_value('Lab Test Template', lab_test.lab_test_code, ['item', 'is_billable'])
|
||||
@ -142,12 +144,12 @@ def get_lab_tests_to_invoice(patient):
|
||||
return lab_tests_to_invoice
|
||||
|
||||
|
||||
def get_clinical_procedures_to_invoice(patient):
|
||||
def get_clinical_procedures_to_invoice(patient, company):
|
||||
clinical_procedures_to_invoice = []
|
||||
procedures = frappe.get_list(
|
||||
'Clinical Procedure',
|
||||
fields='*',
|
||||
filters={'patient': patient.name, 'invoiced': False}
|
||||
filters={'patient': patient.name, 'company': company, 'invoiced': False}
|
||||
)
|
||||
for procedure in procedures:
|
||||
if not procedure.appointment:
|
||||
@ -203,7 +205,7 @@ def get_clinical_procedures_to_invoice(patient):
|
||||
return clinical_procedures_to_invoice
|
||||
|
||||
|
||||
def get_inpatient_services_to_invoice(patient):
|
||||
def get_inpatient_services_to_invoice(patient, company):
|
||||
services_to_invoice = []
|
||||
inpatient_services = frappe.db.sql(
|
||||
'''
|
||||
@ -213,10 +215,11 @@ def get_inpatient_services_to_invoice(patient):
|
||||
`tabInpatient Record` ip, `tabInpatient Occupancy` io
|
||||
WHERE
|
||||
ip.patient=%s
|
||||
and ip.company=%s
|
||||
and io.parent=ip.name
|
||||
and io.left=1
|
||||
and io.invoiced=0
|
||||
''', (patient.name), as_dict=1)
|
||||
''', (patient.name, company), as_dict=1)
|
||||
|
||||
for inpatient_occupancy in inpatient_services:
|
||||
service_unit_type = frappe.db.get_value('Healthcare Service Unit', inpatient_occupancy.service_unit, 'service_unit_type')
|
||||
@ -376,6 +379,7 @@ def check_fee_validity(appointment):
|
||||
|
||||
def manage_fee_validity(appointment):
|
||||
fee_validity = check_fee_validity(appointment)
|
||||
|
||||
if fee_validity:
|
||||
if appointment.status == 'Cancelled' and fee_validity.visited > 0:
|
||||
fee_validity.visited -= 1
|
||||
|
Loading…
Reference in New Issue
Block a user