Files
alla-allaos-fullstack/plans/task-e.md
phaichayon eae0dee1f2 task-e
2026-06-15 16:34:41 +07:00

9.8 KiB

Task E: Quotation Production Module

ALLA OS CRM vNext

คุณคือ Senior Full-stack Engineer ให้ implement Quotation production module โดยต่อยอดจาก Task A, B, B.1, C, D

ต้องอ่านก่อน

docs/implementation/task-a-template-audit.md
docs/implementation/task-b-template-audit.md
docs/implementation/task-b1-foundation-stabilization.md
docs/implementation/technical-debt.md

Layout.md
AGENTS.md
.agents/skills/kiranism-shadcn-dashboard

src/db/schema.ts
src/features/foundation/**
src/features/crm/customers/**
src/features/crm/enquiries/**
src/app/dashboard/crm/**

เป้าหมาย

สร้าง production module สำหรับ:

Quotation
Quotation Items
Quotation Customers
Quotation Topics
Quotation Follow-ups
Quotation Attachments metadata
Quotation Revision
Enquiry → Quotation linkage

ยังไม่ทำ:

Approval workflow เต็ม
PDF generation จริง
Report
Dashboard KPI จริง
Notification

Core Rules

organizationId = tenant boundary
branchId = business sub-scope

ทุก quotation ต้องมี organizationId

Quotation ควรอ้างอิง:

customerId
contactId
enquiryId optional

ห้ามใช้ mock CRM service ห้าม import จาก:

src/features/crm-demo/**
src/constants/mock-api*

Scope E1: Quotation Schema

เพิ่ม production schema ใน src/db/schema.ts

ตารางหลัก:

crm_quotations

Fields ขั้นต่ำ:

id
organizationId
branchId
code

enquiryId
customerId
contactId

quotationDate
validUntil
quotationType

projectName
projectLocation
attention
reference
notes

status
revision
parentQuotationId
revisionRemark

currency
exchangeRate

subtotal
discount
discountType
taxRate
taxAmount
totalAmount

chancePercent
isHotProject
competitor
salesmanId

isSent
sentAt
sentVia
acceptedAt
rejectedAt
rejectionReason

isActive
createdAt
updatedAt
deletedAt
createdBy
updatedBy

Rules:

  • organizationId required
  • customerId required
  • code unique ภายใน organization
  • status, quotationType, currency, discountType ใช้ master options ถ้ามี
  • code ใช้ document sequence quotation -> QT
  • create/update/delete ต้อง audit log
  • ยังไม่ทำ approval table
  • status pending_approval ทำเป็น placeholder ได้

Scope E2: Quotation Items Schema

เพิ่ม table:

crm_quotation_items

Fields ขั้นต่ำ:

id
organizationId
quotationId
itemNumber
productType
description
quantity
unit
unitPrice
discount
discountType
taxRate
totalPrice
notes
sortOrder
createdAt
updatedAt
deletedAt

Rules:

  • item ต้องอยู่ organization เดียวกับ quotation
  • totalPrice คำนวณฝั่ง server
  • quotation total ต้องคำนวณจาก items
  • ห้ามเชื่อ total จาก client โดยตรง

Scope E3: Quotation Customers Schema

เพิ่ม table:

crm_quotation_customers

Fields:

id
organizationId
quotationId
customerId
role
isPrimary
createdAt
updatedAt
deletedAt

Roles:

owner
consultant
contractor
billing

Rules:

  • customer หลักใน quotation ต้องอยู่ใน organization เดียวกัน
  • contractor สำคัญต่อ reporting ภายหลัง
  • ยังไม่ทำ report ใน Task E

Scope E4: Quotation Topics Schema

เพิ่ม tables:

crm_quotation_topics
crm_quotation_topic_items

Topic types:

scope
exclusion
payment

ใช้สำหรับเอกสารใบเสนอราคาในอนาคต

Scope E5: Follow-ups + Attachments Metadata

เพิ่ม tables:

crm_quotation_followups
crm_quotation_attachments

Attachment ใน Task E เก็บ metadata ก่อน:

fileName
originalFileName
filePath
fileSize
fileType
description
uploadedAt
uploadedBy

ยังไม่ต้องทำ upload storage จริง ถ้า scope ใหญ่เกินไป ทำ placeholder service ได้ แต่ schema ต้องพร้อม

Scope E6: API Routes

สร้าง route handlers:

src/app/api/crm/quotations/route.ts
src/app/api/crm/quotations/[id]/route.ts
src/app/api/crm/quotations/[id]/items/route.ts
src/app/api/crm/quotations/[id]/items/[itemId]/route.ts
src/app/api/crm/quotations/[id]/customers/route.ts
src/app/api/crm/quotations/[id]/topics/route.ts
src/app/api/crm/quotations/[id]/followups/route.ts
src/app/api/crm/quotations/[id]/attachments/route.ts
src/app/api/crm/quotations/[id]/revisions/route.ts

รองรับ:

GET list
POST create
GET detail
PATCH update
DELETE soft delete

CRUD items
CRUD customers
CRUD topics
CRUD followups
list/create attachment metadata
create revision

Rules:

  • ใช้ requireOrganizationAccess
  • ใช้ permission helper
  • filter ด้วย organizationId เสมอ
  • customer/contact/enquiry ต้องอยู่ organization เดียวกัน
  • create quotation ต้อง generate code
  • revision ต้องสร้าง code suffix หรือ revision record ตาม design
  • ทุก mutation ต้อง audit

Permissions แนะนำ:

crm.quotation.read
crm.quotation.create
crm.quotation.update
crm.quotation.delete
crm.quotation.item.manage
crm.quotation.customer.manage
crm.quotation.topic.manage
crm.quotation.followup.manage
crm.quotation.attachment.manage
crm.quotation.revision.create

Scope E7: Feature Layer

สร้าง:

src/features/crm/quotations/api/types.ts
src/features/crm/quotations/api/service.ts
src/features/crm/quotations/api/queries.ts
src/features/crm/quotations/api/mutations.ts
src/features/crm/quotations/schemas/quotation.schema.ts
src/features/crm/quotations/server/service.ts
src/features/crm/quotations/components/**

ใช้ pattern จาก:

src/features/products/**
src/features/users/**
src/features/crm/customers/**
src/features/crm/enquiries/**

Scope E8: Quotation UI

แทน placeholder routes:

/dashboard/crm/quotations
/dashboard/crm/quotations/[id]

List page ต้องมี:

PageContainer
DataTable
search
status filter
quotation type filter
branch filter
customer filter
enquiry filter
hot project filter
create button
edit action
view action
soft delete action

Detail page ใช้ Layout.md Template A

Tabs:

Overview
Items
Customers
Topics
Follow-ups
Attachments
Activity
Approval Placeholder
Document Preview Placeholder

Scope E9: Quotation Form

ใช้:

useAppForm
Zod
Sheet/Dialog pattern
React Query mutation

Create/Edit fields:

enquiryId
customerId
contactId
quotationDate
validUntil
quotationType
projectName
projectLocation
branchId
currency
exchangeRate
status
chancePercent
isHotProject
competitor
reference
notes

Rules:

  • enquiry dropdown จาก production enquiry API
  • ถ้าเลือก enquiry ให้ auto-fill customer/contact/project ถ้าทำได้แบบไม่ซับซ้อน
  • customer dropdown จาก production customer API
  • contact dropdown filter ตาม customer
  • status/quotationType/currency ดึงจาก master options
  • ห้าม hardcode option ใน form

Scope E10: Item UI

ใน Quotation Detail tab: Items

ต้องมี:

item list
create item
edit item
delete item
subtotal/tax/total summary

Rules:

  • คำนวณ total ฝั่ง server
  • UI แสดง readonly total summary จาก API

Scope E11: Revision

รองรับ create revision เบื้องต้น

Rules:

  • revision สร้างจาก quotation เดิม
  • copy quotation header + items + customers + topics
  • parentQuotationId ชี้กลับ quotation เดิม
  • revision เริ่ม R01, R02
  • ห้าม revise quotation ที่ draft/cancelled ถ้า business rule ต้องการ
  • mutation ต้อง audit

Scope E12: Integration

Enquiry Detail

เพิ่ม related quotations tab/list จริงใน:

/dashboard/crm/enquiries/[id]

Customer Detail

เพิ่ม related quotations list placeholder หรือจริงถ้าทำไม่ซับซ้อน

ห้ามทำใน Task E

Approval table
Approval matrix
Approval workflow เต็ม
PDF generation จริง
Excel generation จริง
Dashboard KPI จริง
Report
Notification

Output หลังทำเสร็จ

สรุป:

  1. Files Added
  2. Files Modified
  3. Schema Added
  4. API Routes Added
  5. UI Routes Completed
  6. Permissions Used
  7. Audit Integration
  8. Document Sequence Integration
  9. Enquiry/Customer Integration
  10. Revision Support
  11. Remaining Risks
  12. Task F Readiness

Definition of Done

Task E ผ่านเมื่อ:

  • Quotation schema พร้อม
  • Quotation items พร้อม
  • Quotation customers พร้อม
  • Quotation topics พร้อม
  • Quotation follow-ups พร้อม
  • Attachment metadata พร้อม
  • Quotation list ใช้ production data
  • Quotation detail ใช้ production data
  • Quotation create/edit/delete ใช้งานได้
  • Item create/edit/delete ใช้งานได้
  • Revision create ใช้งานได้เบื้องต้น
  • ใช้ organizationId ทุก query
  • customer/contact/enquiry ต้องอยู่ organization เดียวกัน
  • ใช้ master options ใน status/type/currency
  • ใช้ document sequence ตอนสร้าง quotation
  • ใช้ audit log ทุก mutation
  • ไม่ import mock CRM
  • ไม่ทำ Approval workflow เต็ม