[CLAUDE] Master: nạp master data thật từ Excel (62 dự án + 71 hạng mục + 3 NCC) + Project +4 cột (Mig 48)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m33s
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m33s
Nạp master data công ty từ file Excel 'HẠNG MỤC CÔNG VIỆC DỰ ÁN': - 62 Projects (Mã + Năm; tên/CĐT/địa điểm/gói thầu cho ~6 dự án có chi tiết) - 71 WorkItems: Vật tư 16 · Thầu phụ 30 · MEP 9 · Thiết bị 16 - 3 Suppliers (TRUONGGIANG/TANPHU/TGN) Mig 48 AddProjectMasterFields: Project +4 cột nullable (Year/Investor/Location/Package) + ProjectFeatures DTO/Create/Update + ProjectsPage form ×2 app (SHA256 mirror). SeedRealMasterDataAsync per-code idempotent, UNGATED → reaches prod (coexist demo). FLOCK01 collision → skip (demo wins). Verify: build 0-err · test 216 PASS · runtime Dev proof (data landed, Investor col populates). Provenance: scripts/master-import-data.generated.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -23,9 +23,13 @@ type FormState = {
|
||||
endDate: string
|
||||
budgetTotal: string
|
||||
note: string
|
||||
year: string
|
||||
investor: string
|
||||
location: string
|
||||
package: string
|
||||
}
|
||||
|
||||
const emptyForm: FormState = { code: '', name: '', startDate: '', endDate: '', budgetTotal: '', note: '' }
|
||||
const emptyForm: FormState = { code: '', name: '', startDate: '', endDate: '', budgetTotal: '', note: '', year: '', investor: '', location: '', package: '' }
|
||||
|
||||
const fmtMoney = (v: number | null) => (v == null ? '—' : v.toLocaleString('vi-VN'))
|
||||
const fmtDate = (s: string | null) => (s ? new Date(s).toLocaleDateString('vi-VN') : '—')
|
||||
@ -61,6 +65,10 @@ export function ProjectsPage() {
|
||||
managerUserId: null,
|
||||
budgetTotal: d.budgetTotal ? Number(d.budgetTotal) : null,
|
||||
note: d.note || null,
|
||||
year: d.year ? Number(d.year) : null,
|
||||
investor: d.investor || null,
|
||||
location: d.location || null,
|
||||
package: d.package || null,
|
||||
}
|
||||
if (d.id) await api.put(`/projects/${d.id}`, payload)
|
||||
else await api.post('/projects', payload)
|
||||
@ -92,6 +100,10 @@ export function ProjectsPage() {
|
||||
endDate: p.endDate ? p.endDate.slice(0, 10) : '',
|
||||
budgetTotal: p.budgetTotal?.toString() ?? '',
|
||||
note: p.note ?? '',
|
||||
year: p.year?.toString() ?? '',
|
||||
investor: p.investor ?? '',
|
||||
location: p.location ?? '',
|
||||
package: p.package ?? '',
|
||||
})
|
||||
setOpen(true)
|
||||
}
|
||||
@ -99,6 +111,7 @@ export function ProjectsPage() {
|
||||
const columns: Column<Project>[] = [
|
||||
{ key: 'code', header: 'Mã DA', sortable: true, render: p => <span className="font-mono text-xs">{p.code}</span>, width: 'w-32' },
|
||||
{ key: 'name', header: 'Tên dự án', sortable: true, render: p => p.name },
|
||||
{ key: 'investor', header: 'Chủ đầu tư', render: p => p.investor ?? '—' },
|
||||
{ key: 'startDate', header: 'Bắt đầu', render: p => fmtDate(p.startDate), width: 'w-32' },
|
||||
{ key: 'endDate', header: 'Kết thúc', render: p => fmtDate(p.endDate), width: 'w-32' },
|
||||
{ key: 'budgetTotal', header: 'Ngân sách', align: 'right', render: p => fmtMoney(p.budgetTotal) },
|
||||
@ -203,6 +216,22 @@ export function ProjectsPage() {
|
||||
<Label>Ngày kết thúc</Label>
|
||||
<Input type="date" value={form.endDate} onChange={e => setForm({ ...form, endDate: e.target.value })} />
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
<Label>Năm</Label>
|
||||
<Input type="number" value={form.year} onChange={e => setForm({ ...form, year: e.target.value })} />
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
<Label>Chủ đầu tư</Label>
|
||||
<Input value={form.investor} onChange={e => setForm({ ...form, investor: e.target.value })} />
|
||||
</div>
|
||||
<div className="col-span-2 space-y-1.5">
|
||||
<Label>Địa điểm</Label>
|
||||
<Input value={form.location} onChange={e => setForm({ ...form, location: e.target.value })} />
|
||||
</div>
|
||||
<div className="col-span-2 space-y-1.5">
|
||||
<Label>Gói thầu</Label>
|
||||
<Input value={form.package} onChange={e => setForm({ ...form, package: e.target.value })} />
|
||||
</div>
|
||||
<div className="col-span-2 space-y-1.5">
|
||||
<Label>Ghi chú</Label>
|
||||
<Textarea rows={3} value={form.note} onChange={e => setForm({ ...form, note: e.target.value })} />
|
||||
|
||||
@ -52,6 +52,10 @@ export type Project = {
|
||||
managerUserId: string | null
|
||||
budgetTotal: number | null
|
||||
note: string | null
|
||||
year: number | null
|
||||
investor: string | null
|
||||
location: string | null
|
||||
package: string | null
|
||||
createdAt: string
|
||||
updatedAt: string | null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user