# Hướng dẫn phân loại Packing List

# Hướng dẫn sử dụng — Chức năng Phân loại Thành phẩm

---

## Mục lục

1. [Mục đích](#1-mục-đích)
2. [URL truy cập](#2-url-truy-cập)
3. [Mục lục chức năng trên trang](#3-mục-lục-chức-năng-trên-trang)
4. [Truy cập chức năng](#4-truy-cập-chức-năng)
5. [Tìm kiếm và xem lịch sử phân loại](#5-tìm-kiếm-và-xem-lịch-sử-phân-loại)
6. [Tạo phiếu phân loại mới](#6-tạo-phiếu-phân-loại-mới)
7. [Điều kiện quét hợp lệ và không hợp lệ](#7-điều-kiện-quét-hợp-lệ-và-không-hợp-lệ)
8. [Quy tắc nhập số lượng và xác nhận lưu](#8-quy-tắc-nhập-số-lượng-và-xác-nhận-lưu)
9. [Kết quả sau khi lưu](#9-kết-quả-sau-khi-lưu)
10. [Các thông báo lỗi thường gặp](#10-các-thông-báo-lỗi-thường-gặp)
11. [Các trường và hành vi bị khóa hoặc giới hạn thao tác](#11-các-trường-và-hành-vi-bị-khóa-hoặc-giới-hạn-thao-tác)

---

## 1. Mục đích

Chức năng **Phân loại thành phẩm** dùng để ghi nhận việc phân bổ số lượng hàng hóa từ kho vào từng Packing List theo đơn hàng thực tế. Có **3 loại phân loại**:

| Loại | Ý nghĩa | Tồn kho thay đổi |
|---|---|---|
| **Nhập kho** | Hàng từ PKL chuyển vào kho chung (phân loại để giảm bớt dư thừa) | ↓ Giảm |
| **Nhập PKL** | Hàng từ kho phân bổ vào PKL (bổ sung đủ số lượng còn thiếu) | ↑ Tăng |
| **Nhập PKL Customer** | Chuyển hàng từ một PKL gốc sang PKL khách hàng | Cập nhật chéo |

> **Lưu ý quan trọng:** Phân loại phải hoàn thành **trước khi xuất kho**. Nếu bỏ qua bước này, chức năng Xuất kho sẽ báo lỗi *"Phân loại chưa khớp"* và không cho lưu phiếu xuất.

---

## 2. URL truy cập

| Ngôn ngữ | Đường dẫn |
|---|---|
| Tiếng Việt | `/vi/finished-product-classification` |
| Tiếng Anh | `/en/finished-product-classification` |

---

## 3. Mục lục chức năng trên trang

Trang được chia làm hai cột:

- **Cột trái:** Lịch sử các phiếu phân loại đã tạo — tìm kiếm, lọc, chọn để xem chi tiết.
- **Cột phải:** Chi tiết từng phiếu được chọn — hiển thị danh sách đơn hàng, số lượng phân loại, số lượng tồn.

Phía trên cột trái có **3 nút tạo phiếu mới**:

| Nút | Loại phân loại |
|---|---|
| Nhập kho | Phân loại nhập kho (giảm tồn) |
| Nhập PKL | Phân loại nhập PKL (tăng tồn) |
| Nhập PKL Customer | Phân loại chuyển sang PKL khách hàng |

---

## 4. Truy cập chức năng

### Yêu cầu quyền

| Quyền | Cho phép làm gì |
|---|---|
| `View` | Vào trang, xem lịch sử, xem chi tiết |
| `Edit` | Tạo phiếu phân loại mới (3 nút phân loại mới được kích hoạt) |

Nếu không có quyền `View`, hệ thống hiển thị trang **"Từ chối truy cập"**.  
Nếu chỉ có quyền `View` (không có `Edit`), các nút **Nhập kho / Nhập PKL / Nhập PKL Customer** bị vô hiệu hóa.

### Yêu cầu tài khoản

Tài khoản đăng nhập **phải được gán Chi nhánh**. Nếu chưa được gán, khi cố quét mã hệ thống sẽ báo lỗi:  
*"Tài khoản chưa được gán Chi nhánh. Vui lòng liên hệ Admin."*

---

## 5. Tìm kiếm và xem lịch sử phân loại

### Tìm kiếm theo mã

- Nhập mã phiếu hoặc mã Packing List vào ô tìm kiếm ở đầu cột trái.

### Lọc nâng cao

Nhấn biểu tượng **Bộ lọc** (góc trên cột trái) để mở bảng lọc:

| Trường lọc | Mô tả |
|---|---|
| Loại phân loại | Tất cả / Nhập PKL / Nhập kho |
| Từ ngày | Ngày tạo phiếu (định dạng `dd-mm-yyyy`) |
| Đến ngày | Ngày tạo phiếu (định dạng `dd-mm-yyyy`) |
| Người tạo | Tên người tạo phiếu |

Nhấn **"Áp dụng"** để lọc, **"Xóa lọc"** để đặt lại.

> Khi có bộ lọc đang hoạt động, biểu tượng Bộ lọc hiển thị dấu chấm màu để nhắc nhở.

### Xem chi tiết phiếu

1. Nhấp vào một phiếu trong danh sách bên trái.
2. Cột phải hiển thị chi tiết phiếu đó:

| Thông tin | Mô tả |
|---|---|
| Mã phiếu | Mã định danh phiếu phân loại |
| Loại | Badge hiển thị: **Nhập kho** / **Nhập PKL** / **Nhập PKL Customer** |
| Người tạo | Họ tên người thực hiện |
| Thời gian tạo | Ngày giờ tạo phiếu |
| Mã đơn hàng / SKU | Tên và mã định danh sản phẩm |
| SL phân loại | Số lượng đã phân loại trong lần này |
| SL tồn | Số lượng tồn kho sau phân loại |
| SL cần | Số lượng cần phân loại theo kế hoạch |

Nhấn **"Chi tiết"** trên từng dòng đơn hàng để xem danh sách chi tiết theo từng thùng và Packing List.

---

## 6. Tạo phiếu phân loại mới

### 6.1. Phân loại Nhập kho (`Nhập kho`)

Dùng khi hàng đã được **nhập vào kho nhiều hơn đơn hàng yêu cầu**, cần phân loại để điều chỉnh về đúng số lượng.

**Bước 1 — Mở cửa sổ phân loại**

Nhấn nút **"Nhập kho"** → cửa sổ **"Phân loại nhập kho"** (viền xanh lá) mở ra.

**Bước 2 — Quét mã Packing List**

- Ô nhập ở trên cùng: *"Quét mã PKL"*.
- Dùng máy quét QR hoặc nhập tay mã PKL → nhấn **Enter**.
- Thông tin PKL và danh sách thùng hàng / đơn hàng hiện ra bên dưới.
- Có thể quét thêm nhiều PKL khác vào cùng một phiếu.

**Bước 3 — Nhập số lượng phân loại**

Mỗi dòng đơn hàng hiển thị:

| Cột | Ý nghĩa |
|---|---|
| Mã / Tên đơn hàng | Định danh sản phẩm |
| SL cần | Số lượng hệ thống tính cần phân loại (`nhập kho − đơn hàng`) |
| SL thực phân loại | **Nhập tay** — số lượng thực tế phân loại |

> **Cột trái:** Nhấp vào một PKL trong danh sách để xem chi tiết thùng hàng của PKL đó ở cột phải.

**Bước 4 — Xác nhận**

- Kiểm tra tổng `X / Y PCS` ở thanh tiêu đề cửa sổ.
- Nhấn **"Xác nhận"** → hộp thoại xác nhận hiện ra → nhấn **"Xác nhận"** lần nữa để lưu.

---

### 6.2. Phân loại Nhập PKL (`Nhập PKL`)

Dùng khi **đơn hàng còn thiếu số lượng nhập kho**, cần phân bổ thêm hàng từ kho vào PKL.

**Bước 1 — Mở cửa sổ phân loại**

Nhấn nút **"Nhập PKL"** → cửa sổ **"Phân loại nhập PKL"** (viền xanh dương) mở ra.

**Bước 2 — Quét mã Packing List**

Thao tác tương tự mục 6.1. Hệ thống tự động tính:

- **SL cần** = `đơn hàng − nhập kho` (số lượng còn thiếu).
- **SL gợi ý** = số lượng tồn kho còn có thể phân bổ cho đơn hàng này (đã trừ các PKL khác đang quét).

**Bước 3 — Nhập / điều chỉnh số lượng**

- Hệ thống tự điền SL gợi ý vào ô. Có thể sửa lại nếu cần.
- Validation nếu cùng một đơn hàng xuất hiện trên nhiều PKL, hệ thống kiểm tra tổng cộng không vượt quá tồn kho.

**Bước 4 — Xác nhận** — tương tự mục 6.1.

---

### 6.3. Phân loại Nhập PKL cho khách hàng (`Nhập PKL Customer`)

Dùng để chuyển hàng từ **PKL nguồn (inbound)** sang **PKL cho khách hàng (customer)**.

**Bước 1 — Mở cửa sổ**

Nhấn nút **"Nhập PKL Customer"** → cửa sổ có **2 ô quét riêng biệt**.

**Bước 2 — Quét PKL nguồn (bên trái)**

- Ô **"Quét mã PKL"**: quét QR hoặc nhập mã PKL gốc (PKL chứa hàng trong kho).
- PKL được thêm vào danh sách bên trái.

**Bước 3 — Quét PKL khách hàng (bên phải)**

- Ô **"Quét mã Packing List Customer"**: quét QR hoặc nhập mã PKL khách hàng.
- Chỉ chấp nhận **PKL loại Customer** — nếu quét PKL thường sẽ báo lỗi: *"Vui lòng quét Packing List Customer."*

**Bước 4 — Nhập số lượng và xác nhận** — tương tự các bước trên.

---

## 7. Điều kiện quét hợp lệ và không hợp lệ

### ✅ Quét hợp lệ — PKL được thêm vào khi

| Điều kiện | Chi tiết |
|---|---|
| Mã tồn tại | QR code / mã PKL được tìm thấy trong hệ thống |
| Chưa xuất kho | Trạng thái PKL không phải `completed_outbound` hoặc `partial_outbound` |
| Chưa có trong danh sách | PKL chưa được quét trong phiếu đang làm |
| Tài khoản có chi nhánh | Người dùng đã được gán chi nhánh |

### ❌ Quét không hợp lệ — Hệ thống báo lỗi khi

| Trường hợp | Thông báo |
|---|---|
| Ô nhập trống | *"Vui lòng không để trống"* |
| Mã không tồn tại | *"Không tìm thấy Packing List"* |
| PKL đã được xuất kho | *"Packing List đã xuất kho"* |
| PKL đã có trong danh sách | *"Packing List đã tồn tại trong danh sách"* |
| PKL không khả dụng (mọi thùng đều trống) | *"Packing List không khả dụng"* |
| Quét PKL thường vào ô PKL Customer | *"Vui lòng quét Packing List Customer."* |
| Tài khoản chưa có chi nhánh | *"Tài khoản chưa được gán Chi nhánh. Vui lòng liên hệ Admin."* |

---

## 8. Quy tắc nhập số lượng và xác nhận lưu

### Quy tắc chung cho mọi loại phân loại

| Quy tắc | Chi tiết |
|---|---|
| Phải lớn hơn 0 | Không được để trống hoặc nhập 0 |
| Chỉ nhập số nguyên dương | Không nhập số thập phân, chữ cái, ký tự đặc biệt |
| Tối đa 12 chữ số | Hệ thống tự chặn khi vượt giới hạn |

### Quy tắc riêng theo loại

**Nhập kho (giảm tồn):**
- SL thực phân loại ≤ SL nhập kho của đơn hàng đó.
- Lỗi nếu vượt: *"Không nhập vượt quá số lượng đang có của đơn hàng (X)"*

**Nhập PKL (tăng tồn):**
- Tổng SL phân loại của cùng một đơn hàng trên nhiều PKL ≤ tổng tồn kho khả dụng.
- Lỗi nếu vượt: *"Không nhập vượt quá số tồn (X)"*
- Validation chạy theo thời gian thực khi nhập — thông báo lỗi hiện ngay dưới ô nhập.

### Điều kiện để lưu phiếu thành công

Tất cả điều kiện sau phải đồng thời thỏa mãn:

- [x] Đã quét ít nhất **1 Packing List**.
- [x] Tất cả dòng đơn hàng (không bị xóa, không trống) có **SL > 0**.
- [x] Không có dòng nào còn **cảnh báo lỗi** (ô noti không rỗng).
- [x] Tài khoản có **chi nhánh hợp lệ**.
- [x] Phiên đăng nhập **còn hiệu lực**.

---

## 9. Kết quả sau khi lưu

Sau khi xác nhận thành công:

1. **Phiếu phân loại được tạo** — mã phiếu duy nhất được sinh tự động.
2. **Tồn kho cập nhật:**
   - **Nhập kho:** tồn kho **giảm** theo SL phân loại.
   - **Nhập PKL:** tồn kho **tăng** theo SL phân loại.
3. **Lịch sử cập nhật** — phiếu mới xuất hiện đầu danh sách bên trái với badge loại tương ứng.
4. **Cửa sổ tự đóng** — màn hình chính tự làm mới.

### Trạng thái Packing List sau phân loại

| Trường hợp | Trạng thái |
|---|---|
| Tổng SL thực phân loại = SL cần (tất cả dòng) | **Phân loại hoàn tất** (`completed_classification`) |
| Tổng SL thực phân loại < SL cần (có dòng còn thiếu) | **Phân loại một phần** (`partial_classification`) |

> PKL ở trạng thái **phân loại một phần** vẫn có thể xuất kho nhưng hệ thống sẽ báo không khớp nếu tổng số lượng đơn hàng chưa đủ.

---

## 10. Các thông báo lỗi thường gặp

### Lỗi khi quét mã

| Thông báo | Nguyên nhân | Cách xử lý |
|---|---|---|
| *"Vui lòng không để trống"* | Nhấn Enter khi ô trống | Nhập mã trước khi Enter |
| *"Không tìm thấy Packing List"* | Mã không tồn tại | Kiểm tra lại mã PKL |
| *"Packing List đã xuất kho"* | PKL đã được xuất hoàn tất | PKL này không phân loại được nữa |
| *"Packing List đã tồn tại trong danh sách"* | Quét trùng | Không cần quét lại |
| *"Packing List không khả dụng"* | PKL không còn dữ liệu hợp lệ | Kiểm tra lại trạng thái PKL |
| *"Tài khoản chưa được gán Chi nhánh..."* | Tài khoản thiếu cấu hình | Liên hệ Admin để gán chi nhánh |

### Lỗi khi nhập số lượng

| Thông báo | Nguyên nhân | Cách xử lý |
|---|---|---|
| *"Vui lòng nhập số lượng lớn hơn 0"* | Ô để trống hoặc nhập 0 | Nhập số ≥ 1 |
| *"Không nhập vượt quá số lượng đang có của đơn hàng (X)"* | SL > SL nhập kho (mode Nhập kho) | Giảm SL về ≤ X |
| *"Không nhập vượt quá số tồn (X)"* | Tổng SL vượt tồn kho (mode Nhập PKL) | Giảm SL về ≤ X |

### Lỗi khi xác nhận lưu

| Thông báo | Nguyên nhân | Cách xử lý |
|---|---|---|
| *"Vui lòng kiểm tra lại số lượng phân loại"* | Còn dòng có SL = 0 hoặc có lỗi validation | Kiểm tra và sửa các ô đang báo lỗi |
| *"Không có dữ liệu hợp lệ để lưu"* | Tất cả thùng/đơn hàng đã bị xóa hoặc trống | Quét lại PKL và nhập số lượng |
| *"Phiên đăng nhập không hợp lệ..."* | Session hết hạn | Tải lại trang và đăng nhập lại |
| *"Không thể tạo phiếu phân loại"* | Lỗi từ phía hệ thống | Thử lại, hoặc liên hệ bộ phận kỹ thuật |

---

## 11. Các trường và hành vi bị khóa hoặc giới hạn thao tác

### Nút bị vô hiệu hóa theo quyền

| Nút / Thao tác | Điều kiện bị khóa |
|---|---|
| Nút **Nhập kho** | Tài khoản không có quyền `Edit` |
| Nút **Nhập PKL** | Tài khoản không có quyền `Edit` |
| Nút **Nhập PKL Customer** | Tài khoản không có quyền `Edit` |

### Hành vi bị giới hạn trong cửa sổ phân loại

| Hành vi | Giải thích |
|---|---|
| Không thể đóng bằng phím **Esc** | Hệ thống chặn để tránh mất dữ liệu đang nhập |
| Không thể đóng bằng cách nhấp ra ngoài | Tương tự — phải bấm **Hủy** hoặc **Xác nhận** |
| Dòng đơn hàng có SL nhập kho = 0 tự động bị ẩn / đánh dấu xóa | Không hiển thị những dòng không liên quan |
| Thùng hàng tự động bị xóa khi tất cả đơn hàng bên trong bị xóa | Dọn dẹp giao diện tự động |
| PKL tự động bị xóa khỏi danh sách khi tất cả thùng bị xóa | Tương tự |
| Ô SL thực phân loại chỉ nhận số nguyên | Không nhập được số thập phân hoặc chữ |
| Giới hạn 12 chữ số cho ô số lượng | Hệ thống tự chặn khi nhập quá |
| Validation lỗi hiển thị khi nhập | Không cần nhấn Xác nhận mới thấy lỗi |

### Lưu ý về xóa thùng hàng / đơn hàng

Trong cửa sổ phân loại, có nút **xóa** (thùng rác) ở cạnh mỗi thùng hàng và đơn hàng:

- Xóa thùng hàng → tất cả đơn hàng trong thùng đó bị bỏ qua khi lưu.
- Xóa đơn hàng → đơn hàng đó bị bỏ qua khi lưu.
- Khi tất cả thùng của một PKL bị xóa → PKL đó tự động biến mất khỏi danh sách.
- **Thao tác này không thể hoàn tác** trong phiếu hiện tại — nếu xóa nhầm, cần đóng cửa sổ và tạo lại.

---