Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions api/cases/apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class InputSerializer(serializers.Serializer):
photos_urls = serializers.ListField(child=serializers.URLField())
location = inline_serializer(
fields={
"gov_id": serializers.IntegerField(),
"city_id": serializers.IntegerField(),
"gov": serializers.IntegerField(),
"city": serializers.IntegerField(),
"address": serializers.CharField(required=False),
"lon": serializers.DecimalField(
max_digits=9, decimal_places=6, required=False
Expand Down Expand Up @@ -65,11 +65,15 @@ class OutputSerializer(serializers.Serializer):
id = serializers.IntegerField()
type = serializers.CharField()
name = serializers.CharField(source="details.name")
gov = serializers.CharField(source="location.gov.name_ar")
city = serializers.CharField(source="location.city.name_ar")
photo = serializers.URLField(source="photo_urls")
location = inline_serializer(
fields={
"gov": serializers.CharField(source="gov.name_ar"),
"city": serializers.CharField(source="city.name_ar"),
}
)
photos = serializers.ListField(source="photo_urls")
last_seen = serializers.DateField(source="details.last_seen")
posted_at = serializers.DateField()
posted_at = serializers.DateTimeField()

def get(self, request):
# Make sure the filters are valid, if passed
Expand All @@ -92,11 +96,11 @@ class OutputSerializer(serializers.Serializer):
user = serializers.IntegerField()
type = serializers.CharField()
state = serializers.CharField(source="get_state_display")
photos_urls = serializers.ListField(child=serializers.URLField())
photos = serializers.ListField(source="photo_urls")
location = inline_serializer(
fields={
"gov_id": serializers.IntegerField(),
"city_id": serializers.IntegerField(),
"gov": serializers.CharField(),
"city": serializers.CharField(),
"address": serializers.CharField(),
"lon": serializers.DecimalField(
max_digits=9,
Expand Down
8 changes: 7 additions & 1 deletion api/cases/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,10 @@ class CaseFilter(django_filters.FilterSet):

class Meta:
model = Case
fields = ["type", "details__age", "details__last_seen", "location__gov", "name"]
fields = [
"type",
"details__age",
"details__last_seen",
"location__gov",
"details__name",
]
24 changes: 24 additions & 0 deletions api/cases/migrations/0006_auto_20220508_0416.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 3.2.13 on 2022-05-08 04:16

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('cases', '0005_alter_casedetails_last_seen'),
]

operations = [
migrations.AlterField(
model_name='casematch',
name='case',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_matches', to='cases.case'),
),
migrations.AlterField(
model_name='casematch',
name='match',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='new_matches', to='cases.case'),
),
]
7 changes: 4 additions & 3 deletions api/cases/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import datetime

from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django_fsm import FSMField, transition

Expand Down Expand Up @@ -39,6 +38,7 @@ class Types(models.TextChoices):
updated_at = models.DateTimeField(auto_now=True)
posted_at = models.DateTimeField(null=True, default=None, blank=True)
is_active = models.BooleanField(default=False, editable=False)
# TODO thumbnail

@property
def photo_urls(self):
Expand Down Expand Up @@ -73,8 +73,9 @@ def archive(self):
def activate_again(self):
self.is_active = True

# FIXME
def publish(self):
self.posted_at = datetime.now()
self.posted_at = timezone.now()


class CaseDetails(models.Model):
Expand Down
12 changes: 6 additions & 6 deletions api/cases/selectors.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
from django.core.exceptions import PermissionDenied
from django.db.models import Q
from django.db.models.query import Q, QuerySet
from django.shortcuts import get_object_or_404

from api.common.utils import get_object
from api.users.models import User

from .filters import CaseFilter
from .models import Case, CaseMatch


def get_case(*, pk: int, fetched_by: User) -> Case:
case = get_object(Case, pk=pk)
case = get_object_or_404(Case, pk=pk)

if not (case.is_active or fetched_by == case.user):
raise PermissionDenied()

return case


def list_case(*, filters=None):
def list_case(*, filters=None) -> QuerySet[Case]:
filters = filters or {}

# TODO Switch to posted cases only
Expand All @@ -30,8 +30,8 @@ def list_user_case(*, user: User):
return user.cases.all()


def list_case_match(*, pk: int, fetched_by: User):
case = get_object(Case, pk=pk)
def list_case_match(*, pk: int, fetched_by: User) -> QuerySet[Case]:
case = get_object_or_404(Case, pk=pk)

if fetched_by != case.user:
raise PermissionDenied()
Expand Down
6 changes: 3 additions & 3 deletions api/locations/selectors.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from typing import Iterable
from django.db.models.query import QuerySet

from .models import City, Governorate


def list_governorate() -> Iterable[Governorate]:
def list_governorate() -> QuerySet[Governorate]:
return Governorate.objects.all()


def list_cities() -> Iterable[City]:
def list_cities() -> QuerySet[City]:
return City.objects.all()
48 changes: 24 additions & 24 deletions api/locations/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from django.conf import settings
from django.shortcuts import get_object_or_404
from rest_framework.exceptions import ValidationError

from api.common.services import model_update
from api.locations.models import City, Governorate, Location
Expand Down Expand Up @@ -48,44 +47,45 @@ def create_location(
lon: Optional[float] = None,
lat: Optional[float] = None,
address: Optional[str] = None,
gov_id: int,
city_id: int,
gov: int,
city: int,
) -> Location:

gov = Governorate.objects.get(pk=gov_id)
city = City.objects.get(pk=city_id)
loc = Location(lon=lon, lat=lat, address=address, gov=gov, city=city)
loc.full_clean()
# loc.clean()
loc.save()
# Fetch Governorate & City
gov = Governorate.objects.get(pk=gov)
city = City.objects.get(pk=city)

return loc
# Pack location data for validation
location = Location(lon=lon, lat=lat, address=address, gov=gov, city=city)

# Data validation
location.full_clean()

# Save location instance to the database
location.save()

return location


def update_location(
*,
location_id: int,
location: Location,
data: Dict,
) -> Location:

fields = ["lon", "lat", "address", "gov", "city"]
location = get_object_or_404(Location, pk=location_id)

gov_id = data.get("gov_id")
city_id = data.get("city_id")

gov = get_object_or_404(Governorate, pk=gov_id)
city = get_object_or_404(City, pk=city_id)
# Fetch Governorate & City if given
gov_id, city_id = data.get("gov"), data.get("city")

if city.gov != gov:
raise ValidationError("City does not belong to Governorate")
if gov_id:
data["gov"] = get_object_or_404(Governorate, pk=gov_id)
if city_id:
data["city"] = get_object_or_404(City, pk=city_id)

data["gov"] = gov
data["city"] = city
non_side_effect_fields = ["lon", "lat", "address", "gov", "city"]

location, _ = model_update(
instance=location,
fields=fields,
fields=non_side_effect_fields,
data=data,
)

Expand Down
41 changes: 22 additions & 19 deletions api/users/apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ class InputSerializer(serializers.Serializer):
username = serializers.CharField()
password = serializers.CharField()
name = serializers.CharField()
email = serializers.EmailField(required=False)
gov_id = serializers.IntegerField()
city_id = serializers.IntegerField()
location = inline_serializer(
fields={
"gov": serializers.IntegerField(),
"city": serializers.IntegerField(),
}
)
fcm_token = serializers.CharField()
firebase_token = serializers.CharField()

Expand All @@ -35,22 +38,11 @@ class DetailUserApi(APIView):
class OutputSerializer(serializers.Serializer):
username = serializers.CharField()
name = serializers.CharField()
email = serializers.CharField()
location = inline_serializer(
fields={
"address": serializers.CharField(),
"gov": inline_serializer(
fields={
"name_ar": serializers.CharField(),
"name_en": serializers.CharField(),
}
),
"city": inline_serializer(
fields={
"name_ar": serializers.CharField(),
"name_en": serializers.CharField(),
}
),
"gov": serializers.CharField(source="gov.name_ar"),
"city": serializers.CharField(source="city.name_ar"),
}
)

Expand All @@ -65,9 +57,20 @@ class UpdateUserApi(APIView):

class InputSerializer(serializers.Serializer):
name = serializers.CharField(required=False)
email = serializers.CharField(required=False)
gov_id = serializers.IntegerField(required=False)
city_id = serializers.IntegerField(required=False)
location = inline_serializer(
fields={
"gov": serializers.IntegerField(),
"city": serializers.IntegerField(),
"address": serializers.CharField(required=False),
"lon": serializers.DecimalField(
max_digits=9, decimal_places=6, required=False
),
"lat": serializers.DecimalField(
max_digits=8, decimal_places=6, required=False
),
},
required=False,
)

def post(self, request, user_id):
serializer = self.InputSerializer(data=request.data)
Expand Down
18 changes: 18 additions & 0 deletions api/users/migrations/0003_alter_user_email.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.13 on 2022-05-08 04:16

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('users', '0002_remove_user_id_photo_url'),
]

operations = [
migrations.AlterField(
model_name='user',
name='email',
field=models.EmailField(blank=True, max_length=254, verbose_name='email address'),
),
]
1 change: 0 additions & 1 deletion api/users/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ class User(AbstractUser):
last_name = None # type: ignore

name = models.CharField(max_length=256)
email = models.EmailField(null=True, blank=True)
username = models.CharField(max_length=10, unique=True, validators=[is_phone])

id_exp_date = models.DateTimeField(null=True, blank=True)
Expand Down
Loading