# 📋 HƯỚNG DẪN TÍNH NĂNG XUẤT FILE CÔNG VĂN

## 🎯 Mô tả

Tính năng **Xuất file** cho phép quản lý việc xuất công văn từ kho lưu trữ cho nhân viên, bao gồm:
- Ghi nhận số lượng xuất
- Lưu thông tin người nhận
- Ghi lý do xuất
- Tự động giảm số lượng tồn kho
- (Tùy chọn) Lưu lịch sử xuất vào database

---

## ✅ Đã hoàn thành

### Backend (`modules/incoming_service.php`)
- ✅ Thêm case 'export' để xử lý request
- ✅ Validation đầy đủ:
  - Kiểm tra ID document
  - Kiểm tra số lượng > 0
  - Kiểm tra người nhận
  - Kiểm tra lý do xuất
  - Kiểm tra số lượng không vượt quá tồn kho
- ✅ Tự động giảm số lượng trong bảng `Document`
- ✅ Tự động lưu lịch sử vào bảng `DocumentExport` (nếu bảng tồn tại)

### Frontend (`assets/js/incoming.js`)
- ✅ Gửi AJAX request đến server
- ✅ Hiển thị loading notification
- ✅ Xử lý response success/error
- ✅ Tự động reload trang sau khi xuất thành công

### UI Components
- ✅ Modal "XUẤT FILE" với form đầy đủ
- ✅ Validation client-side
- ✅ Number spinner cho trường số lượng
- ✅ Custom dropdown cho người nhận

---

## 📦 Cài đặt (Tùy chọn)

Nếu muốn **lưu lịch sử xuất file**, chạy script SQL:

```bash
# Chạy file SQL trong SSMS hoặc SQL Server Management Studio
database/create_document_export_table.sql
```

Script sẽ tạo:
- ✅ Bảng `DocumentExport` với các trường:
  - `Id`: Primary key (auto increment)
  - `DocumentId`: ID của document (Foreign Key)
  - `Quantity`: Số lượng xuất
  - `Recipient`: MSNV người nhận
  - `Reason`: Lý do xuất
  - `ExportDate`: Ngày xuất (auto GETDATE())
  - `ExportedBy`: MSNV người xuất
- ✅ Các index để tăng hiệu suất

**Lưu ý:** Nếu không chạy script này, tính năng xuất file vẫn hoạt động bình thường, chỉ không lưu lịch sử.

---

## 🔄 Luồng hoạt động

```
1. User click nút "Xuất file" (nút xanh, icon máy in)
   ↓
2. JavaScript mở modal "XUẤT FILE"
   ↓
3. User điền form:
   - Số lượng (có spinner ⬆️⬇️)
   - Người nhận (dropdown: 00092 hoặc 00096)
   - Lý do xuất
   ↓
4. Click "Xuất file" → Validation (client)
   ↓
5. Gửi AJAX POST → modules/incoming_service.php
   ↓
6. Server validation:
   - Kiểm tra số lượng hiện có
   - Kiểm tra số lượng xuất không vượt quá
   ↓
7. Server xử lý:
   - Giảm Quantity trong bảng Document
   - (Nếu có) Tạo record trong DocumentExport
   ↓
8. Trả về JSON response
   ↓
9. Client hiển thị thông báo + reload page
```

---

## 📊 Dữ liệu gửi lên server

**POST Request:** `modules/incoming_service.php`

```javascript
{
  action: 'export',
  license: 'xxx',           // License từ settings
  document_id: 5,           // ID của document
  export_quantity: 2,       // Số lượng xuất
  export_recipient: '00092', // MSNV người nhận
  export_reason: 'Gửi cho ban giám đốc' // Lý do xuất
}
```

**Response Success:**
```json
{
  "success": true,
  "message": "Xuất file thành công. Đã xuất 2 file cho 00092"
}
```

**Response Error:**
```json
{
  "success": false,
  "message": "Số lượng xuất vượt quá số lượng hiện có (1)"
}
```

---

## 🔒 Validation

### Client-side (JavaScript)
1. ✅ Đầy đủ thông tin (document_id, quantity, recipient, reason)
2. ✅ Số lượng > 0
3. ✅ Số lượng không vượt quá max (từ DB)

### Server-side (PHP)
1. ✅ ID document hợp lệ (> 0)
2. ✅ Số lượng > 0
3. ✅ Người nhận không rỗng
4. ✅ Lý do xuất không rỗng
5. ✅ Document tồn tại
6. ✅ Số lượng không vượt quá số lượng hiện có trong DB

---

## 🎨 UI/UX Features

1. **Number Spinner**: Mũi tên lên/xuống để tăng/giảm số lượng
2. **Max Validation**: Placeholder hiển thị "Tối đa: X"
3. **Custom Dropdown**: Dropdown đẹp cho "Người nhận"
4. **Loading State**: Hiển thị "Đang xử lý..." khi submit
5. **Auto Reload**: Tự động reload sau khi xuất thành công
6. **Toast Notifications**: Thông báo đẹp (success/error/info)

---

## 📝 Database Schema

### Bảng Document (Đã có sẵn)
```sql
-- Trường Quantity sẽ tự động giảm khi xuất
ALTER TABLE Document
  Quantity INT DEFAULT 0
```

### Bảng DocumentExport (Tùy chọn - cần chạy script)
```sql
CREATE TABLE DocumentExport (
    Id INT IDENTITY(1,1) PRIMARY KEY,
    DocumentId INT NOT NULL,
    Quantity INT NOT NULL,
    Recipient NVARCHAR(10),
    Reason NVARCHAR(500),
    ExportDate DATETIME DEFAULT GETDATE(),
    ExportedBy NVARCHAR(10),
    FOREIGN KEY (DocumentId) REFERENCES Document(Id) ON DELETE CASCADE
);
```

---

## 🔍 Cách kiểm tra lịch sử xuất

Sau khi chạy script SQL và xuất file, có thể xem lịch sử:

```sql
-- Xem tất cả lịch sử xuất
SELECT 
    de.Id,
    de.DocumentId,
    d.ID_Symbol AS [Số hiệu],
    d.TitleVi AS [Tiêu đề],
    de.Quantity AS [Số lượng xuất],
    de.Recipient AS [Người nhận],
    de.Reason AS [Lý do],
    de.ExportDate AS [Ngày xuất],
    de.ExportedBy AS [Người xuất]
FROM DocumentExport de
LEFT JOIN Document d ON de.DocumentId = d.Id
ORDER BY de.ExportDate DESC;

-- Xem lịch sử xuất của 1 document cụ thể
SELECT * FROM DocumentExport 
WHERE DocumentId = 5 
ORDER BY ExportDate DESC;

-- Thống kê số lượng xuất theo document
SELECT 
    d.ID_Symbol,
    d.TitleVi,
    SUM(de.Quantity) AS [Tổng đã xuất],
    d.Quantity AS [Còn lại]
FROM Document d
LEFT JOIN DocumentExport de ON d.Id = de.DocumentId
GROUP BY d.ID_Symbol, d.TitleVi, d.Quantity
ORDER BY SUM(de.Quantity) DESC;
```

---

## ⚠️ Lưu ý

1. **Không thể hoàn tác**: Khi xuất file, số lượng sẽ giảm ngay lập tức và không thể hoàn tác tự động.
2. **Cần có số lượng**: Nút "Xuất file" chỉ hiển thị khi `Quantity > 0`.
3. **Người nhận**: Hiện tại chỉ có 2 lựa chọn (00092, 00096). Có thể mở rộng sau.
4. **Quyền hạn**: Chưa có kiểm tra quyền. Mọi user đăng nhập đều có thể xuất.

---

## 🚀 Mở rộng tương lai

1. **Quyền hạn**: Chỉ cho phép một số user được xuất file
2. **Người nhận**: Load danh sách từ bảng DataWork thay vì hardcode
3. **In phiếu xuất**: In PDF phiếu xuất kho
4. **Thống kê**: Dashboard thống kê xuất file theo tháng/quý
5. **Notification**: Gửi email/Zalo cho người nhận khi được xuất file
6. **Trả lại**: Chức năng trả lại file vào kho (tăng Quantity)

---

## 📞 Support

Nếu có vấn đề, kiểm tra:
1. Console (F12) xem có lỗi JavaScript không
2. Network tab xem request/response
3. PHP error log
4. Database connection

---

**Version:** 1.0  
**Last Updated:** 2025-10-09  
**Author:** Luna HR System




