diff --git a/back/.env.sample b/back/.env.sample index 13cda928..2ef5ffe0 100644 --- a/back/.env.sample +++ b/back/.env.sample @@ -5,7 +5,7 @@ PGPORT=5432 PGPASSWORD=geoshop PGSCHEMA=geoshop PGPOSTGRESPASSWORD=postgres -ALLOWED_HOST=localhost +ALLOWED_HOST=localhost,127.0.0.1 GDAL_IN_VENV=True GDAL_DATA=path\to\.venv\Lib\site-packages\osgeo\data\gdal ROOTURL=/geoshop2_dev diff --git a/back/api/migrations/0002_auto_20200318_0955.py b/back/api/migrations/0002_auto_20200318_0955.py new file mode 100644 index 00000000..63472716 --- /dev/null +++ b/back/api/migrations/0002_auto_20200318_0955.py @@ -0,0 +1,357 @@ +# Generated by Django 3.0.3 on 2020-03-18 08:55 + +from django.conf import settings +import django.contrib.gis.db.models.fields +from django.db import migrations, models +import django.db.models.deletion +import djmoney.models.fields + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('api', '0001_initial'), + ] + + operations = [ + migrations.AlterModelOptions( + name='copyright', + options={'verbose_name': 'copyright'}, + ), + migrations.AlterModelOptions( + name='document', + options={'verbose_name': 'document'}, + ), + migrations.AlterModelOptions( + name='format', + options={'verbose_name': 'format'}, + ), + migrations.AlterModelOptions( + name='metadata', + options={'verbose_name': 'metadata'}, + ), + migrations.AlterModelOptions( + name='orderitem', + options={'verbose_name': 'order_item'}, + ), + migrations.AlterModelOptions( + name='pricing', + options={'verbose_name': 'pricing'}, + ), + migrations.AlterModelOptions( + name='product', + options={'verbose_name': 'product'}, + ), + migrations.AlterModelOptions( + name='productfield', + options={'verbose_name': 'product_field'}, + ), + migrations.AlterModelOptions( + name='productformat', + options={'verbose_name': 'product_format'}, + ), + migrations.RemoveField( + model_name='metadata', + name='validations_needed', + ), + migrations.AlterField( + model_name='document', + name='link', + field=models.CharField(blank=True, max_length=2000, verbose_name='link'), + ), + migrations.AlterField( + model_name='document', + name='name', + field=models.CharField(blank=True, max_length=80, verbose_name='name'), + ), + migrations.AlterField( + model_name='format', + name='name', + field=models.CharField(blank=True, max_length=30, verbose_name='name'), + ), + migrations.AlterField( + model_name='identity', + name='city', + field=models.CharField(blank=True, max_length=50, verbose_name='city'), + ), + migrations.AlterField( + model_name='identity', + name='company_name', + field=models.CharField(blank=True, max_length=50, verbose_name='company_name'), + ), + migrations.AlterField( + model_name='identity', + name='contract_accepted', + field=models.DateField(blank=True, null=True, verbose_name='contract_accepted'), + ), + migrations.AlterField( + model_name='identity', + name='country', + field=models.CharField(blank=True, max_length=50, verbose_name='country'), + ), + migrations.AlterField( + model_name='identity', + name='phone', + field=models.TextField(blank=True, verbose_name='phone'), + ), + migrations.AlterField( + model_name='identity', + name='postcode', + field=models.PositiveIntegerField(blank=True, null=True, verbose_name='postcode'), + ), + migrations.AlterField( + model_name='identity', + name='sap_id', + field=models.BigIntegerField(blank=True, null=True, verbose_name='sap_id'), + ), + migrations.AlterField( + model_name='identity', + name='street', + field=models.CharField(blank=True, max_length=100, verbose_name='street'), + ), + migrations.AlterField( + model_name='identity', + name='street2', + field=models.CharField(blank=True, max_length=100, verbose_name='street2'), + ), + migrations.AlterField( + model_name='metadata', + name='contact_persons', + field=models.ManyToManyField(blank=True, to='api.Identity', verbose_name='contact_persons'), + ), + migrations.AlterField( + model_name='metadata', + name='copyright', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='api.Copyright', verbose_name='copyright'), + ), + migrations.AlterField( + model_name='metadata', + name='description_long', + field=models.TextField(blank=True, verbose_name='description_long'), + ), + migrations.AlterField( + model_name='metadata', + name='description_short', + field=models.CharField(blank=True, max_length=500, verbose_name='description_short'), + ), + migrations.AlterField( + model_name='metadata', + name='documents', + field=models.ManyToManyField(blank=True, to='api.Document', verbose_name='documents'), + ), + migrations.AlterField( + model_name='metadata', + name='geocat_link', + field=models.CharField(blank=True, max_length=2000, verbose_name='geocat_link'), + ), + migrations.AlterField( + model_name='metadata', + name='image_link', + field=models.CharField(blank=True, max_length=2000, verbose_name='image_link'), + ), + migrations.AlterField( + model_name='metadata', + name='legend_link', + field=models.CharField(blank=True, max_length=2000, verbose_name='legend_link'), + ), + migrations.AlterField( + model_name='metadata', + name='name', + field=models.CharField(blank=True, max_length=50, verbose_name='name'), + ), + migrations.AlterField( + model_name='order', + name='client', + field=models.ForeignKey(blank=True, on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL, verbose_name='client'), + ), + migrations.AlterField( + model_name='order', + name='date_downloaded', + field=models.DateTimeField(blank=True, null=True, verbose_name='date_downloaded'), + ), + migrations.AlterField( + model_name='order', + name='date_ordered', + field=models.DateTimeField(blank=True, null=True, verbose_name='date_ordered'), + ), + migrations.AlterField( + model_name='order', + name='date_processed', + field=models.DateTimeField(blank=True, null=True, verbose_name='date_processed'), + ), + migrations.AlterField( + model_name='order', + name='description', + field=models.TextField(blank=True, verbose_name='description'), + ), + migrations.AlterField( + model_name='order', + name='geom', + field=django.contrib.gis.db.models.fields.PolygonField(srid=2056, verbose_name='geom'), + ), + migrations.AlterField( + model_name='order', + name='invoice_contact', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='invoice_contact', to='api.Identity', verbose_name='invoice_contact'), + ), + migrations.AlterField( + model_name='order', + name='invoice_reference', + field=models.CharField(blank=True, max_length=255, verbose_name='invoice_reference'), + ), + migrations.AlterField( + model_name='order', + name='order_contact', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='order_contact', to='api.Identity', verbose_name='order_contact'), + ), + migrations.AlterField( + model_name='order', + name='order_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='api.OrderType', verbose_name='order_type'), + ), + migrations.AlterField( + model_name='order', + name='part_vat', + field=djmoney.models.fields.MoneyField(decimal_places=2, default_currency='CHF', max_digits=14, null=True, verbose_name='part_vat'), + ), + migrations.AlterField( + model_name='order', + name='processing_fee', + field=djmoney.models.fields.MoneyField(decimal_places=2, default_currency='CHF', max_digits=14, null=True, verbose_name='processing_fee'), + ), + migrations.AlterField( + model_name='order', + name='status', + field=models.CharField(choices=[('DRAFT', 'Draft'), ('PENDING', 'Pending'), ('READY', 'Ready'), ('PARTIALLY_DELIVERED', 'Partially delivered'), ('PROCESSED', 'Processed'), ('DOWNLOADED', 'Downloaded'), ('ARCHIVED', 'Archived'), ('REJECTED', 'Rejected')], default='DRAFT', max_length=20, verbose_name='status'), + ), + migrations.AlterField( + model_name='order', + name='title', + field=models.CharField(blank=True, max_length=255, verbose_name='title'), + ), + migrations.AlterField( + model_name='order', + name='total_cost', + field=djmoney.models.fields.MoneyField(decimal_places=2, default_currency='CHF', max_digits=14, null=True, verbose_name='total_cost'), + ), + migrations.AlterField( + model_name='orderitem', + name='format', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='api.Format', verbose_name='format'), + ), + migrations.AlterField( + model_name='orderitem', + name='last_download', + field=models.DateTimeField(blank=True, null=True, verbose_name='last_download'), + ), + migrations.AlterField( + model_name='orderitem', + name='order', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='api.Order', verbose_name='order'), + ), + migrations.AlterField( + model_name='orderitem', + name='product', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='api.Product', verbose_name='product'), + ), + migrations.AlterField( + model_name='ordertype', + name='name', + field=models.CharField(blank=True, max_length=30, verbose_name='name'), + ), + migrations.AlterField( + model_name='pricing', + name='base_fee', + field=djmoney.models.fields.MoneyField(decimal_places=2, default_currency='CHF', max_digits=14, null=True, verbose_name='base_fee'), + ), + migrations.AlterField( + model_name='pricing', + name='price', + field=djmoney.models.fields.MoneyField(decimal_places=2, default_currency='CHF', max_digits=14, null=True, verbose_name='price'), + ), + migrations.AlterField( + model_name='pricing', + name='price_type', + field=models.CharField(blank=True, max_length=50, verbose_name='price_type'), + ), + migrations.AlterField( + model_name='pricing', + name='product', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='api.Product', verbose_name='product'), + ), + migrations.AlterField( + model_name='product', + name='group', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='api.Product', verbose_name='group'), + ), + migrations.AlterField( + model_name='product', + name='label', + field=models.CharField(blank=True, max_length=250, verbose_name='label'), + ), + migrations.AlterField( + model_name='product', + name='metadata', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='api.Metadata', verbose_name='metadata'), + ), + migrations.AlterField( + model_name='product', + name='order', + field=models.BigIntegerField(blank=True, null=True, verbose_name='order'), + ), + migrations.AlterField( + model_name='product', + name='status', + field=models.CharField(choices=[('DRAFT', 'Draft'), ('PUBLISHED', 'Published'), ('DEPRECATED', 'Deprecated')], default='DRAFT', max_length=10, verbose_name='status'), + ), + migrations.AlterField( + model_name='productfield', + name='db_name', + field=models.CharField(blank=True, max_length=50, verbose_name='db_name'), + ), + migrations.AlterField( + model_name='productfield', + name='export_name', + field=models.CharField(blank=True, max_length=50, verbose_name='export_name'), + ), + migrations.AlterField( + model_name='productfield', + name='field_length', + field=models.SmallIntegerField(verbose_name='field_length'), + ), + migrations.AlterField( + model_name='productfield', + name='field_type', + field=models.CharField(blank=True, choices=[('REAL', 'Real'), ('DATE', 'Date'), ('CHAR', 'Character'), ('VARCHAR', 'Varying character'), ('INT', 'Integer'), ('BIGINT', 'Big integer'), ('FLOAT', 'Floating number')], max_length=10, verbose_name='field_type'), + ), + migrations.AlterField( + model_name='productfield', + name='product', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.Product', verbose_name='product'), + ), + migrations.AlterField( + model_name='productformat', + name='format', + field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='api.Format', verbose_name='format'), + ), + migrations.AlterField( + model_name='productformat', + name='is_manual', + field=models.BooleanField(default=False, verbose_name='is_manual'), + ), + migrations.AlterField( + model_name='productformat', + name='product', + field=models.OneToOneField(on_delete=django.db.models.deletion.DO_NOTHING, primary_key=True, serialize=False, to='api.Product', verbose_name='product'), + ), + migrations.CreateModel( + name='ProductValidation', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('order_type', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='api.OrderType', verbose_name='order_type')), + ('product', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='api.Product', verbose_name='product')), + ('validator', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='api.Identity', verbose_name='validator')), + ], + ), + ] diff --git a/back/api/models.py b/back/api/models.py index 77ce1d4f..7f58f356 100644 --- a/back/api/models.py +++ b/back/api/models.py @@ -68,7 +68,6 @@ class Metadata(models.Model): copyright = models.ForeignKey(Copyright, models.DO_NOTHING, verbose_name=_('copyright'), blank=True, null=True) documents = models.ManyToManyField(Document, verbose_name=_('documents'), blank=True) contact_persons = models.ManyToManyField(Identity, verbose_name=_('contact_persons'), blank=True) - validations_needed = models.ManyToManyField(OrderType, verbose_name=_('validations_needed'), blank=True) class Meta: db_table = 'metadata' @@ -176,11 +175,21 @@ class ProductFieldType(models.TextChoices): field_length = models.SmallIntegerField(_('field_length'), ) product = models.ForeignKey(Product, verbose_name=_('product'), on_delete=models.CASCADE) + class Meta: db_table = 'product_field' verbose_name = _('product_field') +class ProductValidation(models.Model): + """ + Some products need to be validated before order is processed. The validation depends on the order type + """ + product = models.ForeignKey(Product, models.DO_NOTHING, verbose_name=_('product')) + order_type = models.ForeignKey(OrderType, models.DO_NOTHING, verbose_name=_('order_type')) + validator = models.ForeignKey(Identity, models.DO_NOTHING, verbose_name=_('validator')) + + class ProductFormat(models.Model): product = models.OneToOneField(Product, models.DO_NOTHING, verbose_name=_('product'), primary_key=True) format = models.ForeignKey(Format, models.DO_NOTHING, verbose_name=_('format')) diff --git a/back/api/tests.py b/back/api/tests.py index 8af78552..6e69bbd9 100644 --- a/back/api/tests.py +++ b/back/api/tests.py @@ -15,7 +15,7 @@ def setUp(self): self.password1 = 'testPa$$word' self.data = { 'username': self.username, - 'password': self.password + 'password': self.password1 } def test_registration(self): @@ -25,7 +25,7 @@ def test_current_user(self): # URL using path name url = reverse('token_obtain_pair') - user = Identity.objects.create_user(username=self.username, email='test@example.com', password=self.password) + user = Identity.objects.create_user(username=self.username, email='test@example.com', password=self.password1) self.assertEqual(user.is_active, 1, 'Active User') # First post to get token