ข้ามไปที่เนื้อหา

02. Lab Workflow - ขั้นตอนการทำงานแบบละเอียด

📋 ภาพรวม Workflow

ระบบงานชันสูตรประกอบด้วย 6 ขั้นตอนหลัก ที่เชื่อมโยงกันตามลำดับ:

graph LR
    A[1. Doctor Order<br/>แพทย์สั่งตรวจ] --> B[2. Order Queue<br/>คิวงาน]
    B --> C[3. Specimen Collection<br/>เก็บสิ่งส่งตรวจ]
    C --> D[4. Result Entry<br/>ลงผลแล็บ]
    D --> E[5. Result Approval<br/>อนุมัติผล]
    E --> F[6. Report<br/>รายงานผล]

    style A fill:#e3f2fd,stroke:#1976d2
    style C fill:#fff3e0,stroke:#f57c00
    style D fill:#f3e5f5,stroke:#7b1fa2
    style E fill:#e8f5e9,stroke:#388e3c
    style F fill:#c8e6c9,stroke:#2e7d32

🩺 ขั้นตอนที่ 1: Doctor Order (สั่งตรวจแล็บ)

หน้า: modules/lab/doctor-order.html
ผู้ใช้: แพทย์ / เจ้าหน้าที่ OPD
วัตถุประสงค์: สร้าง Lab Order สำหรับผู้ป่วย


📝 ขั้นตอนการทำงาน

Step 1.1: ค้นหาผู้ป่วย

UI Components: - Input field: เลข HN (Hospital Number) - Button: ปุ่ม "ค้นหา" - Quick select buttons: HN ตัวอย่าง (สำหรับทดสอบ)

Process:

searchPatient() {
  1. รับค่า HN จาก input field
  2. เรียก patientService.getPatientByHN(hn)
  3. ถ้าพบผู้ป่วย  แสดง Patient Info Card
  4. ถ้าไม่พบ  แสดง error alert
}

Patient Info แสดง: - HN, ชื่อ-นามสกุล, อายุ - เพศ, หมู่เลือด - สิทธิการรักษา (UC, ประกันสังคม, etc.) - โรคประจำตัว (Chronic diseases) - ประวัติแพ้ยา (Drug allergies)

Mock Data: จาก data/patients.json


Step 1.2: เลือกรายการตรวจ

ระบบรองรับ 2 มุมมองการเลือก:

🔹 View 1: Panel View (แบบชุด)

เลือกรายการเป็นกลุ่ม (Lab Panel) เหมาะสำหรับการสั่งตรวจทั่วไป

ตัวอย่าง Lab Panels (จาก data/lab-panels.json):

Panel Code ชื่อชุด รายการภายใน Use Case
PANEL001 Complete Blood Count (CBC) WBC, RBC, Hb, Hct, MCV, Platelet ตรวจเลือดทั่วไป
PANEL002 Liver Function Test (LFT) AST, ALT, ALP, Total Bilirubin, Direct Bilirubin, Total Protein, Albumin สงสัยโรคตับ
PANEL003 Renal Function Test (RFT) BUN, Creatinine, Electrolytes (Na, K, Cl), eGFR สงสัยโรคไต
PANEL004 Lipid Profile Total Cholesterol, HDL, LDL, Triglyceride ตรวจไขมันในเลือด
PANEL005 Thyroid Function Test TSH, Free T3, Free T4 สงสัยโรคต่อมไทรอยด์

ข้อมูลที่แสดง: - ชื่อชุด (EN + TH) - รายการตรวจภายใน (จำนวน) - ราคา (แสดงตามสิทธิการรักษา) - Turnaround time (เวลาที่ใช้ในการตรวจ)

การเลือก: - คลิกที่ Panel card → เลือก Priority (Routine/Urgent/STAT) - Panel จะถูกเพิ่มไปยัง Order Summary พร้อม แยกเป็นรายการ (auto-expand)


🔹 View 2: Individual View (แบบรายการ)

เลือกรายการตรวจทีละรายการ เหมาะสำหรับการสั่งตรวจเฉพาะเจาะจง

Features: 1. Category Tabs - จัดกลุ่มตามประเภท - Hematology (โลหิตวิทยา): CBC, PT, PTT, ESR - Chemistry (เคมีคลินิก): Glucose, BUN, Cr, Electrolytes - Immunology (ภูมิคุ้มกัน): HIV, HBsAg, Anti-HCV - Microbiology (จุลชีววิทยา): Culture, Gram stain - Urinalysis (ปัสสาวะ): UA, Urine culture - Serology (วิทยาเซรุ่ม): VDRL, RF, ANA

  1. Search Box - ค้นหารายการด้วย:
  2. Lab Code (เช่น CBC, FBS)
  3. ชื่อเต็ม (เช่น Complete Blood Count)
  4. ชื่อย่อ/คำสำคัญ (เช่น เลือด, ตับ)

  5. Lab Item Card แสดง:

  6. Lab Code + ชื่อเต็ม (EN/TH)
  7. Container type (EDTA, Plain, Fluoride, etc.)
  8. Specimen type (Blood, Urine, etc.)
  9. Turnaround time (ปกติ/ด่วน/STAT)
  10. ราคา
  11. Badge: Outlab (ถ้าส่งแล็บนอก)

Mock Data: จาก data/lab-items.json (~150 รายการ)


Step 1.3: กำหนด Priority

สำหรับแต่ละรายการตรวจ ต้องระบุ ความเร่งด่วน:

Priority ความหมาย Turnaround Time Use Case สี Badge
STAT เร่งด่วนที่สุด < 1 ชม. ฉุกเฉิน, ICU, OR 🔴 แดง
Urgent เร่งด่วน < 4 ชม. ผู้ป่วยใน, นัดผ่าตัด 🟠 ส้ม
Routine ปกติ 24-48 ชม. ผู้ป่วยนอกทั่วไป 🟢 เขียว

UI Interaction: - Default = Routine - Dropdown หรือ Radio buttons - STAT Order ต้องระบุ Clinical Note (บังคับ) → เพื่อบันทึกเหตุผลความจำเป็นเร่งด่วน


Step 1.4: สรุปรายการ (Order Summary)

แสดงข้อมูล: - ลำดับที่ (Running number) - รายการตรวจ (Lab Item Name) - Priority Badge - ราคา (แยกเป็น: ราคาเต็ม / เบิกได้ / ผู้ป่วยจ่าย) - ปุ่มลบรายการ (X)

ช่องกรอกเพิ่มเติม: 1. Diagnosis / เหตุผลการส่งตรวจ (Optional) - ระบุการวินิจฉัยเบื้องต้น - ช่วยเทคนิคเข้าใจบริบทของการตรวจ

  1. Clinical Note (Required สำหรับ STAT)
  2. อธิบายความจำเป็นเร่งด่วน
  3. Validation: ถ้ามี Priority = STAT แต่ไม่กรอก → ห้ามยืนยัน Order

การคำนวณราคา:

// ขึ้นอยู่กับสิทธิการรักษาของผู้ป่วย
if (patient.insuranceType === 'uc') {
  // บัตรทอง → เบิกได้ 100%
  เบิกได้ = fullPrice;
  ผู้ป่วยจ่าย = 0;
} else if (patient.insuranceType === 'social') {
  // ประกันสังคม → เบิกได้บางส่วน
  เบิกได้ = claimableAmount;
  ผู้ป่วยจ่าย = fullPrice - claimableAmount;
} else if (patient.insuranceType === 'cash') {
  // จ่ายเงินสด → จ่ายเต็มจำนวน
  เบิกได้ = 0;
  ผู้ป่วยจ่าย = fullPrice;
}

Total Summary: - จำนวนรายการทั้งหมด - ราคารวม - เบิกได้รวม - ผู้ป่วยจ่ายรวม


Step 1.5: ยืนยัน Order

Button: "ยืนยันและสั่งตรวจ"

Validation Checklist: - ✅ มีผู้ป่วยที่เลือกแล้ว - ✅ มีรายการตรวจอย่างน้อย 1 รายการ - ✅ ทุกรายการมี Priority - ✅ ถ้ามี STAT → ต้องมี Clinical Note - ✅ ราคาถูกคำนวณครบถ้วน

Process:

async function confirmOrder() {
  1. Validate ข้อมูลทั้งหมด
  2. สร้าง Lab Order object:
     - Order Number (auto-generate): LAB202512-0001
     - Order Date/Time: current timestamp
     - Patient: ข้อมูลผู้ป่วย
     - Ordered by: current user (แพทย์)
     - Items: รายการตรวจทั้งหมด
     - Status: 'confirmed' (ยืนยันแล้ว รอเก็บสิ่งส่งตรวจ)

  3. เรียก labOrderService.createOrder(orderData)
  4. บันทึกลง LocalStorage (key: 'his_lab_orders')
  5. สร้าง Lab Results (status: 'pending') สำหรับแต่ละรายการ
  6. แสดง Success Modal พร้อม:
     - Order Number
     - ปุ่ม "พิมพ์ใบนำส่ง"
     - ปุ่ม "พิมพ์ Barcode Label"
     - ปุ่ม "สั่งตรวจใหม่" (ผู้ป่วยคนเดิม)
     - ปุ่ม "กลับหน้าหลัก"

  7. Redirect  order-queue.html (คิวงาน) หรือ specimen-collection.html
}

Order Status: confirmed


🎯 Output

Lab Order สร้างแล้ว:

{
  "id": 1,
  "orderNumber": "LAB202512-0001",
  "hn": "HN000123",
  "patientName": "นายสมชาย ใจดี",
  "orderedBy": "นพ.สุรชัย ใจดี",
  "orderedAt": "2025-12-26T10:30:00",
  "diagnosis": "Suspected Anemia",
  "clinicalNote": "ผู้ป่วยหมดสติ BP 80/50",
  "status": "confirmed",
  "priority": "stat",
  "items": [
    {
      "labItemCode": "CBC",
      "labItemName": "Complete Blood Count",
      "priority": "stat",
      "price": 150,
      "claimable": 150,
      "patientPay": 0
    }
  ],
  "totalPrice": 150
}

Next Step: Order เข้าสู่ Order Queue → รอดำเนินการเก็บสิ่งส่งตรวจ


📋 ขั้นตอนที่ 2: Order Queue (คิวงาน)

หน้า: modules/lab/order-queue.html
ผู้ใช้: หัวหน้างาน Lab, เจ้าหน้าที่ประสานงาน
วัตถุประสงค์: จัดการคิว Lab Orders, ติดตามสถานะ, มอบหมายงาน


📊 Dashboard Overview

Statistics Cards (แสดงสถิติแบบ Real-time):

Card ข้อมูลที่แสดง Color
รอดำเนินการ Orders status = confirmed 🟠 Orange
กำลังเก็บสิ่งส่งตรวจ Orders status = collecting 🟣 Purple
เก็บเสร็จแล้ว Orders status = specimen_collected 🔵 Blue
STAT Priority Orders priority = stat 🔴 Red
ถูกปฏิเสธ Orders with rejected specimens 🔴 Red
เสร็จสมบูรณ์ Orders status = completed (วันนี้) 🟢 Green

Filter Options: 1. Status Filter - ทั้งหมด - รอดำเนินการ (confirmed) - กำลังเก็บ (collecting) - เก็บเสร็จแล้ว (specimen_collected) - ส่ง LIS แล้ว (sent_to_lis) - กำลังตรวจ (in_progress) - ลงผลบางส่วน (partial_result)

  1. Priority Filter
  2. ทั้งหมด
  3. STAT
  4. Urgent
  5. Routine

  6. Date Range

  7. วันนี้ (Today)
  8. เมื่อวาน (Yesterday)
  9. สัปดาห์นี้ (This Week)
  10. กำหนดเอง (Custom Range)

  11. Search Box

  12. ค้นหาด้วย: Order Number, HN, ชื่อผู้ป่วย

📑 Order List Table

Columns: | Column | ข้อมูล | Sortable | |--------|--------|----------| | Order# | เลขที่ Order (LAB202512-XXXX) | ✅ | | วันที่/เวลา | Order Date/Time | ✅ | | HN | Hospital Number | ✅ | | ผู้ป่วย | ชื่อ-นามสกุล | ❌ | | Priority | STAT/Urgent/Routine Badge | ✅ | | จำนวนรายการ | จำนวน Lab Items | ❌ | | Status | Status Badge (แสดงเป็นสีและไอคอน) | ✅ | | Actions | ปุ่มดำเนินการ | ❌ |

Status Badge Colors: - confirmed → 🟢 เขียวอ่อน "รอเก็บสิ่งส่งตรวจ" - collecting → 🟣 ม่วง "กำลังเก็บ" - specimen_collected → 🔵 น้ำเงิน "เก็บเสร็จแล้ว" - sent_to_lis → 🟦 ฟ้า "ส่ง LIS แล้ว" - in_progress → 🟨 เหลือง "กำลังตรวจ" - rejected → 🔴 แดง "ถูกปฏิเสธ"


🎛️ Actions

Action Buttons (ขึ้นอยู่กับ Status):

Status Available Actions
confirmed • เริ่มเก็บสิ่งส่งตรวจ
• ดูรายละเอียด
• ยกเลิก Order
collecting • ดูความคืบหน้า
• เร่งงาน (Flag)
specimen_collected • ส่ง LIS
• พิมพ์ Barcode Label
sent_to_lis • ดูสถานะ
• ลงผล (ไปหน้า Result Entry)

คลิกที่แถว → เปิด Order Detail Modal: - ข้อมูลผู้ป่วยเต็ม - รายการตรวจทั้งหมด (แยกตาม Specimen Type) - Timeline: แต่ละขั้นตอนดำเนินการเมื่อไหร่ โดยใคร - Comments/Notes ของแต่ละขั้นตอน - ประวัติการปฏิเสธ (ถ้ามี)


📌 Priority Sorting

Default Sort: Priority (STAT → Urgent → Routine) แล้วเรียงตาม Order Time (เก่าสุดก่อน)

STAT Orders → แสดงที่บนสุดเสมอ พร้อม: - 🔴 Red highlight - ⏰ Countdown timer (เวลาที่เหลือก่อนเกิน TAT) - 🔔 Notification badge (ถ้าใกล้เกินเวลา)


🔄 Auto-refresh

  • Refresh ทุก 30 วินาที (แสดง Spinner ขณะโหลด)
  • แจ้งเตือนเมื่อมี Order ใหม่ (Toast notification)
  • เสียง Alert สำหรับ STAT Orders

💉 ขั้นตอนที่ 3: Specimen Collection (เก็บสิ่งส่งตรวจ)

หน้า: modules/lab/specimen-collection.html
ผู้ใช้: เจ้าหน้าที่เก็บสิ่งส่งตรวจ (Phlebotomist), พยาบาล
วัตถุประสงค์: เจาะเลือด/เก็บตัวอย่างสิ่งส่งตรวจ, ตรวจสอบคุณภาพ (QC)


🔍 ค้นหา Order

Search Methods: 1. Scan Barcode (จาก Order Slip) - Input field + Auto-submit เมื่อ scan - Format: LAB202512-0001

  1. Manual Search
  2. Order Number
  3. HN (Hospital Number)
  4. ชื่อผู้ป่วย

Filter: - Status: confirmed (รอเก็บ) หรือ confirmed + มี rejected specimen (ต้องเก็บใหม่) - Priority: STAT แสดงก่อน - Date: วันนี้ (default)


📋 Order Card

แสดง Order ที่ค้นพบในรูปแบบ Card:

Header: - Order Number (ใหญ่, bold) - Priority Badge (STAT/Urgent/Routine) - Order Date/Time - Status Badge

Patient Info Section: - HN, ชื่อ-นามสกุล, อายุ, เพศ - โรคประจำตัว (ถ้ามี) - ⚠️ Allergy Alert (ถ้ามีประวัติแพ้ยา → แสดงเด่นชัด สีแดง)

Lab Items Summary: แบ่งตาม Specimen Type → เพื่อให้รู้ว่าต้องเก็บอะไรบ้าง

🩸 Blood - EDTA (Purple top): 3 รายการ
   - CBC, HbA1C, ESR

🩸 Blood - Plain (Red top): 2 รายการ
   - Glucose, LFT

🩸 Blood - Citrate (Blue top): 1 รายการ
   - PT/PTT

💧 Urine: 1 รายการ
   - Urinalysis

Actions: - ปุ่ม "เริ่มเก็บสิ่งส่งตรวจ" (เปิด Collection Modal) - ปุ่ม "ดูรายละเอียด" - ปุ่ม "พิมพ์ Barcode Label" (พิมพ์ล่วงหน้า)


📝 Collection Modal (หน้าต่างเก็บสิ่งส่งตรวจ)

เมื่อกดปุ่ม "เริ่มเก็บ" → เปิด Modal:

Section 1: เลือกรายการที่จะเก็บ

แสดงรายการทั้งหมด พร้อม Checkbox:

รายการตรวจ Specimen Type Container Volume
☑️ CBC Blood EDTA (Purple) 2 ml
☑️ Glucose Blood Fluoride (Gray) 2 ml
HIV Blood Plain (Red) 3 ml

Features: - เลือกทั้งหมด / ยกเลิกทั้งหมด - Group by Container Type - แสดง Volume ที่ต้องเก็บรวม


Section 2: Specimen Collection Details

ช่องกรอก (สำหรับแต่ละ Specimen):

  1. Collected By (ผู้เก็บ)
  2. Dropdown: รายชื่อพนักงาน หรือ Auto-fill จาก current user

  3. Collection Date/Time

  4. Default: ปัจจุบัน
  5. สามารถแก้ไขได้ (กรณีเก็บไปแล้วแต่ลงทีหลัง)

  6. Barcode Number

  7. Auto-generate หรือ Manual input
  8. Format: SPEC20251226-0001

  9. Container Type

  10. Auto-fill ตาม Lab Item
  11. Validation: ต้องตรงกับที่กำหนด

  12. Volume Collected

  13. Input: จำนวน ml/cc
  14. Validation: ต้อง >= Minimum required volume
  15. ⚠️ Warning ถ้าน้อยกว่าที่กำหนด

Section 3: Specimen Quality Control (QC) 🔍

Quality Assessment (ประเมินคุณภาพสิ่งส่งตรวจ):

Dropdown: เลือก 1 ระดับ - ✅ Good (ดีมาก) → ผ่าน QC - ⚠️ Acceptable (พอใช้) → ผ่าน แต่มีข้อสังเกต - ❌ Rejected (ไม่ผ่าน) → ปฏิเสธ ต้องเก็บใหม่

ถ้าเลือก Acceptable หรือ Rejected → แสดงช่องเพิ่มเติม:

Quality Issues (Checkboxes): - ☐ Hemolysis (เม็ดเลือดแดกแตก) - ☐ Clotted (เลือดแข็งตัว) - ☐ Insufficient Volume (ปริมาณไม่พอ) - ☐ Lipemic (ไขมันสูง) - ☐ Icteric (ตัวเหลือง) - ☐ Label Error (ฉลากผิด) - ☐ Contamination (ปนเปื้อน)

Notes (Textarea): - กรอกรายละเอียดเพิ่มเติม (บังคับถ้าเป็น Rejected) - ตัวอย่าง: "พบ Hemolysis รุนแรง เลือดแดงแตกมาก อาจเกิดจากการเก็บไม่ถูกต้อง"


Section 4: บันทึกและพิมพ์

ปุ่ม: 1. บันทึกและพิมพ์ฉลาก (Save + Print Label) - บันทึก Specimen record - เปิด Print Dialog สำหรับ Barcode Label

  1. บันทึกอย่างเดียว (Save Only)
  2. บันทึกโดยไม่พิมพ์

  3. ยกเลิก

  4. ปิด Modal โดยไม่บันทึก

🔄 Process Flow

async function saveSpecimen() {
  // 1. Validate
  if (quality === 'rejected' && !notes) {
    alert('กรุณาระบุเหตุผลการปฏิเสธ');
    return;
  }

  // 2. สร้าง Specimen object
  const specimen = {
    id: generateSpecimenId(),
    orderNumber: order.orderNumber,
    barcode: barcodeNumber,
    specimenType: selectedItems[0].specimenType,
    containerType: selectedItems[0].containerType,
    collectedBy: currentUser.name,
    collectedAt: collectionDateTime,
    volume: volumeCollected,
    quality: qualityLevel, // 'good', 'acceptable', 'rejected'
    qualityIssues: selectedIssues,
    notes: notes,
    status: qualityLevel === 'rejected' ? 'rejected' : 'collected',
    labItems: selectedLabItemCodes
  };

  // 3. บันทึกลง LocalStorage
  specimenService.createSpecimen(specimen);

  // 4. Update Order Status
  if (quality === 'rejected') {
    // ไม่เปลี่ยน order status (ยังเป็น 'confirmed')
    // เพิ่ม flag 'hasRejectedSpecimen' = true
    order.hasRejectedSpecimen = true;
  } else {
    // เช็คว่าเก็บครบทุกรายการหรือยัง
    const allCollected = checkAllSpecimensCollected(order);
    if (allCollected) {
      order.status = 'specimen_collected';
    } else {
      order.status = 'collecting';
    }
  }
  labOrderService.updateOrder(order);

  // 5. แสดงผล
  if (quality === 'rejected') {
    showAlert('⚠️ ปฏิเสธสิ่งส่งตรวจ - กรุณาเก็บใหม่', 'warning');
  } else {
    showSuccessModal(specimen);
    if (printLabel) {
      printBarcodeLabel(specimen);
    }
  }
}

✅ Success Case (เก็บสำเร็จ)

Specimen Status: collected
Order Status: specimen_collected (ถ้าเก็บครบทุกรายการแล้ว)

Success Modal แสดง: - ✅ เก็บสิ่งส่งตรวจสำเร็จ - Barcode Number - รายการตรวจที่เก็บ - Specimen Type & Container - ปุ่ม "พิมพ์ฉลากเพิ่ม" - ปุ่ม "เก็บ Order ถัดไป"

Barcode Label ที่พิมพ์ออกมา:

┌──────────────────────────────┐
│  โรงพยาบาลสมมติ               │
│  SPEC20251226-0001           │
│  ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬           │ (Barcode)
│  HN: HN000123                │
│  ชื่อ: นายสมชาย ใจดี          │
│  CBC, HbA1C                  │
│  EDTA (Purple top)           │
│  เก็บ: 26/12/2568 10:30      │
│  โดย: นางสาววรรณา            │
└──────────────────────────────┘

Next Step: Specimen พร้อมส่งห้องแล็บ → Status จะเปลี่ยนเป็น sent_to_lis เมื่อส่งเข้า LIS


❌ Rejection Case (ปฏิเสธสิ่งส่งตรวจ)

Specimen Status: rejected
Order Status: ยังเป็น confirmed (ไม่เปลี่ยน!)

Warning Toast:

⚠️ ปฏิเสธสิ่งส่งตรวจ 2 รายการ
   - CBC: Hemolysis รุนแรง
   - PT/PTT: เลือดแข็งตัวในหลอด Citrate

กรุณาเก็บใหม่

Order Card จะแสดง: - 🔴 Badge: "มี Specimen ถูกปฏิเสธ" - ⚠️ กล่องสีเหลืองด้านล่าง: แสดงรายการที่ถูก reject พร้อมเหตุผล - 🔄 ปุ่ม "เก็บใหม่" (Recollection Button)


🔄 Recollection (เก็บใหม่)

เมื่อคลิกปุ่ม "เก็บใหม่": 1. เปิด Collection Modal 2. Auto-select รายการที่ถูก reject 3. แสดงเหตุผลที่ถูก reject ไว้ด้านบน (Reference) 4. กรอกข้อมูลการเก็บใหม่ (Barcode ใหม่, วันที่/เวลาใหม่) 5. บันทึก → สร้าง Specimen ใหม่ (version 2)

Rejected Specimen เดิม: - ไม่ถูกลบ → เก็บเป็นประวัติ - Track ได้ว่ามี Specimen กี่ version (original + recollections)


📌 Status Summary After Step 3

Scenario Specimen Status Order Status Next Step
เก็บสำเร็จ (Quality = Good) collected specimen_collected ส่ง LIS → Result Entry
เก็บบางส่วน (บาง items เก็บได้) collected (บางรายการ) collecting เก็บต่อ
ปฏิเสธ (Quality = Rejected) rejected confirmed เก็บใหม่
เก็บใหม่สำเร็จ collected (new) specimen_collected ส่ง LIS

� ขั้นตอนที่ 4: Result Entry (ลงผลแล็บ)

หน้า: modules/lab/result-entry.html
ผู้ใช้: นักเทคนิคการแพทย์ (Medical Technologist)
วัตถุประสงค์: ลงผลการตรวจวิเคราะห์ทางห้องปฏิบัติการ


📊 Dashboard & Filter

Statistics Cards: | Card | ข้อมูล | Color | |------|--------|-------| | รอลงผล | Orders status = sent_to_lis | 🟠 Orange | | กำลังลงผล | Orders status = in_progress | 🔵 Blue | | ลงผลบางส่วน | Orders status = partial_result | 🟨 Yellow | | รอตรวจสอบ | Results status = preliminary | 🟣 Purple |

Filter Options: - Status: All / Pending / In Progress / Partial - Priority: STAT (แสดงก่อนเสมอ) / Urgent / Routine - Instrument: เลือกเครื่องที่ใช้ตรวจ (จาก lab-instruments.json) - Date Range: Today / Yesterday / Custom


🔍 Search & Select Order

Search Methods: 1. Scan Barcode (จาก Specimen Label) 2. Order Number 3. HN / ชื่อผู้ป่วย

Order List แสดง: - Order Number + Priority Badge - Patient Info (HN, Name, Age) - จำนวนรายการ (รอลงผล / ลงแล้ว) - Specimen Status (Collected, Received) - Order Time + TAT Remaining (STAT → แสดง Countdown)

คลิกเลือก Order → แสดง Result Entry Form


📝 Result Entry Form

Section 1: Patient & Order Info

แสดงข้อมูลสรุป (ด้านบน): - Patient: HN, ชื่อ-นามสกุล, อายุ, เพศ - Order#, Priority, Ordered By (แพทย์) - Diagnosis / Clinical Note - ⚠️ Allergy Alert (ถ้ามี)


Section 2: Instrument Selection

Dropdown: เลือกเครื่องมือที่ใช้ตรวจ

Instruments (จาก data/lab-instruments.json): - Sysmex XN-1000 (Hematology) ✅ Default - Roche Cobas C311 (Chemistry) ✅ Default - Abbott Architect i1000SR (Immunology) - Bio-Rad D-10 (HbA1C) - Stago STA Compact Max (Coagulation) - Manual Entry (สำหรับลงผลด้วยมือ)

Use Case: Track ว่าผลจากเครื่องไหน, ใครตรวจ, QC ได้


Section 3: Result Entry Table

Columns: | Column | Description | Input Type | |--------|-------------|------------| | รายการตรวจ | Lab Item Name + Code | Display | | ผลเก่า | Previous Result (Delta Check) | Display | | ผลใหม่ | Result Input Field | Input/Select | | หน่วย | Unit | Display | | Reference Range | Normal Range | Display | | Flag | Interpretation (Normal/High/Low/Critical) | Auto-calculated | | หมายเหตุ | Note | Textarea |


📌 Result Input Types

ขึ้นอยู่กับ resultInputType ของแต่ละ Lab Item:

1. Numeric Input (ตัวเลข)
<input type="number" step="0.01" min="0" 
       placeholder="ระบุผลตรวจ"
       oninput="calculateFlag(this)">

ตัวอย่าง: WBC, Glucose, Creatinine
Features: - Auto-calculate Flag (Normal/High/Low/Critical) - Validate ว่าอยู่ในช่วงที่เป็นไปได้ (Panic value check) - แสดง Reference Range ข้างๆ

2. Select Dropdown (เลือกตัวเลือก)
<select onchange="updateFlag(this)">
  <option value="negative">Negative (-)</option>
  <option value="positive">Positive (+)</option>
  <option value="1+">1+</option>
  <option value="2+">2+</option>
  <option value="3+">3+</option>
  <option value="4+">4+</option>
</select>

ตัวอย่าง: Urine Protein, Urine Glucose, Blood Type

3. Text Input (ข้อความ)
<input type="text" placeholder="ระบุผลตรวจ">

ตัวอย่าง: Culture Results, Microscopy

4. File Upload (สำหรับ Outlab)
<button onclick="uploadFile(resultId)">
  <i class="fas fa-upload"></i> แนบผลจากแล็บนอก (PDF/Image)
</button>

ตัวอย่าง: HIV, HBsAg, Tumor Markers ที่ส่งแล็บนอก


🎯 Auto-calculation & Validation

Flag Calculation (อัตโนมัติ)

เมื่อกรอกผล ระบบคำนวณ Flag:

function calculateFlag(result, referenceRange) {
  if (result < referenceRange.criticalLow) 
    return 'critical_low'; // 🔴 วิกฤตต่ำ
  else if (result < referenceRange.normalLow) 
    return 'low'; // 🟡 ต่ำ
  else if (result > referenceRange.criticalHigh) 
    return 'critical_high'; // 🔴 วิกฤตสูง
  else if (result > referenceRange.normalHigh) 
    return 'high'; // 🟡 สูง
  else 
    return 'normal'; // 🟢 ปกติ
}

Visual Feedback: - Input field เปลี่ยนสี: - 🟢 เขียวอ่อน (Normal) - 🟡 เหลือง (High/Low) - 🔴 แดง (Critical) - Badge แสดง Flag ข้างๆ


⚠️ Special Features

🔹 1. Delta Check (เปรียบเทียบผลเก่า-ใหม่)

เมื่อมีผลเก่า (จาก lab-previous-results.json):

แสดงผลเก่าพร้อมเปอร์เซ็นต์เปลี่ยนแปลง:

┌─────────────────────────────────────────┐
│ 📊 Delta Check                          │
│ ผลเดิม: 145 mg/dL (16/12/2568)         │
│ ผลใหม่: 180 mg/dL                       │
│ เปลี่ยนแปลง: ↑ 24% ⚠️ Warning          │
└─────────────────────────────────────────┘

Delta Check Rules: | Change | Alert Level | |--------|-------------| | < 15% | ✅ Normal (สีฟ้าอ่อน) | | 15-30% | ⚠️ Warning (สีเหลือง) | | > 30% | 🔴 Critical (สีแดง) → ต้องตรวจสอบซ้ำ |

Use Case: - ป้องกันผลผิดพลาดจากการพิมพ์ผิด - ตรวจจับภาวะที่เปลี่ยนแปลงรวดเร็ว - เทคนิคต้อง Double-check ก่อนบันทึก


🔹 2. Critical Alert Modal 🚨

เมื่อผลเป็น Critical (Flag = critical_high หรือ critical_low):

ระบบแสดง Critical Alert Modal ทันที:

╔════════════════════════════════════════╗
║     ⚠️  CRITICAL RESULT ALERT         ║
╠════════════════════════════════════════╣
║                                        ║
║  พบผลวิกฤตต้องรายงาน!                 ║
║                                        ║
║  📋 รายการวิกฤต:                       ║
║  • WBC: 22.5 K/µL (วิกฤตสูง)          ║
║  • Potassium: 6.8 mEq/L (วิกฤตสูง)    ║
║                                        ║
║  ⚠️ กรุณาแจ้งแพทย์ทันที                ║
║  ภายใน 30 นาที                         ║
║                                        ║
║  ⏱️ Countdown: 29:45                  ║
║                                        ║
║  [✓] ยืนยันรับทราบและแจ้งแพทย์แล้ว     ║
║                                        ║
║  [บันทึกและแจ้ง]   [ตรวจสอบซ้ำ]       ║
╚════════════════════════════════════════╝

Features: - 🔴 สีแดงสะดุดตา พร้อม Animation pulse - ⏱️ Countdown timer 30 นาที - Checkbox: ยืนยันรับทราบ (ต้องติ๊กถึงจะปิดได้) - บันทึก Log: เวลาที่แจ้ง, แจ้งใคร - ไม่สามารถข้าม → ต้อง acknowledge ก่อน

Critical Values Reference (ตัวอย่าง): | Test | Critical Low | Critical High | |------|--------------|---------------| | WBC | < 2.0 K/µL | > 20.0 K/µL | | Hemoglobin | < 5.0 g/dL | > 20.0 g/dL | | Platelet | < 20 K/µL | > 1000 K/µL | | Glucose | < 40 mg/dL | > 500 mg/dL | | Potassium | < 2.5 mEq/L | > 6.0 mEq/L | | Creatinine | - | > 10.0 mg/dL |


🔹 3. Outlab File Upload 📎

สำหรับรายการที่ส่งแล็บนอก (isOutsourced = true):

แทนการกรอกผล → Upload ไฟล์ PDF/Image ของผลจากแล็บนอก

UI:

┌──────────────────────────────────────┐
│ 📄 HIV Screening (Outlab)            │
│ ส่งตรวจที่: Bangkok Lab Center       │
│                                      │
│ [📎 แนบผลจากแล็บนอก]                │
│                                      │
│ ไฟล์ที่แนบ:                          │
│ • HIV_Result_HN000123.pdf (2.3 MB)  │
│   [👁️ View] [🗑️ Delete]             │
└──────────────────────────────────────┘

Upload Modal: 1. Drag & Drop หรือ Browse File 2. Support: PDF, PNG, JPG, JPEG 3. Max size: 10 MB 4. Auto-preview (แสดง Thumbnail) 5. บันทึก → เก็บไฟล์ใน FileAttachmentService

Mixed Order (มีทั้ง In-house + Outlab): - ลงผล In-house ด้วยมือ - Upload ไฟล์ Outlab - Badge แสดง: "MIXED (2/4)" = ลงแล้ว 2 จาก 4 รายการ


💾 Save Options

3 ปุ่มหลัก:

1. บันทึกผลบางส่วน (Save Partial)

  • บันทึกผลที่กรอกแล้ว
  • ผลที่ยังไม่กรอก → ยังว่างอยู่
  • Order Status → partial_result
  • Result Status → preliminary (ผลที่กรอกแล้ว), pending (ยังว่าง)

2. บันทึกทั้งหมด (Save All)

  • Validate: ทุกรายการต้องกรอกครบ
  • บันทึกผลทั้งหมดพร้อมกัน
  • Order Status → result_ready (รออนุมัติ)
  • Result Status → preliminary (ทุกรายการ)
  • ส่งต่อไปหน้า Result Approval

3. บันทึกและพิมพ์ (Save & Print)

  • บันทึกครบ + พิมพ์ Preliminary Report
  • ใช้กรณี STAT → แพทย์ต้องการผลด่วน
  • พิมพ์ใบผลแล็บชั่วคราว (มี Watermark "Preliminary")

🔄 Re-entry (ลงผลใหม่กรณีถูก Reject)

เมื่อผลถูก Supervisor ปฏิเสธ:

Order จะกลับมาที่หน้า Result Entry พร้อม:

┌───────────────────────────────────────────┐
│ ⚠️ ผลถูกปฏิเสธ - กรุณาลงผลใหม่           │
│                                           │
│ รายการ: Glucose                           │
│ ผลเดิม: 185 mg/dL                         │
│ ผลใหม่: [______] mg/dL 🔴                │
│                                           │
│ เหตุผลการปฏิเสธ:                          │
│ "ผลไม่สอดคล้องกับภาวะผู้ป่วย              │
│  ขอให้ตรวจซ้ำด้วยเครื่องอื่น"             │
│                                           │
│ ปฏิเสธโดย: ผศ.ดร.สมหมาย (16:45)          │
└───────────────────────────────────────────┘

Features: - ไฮไลท์แถวที่ถูก reject (สีแดงอ่อน) - แสดงผลเดิม + เหตุผล + ผู้ปฏิเสธ - Input field เปล่า → กรอกผลใหม่ - กด "บันทึก" → Status เปลี่ยนเป็น preliminary อีกรอบ - ส่ง Approval ใหม่


📊 Process Flow

async function saveResults() {
  // 1. Validate
  const results = collectAllResults(); // รวบรวมผลจากฟอร์ม

  // 2. Check Critical
  const criticalResults = results.filter(r => 
    r.flag === 'critical_high' || r.flag === 'critical_low'
  );

  if (criticalResults.length > 0) {
    // แสดง Critical Alert Modal
    showCriticalAlertModal(criticalResults);
    // รอ user acknowledge ก่อนบันทึก
    await waitForAcknowledgement();
  }

  // 3. Save to Storage
  for (const result of results) {
    if (result.status === 'rejected') {
      // Re-entry case
      labResultService.reEnterResult(
        result.id, result.value, userId, userName, note
      );
    } else {
      // New entry
      labResultService.enterResult(
        result.id, result.value, userId, userName, note
      );
    }
  }

  // 4. Update Order Status
  const allEntered = checkAllResultsEntered(order);
  if (allEntered) {
    order.status = 'result_ready'; // รออนุมัติ
  } else {
    order.status = 'partial_result'; // ลงผลบางส่วน
  }

  // 5. Success
  showSuccessToast('บันทึกผลสำเร็จ');

  // 6. Redirect
  if (allEntered) {
    // ไปหน้า Result Approval (ถ้า user เป็น Supervisor)
    // หรือ กลับหน้าคิว
  }
}

✅ ขั้นตอนที่ 5: Result Approval (อนุมัติผล)

หน้า: modules/lab/result-approval.html
ผู้ใช้: หัวหน้าห้องแล็บ (Lab Supervisor), ผู้เชี่ยวชาญ
วัตถุประสงค์: ตรวจสอบและอนุมัติผลแล็บก่อนรายงาน


📊 Dashboard Statistics

Cards: | Card | ข้อมูล | Color | |------|--------|-------| | รออนุมัติ | Results status = preliminary | 🟡 Yellow | | ผลวิกฤต | Critical Results (รออนุมัติ) | 🔴 Red | | อนุมัติแล้ว | Results status = final (วันนี้) | 🟢 Green |


📋 Pending Approval List

แสดง Orders ที่มีผลรออนุมัติ:

Order Card: - Order Number, Patient Info - Priority Badge (STAT → แสดงก่อน) - จำนวนผลรออนุมัติ (3/5 รายการ) - ⚠️ Badge: "มีผลวิกฤต" (ถ้ามี Critical results) - 🎯 Badge: "มี Delta Check Warning" - ปุ่ม "ตรวจสอบ" → เปิด Approval Modal


🔍 Approval Modal

เมื่อคลิก "ตรวจสอบ" Order:

Section 1: Patient & Order Info

  • แสดงข้อมูลผู้ป่วย, Order details
  • Diagnosis / Clinical Note

Section 2: Results Review Table

Columns: | Column | Description | |--------|-------------| | ☑️ | Checkbox (เลือกอนุมัติบางรายการ) | | รายการตรวจ | Lab Item Name | | ผลเก่า | Previous Result (ถ้ามี) | | ผลใหม่ | Current Result (Bold, สี) | | หน่วย | Unit | | Ref Range | Normal Range | | Flag | Badge (Normal/High/Low/Critical) | | หมายเหตุ | Note จากเทคนิค | | Actions | ปุ่ม Quick Approve/Reject |

Row Highlighting: - 🟢 Normal results → ขาว - 🟡 High/Low → เหลืองอ่อน - 🔴 Critical → แดงอ่อน + ไอคอน ⚠️


🎯 Approval Actions

1️⃣ Quick Approve (อนุมัติรายการเดียว)

  • ปุ่ม ✓ ในแต่ละแถว
  • อนุมัติทันที 1 รายการ
  • Result status → final

2️⃣ Approve All (อนุมัติทั้งหมด)

  • ปุ่มใหญ่ "อนุมัติทั้งหมด"
  • อนุมัติทุกรายการในครั้งเดียว
  • Order status → approved
  • ทุก Result status → final

3️⃣ Approve Selected (อนุมัติบางรายการ) ⭐

  • Checkbox: เลือกรายการที่ต้องการอนุมัติ
  • ปุ่ม "อนุมัติที่เลือก (3)"
  • Confirmation dialog
  • ผลที่เลือก → final
  • ผลที่ไม่เลือก → ยังคง preliminary
  • Order status → partial_approved

Use Case: - อนุมัติผลที่แน่ใจก่อน - เก็บผลที่สงสัยไว้ตรวจสอบเพิ่ม - ผู้ป่วย STAT ต้องการผลบางรายการด่วน


❌ Rejection Actions

1️⃣ Quick Reject (ปฏิเสธรายการเดียว)

  • ปุ่ม ✗ ในแต่ละแถว
  • เปิด Rejection Modal

2️⃣ Reject Selected (ปฏิเสธบางรายการ)

  • Checkbox: เลือกรายการที่ต้องการปฏิเสธ
  • ปุ่ม "ปฏิเสธที่เลือก"
  • เปิด Rejection Modal

Rejection Modal:

╔═══════════════════════════════════════╗
║  ⚠️  ปฏิเสธผลแล็บ                     ║
╠═══════════════════════════════════════╣
║                                       ║
║  รายการที่เลือก:                      ║
║  • Glucose (185 mg/dL)                ║
║  • Creatinine (3.5 mg/dL)             ║
║                                       ║
║  เหตุผลการปฏิเสธ: *                  ║
║  ┌─────────────────────────────────┐  ║
║  │ ผลไม่สอดคล้องกับภาวะผู้ป่วย     │  ║
║  │ ขอให้ตรวจซ้ำด้วยเครื่องอื่น     │  ║
║  └─────────────────────────────────┘  ║
║                                       ║
║  ☑️ ต้องการเก็บ Specimen ใหม่        ║
║                                       ║
║  [ยืนยันปฏิเสธ]   [ยกเลิก]           ║
╚═══════════════════════════════════════╝

Fields: 1. เหตุผลการปฏิเสธ (Textarea - Required) - อธิบายว่าทำไมปฏิเสธ - ตัวอย่าง: "ผล Hemolysis", "ผลไม่สมเหตุสมผล"

  1. ☑️ ต้องการเก็บ Specimen ใหม่ (Checkbox)
  2. ✅ Checked → กลับไปขั้นตอน Specimen Collection
  3. ❌ Unchecked → กลับไปขั้นตอน Result Entry (เทคนิคแก้ไข/ตรวจซ้ำ)

Process:

async function confirmReject() {
  const requireNewSpecimen = checkbox.checked;

  // บันทึก Rejection
  labResultService.rejectSelectedResults(
    selectedIds, userId, userName, 
    'FREE_TEXT', reason, '', requireNewSpecimen
  );

  // Update Status
  results.forEach(r => r.status = 'rejected');

  // Redirect based on flag
  if (requireNewSpecimen) {
    // Order กลับไป Specimen Collection
    order.status = 'confirmed';
    order.hasRejectedResults = true;
    message = '📋 ส่งกลับเก็บสิ่งส่งตรวจใหม่';
  } else {
    // Order อยู่ Result Entry
    order.status = 'sent_to_lis';
    message = '📋 ส่งกลับให้เทคนิคแก้ไข';
  }
}


📌 Special Cases

🔹 Critical Results Workflow

เมื่ออนุมัติผลที่เป็น Critical:

  1. แสดง Critical Summary:

    ╔════════════════════════════════════════╗
    ║  🚨 พบผลวิกฤต 2 รายการ                ║
    ╠════════════════════════════════════════╣
    ║  • WBC: 22.5 K/µL (วิกฤตสูง)          ║
    ║  • K: 6.8 mEq/L (วิกฤตสูง)            ║
    ║                                        ║
    ║  ⚠️ กรุณาแจ้งแพทย์ทันที                ║
    ╚════════════════════════════════════════╝
    

  2. Doctor Notification:

  3. Auto-send notification to ordering doctor
  4. Log: แจ้งเวลาไหน, แจ้งใคร
  5. Print: Critical Result Report (ส่งด่วน)

🔹 Partial Approval Status

เมื่ออนุมัติบางรายการ:

Order Status → partial_approved

แสดงใน Dashboard:

┌──────────────────────────────────────┐
│ LAB202512-0001                       │
│ HN000123 - นายสมชาย ใจดี             │
│                                      │
│ 🟢 อนุมัติแล้ว: 2 รายการ            │
│    • CBC → final                     │
│    • Glucose → final                 │
│                                      │
│ 🟡 รออนุมัติ: 1 รายการ              │
│    • Creatinine → preliminary        │
│                                      │
│ ⏳ รอลงผล: 2 รายการ                  │
│    • HIV → pending (Outlab)          │
│    • HBsAg → pending (Outlab)        │
│                                      │
│ Status: partial_approved (3/5)       │
└──────────────────────────────────────┘

ผลที่อนุมัติแล้ว: - ✅ สามารถพิมพ์รายงานผล (Partial Report) - ✅ แพทย์ดูผลได้ (Finalized Results)

ผลที่ยังรอ: - ⏳ ยังไม่แสดงในรายงาน - ⏳ รออนุมัติหรือรอลงผลให้ครบ


✅ Success Flow

เมื่ออนุมัติครบทุกรายการ:

  1. Order status → approvedcompleted
  2. Result status → final (ทุกรายการ)
  3. Success Toast: "✅ อนุมัติผลสำเร็จ 5 รายการ"
  4. Auto-generate: Final Report (PDF)
  5. Notification: แจ้งแพทย์ว่ามีผลแล้ว

📄 ขั้นตอนที่ 6: Report & Notification (รายงานผล)

วัตถุประสงค์: แจ้งผลให้แพทย์และผู้ป่วย


📊 Report Types

1. Preliminary Report (ผลเบื้องต้น)

  • ใช้กรณี STAT → แพทย์ต้องการผลด่วน
  • พิมพ์จากหน้า Result Entry
  • มี Watermark: "PRELIMINARY - Not Final"
  • ไม่มีลายเซ็น

2. Partial Report (ผลบางส่วน)

  • พิมพ์จาก Partial Approval
  • แสดงเฉพาะผลที่อนุมัติแล้ว
  • ระบุว่า: "มีรายการรอดำเนินการ 2 รายการ"

3. Final Report (ผลสุดท้าย) ✅

  • พิมพ์เมื่ออนุมัติครบทุกรายการ
  • มีลายเซ็นอิเล็กทรอนิกส์
  • QR Code (สำหรับตรวจสอบความถูกต้อง)
  • Official document

Report Format:

┌──────────────────────────────────────────┐
│     โรงพยาบาลสมมติ                       │
│     LABORATORY REPORT                    │
├──────────────────────────────────────────┤
│ HN: HN000123                             │
│ ชื่อ: นายสมชาย ใจดี                      │
│ อายุ: 35 ปี  เพศ: ชาย                   │
│ แพทย์: นพ.สุรชัย ใจดี                    │
│ Order#: LAB202512-0001                   │
│ Order Date: 26/12/2568 10:30             │
├──────────────────────────────────────────┤
│ Test         Result   Unit   Ref Range  │
├──────────────────────────────────────────┤
│ WBC          7.8      K/µL   4.0-11.0   │
│ Hemoglobin   13.5     g/dL   12.0-16.0  │
│ Platelet     245      K/µL   150-450    │
│ Glucose      105 H    mg/dL  70-100     │
│ Creatinine   1.2      mg/dL  0.6-1.2    │
├──────────────────────────────────────────┤
│ Flag: H = High, L = Low                 │
│                                          │
│ ลงผลโดย: นางสาววรรณา ใจดี               │
│ อนุมัติโดย: ผศ.ดร.สมหมาย พิทักษ์        │
│ Approved: 26/12/2568 16:45              │
│                                          │
│ [ลายเซ็นอิเล็กทรอนิกส์]    [QR Code]    │
└──────────────────────────────────────────┘


🔔 Notification System

แจ้งแพทย์:

  • 📧 Email notification (ถ้ามี)
  • 📱 SMS/LINE (สำหรับ Critical results)
  • 🔔 In-app notification (HIS system)
  • 🖨️ พิมพ์ส่งหน้าห้องตรวจ

แจ้งผู้ป่วย (OPD):

  • 📱 SMS: "ผลแล็บพร้อมแล้ว กรุณามารับที่ห้องแล็บ"
  • 🖨️ พิมพ์ใบนัดรับผล

📊 Timeline Summary

Order LAB202512-0001 - Timeline:

09:00 ├─ Order Created (Doctor)
09:15 ├─ Specimen Collected (Phlebotomist)
      │  Barcode: SPEC20251226-0001
09:30 ├─ Sent to Lab (LIS)
10:00 ├─ In Progress (Technician)
      │  Instrument: Sysmex XN-1000
10:30 ├─ Result Entered (Technician)
      │  Status: preliminary
      │  ⚠️ Delta Check: Glucose ↑24%
11:00 ├─ Approved (Supervisor)
      │  Status: final
      │  Approved by: ผศ.ดร.สมหมาย
11:05 ├─ Notification Sent (System)
      │  → แจ้งนพ.สุรชัย
11:10 └─ Completed

TAT: 2 ชั่วโมง 10 นาที ✅

🎯 Special Workflows Summary

1. STAT Order Fast Track 🔴

Doctor Order (STAT)
  → Auto-priority ด้านบนสุด
  → Specimen Collection (ด่วน)
  → Result Entry (Critical Alert)
  → Quick Approval (Preliminary Report)
  → Notify Doctor ทันที

Target TAT: < 1 ชม.

2. Outlab Order 📤

Doctor Order (Outlab items)
  → Specimen Collection
  → ส่งแล็บนอก (External Lab)
  → รอรับผล (2-7 วัน)
  → Upload PDF Result
  → Approval
  → Report

Note: ไม่มี Delta Check, ไม่มี Critical Alert

3. Rejection - Re-entry 🔄

Result Entry → preliminary
  ↓
Approval → ❌ Reject (requireNew = false)
  ↓
Result Entry (แสดงผลเก่า + เหตุผล)
  ↓ Re-enter
preliminary → Approval อีกรอบ

4. Rejection - Recollection 🔄

Specimen Collected → Quality = Rejected
  ↓
Order status ยังคง 'confirmed'
  ↓
Specimen Collection (เก็บใหม่)
  ↓ New specimen
Collected → Result Entry → Approval

📌 Status Transition Diagram

stateDiagram-v2
    [*] --> pending: Order Created
    pending --> confirmed: Doctor Confirm
    confirmed --> collecting: Start Collection
    collecting --> specimen_collected: All Collected
    collecting --> confirmed: Specimen Rejected
    specimen_collected --> sent_to_lis: Send to Lab
    sent_to_lis --> in_progress: Start Testing
    in_progress --> partial_result: Enter Partial
    partial_result --> result_ready: Enter All
    result_ready --> partial_approved: Approve Some
    partial_approved --> approved: Approve Rest
    result_ready --> approved: Approve All
    approved --> completed: Final Report
    result_ready --> sent_to_lis: Reject (no new specimen)
    result_ready --> confirmed: Reject (need new specimen)

    confirmed --> cancelled: Cancel Order

Last Updated: December 26, 2025
Version: 2.0 (Complete)
Status: ✅ Ready for Review


📝 หมายเหตุสำหรับทีม UX/UI

ความสำคัญของแต่ละ Feature:

🔴 Critical (Must Have):

  • STAT Priority → แสดงเด่น, ประมวลผลก่อน
  • Specimen QC → ป้องกันผลแล็บผิดพลาด
  • Result Validation → Auto-calculate Flag, Panic value check
  • Critical Alert Modal → แจ้งเตือนผลวิกฤต
  • Approval/Rejection Flow → ต้องชัดเจน, ไม่สับสน

🟡 Important (Should Have):

  • Delta Check → ตรวจจับความผิดปกติ
  • Outlab File Upload → รองรับแล็บนอก
  • Partial Approval → ยืดหยุ่นการอนุมัติ
  • Auto-refresh → ข้อมูล Real-time

🟢 Nice to Have:

  • Print templates → สวยงาม, มีโลโก้
  • Charts/Graphs → Trend ผลแล็บ
  • Barcode scanning → รวดเร็ว

Design Considerations:

  1. Color Coding สำคัญ:
  2. 🟢 เขียว = ปกติ, สำเร็จ
  3. 🟡 เหลือง = เตือน, รอดำเนินการ
  4. 🔴 แดง = วิกฤต, ปัญหา
  5. 🟣 ม่วง = กำลังดำเนินการ
  6. 🔵 น้ำเงิน = ข้อมูล

  7. Typography:

  8. Lab values → Monospace font (่อ่านตัวเลขชัด)
  9. Critical results → Bold, ใหญ่กว่าปกติ
  10. Thai + English → รองรับทั้งสองภาษา

  11. Responsive:

  12. Desktop → Full feature
  13. Tablet → Optimize for touchscreen
  14. Mobile → Essential features only (Result viewing)

  15. Accessibility:

  16. High contrast สำหรับ Critical results
  17. Keyboard shortcuts (Ctrl+S = Save, Ctrl+P = Print)
  18. Screen reader friendly