misc: use DjangoJSONEncoder for exports (#89091)
gitea/lingo/pipeline/head This commit looks good Details

default json encoder does not handle decimal values
from DjangoJSONEncoder:
    JSONEncoder subclass that knows how to encode date/time, decimal types, and
    UUIDs.
This commit is contained in:
Lauréline Guérin 2024-04-04 11:10:31 +02:00 committed by Lauréline Guérin
parent b8b0da6809
commit 420ffc5f40
6 changed files with 21 additions and 13 deletions

View File

@ -27,7 +27,7 @@ from django.views.generic import FormView
from lingo.invoicing.forms import ExportForm, ImportForm
from lingo.invoicing.utils import export_site, import_site
from lingo.utils.misc import LingoImportError
from lingo.utils.misc import LingoImportError, json_dump
class ConfigExportView(FormView):
@ -40,7 +40,7 @@ class ConfigExportView(FormView):
response['Content-Disposition'] = 'attachment; filename="export_invoicing_config_{}.json"'.format(
today.strftime('%Y%m%d')
)
json.dump(export_site(**form.cleaned_data), response, indent=2)
json_dump(export_site(**form.cleaned_data), response, indent=2)
return response

View File

@ -15,7 +15,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import datetime
import json
from django.http import HttpResponse
from django.urls import reverse
@ -24,6 +23,7 @@ from django.views.generic import CreateView, DeleteView, DetailView, ListView, U
from lingo.export_import.views import WithApplicationsMixin
from lingo.invoicing.forms import NewPayerForm, PayerForm, PayerMappingForm
from lingo.invoicing.models import Payer
from lingo.utils.misc import json_dump
class PayersListView(WithApplicationsMixin, ListView):
@ -118,7 +118,7 @@ class PayerExport(DetailView):
self.get_object().slug, today.strftime('%Y%m%d')
)
response['Content-Disposition'] = attachment
json.dump({'payers': [self.get_object().export_json()]}, response, indent=2)
json_dump({'payers': [self.get_object().export_json()]}, response, indent=2)
return response

View File

@ -17,7 +17,6 @@
import collections
import csv
import datetime
import json
from django.db import transaction
from django.db.models import CharField, IntegerField, JSONField, Prefetch, Q, Value
@ -56,6 +55,7 @@ from lingo.invoicing.models import (
Regie,
)
from lingo.invoicing.views.utils import PDFMixin
from lingo.utils.misc import json_dump
def import_regies(data):
@ -213,7 +213,7 @@ class RegieExport(DetailView):
self.get_object().slug, today.strftime('%Y%m%d')
)
response['Content-Disposition'] = attachment
json.dump({'regies': [self.get_object().export_json()]}, response, indent=2)
json_dump({'regies': [self.get_object().export_json()]}, response, indent=2)
return response

View File

@ -64,7 +64,7 @@ from lingo.pricing.forms import (
)
from lingo.pricing.models import BillingDate, Criteria, CriteriaCategory, Pricing, PricingCriteriaCategory
from lingo.pricing.utils import export_site, import_site
from lingo.utils.misc import LingoImportError
from lingo.utils.misc import LingoImportError, json_dump
class ConfigExportView(FormView):
@ -77,7 +77,7 @@ class ConfigExportView(FormView):
response['Content-Disposition'] = 'attachment; filename="export_pricing_config_{}.json"'.format(
today.strftime('%Y%m%d')
)
json.dump(export_site(**form.cleaned_data), response, indent=2)
json_dump(export_site(**form.cleaned_data), response, indent=2)
return response
@ -287,7 +287,7 @@ class CriteriaCategoryExport(DetailView):
self.get_object().slug, today.strftime('%Y%m%d')
)
response['Content-Disposition'] = attachment
json.dump({'pricing_categories': [self.get_object().export_json()]}, response, indent=2)
json_dump({'pricing_categories': [self.get_object().export_json()]}, response, indent=2)
return response
@ -446,7 +446,7 @@ class AgendaExport(AgendaMixin, DetailView):
response['Content-Disposition'] = 'attachment; filename="export_pricing_agenda_{}_{}.json"'.format(
self.get_object().slug, today.strftime('%Y%m%d')
)
json.dump({'agendas': [self.get_object().export_json()]}, response, indent=2)
json_dump({'agendas': [self.get_object().export_json()]}, response, indent=2)
return response
@ -744,7 +744,7 @@ class PricingExport(DetailView):
self.get_object().slug, today.strftime('%Y%m%d')
)
response['Content-Disposition'] = attachment
json.dump({'pricings': [self.get_object().export_json()]}, response, indent=2)
json_dump({'pricings': [self.get_object().export_json()]}, response, indent=2)
return response
@ -1069,7 +1069,7 @@ class CheckTypeGroupExport(DetailView):
self.get_object().slug, today.strftime('%Y%m%d')
)
response['Content-Disposition'] = attachment
json.dump({'check_type_groups': [self.get_object().export_json()]}, response, indent=2)
json_dump({'check_type_groups': [self.get_object().export_json()]}, response, indent=2)
return response

View File

@ -15,10 +15,12 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import copy
import json
import urllib.parse
from django.conf import settings
from django.core.exceptions import FieldDoesNotExist, ValidationError
from django.core.serializers.json import DjangoJSONEncoder
from django.utils.translation import gettext_lazy as _
@ -81,3 +83,7 @@ def get_known_service_for_url(url):
if urllib.parse.urlparse(remote_url).netloc == netloc:
return service
return None
def json_dump(*args, **kwargs):
return json.dump(cls=DjangoJSONEncoder, *args, **kwargs)

View File

@ -1,5 +1,6 @@
import copy
import datetime
import io
import pytest
@ -7,7 +8,7 @@ from lingo.agendas.models import Agenda, CheckType, CheckTypeGroup
from lingo.invoicing.models import Regie
from lingo.pricing.models import BillingDate, Criteria, CriteriaCategory, Pricing, PricingCriteriaCategory
from lingo.pricing.utils import export_site, import_site
from lingo.utils.misc import LingoImportError
from lingo.utils.misc import LingoImportError, json_dump
pytestmark = pytest.mark.django_db
@ -51,6 +52,7 @@ def test_import_export_pricing(app):
)
pricing.agendas.set([agenda])
data = export_site()
json_dump(data, io.StringIO()) # no error
Agenda.objects.all().delete()
with pytest.raises(LingoImportError) as excinfo: