FU11: anchor cumulative cost at recording start; add daily-reset cost entities; prefill add-version form
- MQTT import_cost_total / export_revenue_total now anchor fixed-fee / tax-credit accrual at max(contract start, first recorded period), so standing charges for untracked pre-recording days are no longer folded into the running total. - Add energy.import_cost_today / energy.export_revenue_today (monetary, total_increasing) that reset at server-local midnight, for per-day cost aggregation in Home Assistant alongside the running totals. - ContractForm add-version mode prefills the contract's open version values, so only the fields that actually change need editing.
This commit is contained in:
@@ -246,4 +246,93 @@ describe('ContractForm', () => {
|
||||
|
||||
expect(onClose).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('prefills fields from the open version when in add-version mode', async () => {
|
||||
// FU11: add-version mode should auto-prefill rate fields from the contract's
|
||||
// current open version so the user only has to change what's different.
|
||||
const CONTRACT_DETAIL = {
|
||||
id: 42,
|
||||
name: 'My Contract',
|
||||
kind: 'manual',
|
||||
active: true,
|
||||
currency: 'EUR',
|
||||
created_at: '2026-01-01T00:00:00Z',
|
||||
updated_at: '2026-01-01T00:00:00Z',
|
||||
versions: [
|
||||
{
|
||||
id: 1,
|
||||
contract_id: 42,
|
||||
effective_from: '2026-01-01T00:00:00Z',
|
||||
effective_to: null, // open version
|
||||
values: {
|
||||
energy: {
|
||||
buy: { normal: 0.133, dal: 0.127 },
|
||||
sell: { normal: 0.05, dal: 0.05 },
|
||||
energy_tax: 0.11,
|
||||
ode: 0.0,
|
||||
},
|
||||
standing: {
|
||||
network_fee: 30.0,
|
||||
management_fee: 60.0,
|
||||
},
|
||||
credits: {
|
||||
heffingskorting: 365.0,
|
||||
},
|
||||
},
|
||||
created_at: '2026-01-01T00:00:00Z',
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
mockGet.mockImplementation((path: string) => {
|
||||
if (path === '/api/energy/profiles') {
|
||||
return Promise.resolve({ data: PROFILES_RESPONSE })
|
||||
}
|
||||
if (path === '/api/energy/contracts/{contract_id}') {
|
||||
return Promise.resolve({ data: CONTRACT_DETAIL })
|
||||
}
|
||||
return Promise.resolve({ data: null })
|
||||
})
|
||||
|
||||
const onClose = vi.fn()
|
||||
const onSaved = vi.fn()
|
||||
|
||||
renderWithProviders(
|
||||
<ContractForm contractId={42} defaultKind="manual" onClose={onClose} onSaved={onSaved} />,
|
||||
)
|
||||
|
||||
const user = userEvent.setup()
|
||||
|
||||
// Wait for the form to render and profile fields to appear
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('contract-section-energy')).toBeInTheDocument()
|
||||
}, { timeout: 3000 })
|
||||
|
||||
// Wait for prefill to apply: both profile and contract detail queries must resolve.
|
||||
// Fill in the required effective_from date and submit; the submitted values
|
||||
// body.values should contain the prefilled rates from the open version.
|
||||
mockPost.mockResolvedValue({ data: {} })
|
||||
|
||||
const effectiveInput = screen.getByTestId('contract-effective-from')
|
||||
await user.type(effectiveInput, '2026-07-01')
|
||||
|
||||
await user.click(screen.getByTestId('contract-form-submit'))
|
||||
|
||||
// The submitted body should contain the prefilled values from CONTRACT_DETAIL
|
||||
await waitFor(() => {
|
||||
expect(mockPost).toHaveBeenCalledWith(
|
||||
'/api/energy/contracts/{contract_id}/versions',
|
||||
expect.objectContaining({
|
||||
body: expect.objectContaining({
|
||||
values: expect.objectContaining({
|
||||
standing: expect.objectContaining({
|
||||
network_fee: 30,
|
||||
management_fee: 60,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
)
|
||||
}, { timeout: 3000 })
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user