# Tài Liệu Đặc Tả & Kế Hoạch Triển Khai: Hợp Nhất Vật Tư Đơn Hàng (OrderItemMaterials)

Tài liệu này đặc tả nghiệp vụ và tài liệu kỹ thuật chi tiết về việc chuyển đổi từ mô hình quản lý vật tư đóng gói riêng lẻ (`OrderPackagingMaterial`) sang mô hình **Hợp nhất Vật tư Đơn hàng (`OrderItemMaterial`)**, hỗ trợ đồng thời cả **Vật tư sản xuất (PRODUCTION)** và **Vật tư đóng gói (PACKAGING)** trong cùng một thực thể, phân tách trực quan trên giao diện chi tiết đơn hàng bán lẻ.

---

## 1. Bối Cảnh Nghiệp Vụ (Business Context)

Trước đây, hệ thống MES của KingstonVN chỉ cho phép thiết lập và nhập thêm vật tư đóng gói (`OrderPackagingMaterial`) ngoài định mức khi lên đơn hàng. Tuy nhiên, trên thực tế, khi lên đơn hàng (`Order`), ngoài vỏ hộp và phụ kiện đóng gói, các bộ phận kỹ thuật xưởng (Planner) còn phát sinh nhu cầu nhập thêm **Vật tư sản xuất** (như vít sắt phụ, pas liên kết, đệm đính kèm...) trực tiếp theo yêu cầu đặc biệt của khách hàng trên dòng đơn hàng đó (`OrderItem`).

Để tối ưu cơ sở dữ liệu và đồng nhất luồng nghiệp vụ:
- Gộp hai loại vật tư đóng gói và sản xuất phát sinh theo đơn hàng thành một thực thể duy nhất: **Vật tư đính kèm đơn hàng (`OrderItemMaterial`)**.
- Phân biệt bằng trường phân loại `type` mang giá trị `PRODUCTION` hoặc `PACKAGING`.
- Khi tạo đơn hàng (`Order`), hệ thống tự động bóc tách định mức từ Variant (gồm vật tư có `assemblyQty` làm vật tư sản xuất và vật tư có `packagingQty` làm vật tư đóng gói), nhân với số lượng đơn hàng để sinh dữ liệu ban đầu cho `OrderItemMaterial`.
- Người dùng có toàn quyền thêm, sửa, xóa hoặc nhập thêm số lượng ngoài định mức cho cả 2 loại vật tư này.
- Khi hiển thị trên trang chi tiết đơn hàng, hệ thống tự động đổ ra **2 bảng riêng biệt**: **Vật tư sản xuất** và **Vật tư đóng gói** để thuận tiện cho việc kiểm kê và xuất kho sản xuất / đóng gói tương ứng.

---

## 2. Mô Hình Dữ Liệu Thực Thể (Database Schema DDL)

Cơ cấu bảng `order_item_materials` thay thế hoàn toàn bảng `order_packaging_materials` cũ:

```prisma
// file: prisma/providers/mysql/prisma-models/order.prisma

model OrderItemMaterial {
  id           Int      @id @unique @default(autoincrement()) @map("id")
  isDeleted    Boolean  @default(false) @map("is_deleted")
  orderItemId  Int      @map("order_item_id")
  materialId   Int      @map("material_id")
  type         String   @db.VarChar(20) @map("type") // "PRODUCTION" | "PACKAGING"
  quantity     Decimal  @db.Decimal(10, 2) @map("quantity")
  note         String?  @db.Text @map("note")
  createdAt    DateTime @default(now()) @map("created_at")
  updatedAt    DateTime @default(now()) @updatedAt @map("updated_at")

  orderItem    OrderItem @relation("orderItemMaterialRelation", fields: [orderItemId], references: [id])
  material     Material  @relation("materialOrderItemRelation", fields: [materialId], references: [id])

  @@map("order_item_materials")
}
```

---

## 3. Luồng Đồng Bộ & Tính Toán BOM Khởi Tạo (API Sync Workflow)

Khi một đơn hàng bán lẻ được tạo ra (`CreateOrder`), hệ thống sẽ thực hiện các bước tự động sau ở Backend:

1. **Tìm kiếm Định mức BOM của Variant/Set**: 
   Duyệt qua danh sách `materials` của Variant (hoặc phân rã Set thành các Variant con và nhân hệ số).
2. **Phân rã theo vai trò vật tư**:
   - Nếu `assemblyQty1 > 0` hoặc `assemblyQty2 > 0`: Sinh bản ghi `OrderItemMaterial` với loại `type = "PRODUCTION"` và số lượng khởi tạo = `(assemblyQty1 + assemblyQty2) * OrderItem.quantity`.
   - Nếu `packagingQty > 0`: Sinh bản ghi `OrderItemMaterial` với loại `type = "PACKAGING"` và số lượng khởi tạo = `packagingQty * OrderItem.quantity`.
3. **Tính toán Extra lượng hao hụt**:
   - Cộng dồn lượng `extraQty * OrderItem.quantity` vào phần vật tư sản xuất tương ứng.
4. **Hợp nhất tùy chỉnh (Custom Override)**:
   - Các vật tư đính kèm ngoài định mức mà người dùng nhập trực tiếp từ giao diện sẽ được cộng dồn hoặc ghi đè vào bảng này.

---

## 4. Các Endpoints API Cập Nhật (Backend REST APIs)

Các API endpoints thao tác trên vật tư đóng gói cũ `/api/admin/order-items/:orderItemId/packaging-materials` được chuyển đổi sang endpoint hợp nhất:

* **Lấy danh sách vật tư đính kèm dòng đơn hàng**:
  - `GET /api/admin/order-items/:orderItemId/materials?type=PRODUCTION|PACKAGING`
* **Thêm vật tư đính kèm ngoài định mức**:
  - `POST /api/admin/order-items/:orderItemId/materials`
  - Payload: `{ materials: [ { materialId: 10, type: "PRODUCTION", quantity: 5, note: "Khách yêu cầu thêm" } ] }`
* **Sửa vật tư đính kèm đơn hàng**:
  - `PUT /api/admin/order-items/:orderItemId/materials/:id`
  - Payload: `{ materials: [ { quantity: 15, note: "Cập nhật số lượng mới" } ] }`
* **Xóa vật tư đính kèm đơn hàng**:
  - `DELETE /api/admin/order-items/:orderItemId/materials/:id`

---

## 5. Thiết Kế Giao Diện Trực Quan (Frontend Architecture)

Trang chi tiết đơn hàng mục vật tư ([DetailOrderMaterials.tsx](file:///Users/lcnghia95/workspace/kingston/web-kingston/packages/main-app/src/clean-architecture/presentation/components/pages/order/DetailOrderMaterials/DetailOrderMaterials.tsx)) được bổ sung các tính năng đột phá:

- **Hai Tab phân loại độc lập**:
  - **Tab Vật tư sản xuất**: Chỉ hiển thị các dòng vật tư lắp ráp thô phục vụ tổ thợ ráp xưởng (bao gồm cả định mức Variant tự động nhân số lượng đơn hàng + vật tư sản xuất nhập thêm ngoài). Hộp thoại thêm vật tư tại tab này mặc định chọn loại `PRODUCTION`.
  - **Tab Vật tư đóng gói**: Chỉ hiển thị các bao bì, vỏ hộp carton, phụ kiện đóng gói (định mức Variant đóng gói + vật tư nhập thêm ngoài). Hộp thoại thêm vật tư tại tab này mặc định chọn loại `PACKAGING`.
- **Ẩn/Hiện cột thông minh**:
  - Khi xem Tab Sản xuất: Hiển thị các cột chuyên dụng `SL Lắp ráp` (fixedQty), `SL Extra` (extraQty) và `Tổng số lượng`.
  - Khi xem Tab Đóng gói: Ẩn các cột lắp ráp, chỉ hiển thị cột `SL Đóng gói` (packagingQty) và `Tổng số lượng`.
- **Hỗ trợ 2 chế độ hiển thị song song**:
  - Chế độ gộp (Tất cả vật tư): Tự động gộp các vật tư định mức của toàn bộ đơn hàng lại thành một bảng tổng hợp gọn gàng cho SCM dễ xem tổng lượng cần mua/xuất kho. Các vật tư nhập thêm ngoài sẽ được liệt kê riêng để phân biệt rõ ràng.
  - Chế độ phân cấp (Theo mục đơn hàng): Hiển thị cây phân rã dạng cha-con, giúp Planner dễ dàng quản lý cụ thể từng mặt hàng đặt mua cần những loại vật tư đính kèm nào.
