lingo: add backends and regies in site import/export (#46895)

This commit is contained in:
Valentin Deniaud 2020-11-03 16:04:57 +01:00
parent 6765819f29
commit fcc41caa81
3 changed files with 114 additions and 0 deletions

View File

@ -29,6 +29,7 @@ from requests import RequestException
from django import template
from django.conf import settings
from django.core import serializers
from django.db import models
from django.forms import models as model_forms, Select
from django.utils.translation import ugettext_lazy as _
@ -94,6 +95,11 @@ def build_remote_item(data, regie):
reference_id=data.get('reference_id'))
class PaymentBackendManager(models.Manager):
def get_by_natural_key(self, slug):
return self.get(slug=slug)
@python_2_unicode_compatible
class PaymentBackend(models.Model):
label = models.CharField(verbose_name=_('Label'), max_length=64)
@ -104,6 +110,8 @@ class PaymentBackend(models.Model):
verbose_name=_('Payment Service'), max_length=64, choices=SERVICES)
service_options = JSONField(blank=True, verbose_name=_('Payment Service Options'))
objects = PaymentBackendManager()
def __str__(self):
return self.label
@ -120,6 +128,37 @@ class PaymentBackend(models.Model):
options = {}
return eopayment.Payment(self.service, options)
def natural_key(self):
return (self.slug,)
@classmethod
def export_all_for_json(cls):
return [x.get_as_serialized_object() for x in cls.objects.all()]
def get_as_serialized_object(self):
serialized_backend = json.loads(
serializers.serialize('json', [self], use_natural_primary_keys=True)
)[0]
del serialized_backend['model']
return serialized_backend
@classmethod
def load_serialized_objects(cls, json_site):
for json_backend in json_site:
cls.load_serialized_object(json_backend)
@classmethod
def load_serialized_object(cls, json_backend):
json_backend['model'] = str(cls._meta)
try:
backend = cls.objects.get_by_natural_key(json_backend['fields']['slug'])
json_backend['pk'] = backend.pk
except cls.DoesNotExist:
pass
backend = next(serializers.deserialize('json', json.dumps([json_backend]), ignorenonexistent=True))
backend.save()
class RegieException(Exception):
pass
@ -374,6 +413,35 @@ class Regie(models.Model):
message.attach('%s.pdf' % invoice.id, invoice_pdf.content, 'application/pdf')
message.send()
@classmethod
def export_all_for_json(cls):
return [x.get_as_serialized_object() for x in cls.objects.all()]
def get_as_serialized_object(self):
serialized_regie = serializers.serialize(
'json', [self], use_natural_primary_keys=True, use_natural_foreign_keys=True
)
serialized_regie = json.loads(serialized_regie)[0]
del serialized_regie['model']
return serialized_regie
@classmethod
def load_serialized_objects(cls, json_site):
for json_regie in json_site:
cls.load_serialized_object(json_regie)
@classmethod
def load_serialized_object(cls, json_regie):
json_regie['model'] = str(cls._meta)
try:
regie = cls.objects.get(slug=json_regie['fields']['slug'])
json_regie['pk'] = regie.pk
except cls.DoesNotExist:
pass
regie = next(serializers.deserialize('json', json.dumps([json_regie]), ignorenonexistent=True))
regie.save()
class BasketItem(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)

View File

@ -31,6 +31,7 @@ from combo.apps.assets.utils import untar_assets_files
from combo.apps.assets.utils import tar_assets_files
from combo.apps.maps.models import MapLayer
from combo.apps.pwa.models import PwaSettings, PwaNavigationEntry
from combo.apps.lingo.models import PaymentBackend, Regie
from .models import Page
@ -54,6 +55,10 @@ def export_site():
'pwa': {
'settings': PwaSettings.export_for_json(),
'navigation': PwaNavigationEntry.export_all_for_json(),
},
'payment': {
'backends': PaymentBackend.export_all_for_json(),
'regies': Regie.export_all_for_json(),
}
}
@ -88,6 +93,8 @@ def import_site(data, if_empty=False, clean=False, request=None):
Page.objects.all().delete()
PwaSettings.objects.all().delete()
PwaNavigationEntry.objects.all().delete()
PaymentBackend.objects.all().delete()
Regie.objects.all().delete()
try:
MapLayer.load_serialized_objects(data.get('map-layers') or [])
@ -97,6 +104,9 @@ def import_site(data, if_empty=False, clean=False, request=None):
if data.get('pwa'):
PwaSettings.load_serialized_settings(data['pwa'].get('settings'))
PwaNavigationEntry.load_serialized_objects(data['pwa'].get('navigation'))
if data.get('payment'):
PaymentBackend.load_serialized_objects(data['payment'].get('backends'))
Regie.load_serialized_objects(data['payment'].get('regies'))
except DeserializationError as e:
message = str(e)
if not message.startswith('Page matching query does not exist.'):

View File

@ -19,6 +19,7 @@ from django.utils.six import BytesIO, StringIO
from combo.apps.assets.models import Asset
from combo.apps.assets.utils import clean_assets_files
from combo.apps.gallery.models import Image, GalleryCell
from combo.apps.lingo.models import PaymentBackend, Regie
from combo.apps.maps.models import MapLayer, Map, MapLayerOptions
from combo.apps.pwa.models import PwaSettings, PwaNavigationEntry
from combo.data.models import Page, TextCell
@ -421,3 +422,38 @@ def test_import_export_tar(tmpdir, some_assets):
tarfile.open(filename, 'w').close() # empty tar file
with pytest.raises(CommandError, match=r'TAR file should provide _site.json file'):
call_command('import_site', filename)
def test_import_export_payment(app):
backend = PaymentBackend.objects.create(label='Test', slug='test', service_options={'test': True})
Regie.objects.create(label='Test regie', slug='test-regie', payment_backend=backend)
Regie.objects.create(label='Test regie 2', slug='test-regie-2', payment_backend=backend)
output = get_output_of_command('export_site')
payload = json.loads(output)
assert len(payload['payment']['backends']) == 1
assert len(payload['payment']['regies']) == 2
import_site(payload)
assert PaymentBackend.objects.count() == 1
assert Regie.objects.count() == 2
PaymentBackend.objects.all().delete()
Regie.objects.all().delete()
import_site(payload)
backend = PaymentBackend.objects.get(slug='test')
assert backend.label == 'Test'
assert backend.service_options == {'test': True}
assert Regie.objects.count() == 2
regie = Regie.objects.first()
assert regie.payment_backend == backend
import_site(data={}, clean=True)
assert PaymentBackend.objects.count() == 0
assert Regie.objects.count() == 0
empty_output = get_output_of_command('export_site')
assert len(json.loads(empty_output)['payment']['backends']) == 0
assert len(json.loads(empty_output)['payment']['regies']) == 0