Workflow การจ่ายยาผู้ป่วยใน (IPD Dispensing Workflow)
📋 สารบัญ
- ภาพรวม
- ประเภทคำสั่งยา IPD
- ขั้นตอนการทำงาน
- Medication Administration Record (MAR)
- UI Components
- Features หลัก
- Use Cases
ภาพรวม
ไฟล์: modules/pharmacy/ipd-dispensing.html (4084 lines)
การจ่ายยาผู้ป่วยใน (IPD Dispensing) มีความซับซ้อนมากกว่า OPD เนื่องจากต้องจัดการกับยาต่อเนื่อง (Continue Order), ยาฉุกเฉิน (STAT), ยาเมื่อจำเป็น (PRN), และต้องส่งยาไปตามหอผู้ป่วยแต่ละหอพร้อมกับบันทึกการให้ยาในแต่ละรอบเวลา
ความแตกต่างหลักจาก OPD
| Feature | OPD | IPD |
|---|---|---|
| จำนวนยา | ครั้งเดียว (จ่ายเต็มจำนวน) | ทยอยจ่ายตามวัน/รอบเวลา |
| การให้ยา | ผู้ป่วยกินเอง | พยาบาลให้ตามเวลา |
| บันทึก | จ่ายยาเสร็จสิ้น | MAR (Medication Administration Record) |
| ประเภทคำสั่ง | ใบสั่งยาปกติ | Continue, STAT, PRN, One Day, Discharge |
| หน่วยงานรับยา | ผู้ป่วย | หอผู้ป่วย (Ward) |
ประเภทคำสั่งยา IPD
1. Continue Order (ยาต่อเนื่อง)
คำอธิบาย: ยาที่ให้ต่อเนื่องตามเวลาที่กำหนด จนกว่าจะมีคำสั่งหยุด
ลักษณะ: - มีวันเริ่ม (Start Date) และวันสิ้นสุด (Stop Date) - มีเวลาให้ยาที่แน่นอน เช่น 08:00, 14:00, 20:00 - ส่งยาเป็นรายวันหรือทุก 3-7 วัน
ตัวอย่าง:
{
"orderType": "continue",
"drugCode": "MED050",
"tradeName": "Omeprazole 40mg",
"dosage": "40 mg",
"frequency": "ทุก 12 ชั่วโมง",
"administrationTime": ["08:00", "20:00"],
"route": "IV",
"startDate": "2025-12-10",
"stopDate": "2025-12-20",
"status": "active"
}
Workflow:
แพทย์สั่ง → เภสัชจัดยาวันละ 2 ครั้ง → ส่งยาไปหอผู้ป่วย →
พยาบาลรับยา → ให้ยาตามเวลา → บันทึก MAR
2. STAT Order (ยาด่วนทันที)
คำอธิบาย: ยาที่ต้องให้ทันทีภายใน 15-30 นาที เช่น ยาแก้ปวด ยาฉุกเฉิน
ลักษณะ: - ให้ครั้งเดียว ทันที - มี Urgency Level: Critical, Urgent - ต้องจัดเตรียมและส่งด่วน
ตัวอย่าง:
{
"orderType": "stat",
"drugCode": "MED045",
"tradeName": "Morphine 10mg",
"dosage": "10 mg",
"route": "IV push",
"urgency": "critical",
"orderedAt": "2025-12-11T14:30:00",
"status": "urgent"
}
Workflow:
แพทย์สั่งด่วน → Alert แจ้งเภสัช → เภสัชจัดยาทันที →
ส่งยาด่วนไปหอผู้ป่วย → พยาบาลให้ยาทันที → บันทึก MAR
3. PRN Order (ยาเมื่อจำเป็น)
คำอธิบาย: ยาที่ให้เมื่อผู้ป่วยมีอาการ ไม่ได้กำหนดเวลาตายตัว
ลักษณะ: - มีเงื่อนไข (Condition) เช่น "เมื่อมีไข้ >38.5°C" - มีขนาดสูงสุดต่อวัน (Max Dose Per Day) - พยาบาล Request เมื่อจำเป็น
ตัวอย่าง:
{
"orderType": "prn",
"drugCode": "MED001",
"tradeName": "Paracetamol 500mg",
"dosage": "500 mg",
"route": "oral",
"indication": "เมื่อมีไข้ >38°C",
"maxDose": "4 grams/day",
"status": "active"
}
Workflow:
แพทย์สั่ง PRN → เภสัชส่งยาไว้ที่หอผู้ป่วย →
ผู้ป่วยมีอาการ → พยาบาล Request → ให้ยา → บันทึก MAR
4. One Day Order (ยาวันเดียว)
คำอธิบาย: ยาที่ให้เฉพาะวันนั้นเท่านั้น
ตัวอย่าง: การเตรียมผ่าตัด (Preop), ยาระบาย
5. Discharge Order (ยากลับบ้าน)
คำอธิบาย: ยาที่จ่ายให้ผู้ป่วยเมื่อกลับบ้าน
ลักษณะ: - คล้าย OPD แต่ขึ้นจากคำสั่ง IPD - มักจ่ายพร้อมใบสรุปการรักษา
ขั้นตอนการทำงาน
Overall Workflow
graph TB
A[แพทย์สั่งยา IPD] --> B{ประเภทคำสั่ง?}
B -->|Continue| C[เข้าคิว Continue Order]
B -->|STAT| D[Alert ด่วน!]
B -->|PRN| E[ส่งยาไว้ล่วงหน้า]
B -->|One Day| F[จัดยาวันเดียว]
B -->|Discharge| G[จัดยากลับบ้าน]
C --> H[เภสัชเลือก Ward]
D --> I[เภสัชจัดยาด่วน]
E --> J[เภสัชส่งยาสำรอง]
H --> K[เลือกผู้ป่วยในหอ]
K --> L[ดูคำสั่งยาทั้งหมด]
L --> M[จัดยาตามรอบเวลา]
M --> N[พิมพ์ใบจ่ายยา Ward]
N --> O[ส่งยาไปหอผู้ป่วย]
I --> P[ส่งยาด่วน STAT]
O --> Q[พยาบาลรับยา]
P --> Q
J --> Q
Q --> R[พยาบาลให้ยาตามเวลา]
R --> S[บันทึก MAR]
S --> T{ยาหมดรอบนี้?}
T -->|No| U[รออีกรอบถัดไป]
T -->|Yes| V[Request ยารอบใหม่]
V --> H
ขั้นตอนละเอียด
Step 1: เลือกหอผู้ป่วย (Ward Selection)
// UI แบบ Collapsible Ward List
function loadWardList() {
const wards = [
{ id: 'WARD-MED', name: 'Medical Ward', patientCount: 5 },
{ id: 'WARD-SUR', name: 'Surgical Ward', patientCount: 3 },
{ id: 'WARD-ICU', name: 'ICU', patientCount: 2 }
];
displayWardList(wards);
}
UI Layout:
┌────────────────────────┐
│ Ward List │
├────────────────────────┤
│ ▼ Medical Ward (5) │
│ ├─ สมหญิง รักษาดี │
│ │ AN-2025-001 │
│ │ Bed: M301-1 │
│ ├─ ประเสริฐ สุขใจ │
│ └─ ... │
│ │
│ ▶ Surgical Ward (3) │
│ │
│ ▶ ICU (2) │
└────────────────────────┘
Step 2: เลือกผู้ป่วย
function selectIPDPatient(an) {
// 1. ดึงข้อมูลผู้ป่วย
const patient = ipdOrders.find(p => p.an === an);
// 2. แสดงข้อมูล Header
displayPatientHeader(patient);
// 3. โหลดคำสั่งยาแยกตามประเภท
loadContinueOrders(patient);
loadPRNOrders(patient);
loadSTATOrders(patient);
// 4. โหลด MAR (Medication Administration Record)
loadMARHistory(patient);
}
Step 3: จัดเตรียมยา Continue Order
function prepareWardMedication(ward, date) {
// 1. ดึงคำสั่งยา Continue ทั้งหมดของหอ
const activeOrders = ipdOrders.filter(order => {
return order.ward === ward &&
order.orderType === 'continue' &&
order.status === 'active' &&
isScheduledForDate(order, date);
});
// 2. จัดกลุ่มตามรอบเวลา
const morningDose = activeOrders.filter(o =>
o.administrationTime.includes('06:00') ||
o.administrationTime.includes('08:00')
);
const afternoonDose = activeOrders.filter(o =>
o.administrationTime.includes('14:00')
);
const eveningDose = activeOrders.filter(o =>
o.administrationTime.includes('18:00') ||
o.administrationTime.includes('20:00')
);
// 3. แสดงรายการพร้อมเลือก
displayMedicationsBySchedule({
morning: morningDose,
afternoon: afternoonDose,
evening: eveningDose
});
}
Step 4: พิมพ์ใบจ่ายยา Ward
function printWardDispenseSheet(ward, medications, date) {
const sheetHTML = `
<div class="ward-dispense-sheet">
<h3>${ward} - ใบจ่ายยา</h3>
<p>วันที่: ${HIS.formatThaiDate(date)}</p>
<table>
<thead>
<tr>
<th>AN</th>
<th>ชื่อผู้ป่วย</th>
<th>เตียง</th>
<th>รายการยา</th>
<th>เวลา</th>
<th>จำนวน</th>
<th>หมายเหตุ</th>
</tr>
</thead>
<tbody>
${medications.map(med => `
<tr>
<td>${med.an}</td>
<td>${med.patientName}</td>
<td>${med.bed}</td>
<td>${med.tradeName}</td>
<td>${med.administrationTime.join(', ')}</td>
<td>${med.quantity}</td>
<td>${med.instruction}</td>
</tr>
`).join('')}
</tbody>
</table>
</div>
`;
printDocument(sheetHTML);
}
Step 5: ส่งยาไปหอผู้ป่วย
async function dispenseToWard(ward, medications) {
// 1. บันทึกการจ่ายยา
const dispenseRecord = {
id: generateDispenseId(),
ward: ward,
dispensedBy: getCurrentUser().userId,
dispensedAt: new Date().toISOString(),
medications: medications.map(med => ({
...med,
dispensedQuantity: med.quantity,
dispensedStatus: 'sent_to_ward'
}))
};
// 2. บันทึกลงระบบ
await saveDispenseRecord(dispenseRecord);
// 3. อัปเดตสถานะคำสั่งยา
medications.forEach(med => {
updateOrderStatus(med.itemId, 'dispensed');
});
// 4. แจ้งเตือนหอผู้ป่วย (ในระบบจริง)
// notifyWard(ward, dispenseRecord);
showSuccessAlert(`ส่งยาไป ${ward} เรียบร้อยแล้ว`);
}
Medication Administration Record (MAR)
MAR คืออะไร?
Medication Administration Record (MAR) คือบันทึกการให้ยาที่พยาบาลต้องบันทึกทุกครั้งที่ให้ยาผู้ป่วย เพื่อติดตามว่ายาถูกให้ตรงเวลาและครบถ้วนหรือไม่
โครงสร้าง MAR
{
"an": "AN-2025-001",
"date": "2025-12-11",
"medications": [
{
"itemId": "IPD-MED-001",
"drugCode": "MED060",
"tradeName": "NSS 0.9% 1000ml",
"scheduledTime": "06:00",
"administeredTime": "06:15",
"administeredBy": "NURSE001",
"administeredByName": "พยาบาล ใจดี",
"status": "given",
"remarks": ""
},
{
"itemId": "IPD-MED-001",
"scheduledTime": "18:00",
"status": "pending"
},
{
"itemId": "IPD-MED-002",
"scheduledTime": "08:00",
"administeredTime": "08:10",
"administeredBy": "NURSE001",
"status": "given"
}
]
}
MAR Status
| Status | คำอธิบาย | Icon |
|---|---|---|
pending |
รอให้ยา | ⏳ |
given |
ให้ยาแล้ว | ✅ |
missed |
พลาดรอบ | ⚠️ |
refused |
ผู้ป่วยปฏิเสธ | ❌ |
held |
พักยา (ตามคำสั่งแพทย์) | ⏸️ |
na |
ไม่สามารถให้ได้ | 🚫 |
MAR Display
<table class="mar-table">
<thead>
<tr>
<th>รายการยา</th>
<th>06:00</th>
<th>08:00</th>
<th>14:00</th>
<th>18:00</th>
<th>20:00</th>
</tr>
</thead>
<tbody>
<tr>
<td>NSS 0.9% 1000ml</td>
<td class="mar-cell">
<span class="mar-status-icon given">✅</span>
<small>NURSE001</small>
</td>
<td class="mar-cell">-</td>
<td class="mar-cell">-</td>
<td class="mar-cell">
<span class="mar-status-icon pending">⏳</span>
</td>
<td class="mar-cell">-</td>
</tr>
<tr>
<td>Omeprazole 40mg</td>
<td class="mar-cell">-</td>
<td class="mar-cell">
<span class="mar-status-icon given">✅</span>
<small>NURSE002</small>
</td>
<td class="mar-cell">-</td>
<td class="mar-cell">-</td>
<td class="mar-cell">
<span class="mar-status-icon pending">⏳</span>
</td>
</tr>
</tbody>
</table>
UI Components
1. Ward List Panel (Left)
<div class="ward-list-panel">
<div class="ward-item expanded">
<div class="ward-header">
<h6>
<i class="bi bi-building"></i> Medical Ward
<span class="badge">5 ผู้ป่วย</span>
</h6>
<span class="ward-toggle">▼</span>
</div>
<div class="patient-sublist">
<div class="patient-subitem active">
<div class="patient-info">
<div class="patient-an">AN-2025-001</div>
<div class="patient-name">สมหญิง รักษาดี</div>
</div>
<span class="bed-badge">M301-1</span>
</div>
<!-- More patients... -->
</div>
</div>
</div>
2. Order Details Panel (Right)
<div class="order-details-panel">
<!-- Patient Header -->
<div class="patient-header">
<h5>สมหญิง รักษาดี</h5>
<div class="patient-meta">
<span>AN: AN-2025-001</span>
<span>Ward: Medical Ward</span>
<span>Bed: M301-1</span>
</div>
</div>
<!-- Tabs -->
<ul class="nav nav-tabs">
<li><a class="active" data-tab="continue">Continue Order</a></li>
<li><a data-tab="prn">PRN Order</a></li>
<li><a data-tab="stat">STAT Order</a></li>
<li><a data-tab="mar">MAR</a></li>
</ul>
<!-- Order Cards -->
<div class="order-card">
<div class="order-card-header">
<div>
<h6>NSS 0.9% 1000ml</h6>
<div class="text-muted small">
IV drip over 8 hours
</div>
</div>
<span class="order-type-badge order-type-continue">Continue</span>
</div>
<div class="order-card-body">
<div class="row">
<div class="col-md-6">
<strong>เวลาให้ยา:</strong> 06:00, 18:00
</div>
<div class="col-md-6">
<strong>ระยะเวลา:</strong> 10-20 ธ.ค. 2567
</div>
</div>
</div>
</div>
</div>
Features หลัก
1. Ward-based Organization
// จัดกลุ่มตามหอผู้ป่วย
const wardGroups = groupByWard(ipdOrders);
// Medical Ward → 5 patients
// Surgical Ward → 3 patients
// ICU → 2 patients
2. Time-based Scheduling
// จัดยาตามรอบเวลา
const schedule = {
'06:00': [], // เช้ามืด
'08:00': [], // เช้า
'12:00': [], // เที่ยง
'14:00': [], // บ่าย
'18:00': [], // เย็น
'20:00': [], // ค่ำ
'22:00': [] // ก่อนนอน
};
3. STAT Priority Handling
// STAT Order มี Priority สูงสุด
if (order.orderType === 'stat') {
showUrgentAlert(order);
prioritizeDispensing(order);
}
4. PRN Request Management
// พยาบาล Request ยา PRN
async function requestPRNMedication(prnOrder, reason) {
// ตรวจสอบเงื่อนไข
if (!meetsPRNCondition(prnOrder, reason)) {
alert('ไม่ตรงตามเงื่อนไขการใช้');
return;
}
// ตรวจสอบ Max Dose
if (exceedsMaxDose(prnOrder)) {
alert('เกินขนาดสูงสุดต่อวัน');
return;
}
// อนุมัติ Request
await approvePRNRequest(prnOrder);
}
Use Cases
Use Case 1: จัดยา Continue Order ประจำวัน
Scenario: เภสัชกรจัดยารอบเช้าให้ Medical Ward
- เภสัชกรเข้าหน้า IPD Dispensing เวลา 05:30
- เลือก "Medical Ward"
- เห็นรายชื่อผู้ป่วย 5 คน
- คลิก "จัดยารอบเช้า (06:00-08:00)"
- ระบบแสดงรายการยาทั้งหมดที่ต้องส่ง:
- สมหญิง: NSS 1000ml, Omeprazole 40mg
- ประเสริฐ: Insulin, Metformin
- ...
- เภสัชกรเลือกยาทั้งหมด
- คลิก "พิมพ์ใบจ่ายยา Ward"
- จัดยาตามใบ
- คลิก "ส่งยาไป Medical Ward"
- บันทึกการจ่ายยา
- ส่งยาไปหอผู้ป่วย
ระยะเวลา: ~30-45 นาที
Use Case 2: จัดการ STAT Order ฉุกเฉิน
Scenario: แพทย์สั่งยา Morphine ด่วนให้ผู้ป่วย ICU
- แพทย์สั่ง STAT: Morphine 10mg IV push
- ระบบ Alert เภสัชกรทันที (🔴 แจ้งเตือนเสียง)
- เภสัชกรเห็น Alert: "STAT Order - ICU - AN-2025-010"
- คลิกดู Order ทันที
- จัดยา Morphine 10mg
- ตรวจสอบความถูกต้อง (Double Check กับ Controlled Drug)
- ส่งยาด่วนไป ICU
- พยาบาลรับยาและให้ผู้ป่วยทันที (ภายใน 15 นาที)
- บันทึก MAR
ระยะเวลา: < 15 นาที
Use Case 3: พยาบาล Request ยา PRN
Scenario: ผู้ป่วยมีไข้ 38.5°C พยาบาลขอยา Paracetamol PRN
- พยาบาลวัดอุณหภูมิ → 38.5°C
- เช็คคำสั่งยา PRN: "Paracetamol 500mg เมื่อไข้ >38°C"
- พยาบาลเข้าระบบ Request ยา PRN
- ระบบแจ้งเภสัชกร (ถ้ายาหมด)
- เภสัชกรอนุมัติและส่งยา
- พยาบาลรับยาและให้ผู้ป่วย
- บันทึก MAR:
- เวลาที่ให้: 14:30
- เหตุผล: ไข้ 38.5°C
- ผู้ให้ยา: NURSE001
ระยะเวลา: ~10 นาที
สรุป
ระบบจ่ายยาผู้ป่วยใน (IPD Dispensing) มีความซับซ้อนและต้องการความแม่นยำสูง:
✅ Ward Management - จัดการตามหอผู้ป่วย
✅ Multiple Order Types - Continue, STAT, PRN, One Day, Discharge
✅ Time-based Scheduling - จัดยาตามรอบเวลา
✅ MAR Tracking - บันทึกการให้ยาครบถ้วน
✅ Priority Handling - จัดการ STAT อย่างรวดเร็ว
✅ PRN Request System - รองรับการขอยาเมื่อจำเป็น
ความแตกต่างสำคัญ: - จ่ายยาทยอย ไม่ใช่ครั้งเดียว - ส่งยาไปหอผู้ป่วย ไม่ใช่ผู้ป่วยโดยตรง - พยาบาลเป็นคนให้ยา - บันทึก MAR ทุกรอบ
อัปเดตล่าสุด: 6 มกราคม 2026
เอกสารอ้างอิง: WORKFLOW_OVERVIEW.md