Initial import: 10 Radix skills across 3 categories
Kategoriserer danske regnskabs-/ERP-skills, ERP-data-afstemnings-
skill og to devops-workflows (gitea-issue-agent, kanban-workflows)
som Radix-medlemmers AI-agenter kan dele.
Struktur:
skills/<kategori>/<skill-navn>/SKILL.md
skills/<kategori>/<skill-navn>/{references,templates,scripts}/
Indekseret af index.json (genereret af scripts/rebuild_index.py).
Kør `python3 scripts/rebuild_index.py --check` i CI for at fange
synkroniseringsfejl.
This commit is contained in:
+122
@@ -0,0 +1,122 @@
|
||||
# Django Accounting UI Formatting
|
||||
|
||||
Former skill: `django-accounting-ui-formatting`.
|
||||
|
||||
Use this when changing how money, balances, invoices, payments, totals, or differences are displayed in a Django accounting/reconciliation webapp.
|
||||
|
||||
## Core rule
|
||||
|
||||
Accounting amounts must be formatted deliberately and consistently. Do not rely on ad-hoc `floatformat:2` everywhere if the app has locale-specific expectations.
|
||||
|
||||
For Danish Radix accounting/reconciliation UIs, render amounts with:
|
||||
|
||||
- thousands separator: `.`
|
||||
- decimal separator: `,`
|
||||
- exactly 2 decimals
|
||||
- minus sign before the formatted number
|
||||
|
||||
Example:
|
||||
|
||||
```text
|
||||
1234567.89 -> 1.234.567,89
|
||||
-1234567.89 -> -1.234.567,89
|
||||
0 -> 0,00
|
||||
```
|
||||
|
||||
## Recommended Django implementation
|
||||
|
||||
Create a shared template filter in a common app, e.g.:
|
||||
|
||||
```text
|
||||
backend/apps/common/templatetags/amount_format.py
|
||||
```
|
||||
|
||||
Example filter:
|
||||
|
||||
```python
|
||||
from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
|
||||
|
||||
from django import template
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.filter
|
||||
def amount_dk(value):
|
||||
if value is None or value == "":
|
||||
return "0,00"
|
||||
|
||||
try:
|
||||
amount = Decimal(str(value)).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
|
||||
except (InvalidOperation, ValueError, TypeError):
|
||||
return value
|
||||
|
||||
sign = "-" if amount < 0 else ""
|
||||
amount = abs(amount)
|
||||
formatted = f"{amount:,.2f}"
|
||||
return sign + formatted.replace(",", "X").replace(".", ",").replace("X", ".")
|
||||
```
|
||||
|
||||
Ensure `templatetags/__init__.py` exists.
|
||||
|
||||
In templates:
|
||||
|
||||
```django
|
||||
{% load amount_format %}
|
||||
{{ amount|amount_dk }} kr
|
||||
```
|
||||
|
||||
## What to update
|
||||
|
||||
Search all relevant templates for amount displays, especially:
|
||||
|
||||
- `floatformat:2`
|
||||
- table columns named Beløb, Sum, Difference, Rest, Betalt
|
||||
- dashboard cards
|
||||
- report tables
|
||||
- invoice/payment status pages
|
||||
- transaction detail pages
|
||||
|
||||
Replace monetary `floatformat:2` with the shared amount filter. Leave percentages, scores, counts, and raw JSON/raw imported data alone unless the user explicitly asks otherwise.
|
||||
|
||||
## Tests
|
||||
|
||||
Follow TDD for behavior changes:
|
||||
|
||||
1. Add a failing unit/template test for the filter:
|
||||
|
||||
```python
|
||||
template = Template("{% load amount_format %}{{ value|amount_dk }}")
|
||||
assert template.render(Context({"value": Decimal("1234567.89")})) == "1.234.567,89"
|
||||
```
|
||||
|
||||
2. Add at least one rendered-page regression test for the main UI path, asserting:
|
||||
|
||||
- formatted amount is present, e.g. `1.234.567,89`
|
||||
- raw unformatted amount is absent, e.g. `1234567.89`
|
||||
|
||||
3. Run the relevant app tests and system check in the project runtime, usually Docker Compose for Radix internal apps:
|
||||
|
||||
```bash
|
||||
docker compose exec -T web python manage.py test apps.core --settings=config.settings.test -v 2
|
||||
docker compose exec -T web python manage.py check
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
Before finalizing:
|
||||
|
||||
- Confirm there are no remaining monetary `|floatformat:2` usages in the changed templates.
|
||||
- Confirm templates that use `amount_dk` include `{% load amount_format %}`.
|
||||
- Restart the web container if the running app needs to load a new template tag module:
|
||||
|
||||
```bash
|
||||
docker compose restart web
|
||||
```
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- Do not alter raw JSON/raw import displays; those are audit data and should preserve original values.
|
||||
- Do not apply money formatting to percentages or match scores.
|
||||
- Avoid Python float math for money formatting; use `Decimal` to avoid binary rounding surprises.
|
||||
- If the app already has a localization/formatting utility, extend that instead of adding a second competing filter.
|
||||
Reference in New Issue
Block a user