> ## Knowledge Base Index
> Fetch the complete knowledge base index at: https://help.bentoweb.com/sitemap.xml
> Use this file to discover available pages before exploring further.
> Pure-Markdown content can be obtained by appending a '.md' suffix to the content URLs listed in the sitemap (without the trailing slash).

# คู่มือการใช้งาน API ปรับสต๊อกสินค้า (Stock Rebalance)

# คู่มือการใช้งาน API ปรับสต็อกสินค้า (Stock Rebalance)
ระบบ Stock Rebalance ช่วยให้การจัดการสต็อกสินค้าเชื่อมต่อไปยัง Marketplace ต่างๆ (Shopee, Lazada, TikTok Shop, Line Shopping, Makro Pro, Shopify) เป็นเรื่องง่าย โดยแบ่งการทำงานออกเป็น 2 โหมดหลักคือ **Manual** และ **Auto**
เอกสารนี้จะอธิบายวิธีการใช้งาน API สำหรับตรวจสอบสถานะ และการอัปเดตสต็อกในแต่ละโหมด
## 1. การตรวจสอบ Mode ปัจจุบันของสินค้า
ก่อนทำการอัปเดตสต็อก สามารถตรวจสอบได้ว่าสินค้านั้นๆ (Product Variant) กำลังทำงานอยู่ในโหมดใด
**API Endpoint:** `GET` `/api/product-variant/{variantId}`
**Parameter ที่ต้องส่ง:**
* `product_variant_id` (Path): ID ของสินค้า (variant)
* `store_id` (Query): ID ของร้านค้า
**Response:** ดูที่ field `allocation_type_id`
| Value | Mode | ความหมาย |
| ---- |
| `0` | **Manual** | จัดการสต็อกด้วยตัวเอง (กำหนดโควต้าแต่ละช่องทางเอง) |
| `1` | **Weighted** (Auto) | ระบบคำนวณแบ่งสต็อกตามน้ำหนัก/สัดส่วนที่ตั้งไว้ |
| `2` | **Equal** (Auto) | ใช้แสดงใน UI / นโยบายร้าน ใน logic ระบบจะใช้ Weighted แทน |
| `3` | **Mirror** (Auto) | ระบบโคลนสต็อกที่พร้อมขาย (sales_stock) ไปทุกช่องทางเท่ากัน |
| `null` | **Default** | ใช้นโยบายตามค่าตั้งต้นของร้าน (Store Policy) |
## 2. การอัปเดตสต็อกแบบ Manual (กำหนดเอง)
ใช้เมื่อต้องการระบุจำนวนสต็อกที่จะขายในแต่ละช่องทางด้วยตัวเอง
**API Endpoint:** `POST` `/api/stock/variants/{variantId}/manual-stock`
**⚠️ ข้อควรระวัง:** การเรียก API นี้จะเปลี่ยน Mode ของสินค้าเป็น **Manual (0)** ทันที
**กฎการตรวจสอบ:** ผลรวม (ช่องทางขาย + buffer) **ต้องไม่เกิน** physical_stock มิฉะนั้นจะได้ `422` พร้อมข้อความ
`Total allocation (sales channels + buffer) exceeds physical stock.`
### Parameter ใน Body
| Parameter | ประเภท | บังคับ | ความหมาย |
| ---- |
| `store_id` | number | ใช่ | ID ของร้านค้า |
| `physical_stock` | number | ใช่ | จำนวนของที่มีอยู่จริงในโกดัง |
| `buffer` | number | ไม่ (default 0) | กันสต็อกไว้ไม่ให้ขายบนช่องทางออนไลน์ |
| `channels` | object | ขึ้นกับโหมด | โควต้าแต่ละช่องทาง |
| `safe_mode` | number | ไม่ (0/1) | ถ้าเป็น 1 อนุญาตเฉพาะเมื่อสินค้าอยู่โหมด Manual อยู่แล้ว |
| `adjustment_mode` | string | ไม่ | `override`, `increase`, `decrease` |
| `actor_id` | number | ไม่ | ID ผู้ดำเนินการ (สำหรับ log) |
**Key ของ channels ที่รองรับ:** `shopee`, `lazada`, `bentoweb`, `line_shopping`, `makro_pro`, `tiktok_shop`, `shopify`
**ตัวอย่าง Body (Override):**
```
{
  "store_id": 99,
  "physical_stock": 100,
  "buffer": 10,
  "channels": {
    "shopee": 20,
    "lazada": 20,
    "bentoweb": 30,
    "tiktok_shop": 20
  }
}
```
**ตัวอย่างใช้ adjustment_mode (เพิ่มของ):**
```
{
  "store_id": 99,
  "physical_stock": 50,
  "buffer": 0,
  "channels": { "shopee": 25, "lazada": 25 },
  "adjustment_mode": "increase"
}
```
ในกรณีนี้ ระบบจะใช้ physical_stock ใหม่ = physical_stock เดิม + 50
**หมายเหตุ:** ถ้าไม่ส่ง `channels` และร้านใช้โหมด Mirror ระบบจะตอบ Action denied: Cannot update manual stock for product in Mirror Mode.
**Response สำเร็จ (status 1):** allocation_mode, mode_label, physical_stock, buffer, sales_stock, channels, is_insufficient, is_low_stock
## 3. การอัปเดตสต็อกแบบ Auto (ให้ระบบคำนวณ)
ใช้เมื่อต้องการเติมของเข้าโกดัง และให้ระบบคำนวณการกระจายสต็อกให้อัตโนมัติตามนโยบายร้าน (Weighted หรือ Mirror)
**API Endpoint:** `POST` `/api/stock/variants/{variantId}/auto-stock`
**⚠️ ข้อควรระวัง:** การเรียก API นี้จะเปลี่ยน Mode ของสินค้าเป็น **Auto** ตามนโยบายร้านทันที
**ข้อจำกัด:** สินค้าแบบ **Product Set (Type 2)** ใช้ API นี้ไม่ได้ — ระบบจะตอบ Action denied.
### Parameter ใน Body
| Parameter | ประเภท | บังคับ | ความหมาย |
| ---- |
| `store_id` | number | ใช่ | ID ของร้านค้า |
| `physical_stock` | number | ใช่ | จำนวนของจริง (หรือจำนวนที่จะเพิ่ม/ลด ถ้าใช้ adjustment_mode) |
| `force_rebalance` | boolean | ไม่ | บังคับ sync ไป Marketplace แม้ค่าจะไม่เปลี่ยน |
| `safe_mode` | number | ไม่ (0/1) | ถ้าเป็น 1 อนุญาตเฉพาะเมื่อสินค้าอยู่โหมด Auto อยู่แล้ว |
| `adjustment_mode` | string | ไม่ | `override`, `increase`, `decrease` |
| `actor_id` | number | ไม่ | ID ผู้ดำเนินการ |
**ตัวอย่าง Body:**
```
{
  "store_id": 99,
  "physical_stock": 500
}
```
**ตัวอย่างใช้ adjustment_mode + force_rebalance:**
```
{
  "store_id": 99,
  "physical_stock": 100,
  "adjustment_mode": "increase",
  "force_rebalance": true
}
```
## สรุปพฤติกรรมของระบบ (Behavior Summary)
1. **การเปลี่ยน Mode:** ระบบยึดตาม Endpoint ล่าสุด — เรียก manual-stock → Manual, เรียก auto-stock → Auto (ตาม Store Policy)
2. **Physical Stock:** จำนวนสินค้าที่มีอยู่จริง (Real Stock) ไม่ใช่จำนวนที่พร้อมขาย
3. **Buffer:** จำนวนที่กันไว้ไม่ให้ขายบนช่องทางออนไลน์
4. **Manual:** ผลรวม (ช่องทางขาย + buffer) ต้องไม่เกิน physical_stock มิฉะนั้นได้ 422
5. **Safe Mode:** Manual → safe_mode=1 อนุญาตเฉพาะโหมด Manual, Auto → safe_mode=1 อนุญาตเฉพาะโหมด Auto
6. **Adjustment Mode:** override = ใช้ค่าที่ส่งมา, increase = ค่าเดิม + ที่ส่งมา, decrease = ค่าเดิม - ที่ส่งมา (ไม่ต่ำกว่า 0)
7. **Channel keys:** ใช้ shopee, lazada, bentoweb, line_shopping, makro_pro, tiktok_shop, shopify (ไม่ใช้ tiktok อย่างเดียว)