feat(accounting): consolidate VAT/financial config into Settings → Accounting

- Remove the orphaned "Default VAT rate %" from Business profile; the rates
  are the Accounting VAT codes. The invoice/quote VAT picker (VatRateSelect)
  is now code-only — options are exactly the Accounting output codes, no
  free-text custom rate. Off-list legacy values on existing invoices are
  preserved as a read-only "(not configured)" option so issued documents
  aren't silently changed.
- Move VAT label + default hourly rate to the Accounting tab (new
  AccountingProfileFields card; storage stays on business_profile, own save).
  Wire vat_label onto the PDF VAT-line label via the issuer block (covers
  invoices + quotes), falling back to the locale default when blank.
- Default currency stays on Business profile but becomes a normalizing
  dropdown (an old free-text "chf" auto-selects "CHF"; unknown values
  preserved). Add a moved-note callout. Strip the moved fields from the
  Business-profile save so it can't clobber an Accounting-tab edit.
This commit is contained in:
Luca
2026-06-18 15:10:44 +02:00
parent 315d15afd4
commit dc7b87bb87
7 changed files with 183 additions and 58 deletions
@@ -14,6 +14,7 @@ import { accountingService } from '../../../services/accounting.service';
import { sortedCountryOptions } from '../../../constants/countries';
import { VatCodesManager } from '../../../components/admin/VatCodesManager';
import { ChartOfAccountsManager } from '../../../components/admin/ChartOfAccountsManager';
import { AccountingProfileFields } from '../../../components/admin/AccountingProfileFields';
const labelCls = 'block text-sm font-medium text-neutral-700 dark:text-neutral-300 mb-1';
const inputCls = 'w-full max-w-xs rounded-md border border-neutral-300 dark:border-neutral-600 bg-white dark:bg-neutral-800 px-3 py-2 text-sm';
@@ -119,6 +120,11 @@ export const AccountingTab: React.FC = () => {
<Button onClick={() => save.mutate()} disabled={save.isPending}><Save className="w-4 h-4 mr-2" /> {save.isPending ? t('common.saving', 'Saving…') : t('common.save', 'Save')}</Button>
</div>
{/* VAT label + default hourly rate — moved here from Business profile so
all financial/VAT config lives in one place (storage stays on
business_profile; this card has its own save). */}
<AccountingProfileFields />
{/* VAT codes + rate→code / treatment→code maps — relocated here from the
Chart-of-accounts page so all VAT config lives in one place. */}
<VatCodesManager />