Files
hqland-app/AGENTS.md
2026-04-25 04:04:14 +00:00

14 KiB

HQLAND - TRẠNG THÁI CODEBASE & LỘ TRÌNH PHÁT TRIỂN

File này được tạo để lưu trữ ngữ cảnh dự án cho các phiên làm việc sau.
Cập nhật: 24/04/2026
Dự án: HQLand - Hệ thống quản lý Bất động sản
Stack: Laravel 13 + Filament v5.5 (Schemas Architecture) + PostgreSQL + UUID


1. THÔNG TIN KẾT NỐI DATABASE (CRITICAL)

Database Chính (Production Data)

  • Connection: pgsql
  • Host: pgsql (trong Docker), 127.0.0.1 (từ Host machine)
  • Port: 5432
  • Database: laravel
  • Username: sail
  • Password: password
  • Dữ liệu hiện có: 120 khách hàng, 45 sản phẩm, 139 hợp đồng

Database Thử Nghiệm

  • Database: laravel_testing (đã tạo)
  • Cách chạy test: DB_HOST=127.0.0.1 ./vendor/bin/pest
  • Cách chạy artisan: DB_HOST=127.0.0.1 php artisan tinker

Quy tắc VÀNG

  • TUYỆT ĐỐI KHÔNG dùng migrate:fresh trên database chính.
  • Tài khoản admin: admin@phuongtc.com / 1Qazxsw2@!321
  • Dữ liệu Excel đã import là tài sản quý - không xóa.

2. KIẾN TRÚC KỸ THUẬT

Tech Stack

Thành phần Phiên bản / Công nghệ
Framework Laravel 13.x
PHP 8.3
Admin Panel Filament v5.5
Kiến trúc UI Schemas Architecture (Tách Form/Table ra khỏi Resource)
Database PostgreSQL
Khóa chính UUID (100% các bảng)
Excel PhpSpreadsheet 5.7
Testing Pest PHP 4.6

Quy chuẩn Code

  1. LUÔN dùng Schemas class. KHÔNG định nghĩa inline trong Resource.
  2. GridSection nằm trong Filament\Schemas\Components.
  3. Khi render HTML động trong Form, dùng Inline Styles thay vì Tailwind class.
  4. Mọi trường JSONB trong Model phải khai báo trong $casts = ['field' => 'array'].
  5. Naming database: snake_case cho mọi bảng và cột.

3. CẤU TRÚC MODULE HIỆN TẠI

3.1. Warehouse (Kho hàng)

Models: Project, Product

Project:

  • code, name, type, address
  • payment_template_id (relationship với PaymentTemplate)

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): block, building_density, legal_status_raw
  • status

Filament Resources:

  • ProjectResourceProjectForm (Schemas)
  • ProductResource

3.2. CRM (Khách hàng)

Model: Customer

Cấu trúc:

  • type: INDIVIDUAL | COMPANY
  • full_name, cmnd_cccd, tax_code, title
  • phone, secondary_phones (JSONB)
  • email, dob
  • permanent_address, contact_address (lưu cứng, không JSON)
  • id_issue_date, id_issue_place
  • representative_id (self-referencing, cho công ty)

Quan hệ:

  • representedCompanies(): Công ty mà khách hàng đại diện
  • representative(): Ngườ đại diện của công ty
  • contracts(): belongsToMany qua contract_customers

Filament Resources:

  • CustomerResourceCustomerForm + CustomersTable (Schemas)
  • Form hỗ trợ chuyển đổi INDIVIDUAL/COMPANY động (live)
  • Copy địa chỉ thường trú → liên hệ (suffixAction)

3.3. Contracts (Hợp đồng & Tài chính)

Model: Contract

Cấu trúc:

  • 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)
  • brokerage_name, stored_contract_count, filing_note
  • transfer_order: 0 = chủ hiện tại, 1 = F0, 2+ = F1, F2...

Logic tự động trong Model (booted):

  • total_value = land_value + foundation_value (nếu có giá trị)
  • Fallback: lấy từ product.total_price khi tạo mới
  • remaining_amount = total_value - paid_amount

Quan hệ:

  • product(), customers() (belongsToMany qua contract_customers)
  • paymentTemplate() (belongsTo PaymentTemplate)
  • appendices(), paymentSchedule(), scheduleItems() (HasManyThrough)
  • payments(), paymentFines()

Accessor:

  • final_value: Giá trị sau chiết khấu (tính từ DiscountEngine)

Filament Resources:

  • ContractResourceContractForm + ContractsTable
  • Action "Tạo lịch TT" trong Table (gọi ContractScheduleService)
  • Form có tính toán live: land_value + foundation_value = total_value
  • Hiển thị discount_details dạng grid inline style

3.4. Finance (Tài chính & Thu tiền)

Models: PaymentTemplate, PaymentSchedule, PaymentScheduleItem, Payment, PaymentFine

PaymentTemplate:

  • project_id, name, is_default
  • items(): các đợt thanh toán mẫu

PaymentSchedule:

  • contract_id, template_id
  • items(): các đợt thanh toán thực tế

PaymentScheduleItem:

  • schedule_id (hoặc template_id - dùng chung bảng)
  • installment_no, type (PaymentType enum), percentage, amount, due_date
  • days_after_signing, days_after_previous

Payment:

  • contract_id, schedule_item_id, amount, paid_date
  • method, receipt_number, metadata (JSONB)

PaymentObserver (TỰ ĐỘNG):

  • Khi tạo/sửa/xóa Payment:
    1. Tính lại contract.paid_amount = SUM(payments)
    2. Tính lại remaining_amountexcess_amount
    3. Nếu có excess_amount > 0: Tự động khấu trừ vào đợt thanh toán tiếp theo chưa đủ tiền (tạo Payment auto)

Filament Resources:

  • PaymentResourcePaymentForm + PaymentsTable
    • Form chọn Contract → chọn Đợt thanh toán (cascade)
    • Validation số tiền không vượt quá công nợ đợt / công nợ HĐ
    • Table có filter theo phương thức và ngày thu
    • Cột đối soát: Đủ / Thiếu / Thừa (tính tổng payments của đợt)
    • Cột còn thiếu tiền theo đợt
  • PaymentFineResource → Quản lý tiền phạt chậm thanh toán
  • AppendixResource → Quản lý phụ lục hợp đồng
  • SettlementResource → Quản lý quyết toán & sổ đỏ

4. CÁC COMMAND IMPORT DỮ LIỆU

import:products-excel {file=sanpham.xlsx}

  • Import sản phẩm vào dự án "Hà Quang 1"
  • Tự động parse hạ tầng từ chuỗi "Key: Value - Key2: Value2"
  • Tạo custom_data (block, building_density...)

import:customers-excel {file=khachhang.xlsx}

  • Import khách hàng cá nhân
  • Tách nhiều số điện thoại (dấu phẩy, gạch chéo, xuống dòng)
  • Parse ngày tháng Excel (số serial hoặc chuỗi)
  • Tự động tạo mẫu Công ty + Ngườ đại diện (Công ty TNHH BĐS Thịnh Vượng)

contracts:generate-schedules {--force}

  • Tự động tạo lịch thanh toán cho các hợp đồng chưa có lịch
  • Ưu tiên contract.payment_template_id, fallback lấy từ product.project.paymentTemplate
  • Option --force để tạo lại lịch cho HĐ đã có schedule

import:contracts-complex {hopdong=hopdong.xlsx} {hdkh=Hd_kh.xlsx}

  • Logic "Bắc cầu" 2 file:
    1. hopdong.xlsx: Dữ liệu tài chính (theo Số HĐMB)
    2. Hd_kh.xlsx: Liên kết Khách hàng - Lô đất - Thứ tự chuyển nhượng
  • Tìm mapping giữa mã lô và số HĐMB (str_contains)
  • Tạo/cập nhật Contract + liên kết pivot contract_customers

Các file Excel quan trọng (KHÔNG ĐƯỢC XÓA)

  • hopdong.xlsx - Dữ liệu hợp đồng tài chính
  • Hd_kh.xlsx - Liên kết hợp đồng-khách hàng
  • khachhang.xlsx - Danh sách khách hàng
  • sanpham.xlsx - Danh sách sản phẩm/lô đất

5. TÌNH TRẠNG CÁC PHẦN ĐÃ LÀM / ĐANG DỞ

5.1. Đã hoàn thành

  • Kiến trúc Schemas cho tất cả Resources
  • Import Customers, Products, Contracts từ Excel
  • Mở rộng bảng customers (type, representative, addresses...)
  • Mở rộng bảng contracts (land_value, foundation_value, discount_details...)
  • ContractScheduleService - Tạo lịch thanh toán từ template
  • PaymentObserver - Tự động tính toán tài chính + khấu trừ dư
  • PaymentResource (Form + Table)
  • Test: ContractFinanceFlowTest (PASS)
  • Cấu hình PHPUnit dùng PostgreSQL testing database
  • Fix ContractForm: payment_template_id đã lưu vào DB, tự động tạo lịch khi tạo HĐ mới
  • PaymentForm validation: Không cho phép thu quá công nợ đợt / HĐ
  • PaymentsTable: Thêm cột Loại đợt, Trạng thái đối soát, Còn thiếu
  • Command generate schedule hàng loạt: php artisan contracts:generate-schedules
  • PaymentFine Resource: Form + Table đầy đủ
  • Appendix Resource: Form + Table đầy đủ
  • Settlement Resource: Form + Table đầy đủ
  • Discount Engine: Tính toán tự động chiết khấu + hiển thị final_value trong ContractForm

5.2. Đang dở / Cần tiếp tục

  • Dashboard thống kê: Đã tạo ContractStatsOverview + UpcomingPaymentsTable
  • Notification: Cảnh báo đợt thanh toán sắp đến hạn (chưa có hệ thống notification)

5.3. Vấn đề kỹ thuật ĐÃ XỬ LÝ

  • ContractTable đã thêm cột paid_amount / remaining_amount, chuyển sang dùng ContractsTable Schemas
  • Logic syncWithoutDetaching trong ImportContractsComplex đảm bảo nhiều KH cùng 1 HĐ không bị ghi đè
  • Fix N+1 query ở PaymentScheduleItem::getPaidAmountAttribute() (dùng relationLoaded)
  • Fix PaymentForm validation khi edit (instanceof Payment thay vì truthy check)
  • Fix ContractForm final_value_display hiển thị được cả khi create (dùng $get state)

6. LỘ TRÌNH PHÁT TRIỂN TIẾP THEO (ĐỀ XUẤT)

Giai đoạn 1: Hoàn thiện Core Finance (Ưu tiên CAO)

  1. Fix ContractForm: Cho phép chọn template và tự động tạo lịch thanh toán ngay khi tạo hợp đồng
  2. Hoàn thiện PaymentForm: Thêm validation số tiền không vượt quá công nợ đợt
  3. Cập nhật PaymentsTable: Thêm cột "Đợt TT", "Trạng thái đối soát", "Còn thiếu"
  4. Command generate schedule hàng loạt: php artisan contracts:generate-schedules cho 139 hợp đồng đã import

Giai đoạn 2: Module Bổ sung (Ưu tiên TRUNG BÌNH)

  1. PaymentFine Resource: Quản lý tiền phạt chậm thanh toán
  2. Appendix Resource: Quản lý phụ lục hợp đồng
  3. Settlement Resource: Quản lý thanh lý hợp đồng
  4. Discount Engine: Tính toán tự động chiết khấu từ discount_details vào giá trị hợp đồng

Giai đoạn 3: Báo cáo & Tối ưu (Ưu tiên THẤP)

  1. Dashboard Tài chính: Tổng doanh thu, dòng tiền dự kiến, công nợ phải thu
  2. Báo cáo theo Dự án: Thống kê bán hàng, thanh toán theo từng dự án
  3. Export Excel: Xuất báo cáo công nợ khách hàng
  4. Notification: Cảnh báo đợt thanh toán sắp đến hạn

7. CÂU LỆNH THƯỜNG DÙNG

# Chạy test
DB_HOST=127.0.0.1 ./vendor/bin/pest

# Chạy test cụ thể
DB_HOST=127.0.0.1 ./vendor/bin/pest --filter="ContractFinanceFlowTest"

# Import dữ liệu
db:host=127.0.0.1 php artisan import:products-excel
db:host=127.0.0.1 php artisan import:customers-excel
db:host=127.0.0.1 php artisan import:contracts-complex

# Tinker
DB_HOST=127.0.0.1 php artisan tinker

# Migrate (KHÔNG dùng fresh!)
DB_HOST=127.0.0.1 php artisan migrate

8. DANH SÁCH FILE MỚI / THAY ĐỔI TRONG PHIÊN NÀY

Migrations mới

  • database/migrations/2026_04_24_083000_add_payment_template_id_to_contracts.php

Services mới

  • app/Services/DiscountEngine.php - Tính toán chiết khấu
  • app/Console/Commands/GenerateContractSchedules.php - Command tạo lịch hàng loạt

Filament Resources mới

  • app/Filament/Resources/PaymentFines/ (Resource + Form + Table + Pages)
  • app/Filament/Resources/Appendices/ (Resource + Form + Table + Pages)
  • app/Filament/Resources/Settlements/ (Resource + Form + Table + Pages)

Widgets mới

  • app/Filament/Widgets/ContractStatsOverview.php - Dashboard tổng quan tài chính
  • app/Filament/Widgets/UpcomingPaymentsTable.php - Danh sách đợt TT sắp đến hạn

Models sửa đổi

  • app/Models/Contract.php - Thêm paymentTemplate(), accessor final_value
  • app/Models/PaymentScheduleItem.php - Thêm accessor paid_amount, remaining_amount
  • app/Models/User.php - Thêm FilamentUser interface để user có quyền truy cập panel

Forms/Tables sửa đổi

  • app/Filament/Resources/Contracts/ContractResource.php - Fix action EditAction namespace (Filament\Actions\EditAction)
  • app/Filament/Resources/Contracts/Schemas/ContractForm.php - Fix payment_template_id, thêm final_value_display
  • app/Filament/Resources/Contracts/Pages/CreateContract.php - Refactor dùng $contract->payment_template_id
  • app/Filament/Resources/Payments/Schemas/PaymentForm.php - Thêm validation amount + helper text công nợ
  • app/Filament/Resources/Payments/Tables/PaymentsTable.php - Thêm cột Loại đợt, Đối soát, Còn thiếu
  • app/Filament/Resources/Payments/PaymentResource.php - Thêm eager load scheduleItem.payments

Config/Provider sửa đổi

  • app/Providers/Filament/AdminPanelProvider.php - Đăng ký widgets mới
  • phpunit.xml - Cấu hình PostgreSQL testing (DB_HOST, DB_DATABASE, etc.)
  • config/database.php - Default pgsql
  • composer.json - Xóa script tạo SQLite

9. FILE HỖ TRỢ CHUYỂN MÁY

  • NEXT_SESSION.md - Checklist và hướng dẫn nhanh cho phiên làm việc tiếp theo
  • COMMIT_GUIDE.md - Hướng dẫn commit toàn bộ thay đổi chưa commit

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 lộ trình phát triển.