@@ -1409,7 +1404,6 @@ function HangMucCard({
const hasQuotes = ev.details.some(dd => dd.quotes.some(qq => qq.purchaseEvaluationSupplierId === s.id))
const canDelete = !isWinner && !hasQuotes
const openQuote = () => setQuoteEdit({ supplier: s, existing: q })
- const cellHover = !readOnly && 'cursor-pointer hover:bg-brand-50'
return (
|
@@ -1438,16 +1432,28 @@ function HangMucCard({
readOnly={readOnly}
/>
|
-
+ {!readOnly ? (
+
+ ) : (
+
+ {q ? `${fmtMoney(q.thanhTien)} đ` : —}
+
)}
- title={!readOnly ? 'Click để nhập / sửa số tiền' : undefined}
- >
- {q ? fmtMoney(q.thanhTien) : —}
|
{!readOnly && (
@@ -1519,14 +1525,18 @@ function HangMucCard({
function DetailDialog({ evaluationId, row, onClose }: { evaluationId: string; row: PeDetailRow | null; onClose: () => void }) {
const qc = useQueryClient()
+ // Session 20 turn 5: user yêu cầu rút gọn — chỉ Tên hạng mục + Số tiền
+ // ngân sách (VND format) + Ghi chú. Các field schema khác (groupCode/
+ // groupName/itemCode/donViTinh/khoiLuongs/donGia) giữ default cho BE
+ // schema backward compat — KHÔNG expose UI cho user.
const [form, setForm] = useState({
- groupCode: row?.groupCode ?? 'A.I',
- groupName: row?.groupName ?? '',
+ groupCode: row?.groupCode ?? '01',
+ groupName: row?.groupName ?? 'Hạng mục chính',
itemCode: row?.itemCode ?? '',
noiDung: row?.noiDung ?? '',
- donViTinh: row?.donViTinh ?? '',
- khoiLuongNganSach: row?.khoiLuongNganSach ?? 0,
- khoiLuongThiCong: row?.khoiLuongThiCong ?? 0,
+ donViTinh: row?.donViTinh ?? 'gói',
+ khoiLuongNganSach: row?.khoiLuongNganSach ?? 1,
+ khoiLuongThiCong: row?.khoiLuongThiCong ?? 1,
donGiaNganSach: row?.donGiaNganSach ?? 0,
thanhTienNganSach: row?.thanhTienNganSach ?? 0,
ghiChu: row?.ghiChu ?? '',
@@ -1540,11 +1550,10 @@ function DetailDialog({ evaluationId, row, onClose }: { evaluationId: string; ro
onError: e => toast.error(getErrorMessage(e)),
})
- const updateAndRecalc = (patch: Partial) => {
- const next = { ...form, ...patch }
- // Auto-compute ThanhTien = KL ngân sách × ĐG ngân sách
- next.thanhTienNganSach = Number(next.khoiLuongNganSach) * Number(next.donGiaNganSach)
- setForm(next)
+ // Sync ngân sách: user nhập "Số tiền ngân sách" → set cả donGia + thanhTien
+ // (KL = 1 ngầm). BE giữ schema 3 field.
+ const setBudgetAmount = (n: number) => {
+ setForm({ ...form, donGiaNganSach: n, thanhTienNganSach: n })
}
return (
@@ -1552,24 +1561,38 @@ function DetailDialog({ evaluationId, row, onClose }: { evaluationId: string; ro
open
onClose={onClose}
title={(row ? 'Sửa' : 'Thêm') + ' hạng mục'}
- size="lg"
footer={<>
>}
>
-
- setForm({ ...form, groupCode: e.target.value })} />
- setForm({ ...form, groupName: e.target.value })} placeholder="Bê tông / Phụ gia..." />
- setForm({ ...form, itemCode: e.target.value })} />
- setForm({ ...form, noiDung: e.target.value })} />
- setForm({ ...form, donViTinh: e.target.value })} />
- updateAndRecalc({ khoiLuongNganSach: Number(e.target.value) })} />
- setForm({ ...form, khoiLuongThiCong: Number(e.target.value) })} />
- updateAndRecalc({ donGiaNganSach: Number(e.target.value) })} />
- setForm({ ...form, thanhTienNganSach: Number(e.target.value) })} />
- setForm({ ...form, ghiChu: e.target.value })} />
+
+
+ setForm({ ...form, noiDung: e.target.value })}
+ placeholder="vd Cung cấp bê tông M250"
+ />
+
+
+
+
+ setBudgetAmount(parseVnd(e.target.value))}
+ placeholder="0"
+ className="pr-12 font-mono text-right"
+ />
+ đ
+
+ VND — nhập số, tự format dấu chấm ngàn (vd 1.000.000)
+
+
+
+ setForm({ ...form, ghiChu: e.target.value })} />
diff --git a/fe-user/src/components/pe/PeDetailTabs.tsx b/fe-user/src/components/pe/PeDetailTabs.tsx
index c853b99..5096a2d 100644
--- a/fe-user/src/components/pe/PeDetailTabs.tsx
+++ b/fe-user/src/components/pe/PeDetailTabs.tsx
@@ -1324,16 +1324,11 @@ function HangMucCard({
- KL
- {detail.khoiLuongNganSach}
-
-
- ĐG ngân sách
- {fmtMoney(detail.donGiaNganSach)}
-
-
- Thành tiền NS
- {fmtMoney(detail.thanhTienNganSach)}
+ Số tiền ngân sách
+
+ {fmtMoney(detail.thanhTienNganSach)}
+ đ
+
{showBudgetCol && bgValue != null && (
@@ -1409,7 +1404,6 @@ function HangMucCard({
const hasQuotes = ev.details.some(dd => dd.quotes.some(qq => qq.purchaseEvaluationSupplierId === s.id))
const canDelete = !isWinner && !hasQuotes
const openQuote = () => setQuoteEdit({ supplier: s, existing: q })
- const cellHover = !readOnly && 'cursor-pointer hover:bg-brand-50'
return (
|
@@ -1438,16 +1432,28 @@ function HangMucCard({
readOnly={readOnly}
/>
|
-
+ {!readOnly ? (
+
+ ) : (
+
+ {q ? `${fmtMoney(q.thanhTien)} đ` : —}
+
)}
- title={!readOnly ? 'Click để nhập / sửa số tiền' : undefined}
- >
- {q ? fmtMoney(q.thanhTien) : —}
|
{!readOnly && (
@@ -1519,14 +1525,18 @@ function HangMucCard({
function DetailDialog({ evaluationId, row, onClose }: { evaluationId: string; row: PeDetailRow | null; onClose: () => void }) {
const qc = useQueryClient()
+ // Session 20 turn 5: user yêu cầu rút gọn — chỉ Tên hạng mục + Số tiền
+ // ngân sách (VND format) + Ghi chú. Các field schema khác (groupCode/
+ // groupName/itemCode/donViTinh/khoiLuongs/donGia) giữ default cho BE
+ // schema backward compat — KHÔNG expose UI cho user.
const [form, setForm] = useState({
- groupCode: row?.groupCode ?? 'A.I',
- groupName: row?.groupName ?? '',
+ groupCode: row?.groupCode ?? '01',
+ groupName: row?.groupName ?? 'Hạng mục chính',
itemCode: row?.itemCode ?? '',
noiDung: row?.noiDung ?? '',
- donViTinh: row?.donViTinh ?? '',
- khoiLuongNganSach: row?.khoiLuongNganSach ?? 0,
- khoiLuongThiCong: row?.khoiLuongThiCong ?? 0,
+ donViTinh: row?.donViTinh ?? 'gói',
+ khoiLuongNganSach: row?.khoiLuongNganSach ?? 1,
+ khoiLuongThiCong: row?.khoiLuongThiCong ?? 1,
donGiaNganSach: row?.donGiaNganSach ?? 0,
thanhTienNganSach: row?.thanhTienNganSach ?? 0,
ghiChu: row?.ghiChu ?? '',
@@ -1540,11 +1550,10 @@ function DetailDialog({ evaluationId, row, onClose }: { evaluationId: string; ro
onError: e => toast.error(getErrorMessage(e)),
})
- const updateAndRecalc = (patch: Partial) => {
- const next = { ...form, ...patch }
- // Auto-compute ThanhTien = KL ngân sách × ĐG ngân sách
- next.thanhTienNganSach = Number(next.khoiLuongNganSach) * Number(next.donGiaNganSach)
- setForm(next)
+ // Sync ngân sách: user nhập "Số tiền ngân sách" → set cả donGia + thanhTien
+ // (KL = 1 ngầm). BE giữ schema 3 field.
+ const setBudgetAmount = (n: number) => {
+ setForm({ ...form, donGiaNganSach: n, thanhTienNganSach: n })
}
return (
@@ -1552,24 +1561,38 @@ function DetailDialog({ evaluationId, row, onClose }: { evaluationId: string; ro
open
onClose={onClose}
title={(row ? 'Sửa' : 'Thêm') + ' hạng mục'}
- size="lg"
footer={<>
>}
>
-
- setForm({ ...form, groupCode: e.target.value })} />
- setForm({ ...form, groupName: e.target.value })} placeholder="Bê tông / Phụ gia..." />
- setForm({ ...form, itemCode: e.target.value })} />
- setForm({ ...form, noiDung: e.target.value })} />
- setForm({ ...form, donViTinh: e.target.value })} />
- updateAndRecalc({ khoiLuongNganSach: Number(e.target.value) })} />
- setForm({ ...form, khoiLuongThiCong: Number(e.target.value) })} />
- updateAndRecalc({ donGiaNganSach: Number(e.target.value) })} />
- setForm({ ...form, thanhTienNganSach: Number(e.target.value) })} />
- setForm({ ...form, ghiChu: e.target.value })} />
+
+
+ setForm({ ...form, noiDung: e.target.value })}
+ placeholder="vd Cung cấp bê tông M250"
+ />
+
+
+
+
+ setBudgetAmount(parseVnd(e.target.value))}
+ placeholder="0"
+ className="pr-12 font-mono text-right"
+ />
+ đ
+
+ VND — nhập số, tự format dấu chấm ngàn (vd 1.000.000)
+
+
+
+ setForm({ ...form, ghiChu: e.target.value })} />
| |