Fix reserve fund balance, dynamic project funding, year-end report, and unit form
- Dashboard reserve fund KPI now uses reserve equity accounts (fund balance position) instead of asset accounts, correctly showing the total reserve fund balance regardless of how users categorize their reserve accounts - Projects findAll() and findForPlanning() dynamically compute funded_percentage and current_fund_balance from reserve equity account balances via CTE, distributing the total reserve balance proportionally across projects - Year-end summary reserve status now queries unified projects table instead of deprecated reserve_components table - Remove standalone Monthly Assessment field from Units form — assessment amount is now inherited from the selected assessment group Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useState } from 'react';
|
||||
import {
|
||||
Title, Table, Group, Button, Stack, TextInput, Modal,
|
||||
NumberInput, Select, Badge, ActionIcon, Text, Loader, Center, Tooltip, Alert,
|
||||
Select, Badge, ActionIcon, Text, Loader, Center, Tooltip, Alert,
|
||||
} from '@mantine/core';
|
||||
import { useForm } from '@mantine/form';
|
||||
import { useDisclosure } from '@mantine/hooks';
|
||||
@@ -56,7 +56,7 @@ export function UnitsPage() {
|
||||
const form = useForm({
|
||||
initialValues: {
|
||||
unit_number: '', address_line1: '', city: '', state: '', zip_code: '',
|
||||
owner_name: '', owner_email: '', owner_phone: '', monthly_assessment: 0,
|
||||
owner_name: '', owner_email: '', owner_phone: '',
|
||||
assessment_group_id: '' as string | null,
|
||||
},
|
||||
validate: {
|
||||
@@ -96,7 +96,7 @@ export function UnitsPage() {
|
||||
form.setValues({
|
||||
unit_number: u.unit_number, address_line1: u.address_line1 || '',
|
||||
city: '', state: '', zip_code: '', owner_name: u.owner_name || '',
|
||||
owner_email: u.owner_email || '', owner_phone: '', monthly_assessment: parseFloat(u.monthly_assessment || '0'),
|
||||
owner_email: u.owner_email || '', owner_phone: '',
|
||||
assessment_group_id: u.assessment_group_id || '',
|
||||
});
|
||||
open();
|
||||
@@ -108,21 +108,10 @@ export function UnitsPage() {
|
||||
// Pre-populate with default group
|
||||
if (defaultGroup) {
|
||||
form.setFieldValue('assessment_group_id', defaultGroup.id);
|
||||
form.setFieldValue('monthly_assessment', parseFloat(defaultGroup.regular_assessment || '0'));
|
||||
}
|
||||
open();
|
||||
};
|
||||
|
||||
const handleGroupChange = (groupId: string | null) => {
|
||||
form.setFieldValue('assessment_group_id', groupId);
|
||||
if (groupId) {
|
||||
const group = assessmentGroups.find(g => g.id === groupId);
|
||||
if (group) {
|
||||
form.setFieldValue('monthly_assessment', parseFloat(group.regular_assessment || '0'));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const filtered = units.filter((u) =>
|
||||
!search || u.unit_number.toLowerCase().includes(search.toLowerCase()) ||
|
||||
(u.owner_name || '').toLowerCase().includes(search.toLowerCase())
|
||||
@@ -213,17 +202,16 @@ export function UnitsPage() {
|
||||
<TextInput label="Owner Phone" {...form.getInputProps('owner_phone')} />
|
||||
<Select
|
||||
label="Assessment Group"
|
||||
description="Required — all units must belong to an assessment group"
|
||||
description="Required — the unit's monthly assessment is inherited from the selected group"
|
||||
required
|
||||
data={assessmentGroups.map(g => ({
|
||||
value: g.id,
|
||||
label: `${g.name}${g.is_default ? ' (Default)' : ''} — $${parseFloat(g.regular_assessment || '0').toFixed(2)}/${g.frequency || 'mo'}`,
|
||||
}))}
|
||||
value={form.values.assessment_group_id}
|
||||
onChange={handleGroupChange}
|
||||
onChange={(v) => form.setFieldValue('assessment_group_id', v)}
|
||||
error={form.errors.assessment_group_id}
|
||||
/>
|
||||
<NumberInput label="Monthly Assessment" prefix="$" decimalScale={2} min={0} {...form.getInputProps('monthly_assessment')} />
|
||||
<Button type="submit" loading={saveMutation.isPending}>{editing ? 'Update' : 'Create'}</Button>
|
||||
</Stack>
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user