Files
WYGIWYH/app/apps/api/serializers/imports.py
T
Asish Kumar 1ed5dc5d31 feat(import): pick the account when running an import
An import run can now be given an account, and every transaction it
creates goes into that account instead of the one the profile maps. This
lets a single profile serve several accounts at the same bank, for
statements that only name the account in a header cell or not at all,
instead of keeping one copy of the profile per account.

- ImportRun gets an optional `account` (SET_NULL), shown on the run card.
- The upload form offers the user's active accounts when the profile
  imports transactions, and leaves the field out for profiles that import
  accounts, currencies, categories, tags or entities.
- CSV and Excel rows take the run's account before deduplication, so
  rules comparing `account` check against the picked account. The
  profile's account mapping is skipped for these rows.
- QIF files use the run's account instead of the account named after the
  file.
- The import API accepts an optional `account_id`, limited to accounts
  the user can access, rejected for profiles that don't import
  transactions, and returns `account` on import runs.

Leaving the account empty keeps the current behaviour.

Closes #538
2026-11-11 22:41:37 +05:30

64 lines
1.9 KiB
Python

from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from apps.accounts.models import Account
from apps.import_app.models import ImportProfile, ImportRun
class ImportProfileSerializer(serializers.ModelSerializer):
"""Serializer for listing import profiles."""
class Meta:
model = ImportProfile
fields = ["id", "name", "version", "yaml_config"]
class ImportRunSerializer(serializers.ModelSerializer):
"""Serializer for listing import runs."""
class Meta:
model = ImportRun
fields = [
"id",
"status",
"profile",
"file_name",
"account",
"logs",
"processed_rows",
"total_rows",
"successful_rows",
"skipped_rows",
"failed_rows",
"started_at",
"finished_at",
]
class ImportFileSerializer(serializers.Serializer):
"""Serializer for uploading a file to import using an existing profile."""
profile_id = serializers.PrimaryKeyRelatedField(
queryset=ImportProfile.objects.all(), source="profile"
)
file = serializers.FileField()
account_id = serializers.PrimaryKeyRelatedField(
queryset=Account.objects.all(),
source="account",
required=False,
allow_null=True,
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Reload the querysets to get an updated version with the requesting user
self.fields["profile_id"].queryset = ImportProfile.objects.all()
self.fields["account_id"].queryset = Account.objects.all()
def validate(self, data):
if data.get("account") and not data["profile"].imports_transactions:
raise serializers.ValidationError(
{"account_id": _("Only transaction imports can use an account.")}
)
return data