task-e
This commit is contained in:
537
plans/task-e.md
Normal file
537
plans/task-e.md
Normal file
@@ -0,0 +1,537 @@
|
||||
# Task E: Quotation Production Module
|
||||
|
||||
## ALLA OS CRM vNext
|
||||
|
||||
คุณคือ Senior Full-stack Engineer
|
||||
ให้ implement Quotation production module โดยต่อยอดจาก Task A, B, B.1, C, D
|
||||
|
||||
## ต้องอ่านก่อน
|
||||
|
||||
```txt
|
||||
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 สำหรับ:
|
||||
|
||||
```txt
|
||||
Quotation
|
||||
Quotation Items
|
||||
Quotation Customers
|
||||
Quotation Topics
|
||||
Quotation Follow-ups
|
||||
Quotation Attachments metadata
|
||||
Quotation Revision
|
||||
Enquiry → Quotation linkage
|
||||
```
|
||||
|
||||
ยังไม่ทำ:
|
||||
|
||||
```txt
|
||||
Approval workflow เต็ม
|
||||
PDF generation จริง
|
||||
Report
|
||||
Dashboard KPI จริง
|
||||
Notification
|
||||
```
|
||||
|
||||
## Core Rules
|
||||
|
||||
```txt
|
||||
organizationId = tenant boundary
|
||||
branchId = business sub-scope
|
||||
```
|
||||
|
||||
ทุก quotation ต้องมี `organizationId`
|
||||
|
||||
Quotation ควรอ้างอิง:
|
||||
|
||||
```txt
|
||||
customerId
|
||||
contactId
|
||||
enquiryId optional
|
||||
```
|
||||
|
||||
ห้ามใช้ mock CRM service
|
||||
ห้าม import จาก:
|
||||
|
||||
```txt
|
||||
src/features/crm-demo/**
|
||||
src/constants/mock-api*
|
||||
```
|
||||
|
||||
## Scope E1: Quotation Schema
|
||||
|
||||
เพิ่ม production schema ใน `src/db/schema.ts`
|
||||
|
||||
ตารางหลัก:
|
||||
|
||||
```txt
|
||||
crm_quotations
|
||||
```
|
||||
|
||||
Fields ขั้นต่ำ:
|
||||
|
||||
```txt
|
||||
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:
|
||||
|
||||
```txt
|
||||
crm_quotation_items
|
||||
```
|
||||
|
||||
Fields ขั้นต่ำ:
|
||||
|
||||
```txt
|
||||
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:
|
||||
|
||||
```txt
|
||||
crm_quotation_customers
|
||||
```
|
||||
|
||||
Fields:
|
||||
|
||||
```txt
|
||||
id
|
||||
organizationId
|
||||
quotationId
|
||||
customerId
|
||||
role
|
||||
isPrimary
|
||||
createdAt
|
||||
updatedAt
|
||||
deletedAt
|
||||
```
|
||||
|
||||
Roles:
|
||||
|
||||
```txt
|
||||
owner
|
||||
consultant
|
||||
contractor
|
||||
billing
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
* customer หลักใน quotation ต้องอยู่ใน organization เดียวกัน
|
||||
* contractor สำคัญต่อ reporting ภายหลัง
|
||||
* ยังไม่ทำ report ใน Task E
|
||||
|
||||
## Scope E4: Quotation Topics Schema
|
||||
|
||||
เพิ่ม tables:
|
||||
|
||||
```txt
|
||||
crm_quotation_topics
|
||||
crm_quotation_topic_items
|
||||
```
|
||||
|
||||
Topic types:
|
||||
|
||||
```txt
|
||||
scope
|
||||
exclusion
|
||||
payment
|
||||
```
|
||||
|
||||
ใช้สำหรับเอกสารใบเสนอราคาในอนาคต
|
||||
|
||||
## Scope E5: Follow-ups + Attachments Metadata
|
||||
|
||||
เพิ่ม tables:
|
||||
|
||||
```txt
|
||||
crm_quotation_followups
|
||||
crm_quotation_attachments
|
||||
```
|
||||
|
||||
Attachment ใน Task E เก็บ metadata ก่อน:
|
||||
|
||||
```txt
|
||||
fileName
|
||||
originalFileName
|
||||
filePath
|
||||
fileSize
|
||||
fileType
|
||||
description
|
||||
uploadedAt
|
||||
uploadedBy
|
||||
```
|
||||
|
||||
ยังไม่ต้องทำ upload storage จริง ถ้า scope ใหญ่เกินไป
|
||||
ทำ placeholder service ได้ แต่ schema ต้องพร้อม
|
||||
|
||||
## Scope E6: API Routes
|
||||
|
||||
สร้าง route handlers:
|
||||
|
||||
```txt
|
||||
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
|
||||
```
|
||||
|
||||
รองรับ:
|
||||
|
||||
```txt
|
||||
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 แนะนำ:
|
||||
|
||||
```txt
|
||||
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
|
||||
|
||||
สร้าง:
|
||||
|
||||
```txt
|
||||
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 จาก:
|
||||
|
||||
```txt
|
||||
src/features/products/**
|
||||
src/features/users/**
|
||||
src/features/crm/customers/**
|
||||
src/features/crm/enquiries/**
|
||||
```
|
||||
|
||||
## Scope E8: Quotation UI
|
||||
|
||||
แทน placeholder routes:
|
||||
|
||||
```txt
|
||||
/dashboard/crm/quotations
|
||||
/dashboard/crm/quotations/[id]
|
||||
```
|
||||
|
||||
List page ต้องมี:
|
||||
|
||||
```txt
|
||||
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:
|
||||
|
||||
```txt
|
||||
Overview
|
||||
Items
|
||||
Customers
|
||||
Topics
|
||||
Follow-ups
|
||||
Attachments
|
||||
Activity
|
||||
Approval Placeholder
|
||||
Document Preview Placeholder
|
||||
```
|
||||
|
||||
## Scope E9: Quotation Form
|
||||
|
||||
ใช้:
|
||||
|
||||
```txt
|
||||
useAppForm
|
||||
Zod
|
||||
Sheet/Dialog pattern
|
||||
React Query mutation
|
||||
```
|
||||
|
||||
Create/Edit fields:
|
||||
|
||||
```txt
|
||||
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
|
||||
|
||||
ต้องมี:
|
||||
|
||||
```txt
|
||||
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 จริงใน:
|
||||
|
||||
```txt
|
||||
/dashboard/crm/enquiries/[id]
|
||||
```
|
||||
|
||||
### Customer Detail
|
||||
|
||||
เพิ่ม related quotations list placeholder หรือจริงถ้าทำไม่ซับซ้อน
|
||||
|
||||
## ห้ามทำใน Task E
|
||||
|
||||
```txt
|
||||
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 เต็ม
|
||||
Reference in New Issue
Block a user