WIP: SoftDelete Contract/Payment/Customer, collected_by, Notifications, ProjectReport, ExportDebtReport
This commit is contained in:
463
WORKFLOW.md
Normal file
463
WORKFLOW.md
Normal file
@@ -0,0 +1,463 @@
|
||||
# HQLAND - WORKFLOW TOÀN HỆ THỐNG
|
||||
|
||||
> Tài liệu này mô tả chi tiết luồng dữ liệu, nghiệp vụ và tương tác giữa các module trong HQLand.
|
||||
> **Cập nhật:** 29/04/2026
|
||||
|
||||
---
|
||||
|
||||
## I. TỔNG QUAN KIẾN TRÚC
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ FILAMENT ADMIN PANEL v5.5 │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
|
||||
│ │ Warehouse │ │ CRM │ │ Contracts │ │ Finance │ │
|
||||
│ │ (Kho hàng) │ │ (Khách hàng)│ │ (Hợp đồng) │ │ (Thu tiền/Báo │ │
|
||||
│ │ │ │ │ │ │ │ cáo) │ │
|
||||
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └────────┬─────────┘ │
|
||||
│ │ │ │ │ │
|
||||
│ ┌──────┴───────┐ ┌──────┴───────┐ ┌──────┴───────┐ ┌───────┴─────────┐ │
|
||||
│ │ Project │ │ Customer │ │ Contract │ │ Payment │ │
|
||||
│ │ Product │ │ (INDIVIDUAL│ │ Appendix │ │ PaymentFine │ │
|
||||
│ │ │ │ /COMPANY) │ │ Settlement │ │ Settlement │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ └─────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────┐│
|
||||
│ │ SUPPORT MODULES ││
|
||||
│ │ PaymentTemplate → PaymentSchedule → PaymentScheduleItem ││
|
||||
│ │ SalesPhase → SalesPhaseProduct (Pivot) ││
|
||||
│ │ FormTemplate → FormField → FormPrintLog ││
|
||||
│ │ MailMergeService | DiscountEngine | PriceCalculationService ││
|
||||
│ └─────────────────────────────────────────────────────────────────────────┘│
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ POSTGRESQL (UUID Primary Keys) │
|
||||
│ 120 Customers | 45 Products | 139 Contracts | Notifications Table │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Tech Stack
|
||||
- **Framework:** Laravel 13.x + PHP 8.3
|
||||
- **Admin Panel:** Filament v5.5 (Schemas Architecture)
|
||||
- **Database:** PostgreSQL + UUID (100% tables)
|
||||
- **Excel:** PhpSpreadsheet 5.7
|
||||
- **Testing:** Pest PHP 4.6
|
||||
|
||||
---
|
||||
|
||||
## II. LUỒNG DỮ LIỆU TỔNG THỂ (END-TO-END)
|
||||
|
||||
### 1. Khởi tạo Dự án & Kho hàng
|
||||
```
|
||||
Project (Hà Quang 1)
|
||||
├── PaymentTemplate (Mẫu lịch thanh toán mặc định)
|
||||
│ └── PaymentScheduleItem x N đợt (% + ngày đến hạn)
|
||||
└── Product x N (Lô đất/Căn hộ)
|
||||
├── Giá gốc (qsdd_value, foundation_temp_value, total_price)
|
||||
├── Hạ tầng (infrastructure_status - JSONB)
|
||||
└── Custom data (block, building_density, legal_status)
|
||||
```
|
||||
|
||||
### 2. Khởi tạo Khách hàng
|
||||
```
|
||||
Customer (INDIVIDUAL hoặc COMPANY)
|
||||
├── INDIVIDUAL: full_name, cmnd_cccd, phone, addresses...
|
||||
└── COMPANY: full_name (tên cty), tax_code, representative_id
|
||||
└── representative → Customer (INDIVIDUAL)
|
||||
```
|
||||
|
||||
### 3. Luồng Bán hàng chuẩn
|
||||
```
|
||||
Bước 1: Tạo Đợt mở bán (SalesPhase)
|
||||
├── Chọn Project
|
||||
├── Chọn PaymentTemplate (mẫu lịch thanh toán)
|
||||
├── Định chính sách chiết khấu mặc định (discount_policy JSONB)
|
||||
└── Thêm sản phẩm vào đợt (SalesPhaseProduct pivot)
|
||||
├── Giá riêng cho đợt (sale_price/land_value/foundation_value)
|
||||
├── Chiết khấu riêng (discount_details JSONB)
|
||||
└── Status: Còn hàng | Đã giữ | Đã bán | Khóa
|
||||
|
||||
Bước 2: Tạo Hợp đồng (Contract)
|
||||
├── Chọn Product (Lô đất)
|
||||
├── [Optional] Chọn SalesPhase → Auto populate giá từ SalesPhaseProduct
|
||||
├── Nhập giá trị tài chính:
|
||||
│ land_value + foundation_value = total_value (auto)
|
||||
├── Chiết khấu (discount_details JSONB)
|
||||
├── Chọn Khách hàng (belongsToMany qua contract_customers)
|
||||
├── Chọn PaymentTemplate (để tạo lịch thanh toán sau khi lưu)
|
||||
└── [Auto] Khi save:
|
||||
├── Booted: total_value = land_value + foundation_value
|
||||
├── Saved: PriceCalculationService tạo calculation_log
|
||||
└── AfterCreate: ContractScheduleService tạo PaymentSchedule
|
||||
|
||||
Bước 3: PaymentSchedule tự động tạo
|
||||
├── Contract → PaymentSchedule (1-1)
|
||||
└── PaymentSchedule → PaymentScheduleItem x N
|
||||
├── Mỗi item = 1 đợt thanh toán
|
||||
├── amount = total_value × (percentage / 100)
|
||||
├── due_date tính từ signing_date + days_after_signing
|
||||
└── Sắp xếp theo installment_no
|
||||
|
||||
Bước 4: Thu tiền (Payment)
|
||||
├── Chọn Contract
|
||||
├── [Optional] Chọn PaymentScheduleItem (đợt thanh toán)
|
||||
│ Nếu không chọn = Tạm ứng / không đối soát đợt
|
||||
├── Nhập amount, paid_date, method, receipt_number
|
||||
├── [Validation] amount không vượt quá công nợ đợt / công nợ HĐ
|
||||
└── [Auto - PaymentObserver] Khi Payment created/updated/deleted:
|
||||
├── recalculateContract: SUM payments → paid_amount
|
||||
│ remaining_amount = total_value - paid_amount
|
||||
│ excess_amount = paid_amount - total_value (nếu > 0)
|
||||
└── applySurplusToNextInstallment:
|
||||
Nếu excess_amount > 0 → Auto tạo Payment mới cho đợt tiếp theo
|
||||
```
|
||||
|
||||
### 4. In ấn (Form Templates)
|
||||
```
|
||||
FormTemplate (Admin tạo mẫu)
|
||||
├── HTML content với placeholder {{ma_truong}}
|
||||
└── FormField x N:
|
||||
├── db_column: Lấy trực tiếp cột từ Model
|
||||
├── db_relation: Lấy qua relation (customers.0.full_name)
|
||||
├── formula: Tính toán (dùng Shunting Yard + bcmath)
|
||||
├── input: Nhập tay khi in
|
||||
└── static: Giá trị cố định
|
||||
|
||||
Khi in:
|
||||
MailMergeService::render(template, record)
|
||||
├── evaluateFields() → Tính giá trị tất cả fields
|
||||
├── Thay placeholder → rendered HTML
|
||||
└── savePrintLog() → Lưu snapshot + rendered HTML + user + timestamp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## III. CHI TIẾT MODULE
|
||||
|
||||
### 3.1. WAREHOUSE (Kho hàng)
|
||||
|
||||
#### Models
|
||||
| Model | Key Fields | Quan hệ |
|
||||
|-------|-----------|---------|
|
||||
| **Project** | code, name, type, address, payment_template_id | hasMany Products, hasMany SalesPhases, hasMany PaymentTemplates |
|
||||
| **Product** | code, project_id, product_type (LAND/APARTMENT), area, price_per_unit, total_price, qsdd_value, foundation_temp_value, contract_temp_value, infrastructure_status (JSONB), custom_data (JSONB), status | belongsTo Project, hasMany Contracts, belongsToMany SalesPhases |
|
||||
|
||||
#### Nghiệp vụ
|
||||
1. **Import từ Excel** (`import:products-excel`):
|
||||
- File: `sanpham.xlsx`
|
||||
- Parse hạ tầng từ chuỗi "Key: Value - Key2: Value2" → `infrastructure_status` JSONB
|
||||
- Parse custom_data: block, building_density, legal_status_raw
|
||||
- `updateOrCreate` theo `code + project_id`
|
||||
|
||||
2. **Tìm đợt mở bán đang active** (`Product::activeSalesPhase()`):
|
||||
- SalesPhase.status = "Đang mở bán"
|
||||
- SalesPhaseProduct.status = "Còn hàng"
|
||||
- Ngày hiện tại nằm trong [start_date, end_date]
|
||||
|
||||
---
|
||||
|
||||
### 3.2. CRM (Khách hàng)
|
||||
|
||||
#### Models
|
||||
| Model | Key Fields | Quan hệ |
|
||||
|-------|-----------|---------|
|
||||
| **Customer** | type (INDIVIDUAL/COMPANY), full_name, cmnd_cccd, tax_code, title, phone, secondary_phones (JSONB), email, dob, permanent_address, contact_address, id_issue_date, id_issue_place, representative_id | belongsToMany Contracts (via contract_customers), representative → Customer, representedCompanies → Customer[] |
|
||||
|
||||
#### Nghiệp vụ
|
||||
1. **Import từ Excel** (`import:customers-excel`):
|
||||
- File: `khachhang.xlsx`
|
||||
- Tách nhiều số điện thoại (dấu phẩy, gạch chéo, xuống dòng) → `phone` + `secondary_phones`
|
||||
- Parse ngày Excel serial number → Carbon
|
||||
- Tạo mẫu: Công ty TNHH BĐS Thịnh Vượng + Ngườ đại diện
|
||||
|
||||
2. **Form tạo/sửa** (CustomerForm):
|
||||
- Chuyển đổi động INDIVIDUAL/COMPANY (live)
|
||||
- INDIVIDUAL: Hiện dob, id_issue_date, id_issue_place
|
||||
- COMPANY: Hiện tax_code, representative_id (chọn từ danh sách cá nhân)
|
||||
- Copy địa chỉ thường trú → liên hệ (suffixAction)
|
||||
|
||||
---
|
||||
|
||||
### 3.3. CONTRACTS (Hợp đồng)
|
||||
|
||||
#### Models
|
||||
| Model | Key Fields | Quan hệ |
|
||||
|-------|-----------|---------|
|
||||
| **Contract** | contract_number, contract_type (HĐMB/HĐGV/HĐDC), product_id, status, signing_date, sale_date, hql_confirmation_date, land_value, foundation_value, total_value, total_value_with_foundation, paid_amount, remaining_amount, excess_amount, discount_details (JSONB), calculation_log (JSONB), brokerage_name, stored_contract_count, filing_note, transfer_order, payment_template_id, sales_phase_id | belongsTo Product, belongsToMany Customers (via contract_customers + pivot role/transfer_order), belongsTo PaymentTemplate, belongsTo SalesPhase, hasOne PaymentSchedule, hasManyThrough PaymentScheduleItem, hasMany Payments, hasMany PaymentFines, hasMany Appendices |
|
||||
|
||||
#### Nghiệp vụ
|
||||
|
||||
**A. Tạo hợp đồng mới (CreateContract)**
|
||||
```
|
||||
1. Chọn Product → Auto điền:
|
||||
- total_value = product.total_price
|
||||
- land_value = product.qsdd_value
|
||||
- foundation_value = product.foundation_temp_value
|
||||
|
||||
2. [Optional] Chọn SalesPhase → Auto điền từ SalesPhaseProduct:
|
||||
- land_value, foundation_value, sale_price
|
||||
- Nếu có sale_price → total_value = sale_price
|
||||
- discount_details từ pivot
|
||||
|
||||
3. Nhập tay land_value, foundation_value → total_value auto cập nhật
|
||||
|
||||
4. Nhập discount_details (Key-Value) + xem tổng quan chiết khấu
|
||||
|
||||
5. Chọn Customers (multiple), nhập các thông tin quản lý
|
||||
|
||||
6. Chọn payment_template_id → [Auto] Sau khi lưu tạo PaymentSchedule
|
||||
```
|
||||
|
||||
**B. Booted Logic (Model Contract)**
|
||||
```
|
||||
static::saving:
|
||||
land_value + foundation_value → total_value
|
||||
Nếu tạo mới và chưa có giá → fallback lấy product.total_price
|
||||
remaining_amount = total_value - paid_amount
|
||||
|
||||
static::saved:
|
||||
Nếu có land_value/foundation_value:
|
||||
PriceCalculationService::calculateForContract() → calculation_log
|
||||
Cập nhật calculation_log (steps, final_values, price_sheet)
|
||||
```
|
||||
|
||||
**C. Calculation Pipeline**
|
||||
```
|
||||
Input: land_value, foundation_value, discount_details, vat_rate
|
||||
Step 1: Giá trị QSDĐ → land_value
|
||||
Step 2: Giá trị Móng → foundation_value
|
||||
Step 3: Subtotal = land_value + foundation_value
|
||||
Step 4: Chiết khấu = total_amount HOẶC total_percentage × subtotal
|
||||
Step 5: Net value = subtotal - discount
|
||||
Step 6: VAT = net_value × vat_rate%
|
||||
Step 7: Total payment = net_value + VAT
|
||||
Output: calculation_log lưu snapshot tất cả bước
|
||||
```
|
||||
|
||||
**D. Lịch thanh toán (ContractScheduleService)**
|
||||
```
|
||||
generateFromTemplate(contract, template):
|
||||
DB::transaction:
|
||||
Xóa lịch cũ (nếu có)
|
||||
Tạo PaymentSchedule
|
||||
Duyệt template.items theo installment_no:
|
||||
due_date = signing_date + days_after_signing
|
||||
amount = contract.total_value × (percentage / 100)
|
||||
Tạo PaymentScheduleItem
|
||||
```
|
||||
|
||||
**E. Các module phụ**
|
||||
- **Appendix (Phụ lục):** belongsTo Contract + Product, custom_data JSONB
|
||||
- **Settlement (Quyết toán):** belongsTo Product, temp_value, final_value, difference
|
||||
- **PaymentFine (Tiền phạt):** belongsTo Contract, amount, due_date, paid_date
|
||||
|
||||
---
|
||||
|
||||
### 3.4. FINANCE (Tài chính & Thu tiền)
|
||||
|
||||
#### Models
|
||||
| Model | Key Fields | Quan hệ |
|
||||
|-------|-----------|---------|
|
||||
| **Payment** | contract_id, schedule_item_id, amount, paid_date, method, receipt_number, metadata (JSONB) | belongsTo Contract, belongsTo PaymentScheduleItem |
|
||||
| **PaymentSchedule** | contract_id, template_id | belongsTo Contract, belongsTo PaymentTemplate, hasMany Items |
|
||||
| **PaymentScheduleItem** | schedule_id, installment_no, type (PaymentType enum), percentage, amount, due_date, days_after_signing, days_after_previous | belongsTo PaymentSchedule, hasMany Payments |
|
||||
|
||||
#### PaymentType Enum
|
||||
| Value | Label |
|
||||
|-------|-------|
|
||||
| QSDD | Tiền QSDĐ |
|
||||
| MONG | Tiền Móng |
|
||||
| THAN | Tiền Thân |
|
||||
| CHI_PHI_TC | Chi phí thi công |
|
||||
| CK | Chiết khấu |
|
||||
| PHAT | Tiền phạt |
|
||||
| OTHER | Khác |
|
||||
|
||||
#### Nghiệp vụ
|
||||
|
||||
**A. Thu tiền (PaymentForm)**
|
||||
```
|
||||
1. Chọn Contract → Cascade: Đợt thanh toán lọc theo contract
|
||||
2. Chọn Đợt TT (optional)
|
||||
- Để trống = Tạm ứng / Không đối soát đợt
|
||||
3. Nhập amount
|
||||
- Helper text hiển thị công nợ đợt / công nợ HĐ
|
||||
- Validation: Không cho phép thu quá công nợ
|
||||
4. Nhập paid_date, method, receipt_number
|
||||
5. Lưu
|
||||
```
|
||||
|
||||
**B. PaymentObserver (Tự động)**
|
||||
```
|
||||
created/updated/deleted:
|
||||
├── recalculateContract(contract):
|
||||
│ totalPaid = SUM(payments.amount)
|
||||
│ paid_amount = totalPaid
|
||||
│ Nếu totalPaid > total_value:
|
||||
│ remaining_amount = 0
|
||||
│ excess_amount = totalPaid - total_value
|
||||
│ Ngược lại:
|
||||
│ remaining_amount = total_value - totalPaid
|
||||
│ excess_amount = 0
|
||||
│ saveQuietly()
|
||||
└── applySurplusToNextInstallment(contract):
|
||||
Nếu excess_amount > 0:
|
||||
Tìm đợt tiếp theo chưa thanh toán đủ (theo installment_no)
|
||||
applyAmount = min(excess, remaining_for_item)
|
||||
Tạo Payment auto:
|
||||
method = "Tự động khấu trừ"
|
||||
receipt_number = "AUTO-SURPLUS-..."
|
||||
metadata = {auto_surplus: true}
|
||||
```
|
||||
|
||||
**C. Bảng thu tiền (PaymentsTable)**
|
||||
- Cột: Hợp đồng, Số tiền, Ngày thu, Phương thức, Số phiếu thu
|
||||
- Cột mở rộng: Loại đợt, Đợt TT, Trạng thái đối soát (Đủ/Thiếu/Thừa/Tạm ứng), Còn thiếu
|
||||
- Filter: Phương thức, Ngày thu (range)
|
||||
- Eager load: `scheduleItem.payments`
|
||||
|
||||
---
|
||||
|
||||
### 3.5. SALES PHASES (Đợt mở bán)
|
||||
|
||||
#### Models
|
||||
| Model | Key Fields | Quan hệ |
|
||||
|-------|-----------|---------|
|
||||
| **SalesPhase** | project_id, name, code, status (Chuẩn bị/Đang mở bán/Tạm dừng/Đã đóng), start_date, end_date, description, payment_template_id, discount_policy (JSONB) | belongsTo Project, belongsTo PaymentTemplate, hasMany phaseProducts, belongsToMany Products |
|
||||
| **SalesPhaseProduct** (Pivot) | sales_phase_id, product_id, sale_price, land_value, foundation_value, discount_details (JSONB), status (Còn hàng/Đã giữ/Đã bán/Khóa) | belongsTo SalesPhase, belongsTo Product |
|
||||
|
||||
#### Nghiệp vụ
|
||||
1. **Tạo đợt mở bán:**
|
||||
- Thông tin cơ bản (name, code, status, dates)
|
||||
- Chính sách & Mẫu thanh toán
|
||||
- Danh sách sản phẩm (Repeater) với giá riêng và chiết khấu riêng
|
||||
|
||||
2. **Tích hợp vào ContractForm:**
|
||||
- Khi chọn `sales_phase_id` + `product_id` → Auto populate giá từ pivot
|
||||
- CreateContract: Nếu không chọn payment_template_id trực tiếp → fallback lấy từ `salesPhase->paymentTemplate`
|
||||
|
||||
---
|
||||
|
||||
### 3.6. FORM TEMPLATES (Biểu mẫu in ấn)
|
||||
|
||||
#### Models
|
||||
| Model | Key Fields | Quan hệ |
|
||||
|-------|-----------|---------|
|
||||
| **FormTemplate** | name, code, target_model (Contract/Product/Customer), html_template, paper_size (A4/A5/Letter), is_active | hasMany fields, hasMany printLogs |
|
||||
| **FormField** | template_id, code, label, source_type (db_column/db_relation/formula/input/static), source_config (JSONB), format (text/number/currency/date/percent), decimal_places, display_order | belongsTo template |
|
||||
| **FormPrintLog** | template_id, target_model, target_id, target_number, snapshot_data (JSONB), rendered_html, printed_by, printed_at | belongsTo template, belongsTo printedBy (User) |
|
||||
|
||||
#### MailMergeService Workflow
|
||||
```
|
||||
evaluateFields(template, record):
|
||||
foreach field:
|
||||
db_column → record->{column}
|
||||
db_relation → record->{relation}[index]->{column}
|
||||
formula → Shunting Yard evaluate (bcmath)
|
||||
input → default value
|
||||
static → fixed value
|
||||
|
||||
render(template, record):
|
||||
evaluateFields() → raw_values
|
||||
formatValue() theo format/currency/date/percent
|
||||
str_replace placeholder {{code}} → value trong html_template
|
||||
|
||||
savePrintLog():
|
||||
Lưu snapshot_data + rendered_html + user + timestamp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## IV. DASHBOARD & BÁO CÁO
|
||||
|
||||
### Widgets
|
||||
| Widget | Dữ liệu |
|
||||
|--------|---------|
|
||||
| **RecentNotifications** | Thông báo chưa đọc của user hiện tại (database notifications) |
|
||||
| **ContractStatsOverview** | Tổng doanh thu, Đã thu, Công nợ phải thu, HĐ hiệu lực, Đợt TT sắp đến hạn |
|
||||
| **UpcomingPaymentsTable** | PaymentScheduleItem trong 30 ngày tới (có đủ công nợ) |
|
||||
|
||||
### Pages
|
||||
| Page | Chức năng |
|
||||
|------|-----------|
|
||||
| **ProjectReport** | Bảng thống kê theo dự án: Tổng SP, Đã bán, Số HĐ, Tổng giá trị, Đã thu, Công nợ |
|
||||
|
||||
### Commands
|
||||
| Command | Chức năng |
|
||||
|---------|-----------|
|
||||
| `export:debt-report` | Xuất Excel 2 sheet: Tổng hợp công nợ + Chi tiết đợt TT |
|
||||
| `notifications:send-due-payments` | Gửi cảnh báo đợt TT sắp đến hạn cho tất cả users (database notification) |
|
||||
| `contracts:generate-schedules` | Tạo lịch thanh toán hàng loạt cho HĐ chưa có lịch |
|
||||
|
||||
---
|
||||
|
||||
## V. CÁC COMMAND IMPORT DỮ LIỆU
|
||||
|
||||
### `import:products-excel {file=sanpham.xlsx}`
|
||||
- Input: File Excel sản phẩm
|
||||
- Output: Product records trong Project "Hà Quang 1"
|
||||
- Logic: `updateOrCreate` theo code, parse infrastructure_status, parse custom_data
|
||||
|
||||
### `import:customers-excel {file=khachhang.xlsx}`
|
||||
- Input: File Excel khách hàng
|
||||
- Output: Customer records (INDIVIDUAL) + Mẫu Công ty
|
||||
- Logic: Tách nhiều phone, parse Excel date serial
|
||||
|
||||
### `import:contracts-complex {hopdong=hopdong.xlsx} {hdkh=Hd_kh.xlsx}`
|
||||
- Input: 2 file (tài chính + liên kết KH)
|
||||
- Logic "Bắc cầu":
|
||||
1. Đọc hopdong.xlsx → Map `contract_number → finance_data`
|
||||
2. Đọc Hd_kh.xlsx → Tìm product theo plotCode, customer theo cmnd_cccd
|
||||
3. Tìm mapping: `str_contains(contract_number, plotCode)`
|
||||
4. `updateOrCreate` Contract + `syncWithoutDetaching` customers qua pivot
|
||||
- Transaction bọc toàn bộ
|
||||
|
||||
### `contracts:generate-schedules {--force}`
|
||||
- Input: HĐ chưa có PaymentSchedule (hoặc --force để tạo lại)
|
||||
- Logic: Ưu tiên `contract.paymentTemplate`, fallback `product.project.paymentTemplate`
|
||||
|
||||
---
|
||||
|
||||
## VI. MÔ HÌNH QUAN HỆ DATABASE (ER Tóm tắt)
|
||||
|
||||
```
|
||||
Project 1───* Product 1───* Contract *───* Customer
|
||||
│ │ │
|
||||
│ │ 1───1 PaymentSchedule 1───* PaymentScheduleItem
|
||||
│ │ │ │
|
||||
│ │ *───* Payment *───────────┘
|
||||
│ │ │
|
||||
│ │ *───* Appendix
|
||||
│ │ *───* PaymentFine
|
||||
│ │ *───* Settlement (qua Product)
|
||||
│ │
|
||||
│ *───* SalesPhase *───* SalesPhaseProduct *───1 Product
|
||||
│ │
|
||||
│ 1───1 PaymentTemplate 1───* PaymentScheduleItem (template)
|
||||
│
|
||||
*───* PaymentTemplate
|
||||
|
||||
FormTemplate 1───* FormField
|
||||
1───* FormPrintLog
|
||||
|
||||
User 1───* Notification (MorphMany)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## VII. ĐIỂM CẦN XEM XÉT (TỪ ASSESSMENT)
|
||||
|
||||
| # | Vấn đề | Mức độ | Ghi chú |
|
||||
|---|--------|--------|---------|
|
||||
| 1 | **Soft Delete** | 🔴 Nghiêm trọng | Tất cả model dùng delete cứng. Xóa nhầm → mất vĩnh viễn |
|
||||
| 2 | **Phân quyền** | 🟡 Trung bình | Chỉ 1 loại user. Ai cũng xóa/sửa được mọi thứ |
|
||||
| 3 | **Payment.collected_by** | 🟡 Trung bình | Không ghi nhận ai thu tiền. Khó truy trách nhiệm |
|
||||
| 4 | **Sổ quỹ** | 🟡 Trung bình | Thu tiền nhưng không ghi vào quỹ TM/NH. Không đối soát được |
|
||||
| 5 | **CRM Pipeline** | 🟢 Thấp | Chưa quản lý Lead/Khách hàng tiềm năng |
|
||||
| 6 | **Báo cáo BCTC** | 🟢 Thấp | Chưa có báo cáo theo chuẩn kế toán VN |
|
||||
|
||||
---
|
||||
|
||||
*File này cần được cập nhật mỗi khi có thay đổi lớn trong kiến trúc hoặc nghiệp vụ.*
|
||||
Reference in New Issue
Block a user