API ข้อมูลหลัก (master / master-detail / itemmaster / itemdetail / barcode / docpicture / itempicture / modifyprice)
กลุ่ม action ที่เขียน/อ่านข้อมูลหลักของ ERP (สินค้า บาร์โค้ด รูปภาพ ราคา กริดย่อย) โดยตรวจกฎจาก C# ฝั่ง Go แล้วเขียนใน transaction เดียว. ทุก action เป็น POST /api/v1/process/<group>/<action> (และ /process/... ชื่อซ้ำ) ยกเว้น 2 route GET .../image. ภาพรวม prefix, envelope {"ok":true,"data":...}, กฎสิทธิ์ routeRights อยู่ที่ API เครื่องยนต์ process /process/* — เส้นทาง สิทธิ์ ขนาดบอดี้ (Process engine run API); แนวคิดข้อมูลหลักที่ ข้อมูลหลักแบบหัว-รายการ รหัสอัตโนมัติ และเลย์เอาต์รายการ (Master-detail, code auto-run, DataList), ข้อมูลสินค้าและข้อมูลสินค้าเพิ่มเติม (Item master & item detail), บาร์โค้ดสินค้า ส่วนลดบาร์โค้ด EAN13 และพิมพ์ป้าย (Barcode menus 2.1.7-2.1.17), แนบรูปเอกสารและรูปสินค้า (Document & item pictures), เครื่องมือหาราคาและแก้ราคา (Price engine / price center / modify price).
กติการ่วม: ProviderCode/DatabaseName/UserCode เติมจาก claims (ฟิลด์ json:"-"), ไม่ใช่จากบอดี้; บอดี้เสีย = 400 "invalid request body"; ชื่อ action ที่ไม่รู้จัก = 404 "unknown <group> action"; error ธุรกิจ = 400 (ข้อความไทย) หรือ 409; ข้อผิดพลาดอื่น = 500 "internal server error" (response.Error). ไม่มี rate limit; เพดานเวลา 60 วินาทีของ router.
master/* — รหัสอัตโนมัติ, DataList, ค่าเริ่มต้นสินทรัพย์ (บอดี้ ≤ 1 MB)
| action | หน้าที่ | input สำคัญ | ตาราง | path:line |
|---|---|---|---|---|
master/nextcode |
รหัสลูกค้า/เจ้าหนี้ถัดไป (รหัสสูงสุด + 1) ใช้ตอนเพิ่มใหม่ / F2 / ชนรหัสซ้ำตอนบันทึก | kind (customer/supplier), code, date |
ar_customer / ap_supplier (ตามชนิด) | master_handler.go:20 → master_autorun.go:64 |
master/codeleave |
ออกจากช่องรหัส: ถ้ารหัสที่พิมพ์ตรงกับ erp_doc_format.code รันตามรูปแบบนั้น มิฉะนั้นใช้เป็น prefix ต่อเลข |
kind, code, date |
erp_doc_format, erp_option, erp_doc_format_gl | master_handler.go:24 → master_autorun.go:83 |
master/assetdepdefaults |
อัตราค่าเสื่อมและวันหยุดคิดค่าเสื่อมเริ่มต้นของหน้าจอสินทรัพย์ | field, calcType, age, calcValue, deadValue, startCalcDate |
erp_option | master_handler.go:28 → asset_depreciation.go:40 |
master/datalistget |
อ่านเลย์เอาต์ DataList ที่ผู้ใช้บันทึก (ไม่มี = config:null) |
listKey, userCode |
erp_user_datalist_config | master_handler.go:32 → master_datalist.go:109 |
master/datalistsave |
บันทึก/ลบ (config=null) เลย์เอาต์ DataList หนึ่งแถวต่อผู้ใช้ต่อ list | listKey, userCode, config |
erp_user_datalist_config | master_handler.go:36 → master_datalist.go:132 |
- ผลลัพธ์
nextcode/codeleave:{"code","format"}(formatว่างถ้าไม่ใช่รหัสรูปแบบ) (master_autorun.go:42-45). - สิทธิ์:
nextcode/codeleave/assetdepdefaults= Read (permission.go:37);datalistget/datalistsave= Read ถ้าuserCodeว่างหรือตรงกับผู้ใช้ใน token มิฉะนั้น Admin (permission.go:87-96). - ตัวอย่าง:
POST /api/v1/process/master/nextcodeบอดี้{"kind":"customer","code":"<prefix>","date":"2026-01-31"} - ผู้เรียก:
account/master/masterAutoCode.ts:25(nextcode/codeleave),MasterDetailScreen.tsx:404(assetdepdefaults),SmlDataListCustomizeModal.tsx:332,359(datalist). Next routesrc/app/api/process/master/[action].
master-detail/* — บันทึก header + กริดย่อยแบบ atomic (บอดี้ ≤ 1 MB)
| action | หน้าที่ | input สำคัญ | ตาราง | path:line |
|---|---|---|---|---|
master-detail/save |
เขียน header และแทนที่/แก้ทุกกริดใน transaction เดียว | menuKey, key, scope, mode (new/edit), header{}, grids{<ชื่อกริด>:[{...}]} |
ตามสเปกของ menuKey: erp_doc_format, erp_doc_format_gl, ic_inventory, ic_inventory_barcode ฯลฯ | master_detail_handler.go:15-37 → master_detail.go:135 |
master-detail/delete |
ลบ header + ลูก; ปฏิเสธถ้ายังถูกอ้างอิง (หน้าจอที่ผูกกับสินค้า ล้างเฉพาะแถวของสินค้านั้น ไม่ลบสินค้า) | menuKey, key, scope |
ตารางเดียวกับสเปก | master_detail_handler.go:15-37 → master_detail.go:177 |
menuKeyต้องอยู่ในmdSpecs(master_detail_specs.go:144) เช่นmenu_ic_item_set,menu_ic_purchase_price,menu_ic_item_saleprice,menu_ic_discount,menu_asset_lists,menu_chart_of_account,menu_setup_user_group; ไม่อยู่ = 400 "ไม่รู้จักเมนู <menuKey>" (master_detail.go:136-138,178-180).- Response:
{"ok":true,"data":{"key":"<key>","saved":{"<ชื่อกริด>":<จำนวนแถว>}}}(MasterDetailResult). - สิทธิ์: save = Write (Add หรือ Edit), delete = Delete (permission.go:40-47).
- ตัวอย่าง:
POST /api/v1/process/master-detail/save (Authorization: Bearer <token>)
{"menuKey":"<menuKey>","key":"<code>","mode":"edit",
"header":{"<column>":"<value>"},
"grids":{"<gridName>":[{"<column>":"<value>"}]}}
- ผู้เรียก:
account/master/MasterDetailScreen.tsx:565(save),:600(delete); สเปกหน้าจอที่src/config/schemas/masterDetailSchemas.ts. ภาพรวมที่ รายการจอข้อมูลหลักแบบตารางเดียว (IC_MASTER_CONFIGS), จอข้อมูลหลักมาตรฐานและจอ master-detail (StandardMasterScreen / MasterDetailScreen).
itemmaster/* — บันทึก/ลบสินค้า (menu 2.1.1, 2.1.2, 2.1.24)
| action | หน้าที่ | input สำคัญ | ตาราง | path:line | บอดี้ |
|---|---|---|---|---|---|
itemmaster/save |
ตรวจกฎ _icMain._saveData ของ C# แล้วเขียนสินค้า + หน่วย + หน่วยตรงข้าม + บาร์โค้ด + คลัง/ชั้น + ต้นทุนมาตรฐาน + รูป ใน transaction เดียว พร้อมเขียน master_logs |
menuKey, isNew, item{}, units[], oppositeUnits[], barcodes[], whShelves[], standardCosts[], images[] |
ic_inventory, ic_inventory_barcode, master_logs, erp_option, erp_user_group(+_detail), ic_trans_detail | itemdetail_handler.go:33,35 → item_master.go:559 | 4 MB |
itemmaster/delete |
ลบสินค้าที่ยังไม่ถูกใช้ + ข้อมูลลูกทั้งหมด; รหัสที่มีใน ic_trans_detail ถูกข้าม | menuKey, codes[] |
ic_inventory, ic_inventory_set_detail, ic_trans_detail, master_logs, erp_user_group(+_detail) | itemdetail_handler.go:39 → item_master.go:817 | 1 MB |
- สิทธิ์: save = Add ถ้า
isNew:trueมิฉะนั้น Edit (permission.go:81-86); delete = Delete (permission.go:47). - Response: save
{"ok":true,"data":{"code","itemsProcessed","rowsUpdated"}}; delete{"data":{"deleted":[...],"used":[...]}}(used= รหัสที่ถูกข้ามพร้อมเหตุผลไทย) (item_master.go:146,806; query-client.ts:85-99). - ผู้เรียก:
itemMasterSave/itemMasterDeleteใน query-client.ts:88,96 →account/master/ItemScreen.tsx:1027.
itemdetail/* — ข้อมูลสินค้าเพิ่มเติม (เมนู menu_ic_item_detail_2 และรุ่นบาร์โค้ด)
| action | หน้าที่ | input สำคัญ | ตาราง | path:line | บอดี้ |
|---|---|---|---|---|---|
itemdetail/get |
โหลดทุกแท็บของสินค้า/บาร์โค้ดหนึ่งตัว | code, barcode |
ic_inventory, ic_inventory_barcode | itemdetail_handler.go:18 → item_detail.go:221 | 1 MB |
itemdetail/save |
เขียนทุกแท็บใน transaction เดียว แล้วโหลดมุมมองใหม่คืน | code, item, detail, market, billing, short, pos, colors |
ic_inventory, ic_inventory_detail, ic_inventory_barcode, erp_doc_format | itemdetail_handler.go:22 → item_detail.go:367 | 4 MB |
- สิทธิ์: get = Read, save = Write (permission.go:32,42). ผู้เรียก:
account/master/ItemDetail2Screen.tsx:412(get),:436(save).
barcode/* — บาร์โค้ด, ส่วนลดตามบาร์โค้ด, EAN13, พิมพ์ป้าย (menu 2.1.7-2.1.17; บอดี้ ≤ 1 MB)
| action | หน้าที่ | input สำคัญ | ตาราง | path:line | สิทธิ์ |
|---|---|---|---|---|---|
barcode/item |
โหลดสินค้าพร้อมบาร์โค้ด หน่วย ชั้นเก็บ (code เป็นรหัสสินค้าหรือบาร์โค้ดก็ได้) | code |
ic_inventory, ic_inventory_barcode, ic_unit, ic_unit_use, ic_wh_shelf, ic_warehouse | barcode_handler.go:22 → barcode.go:123 | Read |
barcode/save |
แทนที่แถวบาร์โค้ดของสินค้าใน transaction เดียว (ลบตาม ic_code แล้วใส่ใหม่) | itemCode, barcodes[], shelf, whCode, locationCode |
ic_inventory, ic_inventory_barcode, ic_wh_shelf | :28 → barcode.go:252 | Write |
barcode/discount-load |
โหลดบาร์โค้ดและแถวส่วนลดแยกตาม discount_type เรียงตาม priority | barcode |
ic_inventory_barcode, ic_inventory_barcode_price | :34 → barcode_discount.go:83 | Read |
barcode/discount-save |
เขียนกริดส่วนลดให้ทุกบาร์โค้ดใน transaction เดียว (ทุกบาร์โค้ดต้องมีอยู่จริง) | barcodes[], replace, grids |
ic_inventory_barcode_price, ic_inventory_barcode | :40 → barcode_discount.go:253 | Write |
barcode/ean13-check |
รายการบาร์โค้ด 13 หลักที่ checksum EAN13 ไม่ผ่าน | (ไม่มี) | ic_inventory_barcode | :46 → barcode.go:436 | Read |
barcode/ean13-generate |
สร้าง EAN13 ใหม่ที่ไม่ซ้ำให้แต่ละบาร์โค้ดเก่า (ไม่เขียนอะไร) | prefix, barcodes[] |
ic_inventory_barcode | :52 → barcode.go:472 | Read |
barcode/ean13-apply |
แทนที่บาร์โค้ดเก่าด้วยใหม่ใน transaction เดียว | rows[] |
ic_inventory_barcode | :58 → barcode.go:531 | Write |
barcode/print-items |
แถวป้ายพร้อมชื่อหน่วยและราคา price_0 จากสูตรราคา | barcodes[], docNo |
ic_trans_detail, ic_inventory_price_formula, ic_inventory_barcode, ic_unit | :66 → barcode.go:588 | Read |
barcode/format |
รายการ/บันทึก(upsert ตามรหัส)/ลบ รูปแบบป้าย | action (list/save/delete), format{} |
sml_barcode_print_format, erp_doc_format | :72 → barcode.go:661 | list=Read, save=Add, delete=Delete (permission.go:102-110) |
- ตัวอย่าง:
POST /api/v1/process/barcode/ean13-generateบอดี้{"prefix":"<prefix>","barcodes":["<barcode>"]}; ผลเป็นอาร์เรย์แถว{barcodeOld, barcodeNew,...}(BarcodeScreens.tsx:162,840). - Next route
src/app/api/process/barcode/[action]/route.ts:12-29มี whitelist ครบ 9 action. ผู้เรียก:account/master/BarcodeScreens.tsx:355,359,819,840,850,BarcodeDiscountScreens.tsx:600,629,783,BarcodePrintScreen.tsx:205,214,222,ItemScreen.tsx:1479.
docpicture/* — รูปประกอบเอกสาร
| action | หน้าที่ | input สำคัญ | ตาราง | path:line | บอดี้ |
|---|---|---|---|---|---|
docpicture/formats |
ประเภทเอกสารของโมดูลหนึ่ง | module (ic/po/so/ap/ar/cb/gl) |
erp_doc_format, erp_doc_format_gl | docpicture_handler.go:44 → doc_picture.go:74 | 1 MB |
docpicture/docs |
รายการเอกสารของประเภทที่เลือก (ค้นทั้ง ic_trans, ap_ar_trans, cb_trans) แบ่งหน้า | module, formatCode, keyword, page |
gl_journal, ic_trans, ap_ar_trans, cb_trans | :52 → doc_picture.go:130 | 1 MB |
docpicture/get |
รูปที่ผูกกับเอกสารหนึ่งใบ | module, formatCode, docNo, docDate, bookCode (สองตัวหลังเฉพาะ GL) |
ic_trans, ap_ar_trans, cb_trans, gl_journal, erp_option | :60 → doc_picture.go:311 | 1 MB |
docpicture/save |
แทนที่ชุดรูปของเอกสารแบบ atomic (ลบทั้งหมดแล้วใส่ตามหน้าจอ) | ฟิลด์ของ get + items[] |
เหมือน get | :68 → doc_picture.go:426 | 64 MB (docPictureBodyLimit, docpicture_handler.go:32; 8 รูป × 5 MB เป็น base64) |
GET docpicture/image?id=<roworder> |
ส่งไบต์รูปหนึ่งรูป | query id (จำนวนเต็ม > 0 มิฉะนั้น 400 "invalid image id") |
sml_doc_images | docpicture_handler.go:89 → doc_picture.go:333 | - |
itempicture/* — รูปสินค้า/บาร์โค้ด/พนักงาน/สินทรัพย์
| action | หน้าที่ | input สำคัญ | ตาราง | path:line | บอดี้ |
|---|---|---|---|---|---|
itempicture/list |
รายการสินค้า (หรือบาร์โค้ด) พร้อมจำนวนรูป | kind (item/barcode/staff/asset), keyword, page |
ic_inventory, erp_user, as_asset, ic_inventory_barcode | stocktools_handler.go:46 → item_picture.go:87 | 1 MB |
itempicture/get |
ชุดรูปของคีย์หนึ่ง | kind, key |
ตารางเดียวกัน | :50 → item_picture.go:210 | 1 MB |
itempicture/save |
แทนที่ชุดรูปของคีย์หนึ่ง และเขียน master_logs | kind, key, items[] |
master_logs + ตารางเดียวกัน | :54 → item_picture.go:252 | 48 MB (itemPictureBodyLimit, stocktools_handler.go:40; 6 รูป × 5 MB) |
GET itempicture/image?id=<roworder> |
ส่งไบต์รูป | query id |
(ตารางรูป) | stocktools_handler.go:64 → item_picture.go:231 | - |
- ทั้งสอง
GET .../imageคืนไบต์ตรงๆ:Content-TypeจากDocPictureMime(data),X-Content-Type-Options: nosniff,Cache-Control: private, max-age=300(docpicture_handler.go:105-107, stocktools_handler.go:80-82); สิทธิ์ Read; ผ่าน Nextsrc/app/api/process/{docpicture,itempicture}/image/route.tsซึ่งตรวจidเป็นเลข ≤ 12 หลัก และ session ก่อน (401NO_TOKENถ้าไม่มี token). - สิทธิ์: list/get/formats/docs = Read; save = Write (permission.go:30-31,42). ผู้เรียก:
account/master/DocumentPictureScreen.tsx:65,77,102,123,ItemPictureScreen.tsx:64,85,106,ItemDetail2Screen.tsx:373. ความหมายของรูปสินค้าที่ แนบรูปเอกสารและรูปสินค้า (Document & item pictures).
modifyprice/* — แก้ราคาเป็นชุด (menu 2.1.25)
| action | หน้าที่ | input สำคัญ | ตาราง | path:line | บอดี้ |
|---|---|---|---|---|---|
modifyprice/preview |
เติมคอลัมน์ "ราคาเดิม" โดยไม่เขียนอะไร | kind, zeroOption, rows[] |
ic_inventory, master_logs | docpicture_handler.go:112 → modify_price.go:75 | 8 MB |
modifyprice/apply |
เขียนกริดราคาและบันทึกการรันใน master_logs | เหมือน preview (zeroOption:true = เขียนเซลล์ที่พิมพ์ 0) |
ic_inventory, master_logs | → modify_price.go:80 | 8 MB |
- action อื่นนอกจาก
preview/apply= 404 "unknown modifyprice action" (docpicture_handler.go:114-118). สิทธิ์: preview = Read, apply = Write. ผู้เรียก:account/master/ModifyPriceScreen.tsx:189.
ที่มาในโค้ด
backend/internal/adapter/inbound/http/router.go:126-208(route ทั้งสอง prefix; กลุ่มนี้คือ barcode, master-detail, docpicture, modifyprice, itempicture, itemdetail, itemmaster, master)backend/internal/adapter/inbound/http/process/permission.go:24-52(routeRights),81-110(isNew → Add/Edit, datalist, barcode/format)backend/internal/adapter/inbound/http/process/{master_handler,master_detail_handler,itemdetail_handler,barcode_handler,docpicture_handler,stocktools_handler}.go(บรรทัดตามตารางด้านบน);decodeChequecheque_handler.go:43-53 (เพดาน 1 MB),decodeLimiteddocpicture_handler.go:18backend/internal/application/process/{master_autorun,master_datalist,master_detail,master_detail_specs,item_master,item_detail,barcode,barcode_discount,doc_picture,item_picture,modify_price,asset_depreciation}.gofrontend/src/lib/query-client.ts:85-99;frontend/src/app/api/process/{barcode,master,master-detail,itemmaster,itemdetail,docpicture,itempicture,modifyprice}/**/route.tsfrontend/account/master/*.tsx(ผู้เรียกตามรายการข้างต้น)