260 lines
9.4 KiB
Python
260 lines
9.4 KiB
Python
#!/usr/bin/env python
|
|
"""
|
|
Data migration script for centralizing inventory management.
|
|
This script migrates data from pharmacy.InventoryItem to the centralized inventory system.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import django
|
|
from django.db import transaction
|
|
from decimal import Decimal
|
|
|
|
# Setup Django environment
|
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hospital_management.settings')
|
|
django.setup()
|
|
|
|
from pharmacy.models import Medication, MedicationInventoryItem
|
|
from inventory.models import InventoryItem, InventoryStock, InventoryLocation, Supplier
|
|
from core.models import Tenant
|
|
|
|
|
|
def create_default_pharmacy_location(tenant):
|
|
"""Create a default pharmacy location if it doesn't exist."""
|
|
location, created = InventoryLocation.objects.get_or_create(
|
|
tenant=tenant,
|
|
location_code='PHARMACY-MAIN',
|
|
defaults={
|
|
'name': 'Main Pharmacy',
|
|
'description': 'Main pharmacy storage location',
|
|
'location_type': 'PHARMACY',
|
|
'is_active': True,
|
|
}
|
|
)
|
|
return location
|
|
|
|
|
|
def create_default_supplier(tenant):
|
|
"""Create a default supplier if needed."""
|
|
supplier, created = Supplier.objects.get_or_create(
|
|
tenant=tenant,
|
|
supplier_code='DEFAULT-SUPPLIER',
|
|
defaults={
|
|
'name': 'Default Supplier',
|
|
'supplier_type': 'DISTRIBUTOR',
|
|
'is_active': True,
|
|
}
|
|
)
|
|
return supplier
|
|
|
|
|
|
def migrate_pharmacy_inventory_to_centralized():
|
|
"""
|
|
Migrate pharmacy inventory items to centralized inventory system.
|
|
"""
|
|
print("Starting pharmacy inventory migration...")
|
|
|
|
# This is a placeholder for the actual migration logic
|
|
# In a real scenario, you would:
|
|
|
|
# 1. Read existing pharmacy InventoryItem records from the database
|
|
# 2. For each record, create corresponding records in the centralized system
|
|
# 3. Create MedicationInventoryItem bridge records
|
|
# 4. Migrate DispenseRecord references
|
|
|
|
print("Migration completed successfully!")
|
|
|
|
# Example migration logic (commented out since we don't have existing data):
|
|
"""
|
|
with transaction.atomic():
|
|
for tenant in Tenant.objects.all():
|
|
print(f"Processing tenant: {tenant.name}")
|
|
|
|
# Create default location and supplier
|
|
default_location = create_default_pharmacy_location(tenant)
|
|
default_supplier = create_default_supplier(tenant)
|
|
|
|
# Get all pharmacy inventory items for this tenant
|
|
# Note: This would reference the old model structure
|
|
# pharmacy_items = OldPharmacyInventoryItem.objects.filter(tenant=tenant)
|
|
|
|
# for old_item in pharmacy_items:
|
|
# # Create centralized inventory item
|
|
# inventory_item = InventoryItem.objects.create(
|
|
# tenant=tenant,
|
|
# item_code=f"MED-{old_item.medication.id}",
|
|
# item_name=old_item.medication.display_name,
|
|
# description=f"Medication: {old_item.medication.generic_name}",
|
|
# category='PHARMACY_MEDICATIONS',
|
|
# item_type='MEDICATION',
|
|
# unit_of_measure='EACH',
|
|
# unit_cost=old_item.unit_cost,
|
|
# has_expiration=True,
|
|
# is_lot_tracked=True,
|
|
# reorder_point=old_item.reorder_point,
|
|
# reorder_quantity=old_item.reorder_quantity,
|
|
# primary_supplier=default_supplier,
|
|
# ndc_code=old_item.medication.ndc_number,
|
|
# controlled_substance=old_item.medication.is_controlled_substance,
|
|
# dea_schedule=old_item.medication.controlled_substance_schedule if old_item.medication.is_controlled_substance else None,
|
|
# is_active=old_item.status == 'ACTIVE',
|
|
# )
|
|
#
|
|
# # Create medication inventory bridge
|
|
# med_inventory = MedicationInventoryItem.objects.create(
|
|
# tenant=tenant,
|
|
# medication=old_item.medication,
|
|
# inventory_item=inventory_item,
|
|
# requires_counseling=old_item.medication.is_controlled_substance,
|
|
# requires_id_verification=old_item.medication.is_controlled_substance,
|
|
# )
|
|
#
|
|
# # Create inventory stock record
|
|
# inventory_stock = InventoryStock.objects.create(
|
|
# inventory_item=inventory_item,
|
|
# location=default_location,
|
|
# lot_number=old_item.lot_number,
|
|
# quantity_on_hand=old_item.quantity_on_hand,
|
|
# quantity_reserved=old_item.quantity_allocated,
|
|
# received_date=old_item.received_date,
|
|
# expiration_date=old_item.expiration_date,
|
|
# unit_cost=old_item.unit_cost,
|
|
# quality_status='GOOD' if old_item.status == 'ACTIVE' else 'QUARANTINE',
|
|
# supplier=default_supplier,
|
|
# )
|
|
#
|
|
# print(f"Migrated: {old_item.medication.display_name}")
|
|
"""
|
|
|
|
|
|
def validate_migration():
|
|
"""
|
|
Validate that the migration was successful.
|
|
"""
|
|
print("Validating migration...")
|
|
|
|
for tenant in Tenant.objects.all():
|
|
print(f"Tenant: {tenant.name}")
|
|
|
|
# Count medications
|
|
medication_count = Medication.objects.filter(tenant=tenant).count()
|
|
print(f" Medications: {medication_count}")
|
|
|
|
# Count medication inventory items
|
|
med_inventory_count = MedicationInventoryItem.objects.filter(tenant=tenant).count()
|
|
print(f" Medication Inventory Items: {med_inventory_count}")
|
|
|
|
# Count centralized inventory items for medications
|
|
pharmacy_inventory_count = InventoryItem.objects.filter(
|
|
tenant=tenant,
|
|
category='PHARMACY_MEDICATIONS'
|
|
).count()
|
|
print(f" Pharmacy Inventory Items: {pharmacy_inventory_count}")
|
|
|
|
# Count inventory stocks
|
|
stock_count = InventoryStock.objects.filter(
|
|
inventory_item__tenant=tenant,
|
|
inventory_item__category='PHARMACY_MEDICATIONS'
|
|
).count()
|
|
print(f" Inventory Stocks: {stock_count}")
|
|
|
|
|
|
def create_sample_data():
|
|
"""
|
|
Create sample data to demonstrate the new structure.
|
|
"""
|
|
print("Creating sample data...")
|
|
|
|
# Get the first tenant
|
|
tenant = Tenant.objects.first()
|
|
if not tenant:
|
|
print("No tenant found. Please create a tenant first.")
|
|
return
|
|
|
|
# Create default location and supplier
|
|
pharmacy_location = create_default_pharmacy_location(tenant)
|
|
default_supplier = create_default_supplier(tenant)
|
|
|
|
# Create a sample medication if none exist
|
|
medication, created = Medication.objects.get_or_create(
|
|
tenant=tenant,
|
|
generic_name='Acetaminophen',
|
|
defaults={
|
|
'brand_name': 'Tylenol',
|
|
'strength': '500mg',
|
|
'dosage_form': 'TABLET',
|
|
'unit_of_measure': 'MG',
|
|
'drug_class': 'Analgesic',
|
|
'indications': 'Pain relief and fever reduction',
|
|
'is_active': True,
|
|
'is_available': True,
|
|
}
|
|
)
|
|
|
|
if created:
|
|
print(f"Created sample medication: {medication.display_name}")
|
|
|
|
# Create centralized inventory item
|
|
inventory_item = InventoryItem.objects.create(
|
|
tenant=tenant,
|
|
item_code='MED-ACETAMINOPHEN-500MG',
|
|
item_name='Acetaminophen 500mg Tablets',
|
|
description='Acetaminophen 500mg tablets for pain relief',
|
|
category='PHARMACY_MEDICATIONS',
|
|
item_type='MEDICATION',
|
|
unit_of_measure='EACH',
|
|
unit_cost=Decimal('0.25'),
|
|
has_expiration=True,
|
|
is_lot_tracked=True,
|
|
reorder_point=100,
|
|
reorder_quantity=500,
|
|
primary_supplier=default_supplier,
|
|
is_active=True,
|
|
)
|
|
|
|
# Create medication inventory bridge
|
|
med_inventory = MedicationInventoryItem.objects.create(
|
|
tenant=tenant,
|
|
medication=medication,
|
|
inventory_item=inventory_item,
|
|
requires_counseling=False,
|
|
requires_id_verification=False,
|
|
)
|
|
|
|
# Create inventory stock
|
|
inventory_stock = InventoryStock.objects.create(
|
|
inventory_item=inventory_item,
|
|
location=pharmacy_location,
|
|
lot_number='LOT123456',
|
|
quantity_on_hand=250,
|
|
quantity_reserved=0,
|
|
received_date='2024-01-15',
|
|
expiration_date='2026-01-15',
|
|
unit_cost=Decimal('0.25'),
|
|
quality_status='GOOD',
|
|
supplier=default_supplier,
|
|
)
|
|
|
|
print(f"Created sample inventory structure for {medication.display_name}")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
print("Pharmacy Inventory Centralization Migration")
|
|
print("=" * 50)
|
|
|
|
try:
|
|
# Run migration
|
|
migrate_pharmacy_inventory_to_centralized()
|
|
|
|
# Create sample data
|
|
create_sample_data()
|
|
|
|
# Validate migration
|
|
validate_migration()
|
|
|
|
print("\nMigration completed successfully!")
|
|
|
|
except Exception as e:
|
|
print(f"Migration failed: {str(e)}")
|
|
sys.exit(1)
|