Lalabase
Tickets, Doku, Zeiterfassung und Kundengespräche an einem Ort, durchsuchbar per KI. Für Softwarefirmen mit Kundenprojekten. Open Source: auf deinem eigenen Server oder in unserer Cloud in Deutschland.
Translation pending
One for All Ultra (OFAU) หนึ่งเดียวเพื่อทุกสิ่ง — คุมสินค้าคงคลัง งานซื้อ งานขาย การจัดส่ง งานลูกค้าสัมพันธ์ และรายงานครบในระบบเดียว
Translation pending
BusinessJavaScript · PLpgSQLGitHub @actingsubltsuteepatchotasing-dotOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
One for All Ultra (OFAU) — หนึ่งเดียวเพื่อทุกสิ่ง สร้างด้วย Next.js 15 (App Router) + React 19 + Supabase ไม่มี dependency อื่นนอกจาก next / react / react-dom — ตัวเชื่อม Supabase เขียนเองด้วย fetch 1. สร้างตาราง — Supabase Dashboard > SQL Editor > New query วางไฟล์ supabase/schema.sql ทั้งไฟล์ > Run ไฟล์เดียวจบทุกอย่าง: ตาราง 30 ตาราง, ฟังก์ชัน, สิทธิ์, RLS และรีเฟรช schema cache ท้ายไฟล์มีตารางสรุป — คอลัมน์ ผล ต้องขึ้น ผ่าน ครบทุกแถว (รันซ้ำได้ ไม่ลบข้อมูลเดิม) 2. สร้างผู้ใช้คนแรก — Authentication > Users > Add user ติ๊ก Auto Confirm User ด้วย ไม่งั้นจะติด "Email not confirmed"Read the full README ↗
One for All Ultra (OFAU) — หนึ่งเดียวเพื่อทุกสิ่ง
ระบบเดียวครบ: สินค้าคงคลัง · งานซื้อ · งานขาย · การจัดส่ง · งานลูกค้าสัมพันธ์ (CRM) · รายงาน
สร้างด้วย Next.js 15 (App Router) + React 19 + Supabase
ไม่มี dependency อื่นนอกจาก next / react / react-dom — ตัวเชื่อม Supabase เขียนเองด้วย fetch
ต้องทำ 3 ขั้นนี้ก่อน ไม่งั้นเข้าระบบไม่ได้
npm run setup
สั่งได้ตลอดทุกขั้น มันจะตรวจให้ว่าติดตั้งถึงไหนแล้ว และบอกเป็นข้อ ๆ ว่าเหลืออะไรต้องทำ
เริ่มโครงการใหม่ทั้งหมด หรือ ล็อกอินไม่ได้ — อ่าน Docs/คู่มือการติดตั้ง.md ซึ่งไล่ทีละขั้นตั้งแต่สร้างโฟลเดอร์ ทำฐานข้อมูล ไปจนตั้งค่าใน Vercel พร้อมตารางไล่สาเหตุตอนล็อกอินไม่ได้ และ Docs/เช็คลิสต์การติดตั้ง.xlsx สำหรับติ๊กว่าทำถึงขั้นไหนแล้ว
1. สร้างตาราง — Supabase Dashboard > SQL Editor > New query
วางไฟล์ supabase/schema.sql ทั้งไฟล์ > Run
ไฟล์เดียวจบทุกอย่าง: สร้างตารางทั้ง 44 ตาราง, ฟังก์ชัน, สิทธิ์, RLS และรีเฟรช schema cache
ท้ายไฟล์มีตารางสรุป — คอลัมน์ ผล ต้องขึ้น ผ่าน ครบทุกแถว (รันซ้ำได้ ไม่ลบข้อมูลเดิม)
2. สร้างผู้ใช้คนแรก — Authentication > Users > Add user ติ๊ก Auto Confirm User ด้วย ไม่งั้นจะติด "Email not confirmed"
คนต่อ ๆ ไปสร้างจากในระบบได้ที่เมนู การจัดการระบบ > เพิ่มผู้ใช้งาน แต่ต้องตั้งค่านี้ก่อนหนึ่งครั้งที่ Authentication > Sign In / Providers > Email: ปิด Confirm email (บัญชีใหม่จะใช้ได้ทันทีไม่ต้องยืนยันอีเมล) และเปิด Allow new users to sign up
3. ใส่ค่า environment — หาที่ Project Settings > API
| ตัวแปร | ค่าที่ใช้ |
|---|---|
NEXT_PUBLIC_SUPABASE_URL | Project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY | anon public key |
GEMINI_API_KEY | คีย์จาก Google AI Studio — เฉพาะถ้าจะใช้ผู้ช่วย AI |
ตอน deploy ใส่ที่ Vercel > Project Settings > Environment Variables แล้ว Redeploy หนึ่งครั้ง
(ตัวแปร NEXT_PUBLIC_ ถูกฝังตอน build) ตอนรันในเครื่องให้คัดลอก .env.local.example เป็น .env.local
anon key เป็น public key เปิดเผยได้ ความปลอดภัยมาจาก RLS policy ที่อนุญาตเฉพาะผู้ที่ล็อกอินแล้ว ห้ามใช้ service_role key ในฝั่ง client เด็ดขาด
เข้าระบบครั้งแรกและฐานข้อมูลยังว่าง ระบบจะสร้างข้อมูลตัวอย่างให้อัตโนมัติ
โอกาสการขาย — กรวยการขาย 6 ขั้น มูลค่ารวมและมูลค่าถ่วงน้ำหนัก อัตราชนะ เวลาเฉลี่ยที่ใช้ปิด กดปุ่มเลื่อนขั้นได้ · ปิดว่าแพ้ต้องบอกเหตุผล
บันทึกกิจกรรม — โทร / เข้าพบ / อีเมล / Line พร้อมนัดครั้งถัดไป มีการ์ด "ต้องตามวันนี้" ที่รวมนัดถึงกำหนดและที่เลยกำหนดไว้บนสุด
ลูกค้าเป้าหมาย — ผู้สนใจที่ยังไม่เป็นลูกค้า แปลงเป็นลูกค้าได้ปุ่มเดียว นำเข้าจาก Excel ได้
ภาพรวมลูกค้า (Customer 360) — ยอดซื้อสะสม ซื้อครั้งล่าสุด ดีลที่เปิดอยู่ ประวัติการติดต่อ และใบขายทั้งหมดของรายนั้น ในหน้าเดียว
รายงาน CRM 4 แท็บ — กรวยการขาย · กิจกรรมการติดต่อ · ชนะ-แพ้และเหตุผล · ลูกค้าเงียบที่ต้องตามกลับ (ตั้งจำนวนวันเองได้)
วิธีการใช้งาน — คู่มือในตัวโปรแกรม: สายงาน 7 สายบอกว่างานแต่ละอย่างเริ่มที่ไหน ไปจบที่ไหน และการ์ดรายหน้าจอบอกว่าหน้านั้นทำอะไร บันทึกอะไร รับข้อมูลจากไหน ส่งต่อไปไหน · กดชื่อหน้าจอในคู่มือแล้วกระโดดไปหน้านั้นได้เลย · พิมพ์ทั้งเล่มได้
กำหนดประเภทลูกค้า — ทะเบียนประเภทลูกค้า (รหัส + ชื่อ) ตั้งเองได้ไม่ต้องรอแก้โปรแกรม เลือกใช้ที่หน้ารายละเอียดลูกค้าแบบพิมพ์ค้นหาได้ · ใบขายเก็บประเภท ณ วันที่ออกเอกสาร ไว้ในตัวใบ รายงานย้อนหลังจึงไม่เปลี่ยนตามเมื่อมีคนแก้ประเภทของลูกค้าทีหลัง
กลุ่ม ยี่ห้อ ประเภทสินค้า — ทะเบียนสามมิติของสินค้า มีรหัสและชื่อเหมือนหน้าพนักงานขาย สลับดูได้ด้วยแท็บ · ที่หน้าข้อมูลสินค้าจะกดเลือกจากทะเบียนหรือพิมพ์ค้นหาบางส่วนได้ ค่าที่เคยพิมพ์ไว้ก่อนมีหน้านี้ยังเลือกได้ตามปกติ และมีปุ่มช่วยจดทะเบียนให้ครบ
ออกแบบฟอร์มพิมพ์ — ออกแบบฟอร์มที่ใช้พิมพ์เองได้ (ใบขาย / ใบซื้อ / ใบส่งคืน) เลือกหัวเอกสาร ขนาดกระดาษ ส่วนที่จะโชว์ คอลัมน์ในตารางและลำดับ และช่องลงนาม มีตัวอย่างให้ดูทันทีที่แก้ ซึ่งใช้ตัววาดเดียวกับตอนพิมพ์จริง จึงไม่เพี้ยนตอนลงกระดาษ เวลาสั่งพิมพ์เลือกฟอร์มได้อีกครั้งที่หน้าขาย ซื้อ และส่งคืน
ขายหน้าร้าน (POS) — ยิงบาร์โค๊ด / คีย์รหัส / กดเลือกจากการ์ดสินค้า คิด VAT 7% ส่วนลด เงินทอน และพิมพ์ใบเสร็จรับเงิน (78 มม. หรือ A4)
ขายสินค้าและบริการ — ขายเป็นเอกสาร เลือกลูกค้าจากทะเบียน ส่วนลดการค้ารายบรรทัด (ทั้ง % และบาท) ส่วนลดท้ายบิล อัตราภาษีปรับได้ และพิมพ์ใบกำกับภาษีเต็มรูปแบบ
การจัดส่งสินค้า — ยิงบาร์โค๊ดเลขที่เอกสารเพื่อเปิดใบ ดูเส้นทางจากคลังต้นทาง ไปที่อยู่ลูกค้าบน Google Maps และเดินสถานะ 4 ขั้น
สถานีสแกนจัดส่ง — เลือกจุดที่ยืนอยู่ครั้งเดียว แล้วยิงบาร์โค๊ดเลขที่เอกสารรัว ๆ สถานะเดินให้เองพร้อมจับเวลา ใช้ได้ทั้งเครื่องยิงต่อสายบนคอมและกล้องมือถือ
สถานะการจัดส่ง — ตารางทั้งกอง ค้นด้วยเลขที่ / รหัสลูกค้า / ชื่อ / จังหวัด / วันที่ กรองตามสถานะและช่วงวันที่ พร้อมจุดสีบอกสถานะ และมุมมอง ที่บอกว่าใบนั้นใช้เวลาช่วงไหนไปเท่าไร
ไอคอน บาร์โค๊ด และกราฟทั้งหมดเขียนเองเป็น inline SVG — ไม่ใช้ Tailwind, Chart.js หรือ icon library
ข้อมูลทั้งหมดอยู่บน Supabase (Postgres) แชร์กับผู้ใช้ทุกคนที่เข้าระบบ เปิด Row Level Security ทั้ง 30 ตาราง อนุญาตเฉพาะผู้ที่ล็อกอินแล้ว
การขายหน้าร้านตัดสต็อกผ่านฟังก์ชัน create_sale() บนฐานข้อมูล ซึ่งเขียน
sales + sale_items + txns ใน transaction เดียว — ไม่มีบิลที่บันทึกแล้วแต่ไม่ได้ตัดสต็อก
ฝั่งโค้ดรัน npm run check ได้ — ตรวจ 13 หมวด: import/export, วงเล็บ,
prop ที่ไม่ได้ประกาศ, หัวตารางตรงกับแถวข้อมูล, เมนู-สิทธิ-สำรองข้อมูล,
schema.sql, วันที่ไม่ใช่ UTC, ตัวแปรสี CSS, ตัวกรองของหน้ารายงาน,
ค่าที่ฐานข้อมูลยอมรับตรงกับโค้ด, ตัวแปลงครบทุกคอลัมน์, deps ของ store
และการปิดปุ่มตามสิทธิ ใช้แทน next build ในเครื่องที่ไม่ได้ลง node_modules
ปุ่ม "ข้อมูล" มุมขวาบนมี "ตรวจสอบระบบ" ที่ไล่ตรวจตารางและฟังก์ชันให้ทีละรายการ
(อ่านอย่างเดียว) รวมถึงส่งออก/นำเข้าไฟล์สำรอง .json, โหลดข้อมูลใหม่ และรีเซ็ต
— การนำเข้าและรีเซ็ตมีผลกับฐานข้อมูลจริง จึงกระทบผู้ใช้ทุกคน
ปุ่มลอยมุมขวาล่าง เปิดได้จากทุกหน้าจอ ถามได้ทั้ง วิธีใช้งานระบบ ("โอนสินค้าระหว่างคลังทำยังไง") และ ข้อมูลในคลังตอนนี้ ("สินค้าไหนใกล้หมด", "คลังหาดใหญ่มีน้ำยางข้นเหลือเท่าไร", "ยอดขายเดือนนี้เท่าไร")
การตั้งค่า — เพิ่มที่ Vercel > Settings > Environment Variables แล้ว Redeploy หนึ่งครั้ง
| ตัวแปร | บังคับ | ค่าเริ่มต้น |
|---|---|---|
GEMINI_API_KEY | ใช่ | — |
GEMINI_MODEL | ไม่ | gemini-2.0-flash |
CHAT_ALLOWED_EMAILS | ไม่ | ว่าง = ทุกคนที่ล็อกอินใช้ได้ |
GEMINI_API_KEYต้องไม่มีNEXT_PUBLIC_นำหน้า — คีย์อ่านได้เฉพาะฝั่งเซิร์ฟเวอร์ ถ้าใส่NEXT_PUBLIC_คีย์จะถูกฝังลงใน JavaScript ที่ส่งให้เบราว์เซอร์ทันที ไม่ต้องตั้งค่าก็ใช้ระบบส่วนอื่นได้ตามปกติ แค่ผู้ช่วย AI จะบอกว่ายังไม่ได้ตั้งค่า
สถาปัตยกรรม — เบราว์เซอร์ไม่เคยเห็นคีย์ คำถามถูกส่งไปที่ /api/chat
ซึ่งตรวจว่าผู้เรียกล็อกอินแล้วจริง (ยืนยัน token กับ Supabase) ตรวจโควตา
แล้วจึงเรียก Gemini REST API ด้วย fetch — ไม่ได้ติดตั้ง SDK ของ Google
ข้อจำกัดที่ควรทราบ
CHAT_ALLOWED_EMAILS
ไม่งั้นใครสมัครเองก็ใช้โควตาของคุณได้เว็บนี้ติดตั้งลงเครื่องได้เหมือนแอปทั่วไป เปิดจากหน้าจอโฮมโดยไม่มีแถบเบราว์เซอร์
| อุปกรณ์ | วิธีติดตั้ง |
|---|---|
| Android (Chrome) | กดปุ่ม "ติดตั้งแอป" บนแถบด้านบน หรือเมนู ⋮ → ติดตั้งแอป |
| Windows / macOS (Chrome, Edge) | กดปุ่ม "ติดตั้งแอป" หรือไอคอนติดตั้งท้ายแถบที่อยู่ |
| iPhone / iPad (Safari) | ปุ่มแชร์ → เพิ่มไปยังหน้าจอโฮม (iOS ไม่รองรับปุ่มติดตั้งในหน้าเว็บ) |
ปุ่ม "ติดตั้งแอป" จะโผล่เฉพาะตอนเบราว์เซอร์พร้อมให้ติดตั้ง และหายไปเองหลังติดตั้งแล้ว
ใช้งานออฟไลน์ไม่ได้ — ข้อมูลทั้งหมดอยู่บน Supabase ที่แชร์กับผู้ใช้ทุกคน
service worker จึงแคชเฉพาะไฟล์หน้าตาของเว็บเพื่อให้เปิดเร็วขึ้นเท่านั้น
ไม่แคชข้อมูลผู้ใช้เลย (ข้ามทุกคำขอที่ไม่ใช่ GET ข้ามคำขอข้ามโดเมน และข้าม /api/)
ถ้าเน็ตหลุดจะขึ้นหน้าแจ้งเตือนพร้อมปุ่มลองใหม่
เวอร์ชันใหม่ — HTML ใช้ network-first เสมอ deploy ใหม่จึงมีผลทันที ถ้ามีเวอร์ชันใหม่ของ service worker จะขึ้นข้อความให้ปิดแล้วเปิดแอปใหม่ (ไม่ reload เองกลางคัน เผื่อกำลังคีย์บิลขายค้างอยู่)
เปลี่ยนโลโก้ — ตราทุกที่ในโปรแกรม (หน้าจอ กระดาษพิมพ์ ไอคอนแอป ไอคอนแท็บ)
มาจากไฟล์ภาพต้นฉบับไฟล์เดียวคือ components/fav/NewLogo.jpg
เปลี่ยนโลโก้ให้เขียนทับไฟล์นั้น แล้วรัน:
powershell -ExecutionPolicy Bypass -File tools/trim-logo.ps1
ต้นฉบับเป็น JPEG พื้นเทาอ่อนและมีขอบว่างกว้างมาก เอามาใช้ตรง ๆ ไม่ได้ สคริปต์จึงตัดขอบว่างออก คีย์พื้นหลังให้โปร่งใส ถอดสีพื้นออกจากขอบที่ถูกเกลี่ย แล้วเขียนไฟล์ปลายทางให้ครบทั้ง 8 ไฟล์:
| ไฟล์ | ใช้ที่ไหน |
|---|---|
public/logo.png | ตราเต็ม ตัวอักษรเขียวเข้ม — หน้าเข้าระบบ หัวกระดาษพิมพ์ |
public/logo-light.png | ตราเต็ม ตัวอักษรขาว — แถบเมนูสีเข้ม |
public/icons/icon-192.png · icon-512.png | ไอคอน PWA |
public/icons/icon-maskable-512.png | ไอคอน PWA แบบเต็มสี่เหลี่ยม (ระบบครอปเอง) |
app/icon.png · app/apple-icon.png | ไอคอนตาม file convention ของ Next.js และหน้าจอโฮม iOS |
app/favicon.ico | ไอคอนแท็บ บรรจุ 16/32/48/64 ในไฟล์เดียว |
ที่ต้องมีตราสองฉบับ เพราะตัวอักษรบนตราเป็นเขียวเข้ม วางบนแถบเมนูสีเขียวเข้มแล้วอ่านไม่ออก
เคยแก้ด้วยการวางบนแผ่นขาว แต่ดูเป็นป้ายแปะทับเมนู ทำฉบับตัวอักษรขาวไว้เลยจึงเรียบร้อยกว่า
ทั้งสองฉบับขนาดเท่ากันเป๊ะ สลับแล้วหน้าจอไม่ขยับ (tools/check.mjs ข้อ 19 เฝ้าไว้)
ส่วนไอคอนแอปจะตัดเฉพาะ เปลวไฟกับลูกศร ออกมาเป็นจัตุรัส ไม่เอาตัวอักษร เพราะย่อลง 16px แล้วตัวอักษร OFAU อ่านไม่ออกอยู่แล้ว เหลือแต่รูปทรงจึงจำได้ง่ายกว่า สคริปต์หาขอบเขตเองด้วยการไล่หาแถวแรกที่เนื้อหากว้างเกินครึ่งภาพ (= หัวตัวอักษร) แล้วเก็บเฉพาะจุดเหนือแถวนั้นที่ไม่ใช่สีเขียวเข้ม จึงไม่ต้องกรอกพิกัดครอปเอง
พื้นของไอคอนเป็นสีขาว ไม่ใช่เขียว เพราะตราวางบนพื้นเขียวแล้วลูกศรเขียวจมหายไปกับพื้น เหลือแต่เปลวไฟให้เห็น และมีขอบจาง ๆ กันไอคอนกลืนไปกับหน้าจอโฮมที่พื้นหลังสว่าง
สคริปต์ใช้ System.Drawing ที่มากับ Windows และเขียนหัวไฟล์ .ico เอง
จึงไม่ต้องติดตั้งไลบรารีอะไรเพิ่มเลย
ส่วนรูปพรีวิวตอนแชร์ลิงก์ใช้ public/logo.png โดยตรง ไม่ต้องสร้างใหม่
ถ้าเจอ
Access deniedตอนรัน ให้ลบไฟล์ในpublic/icons/และapp/*.pngทิ้งก่อนแล้วรันใหม่ (OneDrive ล็อกไฟล์ที่เพิ่งสร้างไว้ชั่วครู่)
ส่งลิงก์เว็บใน LINE, Facebook หรือ X แล้วจะขึ้นการ์ดพรีวิวพร้อมรูป ชื่อ และคำอธิบาย แทนลิงก์เปล่า ๆ
รูปการ์ดคือ public/og-image.png (1200x630) ประกาศไว้ใน app/layout.js
ถ้าใช้โดเมนของตัวเอง ต้องตั้ง env ตัวนี้ ไม่งั้นการ์ดจะชี้ไปโดเมน Vercel:
NEXT_PUBLIC_SITE_URL=https://stock.example.co.th
ถ้าใช้โดเมนของ Vercel เฉย ๆ ไม่ต้องตั้งอะไร ระบบหยิบให้เอง
(LINE ไม่รับ path แบบสัมพัทธ์ og:image จึงต้องเป็น URL เต็มพร้อมโดเมนเสมอ)
รูปการ์ด — ใช้ public/logo.png โดยตรง ไม่มีไฟล์ที่ต้องสร้างเพิ่ม
เปลี่ยนโลโก้แล้วการ์ดพรีวิวเปลี่ยนตามเอง (ดูหัวข้อเปลี่ยนโลโก้ด้านบน)
LINE แคชผลพรีวิวไว้ ถ้าแก้แล้วยังเห็นของเก่า ให้ลองแชร์ลิงก์ที่ต่อ
?v=2ท้าย URL
หมวดนี้แยกเป็นหัวข้อใหญ่ของตัวเองในเมนูซ้าย ไม่ปนกับงานคลัง งานขาย หรืองานลูกค้าสัมพันธ์ เพราะตอบคนละคำถาม — งานส่วนอื่นตอบว่า ขายอะไรไปเท่าไร ส่วนหมวดนี้ตอบว่า เราฟังลูกค้าอย่างเป็นระบบแค่ไหน และอยู่ระดับไหนของเกณฑ์
เกณฑ์ที่ระบบทำตาม (น้ำหนัก 10% แบ่งข้อละ 5%):
| ข้อ | ชื่อเกณฑ์ | ระดับ |
|---|---|---|
| 3.1 | การรับฟังลูกค้า | 1-5 |
| 3.2 | การประเมินความพึงพอใจ ความไม่พึงพอใจ และความผูกพัน | 1-5 |
หน้าจอทั้ง 7 หน้า
| หน้าจอ | ทำอะไร |
|---|---|
| ภาพรวมการรับฟังลูกค้า | ระดับที่ได้ เสียงลูกค้าทุกมิติ และงานที่ต้องตามวันนี้ |
| ช่องทางการรับฟัง | ทะเบียนช่องทาง พร้อมการ์ดบอกว่ายังขาดความครอบคลุมตรงไหน |
| เสียงของลูกค้า | บันทึกทีละเรื่อง จำแนกกลุ่ม วงจรชีวิต มิติ และความสำคัญ |
| ประเมินความพึงพอใจ | รอบประเมินและผลรายกลุ่มลูกค้า รายด้าน พร้อมคะแนนคู่เทียบ |
| ประเมินระดับตามเกณฑ์ | จุดตรวจ 43 ข้อใน 10 ระดับ พร้อมหลักฐาน |
| แผนปรับปรุงและนวัตกรรม | รายงานผู้บริหาร การนำไปใช้ ความรู้ และนวัตกรรม |
| รายงานและนำเสนอ | รายงาน 9 ชุด ส่งออก Excel หลายชีต และไฟล์ PowerPoint |
ระดับที่ได้คำนวณจากข้อมูลจริง ไม่ใช่ตัวเลขที่พิมพ์ใส่
จุดตรวจ 43 ข้อ มี 37 ข้อที่ระบบตรวจให้เอง จากข้อมูลที่มีอยู่แล้วในระบบ เช่น
เหลืออีก 6 ข้อที่ระบบตรวจเองไม่ได้จริง ๆ (เช่น สื่อสารแนวทางให้บุคลากรรับทราบอย่างทั่วถึง) จึงให้คนยืนยัน แต่ ต้องระบุหลักฐานเสมอ — ติ๊กเปล่า ๆ ระบบไม่นับให้
เกณฑ์ที่ติ๊กเองได้ทุกข้อ ไม่ต่างอะไรกับแบบฟอร์มกระดาษ และวันที่ผู้ตรวจขอดูหลักฐาน จะไม่มีอะไรให้ดูนอกจากเครื่องหมายถูก
ทุกจุดตรวจบอกเหตุผลเสมอ ไม่ว่าผ่านหรือไม่ผ่าน เช่น "ยังขาดกลุ่มลูกค้าด้านส่งเสริม" หรือ "4 ไตรมาสล่าสุดมีรายงานเพียง 2 ไตรมาส (ยังขาด 2 ไตรมาส)" รายงานที่บอกแค่ว่าไม่ผ่าน ไม่ช่วยให้ใครรู้ว่าต้องไปทำอะไรต่อ
การคิดระดับ — เกณฑ์เป็นแบบสะสม ระดับ 3 จะได้ก็ต่อเมื่อผ่าน 1 และ 2 มาแล้ว ระดับที่ผ่านแบบข้ามขั้นยังแสดงให้เห็นในรายงาน แต่ไม่นับเป็นระดับที่ได้ และระดับของทั้งหมวดตัดสินจากข้อย่อยที่อ่อนที่สุด ไม่ใช่ค่าเฉลี่ย — ดันข้อเดียวให้สูงจึงไม่ช่วย ต้องดันข้อที่ต่ำกว่าขึ้นมาก่อน
รายการที่ตายตัวในระบบ — กลุ่มลูกค้า 2 กลุ่ม (เชิงพาณิชย์ · ด้านส่งเสริม) และผลิตภัณฑ์ 8 รายการ (ผลิตภัณฑ์จากยางพารา · หมอน · ท้อปเปอร์ · ยางก้อนถ้วย · ยางก้อนแท่ง · ปุ๋ยเคมี · ปุ๋ยอินทรีย์ · น้ำหมักชีวภาพ) ตั้งไว้ในโค้ด ไม่ให้พิมพ์เอง เพราะเกณฑ์บังคับเรื่องความครบถ้วน ถ้าพิมพ์ต่างกันนิดเดียวระบบจะนับเป็นคนละกลุ่ม แล้วรายงานความครอบคลุมจะผิดทันที
คู่มือการใช้งานเป็นไฟล์ Word — หน้ารายงานมีปุ่ม คู่มือ Word ส่งออกคู่มือทั้งเล่มเป็น .docx
อธิบายทีละหน้าจอ พร้อม ตัวอย่างการกรอกจริง ทุกช่อง ข้อควรระวัง และตัวอย่างการทำจริง
ตั้งแต่ต้นจนได้ระดับ — มีสำเนาไว้ในโครงงานแล้วที่ Docs/คู่มือการรับฟังลูกค้า.docx
สร้างใหม่ได้ด้วย:
node tools/make-voc-manual.mjs "ชื่อหน่วยงาน"
เนื้อหาคู่มืออยู่ใน lib/vocManual.js ซึ่งดึงข้อความเกณฑ์ จุดตรวจ และรายการตั้งต้น
จาก lib/voc.js โดยตรง แก้เกณฑ์ที่เดียวคู่มือเปลี่ยนตามทั้งเล่ม
และ tools/check.mjs หมวด 20 บังคับว่าคู่มือต้องมีครบทุกหน้าจอเสมอ
คู่มือที่พิมพ์ทิ้งไว้จะเก่าทันทีที่ระบบเปลี่ยน และไม่มีใครรู้ว่ามันเก่าแล้ว
ไฟล์นำเสนอ — หน้ารายงานส่งออกเป็น .pptx จริงที่เปิดแก้ต่อใน PowerPoint ได้
ไม่ใช่ภาพหรือ PDF เพราะไฟล์นำเสนอถูกเอาไปแก้ต่อเสมอ
ไฟล์ที่แก้ไม่ได้จะถูกพิมพ์ใหม่ด้วยมือทุกครั้ง แล้วตัวเลขในสไลด์จะไม่ตรงกับระบบ
(เขียน XML เองทั้งไฟล์ ไม่ได้ลงไลบรารีเพิ่ม — ใช้ตัวประกอบ zip ตัวเดียวกับไฟล์ Excel)
ตัวเลขที่แสดงบนหน้าจอ ที่อยู่ในไฟล์ Excel และที่อยู่ในสไลด์ มาจากตัวประกอบรายงานชุดเดียวกัน จึงไม่มีทางไม่ตรงกัน
หน้าจอไหนให้เลือกคลัง หน้าจอนั้นให้เลือกที่เก็บด้วยเสมอ และที่เก็บต้องอยู่ในคลังนั้นจริง
บังคับทั้งที่หน้าจอและที่ฐานข้อมูล (foreign key คู่ (loc_id, wh_id))
ยอดในช่องเก็บขยับตามรายการเคลื่อนไหวเอง ไม่ต้องกรอกซ้ำ — บันทึกรับ/เบิก/โอน/ขายแล้ว ผังที่เก็บจะถูกปรับให้ในคราวเดียวกัน ผลรวมของทุกช่องในคลังหนึ่งจึงเท่ากับยอดคงเหลือของคลังนั้นเสมอ
อัปเกรดฐานข้อมูลเดิม — รัน supabase/schema.sql ทั้งไฟล์อีกครั้ง (รันซ้ำได้ ไม่ลบข้อมูล)
แล้วเข้าหน้าจอผังที่เก็บสินค้า กด "ซ่อมผังให้ตรงกับรายการ"
รายการเก่าที่บันทึกก่อนอัปเกรดจะไม่มีที่เก็บ ของส่วนนั้นขึ้นเป็น "ยังไม่ระบุตำแหน่ง" ให้จัดวางเองจากหน้าผัง ส่วนรายการใหม่จะมีที่เก็บครบทุกใบ
ที่หน้า สินค้า → แก้ไข มีช่อง คลังประจำ และ ที่เก็บประจำ (ไม่บังคับ ตั้งแล้วต้องตั้งทั้งคู่)
ตั้งแล้วเวลาเลือกสินค้ารายการนั้นที่หน้า รับ / เบิก / โอน / ปรับปรุง ระบบจะเปลี่ยนคลังและ ที่เก็บให้ตามค่าประจำทันที ส่วนหน้า POS จะหยิบของจากช่องประจำก่อนถ้าช่องนั้นมีของอยู่ (ไม่เปลี่ยนคลังให้ เพราะเปลี่ยนคลังแล้วบิลจะถูกล้างทั้งใบ)
สินค้าที่ไม่ได้ตั้งค่าประจำ จะไม่ไปยุ่งกับคลังที่เลือกไว้อยู่แล้ว
ลากแถบคั่นระหว่างแคตตาล็อกสินค้ากับแผงบิลด้วยเมาส์ได้เลย ระบบจำความกว้างไว้ให้ เปิดใหม่ครั้งหน้าได้ขนาดเดิม (เก็บในเบราว์เซอร์ของเครื่องนั้น ไม่ได้เก็บบนฐานข้อมูล)
Home = คืนค่าเริ่มต้นทุกช่องที่กรอกจำนวนมีปุ่ม − และ + ขนาบสองข้าง กดปรับทีละก้าวหรือพิมพ์เองก็ได้ ใช้ที่หน้ารับ / เบิก / โอน, ปรับปรุงสินค้า, POS, ผังที่เก็บ และข้อมูลสินค้า
ช่องที่เป็นจำนวนเงิน (ราคา ส่วนลด รับเงิน) ไม่มีปุ่มนี้ เพราะกดทีละบาทไม่ได้ช่วยอะไร ส่วนช่องรับเงินมีปุ่มลัด +100 / +500 / +1000 / พอดี อยู่แล้ว
ทุกช่องเลือกสินค้ากดเลือกจากรายการก็ได้ พิมพ์ค้นหาก็ได้ ค้นจากรหัส ชื่อ บาร์โค๊ด หรือหมวดหมู่
ใช้ลูกศรขึ้น-ลงเลื่อน Enter เลือก Esc ปิด
หน้า กราฟสรุป มีแท็บชุดเดียวกับหน้ารายงาน: ยอดคงเหลือ / รับ / เบิก / โอน / ปรับปรุง / ขาย
แต่ละแท็บแสดงกราฟแท่งรายเดือน 10 อันดับสินค้า และยอดแยกตามคลัง แท็บการขายมีกราฟมูลค่าเพิ่มมาอีกอัน ส่วนแท็บปรับปรุงแยกยอดเพิ่มกับยอดลดคนละสี
หน้า รับ / เบิก / โอน / ปรับปรุงสินค้า กรอกเป็นตารางทีละบรรทัด เรียงคอลัมน์ สินค้า → คลังสินค้า → ที่เก็บสินค้า → จำนวน
กรอกบรรทัดสุดท้ายครบเมื่อไร บรรทัดใหม่ขึ้นให้เองทันที ไม่ต้องกดปุ่มเพิ่มบรรทัด และบรรทัดใหม่ใช้คลัง/ที่เก็บต่อจากบรรทัดก่อน เพราะปกติทำเอกสารเดียวคลังเดียว
ตัวเลข "หยิบได้" ใต้ช่องจำนวนหักของที่บรรทัดอื่นในตารางจองไว้แล้ว กรอกสองบรรทัดหยิบจากช่องเดียวกันจึงไม่หลุดไปพังตอนกดบันทึก
กรอกทีละบรรทัดในตารางเดียว แต่ละบรรทัดเลือกสินค้า คลัง ที่เก็บ และยอดที่นับได้จริง ระบบคำนวณยอดตามบัญชีกับผลต่างให้สดตลอด
กด บันทึกเอกสาร แล้วบรรทัดที่ยอดตรงกับบัญชีจะถูกข้ามให้เอง ไม่ต้องมานั่งลบทิ้ง
ปุ่มวงกลมสามสีบนแถบบน — เขียว / ฟ้า / ม่วง กดเลือกได้ทันที ระบบจำไว้ให้ (เก็บในเบราว์เซอร์ของเครื่องนั้น แต่ละคนเลือกของตัวเองได้)
สีเตือน (สำเร็จ / เตือน / ผิดพลาด) ไม่เปลี่ยนตามธีม เพราะต้องสื่อความหมายเหมือนกันทุกโทน
เลือก ตั้งแต่วันที่ / ถึงวันที่ ด้วยปฏิทิน หรือกดปุ่มลัด (วันนี้ / เดือนนี้ / 3 / 6 / 12 เดือน)
ยอดคงเหลือและสินค้าต่ำกว่าเกณฑ์คิด ณ วันสิ้นสุดของช่วง ไม่ใช่ ณ วันนี้เสมอไป เลือกช่วงย้อนหลังจึงเห็นภาพ ณ ตอนนั้นได้จริง
แอดมินเป็นคนกำหนดว่าใครเห็นและแก้หน้าจอไหนได้บ้าง ตั้งได้สองระดับ
| ระดับ | ใช้กับใคร |
|---|---|
| ค่าเริ่มต้นของทุกคน | ทุกคนที่ยังไม่ได้ตั้งสิทธิเฉพาะตัว |
| สิทธิเฉพาะตัว | คนนั้นคนเดียว ไม่ขยับตามค่าเริ่มต้นอีก |
ลำดับการตัดสิน — สิทธิเฉพาะตัว → ค่าเริ่มต้นของทุกคน → ไม่มีทั้งคู่ถือว่าเปิดหมด ไม่ได้เอาสองชั้นมารวมกัน เพราะสิทธิที่ต้องเดาว่าชั้นไหนชนะ คนตั้งค่าอ่านไม่ออก
สิทธิมี 3 อย่างต่อหนึ่งหน้าจอ: แสดงหน้าจอ (ไม่ติ๊ก = หายจากเมนูเลย ไม่ใช่แค่กดไม่ได้) · แก้ไข/บันทึก (ไม่ติ๊ก = ดูได้อย่างเดียว) · เปลี่ยนวันที่ (ไม่ติ๊ก = ล็อกที่วันปัจจุบัน)
บทบาทผู้ใช้ — แอดมิน แก้สิทธิของคนอื่นได้ ส่วน ผู้ใช้ทั่วไป เปิดหน้านี้เข้ามา
จะเห็นแค่สิทธิของตัวเองแบบอ่านอย่างเดียว และหน้านี้จะไม่ขึ้นในเมนูของเขา
ระบบที่ยังไม่มีแอดมินเลยสักคน ถือว่าทุกคนเป็นแอดมินชั่วคราว ไม่งั้นระบบที่เพิ่งติดตั้งจะไม่มีใครตั้งสิทธิให้ใครได้เลย และแก้กลับไม่ได้ พอตั้งแอดมินคนแรกแล้วประตูนี้ปิดเองทันที ตอนรัน
schema.sqlระบบจะตั้งผู้ใช้ที่สมัครเข้ามาก่อนสุดเป็นแอดมินให้อัตโนมัติ
ฐานข้อมูลบังคับกติกานี้ด้วย ไม่ใช่แค่ซ่อนปุ่ม — ตาราง app_users, user_perms
และ screen_perms ตั้ง policy ไว้ว่า อ่านได้ทุกคนที่ล็อกอินแล้ว แต่เขียนได้เฉพาะแอดมิน
ต่อให้ยิง API ตรง ๆ ก็ยกสิทธิให้ตัวเองไม่ได้ (ตัวตรวจหมวด 21 เฝ้าข้อนี้ไว้)
ผู้ใช้เข้าทะเบียนได้เองสองทาง — trigger บน auth.users ตอนสร้างบัญชี
และตัวโปรแกรมลงทะเบียนตัวเองตอนล็อกอินครั้งแรก มีสองทางเพราะบางโปรเจกต์
สร้าง trigger บน schema auth ไม่ได้ ถ้าพึ่งทางเดียวผู้ใช้จะไม่โผล่ในทะเบียน
แล้วแอดมินจะตั้งสิทธิให้ไม่ได้เลย
สิทธิชุดนี้คุม การใช้งานผ่านหน้าจอ ไม่ได้แบ่งสิทธิระดับตารางข้อมูล ผู้ใช้ที่ล็อกอินแล้วยังอ่านและแก้ตารางข้อมูลผ่าน API ได้เหมือนเดิม ถ้าต้องการแบ่งถึงระดับนั้น ต้องเขียน policy ตามบทบาทให้ทุกตาราง ซึ่งเป็นงานอีกก้อน
เมนู งานขาย → สถานะการจัดส่ง — กระดานแสดงผล ดูอย่างเดียว
ตาราง: เลขที่เอกสาร / วันที่เอกสาร / รหัสลูกค้า / ชื่อลูกค้า / จังหวัดที่ส่ง / ยอดสุทธิ / ระยะทาง (กม.) / สถานะ
ช่องค้นหาเดียวครอบคลุม เลขที่เอกสาร รหัสลูกค้า ชื่อลูกค้า จังหวัด ที่อยู่ วันที่ และชื่อสถานะ (ยิงบาร์โค๊ดได้) กรองเพิ่มด้วยสถานะและจังหวัดที่ส่ง · ส่งออก CSV ได้
สมชาย สงขลาIV-202609-0001 / iv2026090001 / IV 202609 0001 ได้ผลเหมือนกันช่วงวันที่เริ่มที่วันนี้เสมอ เพราะกระดานนี้ใช้ดูงานของวันนี้เป็นหลัก (เปิดค้างข้ามเที่ยงคืนแล้วเลื่อนวันให้เอง ถ้ายังไม่ได้ตั้งช่วงวันที่เอง)
พอเริ่มพิมพ์ค้นหา ช่วงวันที่จะถูกข้ามไป ค้นทั้งหมดทุกวันที่ — คนที่พิมพ์ชื่อลูกค้าลงไป คือคนที่กำลังตามหาใบนั้น ไม่ใช่คนที่อยากดูเฉพาะงานวันนี้ ถ้ายังกรองวันที่อยู่ เขาจะพิมพ์ถูกทุกตัวแต่ได้ตารางว่าง แล้วนึกว่าไม่มีใบนั้นในระบบ (ช่องวันที่จะถูกปิดขณะค้นหา ให้เห็นชัดว่าไม่ได้ใช้)
อัพเดทข้อมูลเองทุก 10 นาที พร้อมปุ่ม "อัพเดทข้อมูล" และเวลาที่อัพเดทล่าสุดกำกับไว้ คนดูกระดานจะได้รู้ว่าตัวเลขบนจอสดแค่ไหน — แท็บที่ซ่อนอยู่จะไม่ดึงข้อมูล และถ้าเน็ตกระตุกระหว่างดึง ข้อมูลเดิมยังอยู่บนจอ ไม่กลายเป็นหน้า error
สถานะ 4 ขั้นพร้อมสี — 🟠 กำลังจัดสินค้า → 🔵 จัดสินค้าเสร็จแล้ว → 🟣 ส่งสินค้าแล้ว → 🟢 ถึงมือลูกค้า
แต่ละใบมีแถบไล่ขั้น 4 ช่องระบายสีถึงขั้นที่ไปถึง ดูจากระยะไกลก็รู้ว่าค้างตรงไหน ใบที่ยังส่งไม่ถึงกะพริบเบา ๆ ใบที่ถึงแล้วอยู่นิ่ง ตาจะได้ไปเกาะเฉพาะงานที่ยังค้าง (เอฟเฟกต์ปิดเองถ้าผู้ใช้ตั้งเครื่องเป็น reduced motion)
เปลี่ยนสถานะที่หน้านี้ไม่ได้ — ต้องไปทำที่ การจัดส่งสินค้า เพราะสถานะควรมาจาก คนที่จับของจริง ไม่ใช่คนที่นั่งดูกระดาน ถ้าแก้ได้สองที่แล้วชนกัน จะไม่มีใครรู้ว่าของอยู่ไหน
"จัดสินค้าเสร็จแล้ว" แยกจาก "กำลังจัดสินค้า" เพราะเป็นคนละคนทำ — คนคลังจัดของเสร็จแล้ว ส่งต่อให้คนขนส่ง ถ้าไม่มีขั้นนี้จะไม่รู้ว่าของพร้อมส่งหรือยัง
เมนู งานขาย → ขายสินค้าและบริการ — คนละหน้ากับ POS
| POS | ขายสินค้าและบริการ | |
|---|---|---|
| ลูกค้า | พิมพ์ชื่ออิสระ | เลือกจากทะเบียนลูกค้า |
| ส่วนลด | ท้ายบิลอย่างเดียว | รายบรรทัด (% และบาท) + ท้ายบิล |
| ภาษี | 7% ตายตัว | ปรับได้รายใบ (เริ่มต้น 7%) |
| เอกสาร | ใบเสร็จอย่างย่อ 78 มม. | ใบกำกับภาษีเต็มรูปแบบ A4 |
| จัดส่ง | ไม่มี | ส่งต่อไปหน้าการจัดส่งสินค้า |
เลือกรหัสลูกค้าแล้วชื่อ ที่อยู่ และเลขประจำตัวผู้เสียภาษีขึ้นตามให้เอง (แก้ทับไม่ได้ ไม่งั้นชื่อกับรหัสจะไม่ตรงกัน) ตารางสินค้าใช้โครงเดียวกับหน้าเบิกสินค้า — สินค้า → คลังสินค้า → ที่เก็บสินค้า → จำนวน แล้วเพิ่ม ราคา/หน่วย → ส่วนลด % → ส่วนลดบาท → รวมเงิน
การคิดเงิน — หักส่วนลด % ก่อน แล้วค่อยหักส่วนลดบาท (ลำดับที่ใช้กันในเอกสารการค้า) ภาษีคิดจาก ยอดหลังหักส่วนลดท้ายบิล เพราะส่วนลดการค้าลดฐานภาษีจริง
บันทึกแล้วตัดสต็อกจริงผ่านฟังก์ชัน
create_invoice()ซึ่งเขียนinvoices+invoice_items+txnsใน transaction เดียว — ยอดคงเหลือยังมาจากtxnsที่เดียวเหมือนเดิมชื่อและที่อยู่ลูกค้าถูกคัดลอกเก็บไว้ในใบ แก้ทะเบียนลูกค้าทีหลังใบเก่าไม่เปลี่ยนตาม เอกสารภาษีต้องคงข้อความเดิม ณ วันที่ออก
ใบกำกับภาษีที่พิมพ์มีครบตามที่กฎหมายบังคับ (ชื่อ/ที่อยู่/เลขผู้เสียภาษีทั้งผู้ขายและผู้ซื้อ เลขที่ วันที่ รายการ มูลค่า ภาษีที่แยกออกมา ยอดรวม) พร้อม จำนวนเงินเป็นตัวอักษร และ บาร์โค๊ดเลขที่เอกสาร สำหรับยิงที่หน้าจัดส่ง
เมนู งานขาย → การจัดส่งสินค้า
ยิงบาร์โค๊ดแล้วเลือกสถานะได้ทันที — ยิงเลขที่เอกสารบนใบกำกับภาษี แล้วกล่องเลือกสถานะ จะเด้งขึ้นมาเลย กดขั้นที่ของไปถึงแล้ว กล่องปิดเองและกลับไปรอยิงใบถัดไปต่อ
เครื่องอ่านบาร์โค๊ดทำงานเหมือนคีย์บอร์ด ไม่ต้องต่ออุปกรณ์อะไรเป็นพิเศษ ระบบโฟกัสช่องให้ตั้งแต่ เปิดหน้า (พิมพ์ค้นหาเลขที่ / รหัสลูกค้า / ชื่อ / ที่อยู่ ก็ได้)
ทำแบบนี้เพราะคนที่ยิงคือคนที่กำลังจับของอยู่ตรงนั้น เขายิงเพื่อบอกว่า "ของถึงขั้นนี้แล้ว" ถ้าให้ยิงเสร็จแล้วต้องเลื่อนหาปุ่มต่ออีก คือเพิ่มขั้นตอนให้คนที่มือไม่ว่าง
เลือกคลังต้นทางแล้วแผนที่เปลี่ยนเป็นเส้นทางจากคลังนั้นไปที่อยู่ลูกค้า พร้อมปุ่มเปิด เส้นทางใน Google Maps จริงสำหรับนำทางบนมือถือ
สถานะ 4 ขั้น — กำลังจัดสินค้า → จัดสินค้าเสร็จแล้ว → ส่งสินค้าแล้ว → ถึงมือลูกค้า กดย้อนกลับได้ถ้าของตีกลับ
ระยะทางตามถนนจริง จากคลังต้นทางไปที่อยู่ลูกค้า แสดงก่อนคอลัมน์สถานะทั้งสองหน้าจอ
เลือกคลังต้นทางแล้วคำนวณให้ทันที · ปุ่ม "คำนวณระยะทาง" คำนวณซ้ำรายใบ · ปุ่ม "คำนวณระยะทาง (n)" บนหัวการ์ดเติมให้ใบที่ยังไม่มีทั้งหมด
ใช้ OSRM + Nominatim ของ OpenStreetMap ซึ่งฟรีและไม่ต้องมี API key (Google Distance Matrix ให้ผลแบบเดียวกันแต่บังคับใช้คีย์และคิดเงินรายคำขอ)
ผลถูกเก็บไว้ในใบ ไม่ได้คำนวณสดทุกครั้งที่เปิดหน้าจอ — ตาราง 50 ใบจะกลายเป็น 100 คำขอ ทุกครั้งที่เปิดหน้า ซึ่งเกินโควตาฟรีแน่นอน และระยะทางจากคลังเดิมไปที่อยู่เดิมก็ไม่เปลี่ยน
ความแม่นขึ้นกับที่อยู่ — ที่อยู่ที่ระบุได้แค่ระดับอำเภอจะคลาดเคลื่อนได้ระดับสิบกิโลเมตร พอสำหรับวางแผนเส้นทาง แต่ไม่ควรเอาไปคิดค่าขนส่งตรง ๆ · ยังไม่ได้คำนวณจะขึ้น
—ไม่ใช่0
ที่อยู่ปลายทางอ่านจากที่อยู่ที่บันทึกไว้ในใบ ไม่ใช่จากทะเบียนลูกค้าสด ๆ เพราะของต้องไปตามที่อยู่ที่ตกลงกันตอนออกใบ
เมนู การจัดการระบบ → ข้อมูลกิจการ — ชื่อ ที่อยู่ และเลขประจำตัวผู้เสียภาษีที่พิมพ์เป็น หัวใบกำกับภาษี ต้องแก้ให้ตรงกับที่จดทะเบียนจริงก่อนออกเอกสาร ไม่งั้นใบที่พิมพ์ออกไปใช้ไม่ได้
เก็บในฐานข้อมูล ไม่ได้ฝังในโค้ด — วันที่กิจการย้ายที่อยู่จะได้แก้เองได้ทันทีโดยไม่ต้อง deploy ใหม่
ที่หน้า สินค้าตามจังหวัด กดปุ่ม "ปักหมุดตำแหน่ง" บนการ์ดแผนที่
ช่องค้นหารับสองอย่างในช่องเดียว:
13.7563, 100.5018 (จาก Google Maps) หมุดย้ายทันที ไม่ต้องยิงเน็ตบนแผนที่: คลิก = วางหมุด · ลาก = เลื่อนภาพ · ปุ่ม + / − = ซูม · ปุ่มหมุด = กลับไปที่หมุด คลิกที่แผนที่แล้วกดลูกศรขยับหมุดทีละน้อย (Shift ค้าง = เร็วขึ้น) ใช้ด้วยคีย์บอร์ดล้วนได้
แผนที่ปักหมุดเขียนเองด้วยภาพ tile ของ OpenStreetMap ไม่ใช้ไลบรารีแผนที่และไม่ต้องมี API key — แผนที่ Google Maps Embed ที่ใช้แสดงผลเป็น iframe ข้ามโดเมน จึงรู้ไม่ได้ว่าผู้ใช้คลิกตรงไหน
การค้นหาใช้ Nominatim ซึ่งจำกัด 1 คำขอต่อวินาที ระบบจึงค้นเมื่อกดปุ่มหรือกด Enter เท่านั้น
เมนู ข้อมูลหลัก → รายละเอียดลูกค้า เก็บทะเบียนลูกค้า: รหัส (ออกให้อัตโนมัติแบบ C0001)
ชื่อ ที่อยู่ ตำบล อำเภอ จังหวัด รหัสไปรษณีย์ เบอร์โทร และประเภทลูกค้า
ที่อยู่แยกเป็นคนละช่อง ไม่ได้เก็บรวมเป็นก้อนเดียว เพราะต้องเอาไปกรองและออกรายงานรายจังหวัด ค้นหาได้จากทุกช่องพร้อมกัน (รหัส ชื่อ เบอร์โทร ที่อยู่) และกรองตามประเภทได้
จังหวัด / อำเภอ / ตำบล เลือกเอา ไม่ต้องพิมพ์ — เลือกจังหวัดแล้วเห็นเฉพาะอำเภอของจังหวัดนั้น เลือกอำเภอแล้วเห็นเฉพาะตำบลของอำเภอนั้น พอเลือกตำบลแล้ว รหัสไปรษณีย์เติมให้เองและแก้ไม่ได้ (รหัสที่ไม่ตรงกับตำบลคือที่อยู่ที่ส่งของไม่ถึง) กรุงเทพฯ ป้ายเปลี่ยนเป็น เขต/แขวง ให้เอง
ข้อมูล 77 จังหวัด · 930 อำเภอ/เขต · 7,452 ตำบล/แขวง ฝังไว้ในโปรเจกต์ที่ lib/thaiAddress.js
ไม่ได้ยิง API ตอนใช้งาน — ที่อยู่ต้องกรอกได้ตลอด ถ้าไปพึ่งเว็บนอกแล้ววันไหนเขาปิด
หน้าจอนี้จะกรอกไม่ได้ทันที ไฟล์นี้โหลดแบบ dynamic เฉพาะตอนเปิดหน้าลูกค้า ไม่ติดไปกับหน้าอื่น
อัปเดตข้อมูลเมื่อมีการเปลี่ยนเขตปกครอง (ต้องต่อเน็ต):
node tools/make-thai-address.mjs
ที่มาข้อมูล: kongvut/thai-province-data (MIT) อ้างอิงกรมการปกครอง
ช่อง "ชื่อลูกค้า" ที่หน้า POS ยังเป็นข้อความอิสระเหมือนเดิม ยังไม่ได้ผูกกับทะเบียนนี้
เมนู การจัดการระบบ → กำหนดคลังและที่เก็บ เลือกคลังทางซ้าย จัดการช่องเก็บของคลังนั้นทางขวา (ต่างจาก ผังที่เก็บสินค้า ที่เน้นดูเป็นภาพและจัดวางสินค้าลงช่อง)
ลบไม่ได้ถ้าของยังอยู่ — คลังที่ยังมีสินค้าคงเหลือหรือเคยมีรายการเคลื่อนไหวลบไม่ได้ (ประวัติต้องเก็บไว้ตรวจสอบย้อนหลัง) ช่องเก็บที่ยังมีของก็ลบไม่ได้ ต้องย้ายของออกก่อน ไม่งั้นผลรวมของทุกช่องจะไม่เท่ากับยอดคงเหลือของคลัง ซึ่งเป็นกติกาที่ทั้งระบบยึดไว้
เมนู การจัดการระบบ → การกำหนดกลุ่มเอกสาร ตั้งรูปแบบเลขที่เอกสารของแต่ละหน้าจอทำรายการ (รับ / เบิก / โอน / ปรับปรุง / ขาย) ได้ 3 อย่าง:
| ตั้งได้ | ค่าเริ่มต้น | หมายเหตุ |
|---|---|---|
| อักษรนำหน้า | RC IS TF AD SL | A-Z และ 0-9 ไม่เกิน 6 ตัว |
| การขึ้นเลขใหม่ | ขึ้นใหม่ทุกเดือน | ต่อเนื่องตลอด / ทุกปี / ทุกเดือน |
| จำนวนหลัก | 4 | 2 ถึง 8 |
เลขถัดไปนับจากเอกสารที่บันทึกไว้จริง ไม่ได้เก็บตัวนับไว้ที่ไหน เพราะฐานข้อมูลใช้ร่วมกัน หลายเครื่อง ถ้าเก็บตัวนับแล้วสองเครื่องอ่านพร้อมกันจะได้เลขซ้ำ
เปลี่ยนรูปแบบแล้วเลขเริ่มนับหนึ่งใหม่ — เป็นผลโดยตรงจากวิธีนับ เพราะเลขถัดไปดูจาก เอกสารที่ขึ้นต้นด้วยอักษรนำหน้าชุดเดียวกันเท่านั้น เอกสารเดิมไม่ถูกแก้ไข ยังค้นหาได้ตามปกติ ระบบจะถามยืนยันให้ก่อนถ้ากลุ่มนั้นมีเอกสารอยู่แล้ว
กดที่หัวข้อกลุ่ม (ภาพรวม / ทำรายการ / ขายหน้าร้าน / ข้อมูลหลัก / การจัดการระบบ / รายงาน) เพื่อหุบกลุ่มนั้น ระบบจำไว้ให้ในเบราว์เซอร์ของเครื่องนั้น
ถ้ากดทางลัดไปหน้าที่อยู่ในกลุ่มที่หุบไว้ กลุ่มนั้นจะกางออกให้เอง จะได้เห็นว่าตัวเองอยู่ตรงไหน
Deploy บน Vercel — ไม่ต้องตั้งค่าอะไรเพิ่ม Vercel ตรวจจับ Next.js จาก package.json
แล้วรัน npm install + next build ให้เองบนคลาวด์
npm install
npm run dev # เปิด http://localhost:3000
รายละเอียดสเปก โครงสร้างไฟล์ ผลการทดสอบ และบันทึกการแก้ไข อยู่ที่ Docs/ProjectPlan.txt
Docs/ProjectProcess.xlsx — กระบวนการสร้างโครงงานนี้แบบละเอียด 9 ชีต:
ภาพรวมโครงงาน · ขั้นตอนการทำงานมาตรฐาน 18 ขั้น · ขั้นตอนการสร้างจริง 69 รอบ
(พร้อมเหตุผลของแต่ละการตัดสินใจ) · ประวัติการส่งงานจาก git · หน้าจอทั้งหมด ·
ตารางฐานข้อมูลและคอลัมน์ · ตรรกะกลางที่เขียนเอง · ตัวตรวจอัตโนมัติทุกหมวด ·
กฎที่ยึดตลอดโครงงาน
สร้างใหม่ให้ตรงกับโค้ดปัจจุบันได้ทุกเมื่อ:
node tools/make-process-xlsx.mjs
ไฟล์นี้อ่านข้อมูลจากของจริง (แผนงาน · เมนู · schema.sql · ตัวตรวจ · ประวัติ git) จึงไม่มีตัวเลขที่พิมพ์ค้างไว้ให้เก่าโดยไม่มีใครรู้
การดึงบิลอัตโนมัติ — ดึงบิลจากไฟล์ Excel (.xlsx) หรือ CSV เข้ามาติดตามการจัดส่ง หน้าจอบอกรูปแบบไฟล์ที่ต้องใช้ครบ พร้อมปุ่มโหลดแบบฟอร์มที่มีหัวคอลัมน์ให้แล้ว (เลขที่เอกสาร · วันที่เอกสาร · รหัสลูกค้า · ชื่อลูกค้า · ที่อยู่จัดส่ง · จังหวัด · ยอดเงิน) จับคู่คอลัมน์ให้อัตโนมัติ ดูข้อมูลในไฟล์ก่อนได้ และถามยืนยันก่อนอัพโหลดทุกครั้ง
เพิ่มผู้ใช้งาน — สร้างบัญชีเข้าระบบด้วยอีเมลและรหัสผ่าน ใช้ได้ทันทีไม่ต้องยืนยันอีเมล
เชื่อมต่อฐานข้อมูลภายนอก — SQL Server / MySQL-MariaDB / Microsoft Access เก็บค่าการเชื่อมต่อ (Server / ฐานข้อมูล / ผู้ใช้ / รหัสผ่าน หรือที่อยู่ไฟล์สำหรับ Access) ไว้ได้หลายชุด ตั้งค่าเริ่มต้นได้ คัดลอก connection string ไปใช้ที่อื่นได้ และทดสอบการเชื่อมต่อผ่าน "ตัวเชื่อม" ที่รันไว้ในวงเดียวกับเซิร์ฟเวอร์ (เบราว์เซอร์ต่อฐานข้อมูลพวกนี้ตรง ๆ ไม่ได้ เพราะเป็น TCP ดิบ ส่วน Access เป็นไฟล์)
นำเข้าข้อมูลจาก Excel — เลือกหน้าจอที่จะนำเข้า (สินค้า / ลูกค้า / เจ้าหนี้ / คลัง / บิล) ดูตัวอย่างรูปแบบไฟล์ กดสร้างแบบฟอร์มไปกรอก แล้วโหลดกลับเข้ามา เห็นข้อมูลในไฟล์ก่อน ตรวจรายแถว บอกชัดว่าซ้ำเลขที่/รหัสไหน และถามยืนยันก่อนอัพโหลด
เปลี่ยนรหัสผ่าน — ใส่รหัสเดิมแล้วตั้งรหัสใหม่สองครั้งให้ตรงกัน
รายละเอียดเจ้าหนี้ — ทะเบียนเจ้าหนี้ โครงเดียวกับทะเบียนลูกค้าทุกอย่าง
ซื้อสินค้าและบริการ — รับของเข้าคลังพร้อมบันทึกภาษีซื้อและเลขที่ใบของเจ้าหนี้
ส่งคืนสินค้าและบริการ — คืนของให้เจ้าหนี้ อ้างใบซื้อเสมอ คืนเกินที่ซื้อมาไม่ได้
เตรียมใบตรวจนับ — เลือกคลัง ขอบเขต (เฉพาะที่มีของ / ทั้งหมด) และผู้ตรวจนับ 2 คน ระบบเก็บยอด ณ ตอนสร้างใบไว้เป็นตัวเทียบ ปิดใบแล้วออกเอกสารปรับปรุงเฉพาะบรรทัดที่ต่างให้เอง
นับสินค้า (มือถือ) — ถือมือถือเดินนับ เปิดกล้องส่องบาร์โค๊ดที่ตัวสินค้า เด้งรหัสและชื่อขึ้นมาให้กรอกจำนวน กดตกลงแล้วกล้องเปิดใหม่รอชิ้นต่อไปทันที แสดงรายการทั้งใบพร้อมสถานะ (ยังไม่ได้นับ = ขอบกะพริบ / ตรวจนับแล้ว / มีผลต่าง) กดที่บรรทัดเพื่อนับเองได้ และพิมพ์หรือส่งออกเป็นรายงานผลการตรวจนับได้จากหน้านี้
สร้างรายงาน — ตารางสรุปแบบ pivot เลือกแถว/คอลัมน์/ค่าที่จะรวมเองได้เหมือนใน Excel
สำรองและกู้คืนข้อมูล — สำรองทุกตารางลงไฟล์เดียว เลือกโฟลเดอร์ปลายทางในเครื่องได้
กำหนดสิทธิการใช้งาน — ติ๊กเลือกว่าหน้าจอไหนแสดง แก้ไขได้ และเปลี่ยนวันที่ได้
รายงาน 18 แท็บ — ครบทุกหน้าจอที่มีการบันทึกข้อมูล แบ่งกลุ่มตามงาน: ภาพรวม (ยอดคงเหลือ, บัตรสินค้า) · ทำรายการ (รับ/เบิก/โอน/ปรับปรุง, ใบตรวจนับ) · งานซื้อ (ใบซื้อ, ใบส่งคืน) · งานขาย (รายการขาย, บิล/ใบเสร็จ, ใบขาย) · งานจัดส่ง (เวลาแต่ละขั้น) · ข้อมูลหลัก (ทะเบียนสินค้า/ลูกค้า/เจ้าหนี้, คลังและช่องเก็บ) ทุกแท็บพิมพ์ ส่งออก CSV/Excel และค้นหาได้ — ช่องค้นหาพิมพ์แค่ส่วนใดส่วนหนึ่งก็เจอ ช่องเลือกลูกค้า/เจ้าหนี้/สินค้า กดเลือกหรือพิมพ์ค้นก็ได้ แถบตัวกรองเปลี่ยนตามแท็บ แสดงเฉพาะช่องที่มีผลกับข้อมูลในแท็บนั้นจริง
กราฟสรุป — แนวโน้มยอดคงเหลือ, รับเข้าเทียบจ่ายออก, แยกหมวดหมู่, 10 อันดับสูงสุด
Quick View (มือถือ) — ดูยอดขายเทียบเป้าเร็ว ๆ เลือกช่วงเวลา พนักงานขาย ยี่ห้อสินค้า มีทั้งตัวเลข กราฟ (แท่ง / แท่งนอน / โดนัท) และยอดขายรายลูกค้าเรียงมากไปน้อย
กำหนดเป้าขาย — ตั้งเป้ารายงวด แยกรายพนักงานขาย กลุ่ม ยี่ห้อ ประเภทสินค้า เทียบกับยอดขายจริงให้อัตโนมัติ · โหลดจาก Excel ได้
กำหนดพนักงานขาย — รหัส (ไม่เกิน 50 ตัว) และชื่อ (ไม่เกิน 200 ตัว) เลือกได้ที่หน้าขายและตั้งเป็นคนประจำของลูกค้าได้
แดชบอร์ดที่เลือกได้ — ดรอปดาวน์เลือกหน้าจอที่จะดูข้อมูล (ภาพรวมคลัง / ขาย / POS / ซื้อ / จัดส่ง / ทำรายการ) แล้วติ๊กเลือกว่าจะเอาการ์ดหรือกราฟใบไหนมาแสดง ระบบจัดตำแหน่งให้เอง เลือกรูปแบบกราฟได้ (แท่ง / เส้น / แท่งนอน / โดนัท) และจำสิ่งที่เลือกไว้ในเครื่องนั้น
ผู้ช่วย AI — ปุ่มลอยมุมขวาล่าง ถามได้ทั้งวิธีใช้งานระบบและข้อมูลในคลังตอนนี้
ติดตั้งเป็นแอปได้ (PWA) — เปิดจากหน้าจอโฮมเหมือนแอปทั่วไป ไม่มีแถบเบราว์เซอร์