Skip to content

Instantly share code, notes, and snippets.

@disp-rohin
Last active May 2, 2025 10:49
Show Gist options
  • Save disp-rohin/61fa272a0dd289731d8a5401939292e8 to your computer and use it in GitHub Desktop.
Save disp-rohin/61fa272a0dd289731d8a5401939292e8 to your computer and use it in GitHub Desktop.
import logging
import io
import base64
from typing import BinaryIO
from io import BytesIO, StringIO
from datetime import datetime
from django.core.files.base import ContentFile, File
from dispensed_management.mixins import UserOrderDetailPatientSummaryPDFMixin
from dispensed_management.models import PRESCRIPTION_DOCUMENT_PATIENT_APPROVAL_LETTER, PRESCRIPTION_DOCUMENT_PATIENT_SUMMARY_NOTES, PRESCRIPTION_DOCUMENT_VETERAN_REFERRAL, Notes, UserOrderPrescription, UserOrderPrescriptionDocument
from commons.constants import NZ_REGION
from chargebee_integration.constants import UNIT_ADDON
from chargebee_integration.product import get_plan_attached_addons
from dispensed_management.pdf_helpers import generate_dva_patient_approval_pdf, generate_referral_pdf
from document_management.document_strategy import DocumentStrategyFactory
from document_management.document_types import PrescriptionDocumentType
from document_management.managers import SaveDocumentRequest
from helpers.fill_pdf import DispensedPatientApprovalLetter, get_data_dict, fill_pdf
from django.conf import settings
from dispensed_management.tasks import (
create_save_dva_application_pdf,
create_save_letter_to_dva_document,
create_save_cssrs_application_pdf,
create_save_dass21_application_pdf,
create_save_bpi_application_pdf
)
from django.template.loader import render_to_string
from weasyprint import CSS, HTML
logger = logging.getLogger(__name__)
start_date = datetime(2025, 5, 1)
documents = UserOrderPrescriptionDocument.objects.filter(
document__icontains='pk_None',
created__gte=start_date
)
def get_quantity_by_id(item_list, target_id):
quantities = [item["quantity"] for item in item_list if item["id"] == target_id]
quantity = int(quantities[0] if quantities else 0)
unit = "unit" if target_id in UNIT_ADDON else "gram"
if quantity > 1:
unit += "s"
if target_id not in UNIT_ADDON:
quantity *= 10
return f"{quantity} {unit}"
def generate_dispensed_patient_approval_letter_pdf(user_order_prescription, date) -> BinaryIO:
user_order = user_order_prescription.user_order
user = user_order.user
profile = user.profile
doctor = (
user_order.assigned_doctor.doctor.managing_approver.approver
if (user_order.assigned_doctor.doctor.managing_approver)
else None
)
mandatory_addons = getattr(user_order_prescription, "mandatory_addons", [])
optional_addons = getattr(user_order_prescription, "optional_addons", [])
if None in (mandatory_addons, optional_addons):
return ValueError(
"Mandatory addons or optional addons of prescription cannot be None."
)
addons = mandatory_addons + optional_addons
mandatory_addon_ids = [product_addon["id"] for product_addon in mandatory_addons]
optional_addon_ids = [product_addon["id"] for product_addon in optional_addons]
all_addons = {*mandatory_addon_ids, *optional_addon_ids}
all_attached_addons = get_plan_attached_addons(
user_order_prescription.product_family_plan_id,
user_order.user.is_veteran_patient,
)
treatment_plan = []
for attached_addon in all_attached_addons:
if attached_addon.addon.id in all_addons:
quantity_description = (
get_quantity_by_id(addons, attached_addon.addon.id) + " x "
)
addon_description = ", ".join(attached_addon.addon.description.split("\n"))
treatment_plan.append(quantity_description + addon_description)
prescription = "\n".join(treatment_plan)
# creating a dataclass for pdf
base_fields = {
"patient_name": user.get_full_name(),
"patient_name2": user.get_full_name(),
"dob": profile.dob.strftime("%d/%m/%Y") if profile.dob else "",
"prescribing_date": user_order_prescription.created.strftime("%d/%m/%Y"),
"date_of_letter": date.strftime("%d/%m/%Y"),
"doctor_name": "",
"prescriber_number": "",
"prescription": prescription,
}
if settings.SERVER_REGION != NZ_REGION:
base_fields.update(
{
"doctor_name": doctor.get_full_name() if doctor else "",
"prescriber_number": (
doctor.profile.prescriber_no or ""
if doctor and doctor.profile
else ""
),
}
)
form_details = DispensedPatientApprovalLetter(**base_fields)
# converting the data into dict of pdf field name and respective value
data_dict = get_data_dict(form_details)
# filling respective pdf field with their value in given pdf
fo = io.BytesIO()
fi = io.BytesIO(doctor.profile.patient_approval_letter_pdf.read())
fill_pdf(fi, fo, data_dict)
fo.seek(0)
return fo
def create_save_dva_patient_approval_letter_pdf(uo_prescription_pk, created):
logger.info(
"Started task veteran save patient approval pdf for User Order Prescription: %s", # noqa: E501
uo_prescription_pk,
)
uo_prescription = UserOrderPrescription.objects.filter(
pk=uo_prescription_pk
).first()
if uo_prescription is None:
logger.warning("User order Prescription : %s not found.", uo_prescription)
return
pdf_file_io = (
generate_dva_patient_approval_pdf(uo_prescription)
if uo_prescription.user_order.user.is_veteran_patient
else generate_dispensed_patient_approval_letter_pdf(uo_prescription, created)
)
patient_apporval_letter_file = ContentFile(
pdf_file_io.read(),
name=f"{PRESCRIPTION_DOCUMENT_PATIENT_APPROVAL_LETTER}.pdf",
)
existing_document_management = DocumentStrategyFactory.get_strategy(
use_centralized=False
)
doc_type = PrescriptionDocumentType.PRESCRIPTION_DOCUMENT_PATIENT_APPROVAL_LETTER
request = SaveDocumentRequest(
user_order_prescription_id=uo_prescription.id,
document_type=doc_type,
document=patient_apporval_letter_file,
)
existing = existing_document_management.save_document(request=request)
document = existing
logger.info(
"Successfully created & saved patient approval for User Order Prescription : %s.", # noqa: E501
uo_prescription_pk,
)
return document.document.url
def save_send_veteran_referral_pdf(uo_prescription_pk): # noqa
logger.info(
"Started task veteran referral template for User Order Prescription : %s",
uo_prescription_pk,
)
uo_prescription = UserOrderPrescription.objects.filter(
pk=uo_prescription_pk
).first()
if uo_prescription is None:
logger.warning("User order Prescription : %s not found.", uo_prescription)
return
user_order = uo_prescription.user_order
referral_file = generate_referral_pdf(user_order)
context = {
"object": user_order,
"patient_note": Notes.get_note(user_order.user),
**UserOrderDetailPatientSummaryPDFMixin.get_summary_context(user_order),
}
html = render_to_string(
"dispensed_management/user_order_detail_patient_summary_pdf.html",
context=context,
)
patient_summary_notes_file = BytesIO()
css = CSS(string=""" @page { size: 315mm 2000mm; } """)
HTML(string=html, base_url=settings.SITE_URL).write_pdf(
patient_summary_notes_file, presentational_hints=True, stylesheets=[css]
)
patient_summary_notes_file.seek(0)
referral_file_content = base64.b64encode(referral_file.read()).decode()
patient_summary_notes_file_content = base64.b64encode(
patient_summary_notes_file.read()
).decode()
referral_file.seek(0)
patient_summary_notes_file.seek(0)
existing_document_management = DocumentStrategyFactory.get_strategy(
use_centralized=False
)
# ---------- referral-file ----------
content_file = ContentFile(
referral_file.read(), name=f"{PRESCRIPTION_DOCUMENT_VETERAN_REFERRAL}.pdf"
)
document_request = SaveDocumentRequest(
user_order_prescription_id=uo_prescription.id,
document_type=PrescriptionDocumentType.PRESCRIPTION_DOCUMENT_VETERAN_REFERRAL,
document=content_file,
)
existing_document_management.save_document(request=document_request)
# ---------- patient-summary-notes-file ----------
content_file = ContentFile(
patient_summary_notes_file.read(),
name=f"{PRESCRIPTION_DOCUMENT_PATIENT_SUMMARY_NOTES}.pdf",
)
doc_type = PrescriptionDocumentType.PRESCRIPTION_DOCUMENT_PATIENT_SUMMARY_NOTES
request = SaveDocumentRequest(
user_order_prescription_id=uo_prescription.id,
document_type=doc_type,
name=f"{PRESCRIPTION_DOCUMENT_PATIENT_SUMMARY_NOTES}.pdf",
document=content_file,
)
existing_document_management.save_document(request=request)
logger.info(
"Successfully sent referral email for User Order : %s.", uo_prescription_pk
)
def create_new_pdfs(uo_prescription_pk, created_date=None, document_type=None):
if not document_type:
return
function_map = {
'VETERAN_REFERRAL': lambda: save_send_veteran_referral_pdf(uo_prescription_pk),
'DVA_APPLICATION': lambda: create_save_dva_application_pdf(uo_prescription_pk),
'LETTER_TO_DVA': lambda: create_save_letter_to_dva_document(uo_prescription_pk),
'CSSRS': lambda: create_save_cssrs_application_pdf(uo_prescription_pk),
'DASS21': lambda: create_save_dass21_application_pdf(uo_prescription_pk),
'BPI': lambda: create_save_bpi_application_pdf(uo_prescription_pk),
'PATIENT_APPROVAL_LETTER': lambda: create_save_dva_patient_approval_letter_pdf(uo_prescription_pk, created_date),
}
func = function_map.get(document_type)
if func:
func()
else:
print(f"No matching function for document type: {document_type}")
for document in documents:
create_new_pdfs(document.user_order_prescription.pk, document.created, document.document_type)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment