# 🔗 ฟังก์ชัน showSurveyByToken - วิธีใช้งาน

## 📍 ตำแหน่ง
- **File**: `app/Http/Controllers/SurveyController.php`
- **Method**: `showSurveyByToken($token)`
- **Route**: `GET /survey/{token}`

## 🎯 วัตถุประสงค์
แสดงแบบประเมินให้ผู้ใช้ทำ โดยใช้ Token แทนการล็อกอิน

## 🔄 วิธีการทำงาน

### 1. **รับ Token**
```php
public function showSurveyByToken($token)
```
- รับ Token จาก URL: `/survey/abc123def456`
- Token นี้ถูกสร้างเมื่อ Admin ส่งแบบประเมิน

### 2. **ค้นหา SurveyInvitation**
```php
$invitation = SurveyInvitation::with(['survey', 'customer', 'serviceRequest'])
    ->where('token', $token)
    ->first();
```
- ค้นหาแบบประเมินจาก Token
- ดึงข้อมูลที่เกี่ยวข้อง: survey, customer, serviceRequest

### 3. **ตรวจสอบความถูกต้อง**
```php
if (!$invitation) {
    return view('survey.error', [
        'message' => 'ไม่พบแบบประเมินหรือ Token ไม่ถูกต้อง'
    ]);
}
```

### 4. **ตรวจสอบวันหมดอายุ**
```php
if ($invitation->expires_at && $invitation->expires_at->isPast()) {
    return view('survey.error', [
        'message' => 'แบบประเมินนี้หมดอายุแล้ว'
    ]);
}
```

### 5. **ตรวจสอบสถานะ**
```php
if ($invitation->status === 'completed') {
    return view('survey.completed', [
        'message' => 'คุณทำแบบประเมินนี้เสร็จแล้ว'
    ]);
}
```

### 6. **อัปเดตสถานะเมื่อเปิด**
```php
if ($invitation->status === 'sent' && !$invitation->email_opened_at) {
    $invitation->update([
        'status' => 'opened',
        'email_opened_at' => now()
    ]);
}
```

### 7. **ดึงคำถาม**
```php
$questions = DB::table('survey_questions')
    ->where('Survey_ID', $invitation->Survey_ID)
    ->where('is_active', 1)
    ->orderBy('order')
    ->get();
```

### 8. **แสดงหน้าแบบประเมิน**
```php
return view('survey.take', [
    'invitation' => $invitation,
    'survey' => $invitation->survey,
    'questions' => $formattedQuestions,
    'hasSuggestions' => $invitation->survey->has_suggestions ?? false
]);
```

## 🌐 วิธีเข้าถึง

### URL Format
```
http://localhost:8000/survey/{token}
```

### ตัวอย่าง
```
http://localhost:8000/survey/9WBuWAx2jplzEh3W43JFILz43bWxRUXw
```

## 📱 หน้าจอที่แสดง

### 1. **สำเร็จ** - `survey.take`
- หน้าแบบประเมินพร้อมคำถาม
- ปุ่มส่งคำตอบ
- ข้อมูลแบบประเมินและผลิตภัณฑ์

### 2. **ข้อผิดพลาด** - `survey.error`
- Token ไม่ถูกต้อง
- แบบประเมินหมดอายุ
- เกิดข้อผิดพลาด

### 3. **เสร็จสิ้น** - `survey.completed`
- แบบประเมินทำเสร็จแล้ว

## 🔐 ความปลอดภัย

### 1. **Token-based Access**
- ไม่ต้องล็อกอิน
- ใช้ Token แทนการยืนยันตัวตน
- Token มีอายุจำกัด

### 2. **การตรวจสอบ**
- ตรวจสอบ Token ถูกต้อง
- ตรวจสอบวันหมดอายุ
- ตรวจสอบสถานะแบบประเมิน

### 3. **การติดตาม**
- บันทึกเวลาที่เปิด email
- อัปเดตสถานะเป็น 'opened'
- Log ข้อผิดพลาด

## 📊 Flow การทำงาน

```mermaid
graph TD
    A[ผู้ใช้คลิกลิงก์ใน Email] --> B[GET /survey/{token}]
    B --> C[showSurveyByToken]
    C --> D{Token ถูกต้อง?}
    D -->|ไม่| E[แสดงหน้า Error]
    D -->|ใช่| F{หมดอายุ?}
    F -->|ใช่| E
    F -->|ไม่| G{ทำเสร็จแล้ว?}
    G -->|ใช่| H[แสดงหน้า Completed]
    G -->|ไม่| I[อัปเดตสถานะเป็น 'opened']
    I --> J[ดึงคำถาม]
    J --> K[แสดงหน้าแบบประเมิน]
```

## 🛠️ การใช้งานจริง

### 1. **Admin ส่งแบบประเมิน**
- สร้าง SurveyInvitation
- สร้าง Token (32 ตัวอักษร)
- ส่ง Email พร้อมลิงก์

### 2. **ผู้ใช้ได้รับ Email**
- คลิกลิงก์ใน Email
- เปิดหน้าแบบประเมิน
- ทำแบบประเมิน

### 3. **ระบบติดตาม**
- บันทึกเวลาที่เปิด
- บันทึกเวลาที่ทำเสร็จ
- อัปเดตสถานะ

## 📝 ตัวอย่างการใช้งาน

### ใน Email Template
```html
<a href="{{ route('survey.take', ['token' => $invitation->token]) }}">
    ทำแบบประเมินตอนนี้ →
</a>
```

### URL ที่ได้
```
http://localhost:8000/survey/9WBuWAx2jplzEh3W43JFILz43bWxRUXw
```

## ⚠️ ข้อควรระวัง

1. **Token ต้องถูกต้อง** - ตรวจสอบจากฐานข้อมูล
2. **ไม่หมดอายุ** - ตรวจสอบ expires_at
3. **ยังไม่เสร็จ** - ตรวจสอบ status
4. **Error Handling** - จัดการข้อผิดพลาดให้ดี

## 🎯 สรุป

`showSurveyByToken` เป็นฟังก์ชันหลักที่ทำให้ผู้ใช้สามารถทำแบบประเมินได้โดยไม่ต้องล็อกอิน ใช้ Token เป็นตัวยืนยันตัวตน และมีการตรวจสอบความถูกต้องหลายระดับเพื่อความปลอดภัย
