Skip to content

Commit

Permalink
Merge pull request #10 from camptocamp/api_documentation
Browse files Browse the repository at this point in the history
API Documentation
  • Loading branch information
marionb authored May 6, 2024
2 parents f851847 + 72f0048 commit bab952a
Show file tree
Hide file tree
Showing 14 changed files with 130 additions and 73 deletions.
6 changes: 3 additions & 3 deletions api/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ class OrderAdmin(CustomGeoModelAdmin):
raw_id_fields = ['client', 'invoice_contact']
ordering = ['-id']
actions = ['quote']
list_filter = ['status', 'date_ordered']
list_filter = ['order_status', 'date_ordered']

def title_small(self, order):
title = order.title
Expand Down Expand Up @@ -168,7 +168,7 @@ def response_change(self, request, obj):
for item in obj.items.all():
item.status = OrderItem.OrderItemStatus.PENDING
item.save()
obj.status = Order.OrderStatus.READY
obj.order_status = Order.OrderStatus.READY
obj.save()
self.message_user(
request,
Expand Down Expand Up @@ -198,7 +198,7 @@ class ProductAdmin(CustomGeoModelAdmin):
raw_id_fields = ('metadata', 'group')
exclude = ('ts',)
search_fields = ['label']
list_filter = ('status',)
list_filter = ('product_status',)
readonly_fields = ('thumbnail_tag',)


Expand Down
6 changes: 3 additions & 3 deletions api/management/commands/prepareusertests.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def handle(self, *args, **options):
# Set all ready orders to ARCHIVED
orders_ready = Order.objects.filter(status=Order.OrderStatus.READY).all()
for order in orders_ready:
order.status = Order.OrderStatus.ARCHIVED
order.order_status = Order.OrderStatus.ARCHIVED
order.save()

# Create users
Expand Down Expand Up @@ -277,7 +277,7 @@ def handle(self, *args, **options):
order_mka2.invoice_contact = contact_mka2
order_mka2.set_price()
order_mka2.date_ordered = datetime.datetime(2018, 12, 1, 8, 20, 3, 0, tzinfo=datetime.timezone.utc)
order_mka2.status = Order.OrderStatus.ARCHIVED
order_mka2.order_status = Order.OrderStatus.ARCHIVED
order_mka2.save()

order_download.set_price()
Expand All @@ -287,7 +287,7 @@ def handle(self, *args, **options):
order_item.extract_result = extract_file
order_item.status = OrderItem.OrderItemStatus.PROCESSED
order_item.save()
order_download.status = Order.OrderStatus.PROCESSED
order_download.order_status = Order.OrderStatus.PROCESSED

# Creating zip with all zips without background process unsupported by manage.py
zip_list_path = list(order_download.items.all().values_list('extract_result', flat=True))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Generated by Django 4.1.10 on 2024-04-29 06:21

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0047_alter_document_link_and_more'),
]

operations = [
migrations.RemoveField(
model_name='order',
name='status',
),
migrations.RemoveField(
model_name='product',
name='status',
),
migrations.AddField(
model_name='order',
name='order_status',
field=models.CharField(choices=[('DRAFT', 'Draft'), ('PENDING', 'Pending'), ('QUOTE_DONE', 'Quote done'), ('READY', 'Ready'), ('IN_EXTRACT', 'In extract'), ('PARTIALLY_DELIVERED', 'Partially delivered'), ('PROCESSED', 'Processed'), ('ARCHIVED', 'Archived'), ('REJECTED', 'Rejected')], default='DRAFT', max_length=20, verbose_name='order_status'),
),
migrations.AddField(
model_name='product',
name='product_status',
field=models.CharField(choices=[('DRAFT', 'Draft'), ('PUBLISHED', 'Published'), ('PUBLISHED_ONLY_IN_GROUP', 'Published only in group'), ('DEPRECATED', 'Deprecated')], default='DRAFT', max_length=30, verbose_name='product_status'),
),
]
28 changes: 14 additions & 14 deletions api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,8 +453,8 @@ class ProductStatus(models.TextChoices):
),
],
)
status = models.CharField(
_("status"),
product_status = models.CharField(
_("product_status"),
max_length=30,
choices=ProductStatus.choices,
default=ProductStatus.DRAFT,
Expand Down Expand Up @@ -591,8 +591,8 @@ class OrderStatus(models.TextChoices):
order_type = models.ForeignKey(
OrderType, models.PROTECT, verbose_name=_("order_type")
)
status = models.CharField(
_("status"),
order_status = models.CharField(
_("order_status"),
max_length=20,
choices=OrderStatus.choices,
default=OrderStatus.DRAFT,
Expand Down Expand Up @@ -653,7 +653,7 @@ def quote_done(self):
"""Admins confirmation they have given a manual price"""
price_is_set = self.set_price()
if price_is_set:
self.status = self.OrderStatus.QUOTE_DONE
self.order_status = self.OrderStatus.QUOTE_DONE
self.save()
send_geoshop_email(
_("Geoshop - Quote has been done"),
Expand Down Expand Up @@ -726,10 +726,10 @@ def confirm(self):
item.ask_validation()
item.save()
if has_all_prices_calculated:
self.status = Order.OrderStatus.READY
self.order_status = Order.OrderStatus.READY
else:
self.ask_price()
self.status = Order.OrderStatus.PENDING
self.order_status = Order.OrderStatus.PENDING

def next_status_on_extract_input(self):
"""Controls status when Extract uploads a file or cancel an order item"""
Expand All @@ -738,7 +738,7 @@ def next_status_on_extract_input(self):
Order.OrderStatus.IN_EXTRACT,
Order.OrderStatus.PARTIALLY_DELIVERED,
]
if self.status not in previous_accepted_status:
if self.order_status not in previous_accepted_status:
raise Exception("Order has an inappropriate status after input")
items_statuses = set(self.items.all().values_list("status", flat=True))

Expand All @@ -747,15 +747,15 @@ def next_status_on_extract_input(self):
or OrderItem.OrderItemStatus.PENDING in items_statuses
):
if OrderItem.OrderItemStatus.PROCESSED in items_statuses:
self.status = Order.OrderStatus.PARTIALLY_DELIVERED
self.order_status = Order.OrderStatus.PARTIALLY_DELIVERED
else:
self.status = Order.OrderStatus.READY
self.order_status = Order.OrderStatus.READY
else:
if OrderItem.OrderItemStatus.PROCESSED in items_statuses:
if OrderItem.OrderItemStatus.VALIDATION_PENDING in items_statuses:
self.status = Order.OrderStatus.PARTIALLY_DELIVERED
self.order_status = Order.OrderStatus.PARTIALLY_DELIVERED
else:
self.status = Order.OrderStatus.PROCESSED
self.order_status = Order.OrderStatus.PROCESSED
self.date_processed = timezone.now()
send_geoshop_email(
_("Geoshop - Download ready"),
Expand All @@ -774,8 +774,8 @@ def next_status_on_extract_input(self):
},
)
else:
self.status = Order.OrderStatus.REJECTED
return self.status
self.order_status = Order.OrderStatus.REJECTED
return self.order_status

@property
def geom_srid(self):
Expand Down
15 changes: 9 additions & 6 deletions api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
Metadata, MetadataCategoryEch, MetadataContact, Order, OrderItem, OrderType,
Pricing, Product, ProductFormat, UserChange)

from typing import List, Dict

# Get the UserModel
UserModel = get_user_model()

Expand All @@ -31,14 +33,15 @@ class WKTPolygonField(serializers.Field):
Polygons are serialized to POLYGON((Long, Lat)) notation
"""

def to_representation(self, value):
def to_representation(self, value) -> str:
if isinstance(value, dict) or value is None:
return value
new_value = copy.copy(value)
wkt_w = WKTWriter()

# Use buffer and Douglas-Peucker to simplify geom (one vertex 0.2m) for large polygons
# The smallest Cadastre has 156 vertices
# TODO is this generally true or only for NE?
if new_value.num_coords > 156:
new_value = new_value.buffer(0.5)
new_value = new_value.simplify(0.2, preserve_topology=False)
Expand Down Expand Up @@ -196,15 +199,15 @@ class Meta:
'url': {'lookup_field': 'id_name'}
}

def get_contact_persons(self, obj):
def get_contact_persons(self, obj) -> List[Dict[str, str]]:
"""obj is a Metadata instance. Returns list of dicts"""
qset = MetadataContact.objects.filter(metadata=obj)
return [
MetadataContactSerializer(m, context={
'request': self.context['request']
}).data for m in qset]

def get_legend_link(self, obj):
def get_legend_link(self, obj) -> str:
return obj.get_legend_link()


Expand Down Expand Up @@ -258,7 +261,7 @@ class OrderItemValidationSerializer(OrderItemSerializer):
"""
order_guid = serializers.SerializerMethodField()

def get_order_guid(self, obj):
def get_order_guid(self, obj) -> str:
return obj.order.download_guid


Expand Down Expand Up @@ -292,7 +295,7 @@ class Meta:
'processing_fee_currency', 'processing_fee',
'total_cost_currency', 'total_cost',
'part_vat_currency', 'part_vat',
'status']
'order_status']

def create(self, validated_data):
items_data = validated_data.pop('items', None)
Expand Down Expand Up @@ -325,7 +328,7 @@ def create(self, validated_data):
return order

def update(self, instance, validated_data):
if instance.status != Order.OrderStatus.DRAFT:
if instance.order_status != Order.OrderStatus.DRAFT:
raise serializers.ValidationError()

items_data = validated_data.pop('items', None)
Expand Down
14 changes: 7 additions & 7 deletions api/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,50 +100,50 @@ def __init__(self, webclient=None):
label="Produit gratuit",
pricing=self.pricings['free'],
metadata=self.public_metadata,
status=Product.ProductStatus.PUBLISHED,
product_status=Product.ProductStatus.PUBLISHED,
provider=self.provider
),
'single': Product.objects.create(
label="Produit forfaitaire",
pricing=self.pricings['single'],
metadata=self.public_metadata,
status=Product.ProductStatus.PUBLISHED,
product_status=Product.ProductStatus.PUBLISHED,
provider=self.provider
),
'by_number_objects': Product.objects.create(
label="Bâtiments 3D",
pricing=self.pricings['by_number_objects'],
metadata=self.public_metadata,
status=Product.ProductStatus.PUBLISHED,
product_status=Product.ProductStatus.PUBLISHED,
provider=self.provider
),
'by_area': Product.objects.create(
label="Produit vendu au m²",
pricing=self.pricings['by_area'],
metadata=self.public_metadata,
status=Product.ProductStatus.PUBLISHED,
product_status=Product.ProductStatus.PUBLISHED,
provider=self.provider
),
'from_pricing_layer': Product.objects.create(
label="MO",
pricing=self.pricings['from_pricing_layer'],
metadata=self.public_metadata,
status=Product.ProductStatus.PUBLISHED,
product_status=Product.ProductStatus.PUBLISHED,
free_when_subscribed=True,
provider=self.provider
),
'manual': Product.objects.create(
label="Maquette 3D",
pricing=self.pricings['manual'],
metadata=self.public_metadata,
status=Product.ProductStatus.PUBLISHED,
product_status=Product.ProductStatus.PUBLISHED,
provider=self.provider
),
'yet_unknown_pricing': Product.objects.create(
label="Produit facturé au Mb (non implémenté)",
pricing=self.pricings['yet_unknown_pricing'],
metadata=self.public_metadata,
status=Product.ProductStatus.PUBLISHED,
product_status=Product.ProductStatus.PUBLISHED,
provider=self.provider
)
}
Expand Down
18 changes: 9 additions & 9 deletions api/tests/test_extract.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def test_put_files(self):
response = self.client.put(url, {'extract_result': extract_file, 'comment': 'ok'})
self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED, response.content)
self.assertEqual(
Order.objects.get(pk=order_id).status,
Order.objects.get(pk=order_id).order_status,
Order.OrderStatus.PARTIALLY_DELIVERED,
"Check order status is partially delivered"
)
Expand All @@ -75,7 +75,7 @@ def test_put_files(self):
response = self.client.put(url, {'extract_result': extract_file})
self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED, response.content)
self.assertEqual(
Order.objects.get(pk=order_id).status,
Order.objects.get(pk=order_id).order_status,
Order.OrderStatus.PROCESSED,
"Check order status is processed"
)
Expand All @@ -86,7 +86,7 @@ def test_put_files(self):
url = reverse('order-detail', kwargs={'pk': order_id})
response = self.client.get(url)
self.assertEqual(
response.data['status'], Order.OrderStatus.PROCESSED, 'Check order status is processed')
response.data['order_status'], Order.OrderStatus.PROCESSED, 'Check order status is processed')
url = reverse('orderitem-download-link', kwargs={'pk': order_item_id1})
response = self.client.get(url)
self.assertIsNotNone(response.data['download_link'], 'Check file is visible for user')
Expand Down Expand Up @@ -123,7 +123,7 @@ def test_cancel_order_item(self):
response = self.client.put(url, {'is_rejected': True, 'comment': 'Interdit de commander ces données'})
self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED, response.content)
self.assertEqual(
Order.objects.get(pk=self.config.order.id).status,
Order.objects.get(pk=self.config.order.id).order_status,
Order.OrderStatus.READY,
"Check order status is still ready"
)
Expand All @@ -133,7 +133,7 @@ def test_cancel_order_item(self):
response = self.client.put(url, {'extract_result': extract_file})
self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED, response.content)
self.assertEqual(
Order.objects.get(pk=self.config.order.id).status,
Order.objects.get(pk=self.config.order.id).order_status,
Order.OrderStatus.PROCESSED,
"Check order status is processed"
)
Expand All @@ -150,7 +150,7 @@ def test_reject_order(self):
response = self.client.put(url, {'is_rejected': True, 'comment': 'Interdit de commander ces données'})
self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED, response.content)
self.assertEqual(
Order.objects.get(pk=self.config.order.id).status,
Order.objects.get(pk=self.config.order.id).order_status,
Order.OrderStatus.READY,
"Check order status is still ready for extract"
)
Expand All @@ -159,7 +159,7 @@ def test_reject_order(self):
response = self.client.put(url, {'is_rejected': True, 'comment': 'Interdit de commander ces données'})
self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED, response.content)
self.assertEqual(
Order.objects.get(pk=self.config.order.id).status,
Order.objects.get(pk=self.config.order.id).order_status,
Order.OrderStatus.REJECTED,
"Check order status is rejected"
)
Expand Down Expand Up @@ -188,7 +188,7 @@ def multi_extract_user_order(self):
response = self.client.put(url, {'is_rejected': True, 'comment': 'Interdit de commander ces données'})
self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED, response.content)
self.assertEqual(
Order.objects.get(pk=self.config.order.id).status,
Order.objects.get(pk=self.config.order.id).order_status,
Order.OrderStatus.READY,
"Check order status is still ready for extract"
)
Expand All @@ -211,7 +211,7 @@ def multi_extract_user_order(self):
response = self.client.put(url, {'extract_result': extract_file})
self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED, response.content)
self.assertEqual(
Order.objects.get(pk=self.config.order.id).status,
Order.objects.get(pk=self.config.order.id).order_status,
Order.OrderStatus.PROCESSED,
"Check order status is processed"
)
Expand Down
Loading

0 comments on commit bab952a

Please sign in to comment.