1493 lines
55 KiB
Python
1493 lines
55 KiB
Python
# Generated by Django 5.2.4 on 2025-08-04 04:41
|
|
|
|
import django.core.validators
|
|
import django.db.models.deletion
|
|
import django.utils.timezone
|
|
import uuid
|
|
from decimal import Decimal
|
|
from django.conf import settings
|
|
from django.db import migrations, models
|
|
|
|
|
|
class Migration(migrations.Migration):
|
|
|
|
initial = True
|
|
|
|
dependencies = [
|
|
("core", "0001_initial"),
|
|
("emr", "0001_initial"),
|
|
("patients", "0001_initial"),
|
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
]
|
|
|
|
operations = [
|
|
migrations.CreateModel(
|
|
name="Medication",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"medication_id",
|
|
models.UUIDField(
|
|
default=uuid.uuid4,
|
|
editable=False,
|
|
help_text="Unique medication identifier",
|
|
unique=True,
|
|
),
|
|
),
|
|
(
|
|
"generic_name",
|
|
models.CharField(help_text="Generic drug name", max_length=200),
|
|
),
|
|
(
|
|
"brand_name",
|
|
models.CharField(
|
|
blank=True,
|
|
help_text="Brand/trade name",
|
|
max_length=200,
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"ndc_number",
|
|
models.CharField(
|
|
blank=True,
|
|
help_text="National Drug Code (NDC) number",
|
|
max_length=20,
|
|
null=True,
|
|
validators=[
|
|
django.core.validators.RegexValidator(
|
|
"^\\d{4,5}-\\d{3,4}-\\d{1,2}$"
|
|
)
|
|
],
|
|
),
|
|
),
|
|
(
|
|
"rxcui",
|
|
models.CharField(
|
|
blank=True,
|
|
help_text="RxNorm Concept Unique Identifier",
|
|
max_length=20,
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"drug_class",
|
|
models.CharField(
|
|
help_text="Therapeutic drug class", max_length=100
|
|
),
|
|
),
|
|
(
|
|
"controlled_substance_schedule",
|
|
models.CharField(
|
|
choices=[
|
|
("CI", "Schedule I"),
|
|
("CII", "Schedule II"),
|
|
("CIII", "Schedule III"),
|
|
("CIV", "Schedule IV"),
|
|
("CV", "Schedule V"),
|
|
("NON", "Non-Controlled"),
|
|
],
|
|
default="NON",
|
|
help_text="DEA controlled substance schedule",
|
|
max_length=5,
|
|
),
|
|
),
|
|
(
|
|
"dosage_form",
|
|
models.CharField(
|
|
choices=[
|
|
("TABLET", "Tablet"),
|
|
("CAPSULE", "Capsule"),
|
|
("LIQUID", "Liquid"),
|
|
("INJECTION", "Injection"),
|
|
("TOPICAL", "Topical"),
|
|
("INHALER", "Inhaler"),
|
|
("PATCH", "Patch"),
|
|
("SUPPOSITORY", "Suppository"),
|
|
("CREAM", "Cream"),
|
|
("OINTMENT", "Ointment"),
|
|
("DROPS", "Drops"),
|
|
("SPRAY", "Spray"),
|
|
("OTHER", "Other"),
|
|
],
|
|
help_text="Dosage form",
|
|
max_length=50,
|
|
),
|
|
),
|
|
(
|
|
"strength",
|
|
models.CharField(
|
|
help_text="Drug strength (e.g., 500mg, 10mg/ml)", max_length=50
|
|
),
|
|
),
|
|
(
|
|
"unit_of_measure",
|
|
models.CharField(
|
|
choices=[
|
|
("MG", "Milligrams"),
|
|
("G", "Grams"),
|
|
("MCG", "Micrograms"),
|
|
("ML", "Milliliters"),
|
|
("L", "Liters"),
|
|
("UNITS", "Units"),
|
|
("IU", "International Units"),
|
|
("MEQ", "Milliequivalents"),
|
|
("PERCENT", "Percent"),
|
|
("OTHER", "Other"),
|
|
],
|
|
help_text="Unit of measure",
|
|
max_length=20,
|
|
),
|
|
),
|
|
("indications", models.TextField(help_text="Clinical indications")),
|
|
(
|
|
"contraindications",
|
|
models.TextField(
|
|
blank=True, help_text="Contraindications", null=True
|
|
),
|
|
),
|
|
(
|
|
"side_effects",
|
|
models.TextField(
|
|
blank=True, help_text="Common side effects", null=True
|
|
),
|
|
),
|
|
(
|
|
"warnings",
|
|
models.TextField(
|
|
blank=True, help_text="Warnings and precautions", null=True
|
|
),
|
|
),
|
|
(
|
|
"adult_dose_range",
|
|
models.CharField(
|
|
blank=True,
|
|
help_text="Adult dosing range",
|
|
max_length=100,
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"pediatric_dose_range",
|
|
models.CharField(
|
|
blank=True,
|
|
help_text="Pediatric dosing range",
|
|
max_length=100,
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"max_daily_dose",
|
|
models.CharField(
|
|
blank=True,
|
|
help_text="Maximum daily dose",
|
|
max_length=50,
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"routes_of_administration",
|
|
models.JSONField(
|
|
default=list, help_text="Routes of administration"
|
|
),
|
|
),
|
|
(
|
|
"administration_instructions",
|
|
models.TextField(
|
|
blank=True, help_text="Administration instructions", null=True
|
|
),
|
|
),
|
|
(
|
|
"storage_requirements",
|
|
models.CharField(
|
|
blank=True,
|
|
help_text="Storage requirements",
|
|
max_length=100,
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"special_handling",
|
|
models.TextField(
|
|
blank=True, help_text="Special handling requirements", null=True
|
|
),
|
|
),
|
|
(
|
|
"formulary_status",
|
|
models.CharField(
|
|
choices=[
|
|
("PREFERRED", "Preferred"),
|
|
("NON_PREFERRED", "Non-Preferred"),
|
|
("RESTRICTED", "Restricted"),
|
|
("NOT_COVERED", "Not Covered"),
|
|
("PRIOR_AUTH", "Prior Authorization Required"),
|
|
],
|
|
default="PREFERRED",
|
|
help_text="Formulary status",
|
|
max_length=20,
|
|
),
|
|
),
|
|
(
|
|
"is_active",
|
|
models.BooleanField(
|
|
default=True, help_text="Medication is active and available"
|
|
),
|
|
),
|
|
(
|
|
"is_available",
|
|
models.BooleanField(
|
|
default=True, help_text="Currently available in inventory"
|
|
),
|
|
),
|
|
(
|
|
"unit_cost",
|
|
models.DecimalField(
|
|
blank=True,
|
|
decimal_places=2,
|
|
help_text="Cost per unit",
|
|
max_digits=10,
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"awp",
|
|
models.DecimalField(
|
|
blank=True,
|
|
decimal_places=2,
|
|
help_text="Average Wholesale Price",
|
|
max_digits=10,
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"manufacturer",
|
|
models.CharField(
|
|
blank=True,
|
|
help_text="Manufacturer name",
|
|
max_length=100,
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"manufacturer_ndc",
|
|
models.CharField(
|
|
blank=True,
|
|
help_text="Manufacturer NDC",
|
|
max_length=20,
|
|
null=True,
|
|
),
|
|
),
|
|
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
("updated_at", models.DateTimeField(auto_now=True)),
|
|
(
|
|
"created_by",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
help_text="User who created the medication record",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="created_medications",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
(
|
|
"tenant",
|
|
models.ForeignKey(
|
|
help_text="Organization tenant",
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="medications",
|
|
to="core.tenant",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Medication",
|
|
"verbose_name_plural": "Medications",
|
|
"db_table": "pharmacy_medication",
|
|
"ordering": ["generic_name"],
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="InventoryItem",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"inventory_id",
|
|
models.UUIDField(
|
|
default=uuid.uuid4,
|
|
editable=False,
|
|
help_text="Unique inventory identifier",
|
|
unique=True,
|
|
),
|
|
),
|
|
(
|
|
"lot_number",
|
|
models.CharField(help_text="Lot/batch number", max_length=50),
|
|
),
|
|
("expiration_date", models.DateField(help_text="Expiration date")),
|
|
(
|
|
"quantity_on_hand",
|
|
models.PositiveIntegerField(
|
|
default=0, help_text="Current quantity on hand"
|
|
),
|
|
),
|
|
(
|
|
"quantity_allocated",
|
|
models.PositiveIntegerField(
|
|
default=0, help_text="Quantity allocated for pending orders"
|
|
),
|
|
),
|
|
(
|
|
"quantity_available",
|
|
models.PositiveIntegerField(
|
|
default=0, help_text="Available quantity (on hand - allocated)"
|
|
),
|
|
),
|
|
(
|
|
"reorder_point",
|
|
models.PositiveIntegerField(default=10, help_text="Reorder point"),
|
|
),
|
|
(
|
|
"reorder_quantity",
|
|
models.PositiveIntegerField(
|
|
default=100, help_text="Reorder quantity"
|
|
),
|
|
),
|
|
(
|
|
"storage_location",
|
|
models.CharField(
|
|
help_text="Storage location (e.g., Shelf A1, Refrigerator 2)",
|
|
max_length=50,
|
|
),
|
|
),
|
|
(
|
|
"bin_location",
|
|
models.CharField(
|
|
blank=True,
|
|
help_text="Specific bin location",
|
|
max_length=20,
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"unit_cost",
|
|
models.DecimalField(
|
|
decimal_places=2, help_text="Cost per unit", max_digits=10
|
|
),
|
|
),
|
|
(
|
|
"total_cost",
|
|
models.DecimalField(
|
|
decimal_places=2,
|
|
help_text="Total cost of inventory",
|
|
max_digits=12,
|
|
),
|
|
),
|
|
(
|
|
"supplier",
|
|
models.CharField(help_text="Supplier name", max_length=100),
|
|
),
|
|
(
|
|
"purchase_order_number",
|
|
models.CharField(
|
|
blank=True,
|
|
help_text="Purchase order number",
|
|
max_length=50,
|
|
null=True,
|
|
),
|
|
),
|
|
("received_date", models.DateField(help_text="Date received")),
|
|
(
|
|
"last_counted",
|
|
models.DateField(
|
|
blank=True, help_text="Last physical count date", null=True
|
|
),
|
|
),
|
|
(
|
|
"status",
|
|
models.CharField(
|
|
choices=[
|
|
("ACTIVE", "Active"),
|
|
("QUARANTINE", "Quarantine"),
|
|
("EXPIRED", "Expired"),
|
|
("RECALLED", "Recalled"),
|
|
("DAMAGED", "Damaged"),
|
|
("RETURNED", "Returned"),
|
|
],
|
|
default="ACTIVE",
|
|
help_text="Inventory status",
|
|
max_length=20,
|
|
),
|
|
),
|
|
(
|
|
"quality_checked",
|
|
models.BooleanField(
|
|
default=False, help_text="Quality check completed"
|
|
),
|
|
),
|
|
(
|
|
"quality_check_date",
|
|
models.DateField(
|
|
blank=True, help_text="Quality check date", null=True
|
|
),
|
|
),
|
|
(
|
|
"quality_notes",
|
|
models.TextField(
|
|
blank=True, help_text="Quality control notes", null=True
|
|
),
|
|
),
|
|
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
("updated_at", models.DateTimeField(auto_now=True)),
|
|
(
|
|
"created_by",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
help_text="User who created the inventory item",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="created_pharmacy_inventory_items",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
(
|
|
"tenant",
|
|
models.ForeignKey(
|
|
help_text="Organization tenant",
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="pharmacy_inventory",
|
|
to="core.tenant",
|
|
),
|
|
),
|
|
(
|
|
"medication",
|
|
models.ForeignKey(
|
|
help_text="Medication",
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="inventory_items",
|
|
to="pharmacy.medication",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Inventory Item",
|
|
"verbose_name_plural": "Inventory Items",
|
|
"db_table": "pharmacy_inventory_item",
|
|
"ordering": ["medication__generic_name", "expiration_date"],
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="DrugInteraction",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"interaction_id",
|
|
models.UUIDField(
|
|
default=uuid.uuid4,
|
|
editable=False,
|
|
help_text="Unique interaction identifier",
|
|
unique=True,
|
|
),
|
|
),
|
|
(
|
|
"severity",
|
|
models.CharField(
|
|
choices=[
|
|
("MINOR", "Minor"),
|
|
("MODERATE", "Moderate"),
|
|
("MAJOR", "Major"),
|
|
("CONTRAINDICATED", "Contraindicated"),
|
|
],
|
|
help_text="Interaction severity",
|
|
max_length=20,
|
|
),
|
|
),
|
|
(
|
|
"interaction_type",
|
|
models.CharField(
|
|
choices=[
|
|
("PHARMACOKINETIC", "Pharmacokinetic"),
|
|
("PHARMACODYNAMIC", "Pharmacodynamic"),
|
|
("ADDITIVE", "Additive"),
|
|
("SYNERGISTIC", "Synergistic"),
|
|
("ANTAGONISTIC", "Antagonistic"),
|
|
("OTHER", "Other"),
|
|
],
|
|
help_text="Type of interaction",
|
|
max_length=30,
|
|
),
|
|
),
|
|
("mechanism", models.TextField(help_text="Mechanism of interaction")),
|
|
(
|
|
"clinical_effect",
|
|
models.TextField(help_text="Clinical effect of interaction"),
|
|
),
|
|
(
|
|
"management_recommendations",
|
|
models.TextField(help_text="Management recommendations"),
|
|
),
|
|
(
|
|
"monitoring_parameters",
|
|
models.TextField(
|
|
blank=True, help_text="Parameters to monitor", null=True
|
|
),
|
|
),
|
|
(
|
|
"evidence_level",
|
|
models.CharField(
|
|
choices=[
|
|
("ESTABLISHED", "Established"),
|
|
("PROBABLE", "Probable"),
|
|
("SUSPECTED", "Suspected"),
|
|
("POSSIBLE", "Possible"),
|
|
("UNLIKELY", "Unlikely"),
|
|
],
|
|
help_text="Level of evidence",
|
|
max_length=20,
|
|
),
|
|
),
|
|
(
|
|
"references",
|
|
models.TextField(
|
|
blank=True, help_text="Literature references", null=True
|
|
),
|
|
),
|
|
(
|
|
"is_active",
|
|
models.BooleanField(
|
|
default=True, help_text="Interaction is active"
|
|
),
|
|
),
|
|
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
("updated_at", models.DateTimeField(auto_now=True)),
|
|
(
|
|
"created_by",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
help_text="User who created the interaction record",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="created_drug_interactions",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
(
|
|
"tenant",
|
|
models.ForeignKey(
|
|
help_text="Organization tenant",
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="drug_interactions",
|
|
to="core.tenant",
|
|
),
|
|
),
|
|
(
|
|
"medication_1",
|
|
models.ForeignKey(
|
|
help_text="First medication",
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="interactions_as_drug1",
|
|
to="pharmacy.medication",
|
|
),
|
|
),
|
|
(
|
|
"medication_2",
|
|
models.ForeignKey(
|
|
help_text="Second medication",
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="interactions_as_drug2",
|
|
to="pharmacy.medication",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Drug Interaction",
|
|
"verbose_name_plural": "Drug Interactions",
|
|
"db_table": "pharmacy_drug_interaction",
|
|
"ordering": ["-severity", "medication_1__generic_name"],
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="Prescription",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"prescription_id",
|
|
models.UUIDField(
|
|
default=uuid.uuid4,
|
|
editable=False,
|
|
help_text="Unique prescription identifier",
|
|
unique=True,
|
|
),
|
|
),
|
|
(
|
|
"prescription_number",
|
|
models.CharField(
|
|
help_text="Prescription number", max_length=20, unique=True
|
|
),
|
|
),
|
|
(
|
|
"quantity_prescribed",
|
|
models.PositiveIntegerField(help_text="Quantity prescribed"),
|
|
),
|
|
(
|
|
"quantity_unit",
|
|
models.CharField(
|
|
choices=[
|
|
("TABLETS", "Tablets"),
|
|
("CAPSULES", "Capsules"),
|
|
("ML", "Milliliters"),
|
|
("GRAMS", "Grams"),
|
|
("UNITS", "Units"),
|
|
("PATCHES", "Patches"),
|
|
("INHALERS", "Inhalers"),
|
|
("BOTTLES", "Bottles"),
|
|
("TUBES", "Tubes"),
|
|
("VIALS", "Vials"),
|
|
("OTHER", "Other"),
|
|
],
|
|
help_text="Unit of quantity",
|
|
max_length=20,
|
|
),
|
|
),
|
|
(
|
|
"dosage_instructions",
|
|
models.TextField(help_text="Dosing instructions (SIG)"),
|
|
),
|
|
(
|
|
"frequency",
|
|
models.CharField(
|
|
help_text="Frequency of administration", max_length=50
|
|
),
|
|
),
|
|
(
|
|
"duration",
|
|
models.CharField(
|
|
blank=True,
|
|
help_text="Duration of therapy",
|
|
max_length=50,
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"refills_authorized",
|
|
models.PositiveIntegerField(
|
|
default=0, help_text="Number of refills authorized"
|
|
),
|
|
),
|
|
(
|
|
"refills_remaining",
|
|
models.PositiveIntegerField(
|
|
default=0, help_text="Number of refills remaining"
|
|
),
|
|
),
|
|
(
|
|
"date_prescribed",
|
|
models.DateTimeField(
|
|
default=django.utils.timezone.now,
|
|
help_text="Date and time prescribed",
|
|
),
|
|
),
|
|
(
|
|
"date_written",
|
|
models.DateField(help_text="Date written on prescription"),
|
|
),
|
|
(
|
|
"expiration_date",
|
|
models.DateField(
|
|
blank=True, help_text="Prescription expiration date", null=True
|
|
),
|
|
),
|
|
(
|
|
"status",
|
|
models.CharField(
|
|
choices=[
|
|
("PENDING", "Pending"),
|
|
("ACTIVE", "Active"),
|
|
("DISPENSED", "Dispensed"),
|
|
("PARTIALLY_DISPENSED", "Partially Dispensed"),
|
|
("COMPLETED", "Completed"),
|
|
("CANCELLED", "Cancelled"),
|
|
("EXPIRED", "Expired"),
|
|
("ON_HOLD", "On Hold"),
|
|
("TRANSFERRED", "Transferred"),
|
|
],
|
|
default="PENDING",
|
|
help_text="Prescription status",
|
|
max_length=20,
|
|
),
|
|
),
|
|
(
|
|
"indication",
|
|
models.CharField(
|
|
blank=True,
|
|
help_text="Indication for prescription",
|
|
max_length=200,
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"diagnosis_code",
|
|
models.CharField(
|
|
blank=True,
|
|
help_text="ICD-10 diagnosis code",
|
|
max_length=20,
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"pharmacy_notes",
|
|
models.TextField(
|
|
blank=True, help_text="Notes for pharmacy", null=True
|
|
),
|
|
),
|
|
(
|
|
"patient_instructions",
|
|
models.TextField(
|
|
blank=True, help_text="Patient instructions", null=True
|
|
),
|
|
),
|
|
(
|
|
"prior_authorization_required",
|
|
models.BooleanField(
|
|
default=False, help_text="Prior authorization required"
|
|
),
|
|
),
|
|
(
|
|
"prior_authorization_number",
|
|
models.CharField(
|
|
blank=True,
|
|
help_text="Prior authorization number",
|
|
max_length=50,
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"prior_authorization_expiry",
|
|
models.DateField(
|
|
blank=True,
|
|
help_text="Prior authorization expiry date",
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"generic_substitution_allowed",
|
|
models.BooleanField(
|
|
default=True, help_text="Generic substitution allowed"
|
|
),
|
|
),
|
|
(
|
|
"dispense_as_written",
|
|
models.BooleanField(
|
|
default=False, help_text="Dispense as written (DAW)"
|
|
),
|
|
),
|
|
(
|
|
"electronic_prescription",
|
|
models.BooleanField(
|
|
default=True, help_text="Electronic prescription"
|
|
),
|
|
),
|
|
(
|
|
"e_prescription_id",
|
|
models.CharField(
|
|
blank=True,
|
|
help_text="Electronic prescription ID",
|
|
max_length=50,
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"verified",
|
|
models.BooleanField(
|
|
default=False, help_text="Prescription has been verified"
|
|
),
|
|
),
|
|
(
|
|
"verified_datetime",
|
|
models.DateTimeField(
|
|
blank=True, help_text="Date and time of verification", null=True
|
|
),
|
|
),
|
|
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
("updated_at", models.DateTimeField(auto_now=True)),
|
|
(
|
|
"encounter",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
help_text="Related encounter",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="prescriptions",
|
|
to="emr.encounter",
|
|
),
|
|
),
|
|
(
|
|
"medication",
|
|
models.ForeignKey(
|
|
help_text="Prescribed medication",
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="prescriptions",
|
|
to="pharmacy.medication",
|
|
),
|
|
),
|
|
(
|
|
"patient",
|
|
models.ForeignKey(
|
|
help_text="Patient",
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="prescriptions",
|
|
to="patients.patientprofile",
|
|
),
|
|
),
|
|
(
|
|
"prescriber",
|
|
models.ForeignKey(
|
|
help_text="Prescribing provider",
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="prescribed_medications",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
(
|
|
"tenant",
|
|
models.ForeignKey(
|
|
help_text="Organization tenant",
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="prescriptions",
|
|
to="core.tenant",
|
|
),
|
|
),
|
|
(
|
|
"verified_by",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
help_text="Pharmacist who verified prescription",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="verified_prescriptions",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Prescription",
|
|
"verbose_name_plural": "Prescriptions",
|
|
"db_table": "pharmacy_prescription",
|
|
"ordering": ["-date_prescribed"],
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="MedicationAdministration",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"administration_id",
|
|
models.UUIDField(
|
|
default=uuid.uuid4,
|
|
editable=False,
|
|
help_text="Unique administration identifier",
|
|
unique=True,
|
|
),
|
|
),
|
|
(
|
|
"scheduled_datetime",
|
|
models.DateTimeField(help_text="Scheduled administration time"),
|
|
),
|
|
(
|
|
"actual_datetime",
|
|
models.DateTimeField(
|
|
blank=True, help_text="Actual administration time", null=True
|
|
),
|
|
),
|
|
("dose_given", models.CharField(help_text="Dose given", max_length=50)),
|
|
(
|
|
"route_given",
|
|
models.CharField(
|
|
choices=[
|
|
("PO", "Oral"),
|
|
("IV", "Intravenous"),
|
|
("IM", "Intramuscular"),
|
|
("SC", "Subcutaneous"),
|
|
("SL", "Sublingual"),
|
|
("TOP", "Topical"),
|
|
("INH", "Inhalation"),
|
|
("PR", "Rectal"),
|
|
("PV", "Vaginal"),
|
|
("NASAL", "Nasal"),
|
|
("OPTH", "Ophthalmic"),
|
|
("OTIC", "Otic"),
|
|
("OTHER", "Other"),
|
|
],
|
|
help_text="Route of administration",
|
|
max_length=30,
|
|
),
|
|
),
|
|
(
|
|
"status",
|
|
models.CharField(
|
|
choices=[
|
|
("SCHEDULED", "Scheduled"),
|
|
("GIVEN", "Given"),
|
|
("NOT_GIVEN", "Not Given"),
|
|
("HELD", "Held"),
|
|
("REFUSED", "Refused"),
|
|
("OMITTED", "Omitted"),
|
|
],
|
|
default="SCHEDULED",
|
|
help_text="Administration status",
|
|
max_length=20,
|
|
),
|
|
),
|
|
(
|
|
"reason_not_given",
|
|
models.CharField(
|
|
blank=True,
|
|
choices=[
|
|
("PATIENT_REFUSED", "Patient Refused"),
|
|
("PATIENT_UNAVAILABLE", "Patient Unavailable"),
|
|
("MEDICATION_UNAVAILABLE", "Medication Unavailable"),
|
|
("HELD_BY_PROVIDER", "Held by Provider"),
|
|
("PATIENT_NPO", "Patient NPO"),
|
|
("PATIENT_ASLEEP", "Patient Asleep"),
|
|
("ADVERSE_REACTION", "Adverse Reaction"),
|
|
("OTHER", "Other"),
|
|
],
|
|
help_text="Reason medication was not given",
|
|
max_length=100,
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"reason_notes",
|
|
models.TextField(
|
|
blank=True, help_text="Additional notes about reason", null=True
|
|
),
|
|
),
|
|
(
|
|
"patient_response",
|
|
models.TextField(
|
|
blank=True,
|
|
help_text="Patient response to medication",
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"side_effects_observed",
|
|
models.TextField(
|
|
blank=True, help_text="Side effects observed", null=True
|
|
),
|
|
),
|
|
(
|
|
"injection_site",
|
|
models.CharField(
|
|
blank=True, help_text="Injection site", max_length=50, null=True
|
|
),
|
|
),
|
|
(
|
|
"site_condition",
|
|
models.CharField(
|
|
blank=True,
|
|
help_text="Condition of injection site",
|
|
max_length=100,
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"double_checked",
|
|
models.BooleanField(
|
|
default=False, help_text="Medication was double-checked"
|
|
),
|
|
),
|
|
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
("updated_at", models.DateTimeField(auto_now=True)),
|
|
(
|
|
"administered_by",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
help_text="Nurse who administered medication",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="administered_medications",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
(
|
|
"double_checked_by",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
help_text="Second nurse who verified medication",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="double_checked_administrations",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
(
|
|
"encounter",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
help_text="Related encounter",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="medication_administrations",
|
|
to="emr.encounter",
|
|
),
|
|
),
|
|
(
|
|
"patient",
|
|
models.ForeignKey(
|
|
help_text="Patient",
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="medication_administrations",
|
|
to="patients.patientprofile",
|
|
),
|
|
),
|
|
(
|
|
"witnessed_by",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
help_text="Witness (for controlled substances)",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="witnessed_administrations",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
(
|
|
"prescription",
|
|
models.ForeignKey(
|
|
help_text="Related prescription",
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="administration_records",
|
|
to="pharmacy.prescription",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Medication Administration",
|
|
"verbose_name_plural": "Medication Administrations",
|
|
"db_table": "pharmacy_medication_administration",
|
|
"ordering": ["-scheduled_datetime"],
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="DispenseRecord",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"dispense_id",
|
|
models.UUIDField(
|
|
default=uuid.uuid4,
|
|
editable=False,
|
|
help_text="Unique dispense identifier",
|
|
unique=True,
|
|
),
|
|
),
|
|
(
|
|
"quantity_dispensed",
|
|
models.PositiveIntegerField(help_text="Quantity dispensed"),
|
|
),
|
|
(
|
|
"quantity_remaining",
|
|
models.PositiveIntegerField(
|
|
help_text="Quantity remaining on prescription"
|
|
),
|
|
),
|
|
(
|
|
"date_dispensed",
|
|
models.DateTimeField(
|
|
default=django.utils.timezone.now,
|
|
help_text="Date and time dispensed",
|
|
),
|
|
),
|
|
(
|
|
"unit_price",
|
|
models.DecimalField(
|
|
decimal_places=2, help_text="Price per unit", max_digits=10
|
|
),
|
|
),
|
|
(
|
|
"total_price",
|
|
models.DecimalField(
|
|
decimal_places=2, help_text="Total price", max_digits=10
|
|
),
|
|
),
|
|
(
|
|
"copay_amount",
|
|
models.DecimalField(
|
|
decimal_places=2,
|
|
default=Decimal("0.00"),
|
|
help_text="Patient copay amount",
|
|
max_digits=8,
|
|
),
|
|
),
|
|
(
|
|
"insurance_amount",
|
|
models.DecimalField(
|
|
decimal_places=2,
|
|
default=Decimal("0.00"),
|
|
help_text="Insurance payment amount",
|
|
max_digits=10,
|
|
),
|
|
),
|
|
(
|
|
"patient_counseled",
|
|
models.BooleanField(
|
|
default=False, help_text="Patient was counseled"
|
|
),
|
|
),
|
|
(
|
|
"counseling_notes",
|
|
models.TextField(
|
|
blank=True, help_text="Counseling notes", null=True
|
|
),
|
|
),
|
|
(
|
|
"is_refill",
|
|
models.BooleanField(default=False, help_text="This is a refill"),
|
|
),
|
|
(
|
|
"refill_number",
|
|
models.PositiveIntegerField(default=0, help_text="Refill number"),
|
|
),
|
|
(
|
|
"status",
|
|
models.CharField(
|
|
choices=[
|
|
("DISPENSED", "Dispensed"),
|
|
("PICKED_UP", "Picked Up"),
|
|
("RETURNED", "Returned"),
|
|
("CANCELLED", "Cancelled"),
|
|
],
|
|
default="DISPENSED",
|
|
help_text="Dispense status",
|
|
max_length=20,
|
|
),
|
|
),
|
|
(
|
|
"picked_up_by",
|
|
models.CharField(
|
|
blank=True,
|
|
help_text="Person who picked up medication",
|
|
max_length=100,
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"pickup_datetime",
|
|
models.DateTimeField(
|
|
blank=True, help_text="Date and time of pickup", null=True
|
|
),
|
|
),
|
|
(
|
|
"identification_verified",
|
|
models.BooleanField(
|
|
default=False, help_text="Identification was verified"
|
|
),
|
|
),
|
|
(
|
|
"quality_check_performed",
|
|
models.BooleanField(
|
|
default=False, help_text="Quality check performed"
|
|
),
|
|
),
|
|
(
|
|
"quality_notes",
|
|
models.TextField(
|
|
blank=True, help_text="Quality control notes", null=True
|
|
),
|
|
),
|
|
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
("updated_at", models.DateTimeField(auto_now=True)),
|
|
(
|
|
"dispensed_by",
|
|
models.ForeignKey(
|
|
help_text="Pharmacist who dispensed medication",
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="dispensed_medications",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
(
|
|
"verified_by",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
help_text="Pharmacist who verified dispense",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="verified_dispenses",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
(
|
|
"inventory_item",
|
|
models.ForeignKey(
|
|
help_text="Inventory item dispensed",
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="dispense_records",
|
|
to="pharmacy.inventoryitem",
|
|
),
|
|
),
|
|
(
|
|
"prescription",
|
|
models.ForeignKey(
|
|
help_text="Related prescription",
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="dispense_records",
|
|
to="pharmacy.prescription",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Dispense Record",
|
|
"verbose_name_plural": "Dispense Records",
|
|
"db_table": "pharmacy_dispense_record",
|
|
"ordering": ["-date_dispensed"],
|
|
},
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="medication",
|
|
index=models.Index(
|
|
fields=["tenant", "is_active"], name="pharmacy_me_tenant__08e3c1_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="medication",
|
|
index=models.Index(
|
|
fields=["generic_name"], name="pharmacy_me_generic_3b0dc0_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="medication",
|
|
index=models.Index(
|
|
fields=["brand_name"], name="pharmacy_me_brand_n_3f2779_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="medication",
|
|
index=models.Index(
|
|
fields=["ndc_number"], name="pharmacy_me_ndc_num_343d8b_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="medication",
|
|
index=models.Index(
|
|
fields=["drug_class"], name="pharmacy_me_drug_cl_7c76ce_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="medication",
|
|
index=models.Index(
|
|
fields=["controlled_substance_schedule"],
|
|
name="pharmacy_me_control_c65611_idx",
|
|
),
|
|
),
|
|
migrations.AlterUniqueTogether(
|
|
name="medication",
|
|
unique_together={("tenant", "ndc_number")},
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="inventoryitem",
|
|
index=models.Index(
|
|
fields=["tenant", "status"], name="pharmacy_in_tenant__8468e7_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="inventoryitem",
|
|
index=models.Index(
|
|
fields=["medication"], name="pharmacy_in_medicat_9e022d_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="inventoryitem",
|
|
index=models.Index(
|
|
fields=["lot_number"], name="pharmacy_in_lot_num_b5daf2_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="inventoryitem",
|
|
index=models.Index(
|
|
fields=["expiration_date"], name="pharmacy_in_expirat_b05426_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="inventoryitem",
|
|
index=models.Index(
|
|
fields=["storage_location"], name="pharmacy_in_storage_e75bb7_idx"
|
|
),
|
|
),
|
|
migrations.AlterUniqueTogether(
|
|
name="inventoryitem",
|
|
unique_together={("tenant", "medication", "lot_number")},
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="druginteraction",
|
|
index=models.Index(
|
|
fields=["tenant", "is_active"], name="pharmacy_dr_tenant__cb2d7c_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="druginteraction",
|
|
index=models.Index(
|
|
fields=["medication_1"], name="pharmacy_dr_medicat_86d0e2_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="druginteraction",
|
|
index=models.Index(
|
|
fields=["medication_2"], name="pharmacy_dr_medicat_3f8756_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="druginteraction",
|
|
index=models.Index(
|
|
fields=["severity"], name="pharmacy_dr_severit_d33361_idx"
|
|
),
|
|
),
|
|
migrations.AlterUniqueTogether(
|
|
name="druginteraction",
|
|
unique_together={("tenant", "medication_1", "medication_2")},
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="prescription",
|
|
index=models.Index(
|
|
fields=["tenant", "status"], name="pharmacy_pr_tenant__f16ec5_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="prescription",
|
|
index=models.Index(
|
|
fields=["patient", "status"], name="pharmacy_pr_patient_903ab2_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="prescription",
|
|
index=models.Index(
|
|
fields=["prescriber"], name="pharmacy_pr_prescri_2939ae_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="prescription",
|
|
index=models.Index(
|
|
fields=["medication"], name="pharmacy_pr_medicat_581fe2_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="prescription",
|
|
index=models.Index(
|
|
fields=["date_prescribed"], name="pharmacy_pr_date_pr_76ae06_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="prescription",
|
|
index=models.Index(
|
|
fields=["prescription_number"], name="pharmacy_pr_prescri_2aaaee_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="medicationadministration",
|
|
index=models.Index(
|
|
fields=["patient", "scheduled_datetime"],
|
|
name="pharmacy_me_patient_371cb8_idx",
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="medicationadministration",
|
|
index=models.Index(
|
|
fields=["prescription"], name="pharmacy_me_prescri_0695c7_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="medicationadministration",
|
|
index=models.Index(
|
|
fields=["encounter"], name="pharmacy_me_encount_17463a_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="medicationadministration",
|
|
index=models.Index(fields=["status"], name="pharmacy_me_status_4ebdaa_idx"),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="medicationadministration",
|
|
index=models.Index(
|
|
fields=["administered_by"], name="pharmacy_me_adminis_838104_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="dispenserecord",
|
|
index=models.Index(
|
|
fields=["prescription"], name="pharmacy_di_prescri_ba15b2_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="dispenserecord",
|
|
index=models.Index(
|
|
fields=["inventory_item"], name="pharmacy_di_invento_540227_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="dispenserecord",
|
|
index=models.Index(
|
|
fields=["date_dispensed"], name="pharmacy_di_date_di_c7bf71_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="dispenserecord",
|
|
index=models.Index(
|
|
fields=["dispensed_by"], name="pharmacy_di_dispens_626f46_idx"
|
|
),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name="dispenserecord",
|
|
index=models.Index(fields=["status"], name="pharmacy_di_status_9fe994_idx"),
|
|
),
|
|
]
|