feat(accounting): VAT-code dropdown in the quote editor (+ reusable VatRateSelect)
Slice 3a — replaces the free-typed VAT rate in the quote editor with a dropdown of configured output VAT codes (+ 'Other (custom rate)'), reading the un-gated /admin/vat-codes endpoint. Selecting a code sends vatCode → the backend snapshots it (migration 130) and the export emits it. New VatRateSelect component + a read-only vatCodes.service. Create flow snapshots correctly; loading a saved code into the editor (serialization return) + the bill editor are the next slices. Build green.
This commit is contained in:
@@ -191,6 +191,8 @@ export interface QuoteCreatePayload {
|
||||
* the template's value as-is. */
|
||||
installments?: PaymentTermInstallment[];
|
||||
vatRate?: number;
|
||||
/** Migration 130 — snapshot of the chosen output VAT code (null = custom rate). */
|
||||
vatCode?: string | null;
|
||||
shippingAmountMinor?: number;
|
||||
introText?: string;
|
||||
outroText?: string;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Read-only VAT-code registry for the invoice/quote editors. Hits the un-gated
|
||||
* /admin/vat-codes endpoint (works without the accounting feature). Management
|
||||
* lives in Settings → Accounting (ledger.service).
|
||||
*/
|
||||
import { api } from '../config/api';
|
||||
|
||||
export interface VatCodeOption {
|
||||
id: number;
|
||||
code: string;
|
||||
name: string;
|
||||
rate: number;
|
||||
direction: 'output' | 'input';
|
||||
}
|
||||
|
||||
export const vatCodesService = {
|
||||
async listOutput(): Promise<VatCodeOption[]> {
|
||||
const { data } = await api.get('/admin/vat-codes', { params: { direction: 'output' } });
|
||||
return (data?.items ?? []) as VatCodeOption[];
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user