The pharmacy is a standalone sub-application (at /pharmacy/) with its own login, database schema (database_pharmacy.sql), and RBAC layer, sharing only the patients and prescriptions tables with the main app. It can be installed independently or alongside the main app.
pharm_drug_master stores the canonical drug catalog: generic name, brand name, form (tablet/capsule/liquid/injection), strength, unit, HSN code for GST, and a controlled_substance flag. The catalog is shared across all pharmacists in the clinic.
pharm_stock_batches tracks inventory at the batch/lot level: batch number, expiry date, purchase price, MRP, and quantity remaining. Multiple batches per drug can exist simultaneously; dispense logic uses FEFO (First Expiry, First Out) by default.
pharm_stock_adjustments records every manual stock change (reason, quantity delta, user, timestamp) — required for audit trails and to reconcile physical stock counts against the system.
The pharmacy cron job (pharmacy/api/cron.php) scans pharm_stock_batches daily and raises notifications for batches expiring within the configured lead time (default 30 days). Notifications go to pharmacist accounts via the notification_queue.
pharm_dispense_queue holds pending dispense requests linked to prescription IDs. pharmacy/pages/queue.php is the main pharmacist workstation view — it shows all pending items, lets the pharmacist confirm quantities, and records the dispense in pharm_dispense_items.
pharm_drug_interactions stores known DDI pairs (drug_a_id, drug_b_id, severity, description). Before dispensing, the system cross-checks all drugs being dispensed against all active medications in the patient's record (medications table) and raises a warning for any severity level — the pharmacist must acknowledge before proceeding.
pharm_returns + pharm_return_items + pharmacy/api/returns.php: a return can be against a dispense (full or partial) or an external prescription. Approved returns credit the patient's account or trigger a cash refund, logged in pharm_payment_log.
pharm_external_prescriptions + pharm_ext_rx_items: prescriptions written by outside doctors (scanned or manually entered) can be received and dispensed via pharmacy/pages/external_prescriptions.php. A printable receipt is generated via pharmacy/pages/print_ext_rx.php.
pharm_cash_shifts mirrors the main app's cash shift concept for the pharmacy — shift open/close with cash-in-hand count, auto-reconciled against pharm_payment_log totals for the shift period.
pharm_controlled_register is a dedicated table with one row per controlled-substance dispense: drug, batch, quantity, patient, prescriber, date, and a remarks field. pharmacy/pages/controlled_register.php renders the register in the format required by India's Pharmacy Act for narcotics and Schedule H1 drugs.
For de-addiction facilities, IPD-level NDPS register entries (ipd_ndps_register) are separate from the pharmacy-level controlled register, reflecting that OST dispensing in a de-addiction ward follows NDPS Act regulations rather than standard Pharmacy Act requirements.
pharm_suppliers stores supplier name, GST number, contact, and payment terms. pharm_purchase_orders + pharm_po_items model purchase orders with line-item detail, expected delivery date, and received-quantity tracking.
Receiving a PO auto-creates stock batch entries in pharm_stock_batches. The PO status transitions from draft → sent → partial → received, with each received line updating stock.
pharmacy/pages/store_bridge.php (and includes/pharmacy_store.php) links pharmacy stock to the patient-facing store. When a patient orders a product that maps to a drug in pharm_drug_master, a dispense queue entry is automatically created when the store order is confirmed.
Shipping is handled via the Shiprocket API (includes/shiprocket.php). When a store order requires physical delivery, a shipment is created in Shiprocket, and tracking updates are received via api/shiprocket_webhook.php and reflected on the store order.
pharmacy/api/billing.php generates pharmacy invoices that can be standalone (walk-in customer) or linked to the main app's invoice (IPD/OPD patient). The pharmacy billing migration (includes/pharm_billing_migration.php) handles schema version upgrades.
The demo has real sample data — appointments, patients, prescriptions — so you can explore freely.