Skip to content

Commit

Permalink
Merge pull request #164 from fga-eps-mds/feature/67-tree-registration
Browse files Browse the repository at this point in the history
Cadastro de Árvore
  • Loading branch information
shayanealcantara authored Nov 11, 2019
2 parents ef2437b + e76401b commit f946667
Show file tree
Hide file tree
Showing 26 changed files with 1,132 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ media
.vscode/
env/
.env-staging

pictures/
# Ignore automatic migrations
src/*/migrations/*_auto_*.py
src/*/migrations/*_merge_*.py
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ flake8==3.7.8
djangorestframework-simplejwt==4.3.0
coverage==4.5.4
django-localflavor==2.2
whitenoise
pillow
whitenoise
4 changes: 2 additions & 2 deletions src/acacia/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import os
from django.utils.translation import ugettext_lazy as _
from .wait_db import start_services
from datetime import timedelta

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
Expand Down Expand Up @@ -52,6 +53,7 @@
'users',
'harvest',
'property',
'tree'
]

INSTALLED_APPS = DEFAULT_APPS + THIRD_PARTY_APPS + LOCAL_APPS
Expand Down Expand Up @@ -177,8 +179,6 @@
"https://acacia-staging.herokuapp.com",
]

from datetime import timedelta

SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(days=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=10),
Expand Down
1 change: 1 addition & 0 deletions src/acacia/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from django.urls import path, include
from .helpers import list_all_endpoints


urlpatterns = [
path('admin/', admin.site.urls),
path('users/', include('users.urls')),
Expand Down
2 changes: 1 addition & 1 deletion src/harvest/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 2.2.4 on 2019-11-04 19:07
# Generated by Django 2.2.4 on 2019-11-11 10:58

from django.db import migrations, models
import django.db.models.deletion
Expand Down
2 changes: 1 addition & 1 deletion src/property/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 2.2.4 on 2019-10-26 18:43
# Generated by Django 2.2.4 on 2019-11-11 10:58

from django.conf import settings
from django.db import migrations, models
Expand Down
1 change: 0 additions & 1 deletion src/property/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from django.db import models
from django.utils.translation import ugettext as _
from localflavor.br.br_states import STATE_CHOICES

from users.models import User


Expand Down
10 changes: 9 additions & 1 deletion src/property/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@
from django.utils.translation import ugettext as _
from .models import Property

from tree.serializers import TreeSerializer


class PropertySerializer(ModelSerializer):

trees = TreeSerializer(
many=True,
read_only=True
)

class Meta:
model = Property
fields = (
'id',
'pk',
'type_of_address',
'BRZipCode',
'state',
Expand All @@ -18,6 +25,7 @@ class Meta:
'address',
'complement',
'reference_point',
'trees',
)

# Customizing error messages
Expand Down
17 changes: 13 additions & 4 deletions src/property/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def setUp(self):

self.url_detail = reverse(
'property:property-detail',
kwargs={'pk': self.property.id}
kwargs={'pk': self.property.pk}
)

self.url_list = reverse(
Expand All @@ -74,21 +74,30 @@ def test_list_property(self):
def test_delete_property(self):
request = self.factory.delete(self.url_detail)
force_authenticate(request, user=self.user)
response = self.view_detail(request, pk=self.property.id)
response = self.view_detail(
request,
pk=self.property.pk
)
self.assertEqual(204, response.status_code)

def test_retrieve_property(self):
request = self.factory.get(self.url_detail)
force_authenticate(request, user=self.user)
response = self.view_detail(request, pk=self.property.id)
response = self.view_detail(
request,
pk=self.property.pk
)
self.assertEqual(200, response.status_code)
self.assertDictContainsSubset(self.data, response.data)

def test_update_property(self):
self.data['state'] = 'GO'
request = self.factory.patch(self.url_detail, self.data)
force_authenticate(request, user=self.user)
response = self.view_detail(request, pk=self.property.id)
response = self.view_detail(
request,
pk=self.property.pk
)
self.assertEqual(200, response.status_code)
self.assertEqual(response.data['state'], self.data['state'])
self.assertDictContainsSubset(self.data, response.data)
13 changes: 7 additions & 6 deletions src/property/urls.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from django.urls import path, include
from .viewsets import PropertyViewSet
from rest_framework.routers import DefaultRouter
from rest_framework import routers

router = DefaultRouter()
router.register(r'', PropertyViewSet, base_name='property')

app_name = 'property'

urlpatterns = [
]
router = routers.SimpleRouter()
router.register(r'', PropertyViewSet, basename='property')

urlpatterns += router.urls
urlpatterns = [
path('<int:property_pk>/trees/', include('tree.urls')),
] + router.urls
7 changes: 3 additions & 4 deletions src/property/viewsets.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import ModelViewSet

from users.models import User

from .serializers import PropertySerializer
from .permissions import UserIsPropertyOwner
from .serializers import PropertySerializer
from users.models import User
from .models import Property


class PropertyViewSet(ModelViewSet):
serializer_class = PropertySerializer
queryset = Property.objects.all()
pk_url_kwarg = 'property_pk'

permission_classes = (
IsAuthenticated,
Expand Down
Empty file added src/tree/__init__.py
Empty file.
5 changes: 5 additions & 0 deletions src/tree/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.contrib import admin
from .models import Tree, HarvestMonth

admin.site.register(Tree)
admin.site.register(HarvestMonth)
5 changes: 5 additions & 0 deletions src/tree/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class TreeConfig(AppConfig):
name = 'tree'
41 changes: 41 additions & 0 deletions src/tree/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Generated by Django 2.2.4 on 2019-11-11 10:58

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


class Migration(migrations.Migration):

initial = True

dependencies = [
('property', '0001_initial'),
]

operations = [
migrations.CreateModel(
name='Tree',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('tree_type', models.CharField(choices=[('Avocado', 'Avocado'), ('Pineapple', 'Pineapple'), ('Banana', 'Banana'), ('Persimmon', 'Persimmon'), ('Coconut', 'Coconut'), ('FIG', 'FIG'), ('Guava', 'Guava'), ('Jabuticaba', 'Jabuticaba'), ('Orange', 'Orange'), ('Lemon', 'Lemon'), ('Apple', 'Apple'), ('Papaya', 'Papaya'), ('Mango', 'Mango'), ('Passion Fruit', 'Passion Fruit'), ('Quince', 'Quince'), ('Nectarine', 'Nectarine'), ('Loquat', 'Loquat'), ('Pear', 'Pear'), ('Pequizeiro', 'Pequizeiro'), ('Tangerine', 'Tangerine'), ('Peach', 'Peach'), ('Vine', 'Vine')], max_length=13, verbose_name='Tree of type')),
('number_of_tree', models.IntegerField(default=1, verbose_name='Number of tree')),
('tree_height', models.DecimalField(decimal_places=1, max_digits=3, verbose_name='Average tree height')),
('property', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='trees', to='property.Property', verbose_name='Property trees')),
],
options={
'unique_together': {('property', 'tree_type')},
},
),
migrations.CreateModel(
name='HarvestMonth',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('harvest_month', models.CharField(choices=[('January', 'January'), ('February', 'February'), ('March', 'March'), ('April', 'April'), ('May', 'May'), ('June', 'June'), ('July', 'July'), ('August', 'August'), ('September', 'September'), ('October', 'October'), ('November', 'November'), ('December', 'December')], max_length=9, verbose_name='Harvest month')),
('tree', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='harvest_months', to='tree.Tree')),
],
options={
'verbose_name_plural': 'Harvest Months',
'unique_together': {('tree', 'harvest_month')},
},
),
]
Empty file added src/tree/migrations/__init__.py
Empty file.
118 changes: 118 additions & 0 deletions src/tree/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
from django.db import models
from django.utils.translation import ugettext as _
from property.models import Property


class Tree(models.Model):

class Meta:
unique_together = ('property', 'tree_type')

property = models.ForeignKey(
Property,
on_delete=models.CASCADE,
verbose_name=_('Property trees'),
related_name=_('trees'),
)

TYPE_OF_TREES = (
(_('Avocado'), _('Avocado')),
(_('Pineapple'), _('Pineapple')),
(_('Banana'), _('Banana')),
(_('Persimmon'), _('Persimmon')),
(_('Coconut'), _('Coconut')),
(_('FIG'), _('FIG')),
(_('Guava'), _('Guava')),
(_('Jabuticaba'), _('Jabuticaba')),
(_('Orange'), _('Orange')),
(_('Lemon'), _('Lemon')),
(_('Apple'), _('Apple')),
(_('Papaya'), _('Papaya')),
(_('Mango'), _('Mango')),
(_('Passion Fruit'), _('Passion Fruit')),
(_('Quince'), _('Quince')),
(_('Nectarine'), _('Nectarine')),
(_('Loquat'), _('Loquat')),
(_('Pear'), _('Pear')),
(_('Pequizeiro'), _('Pequizeiro')),
(_('Tangerine'), _('Tangerine')),
(_('Peach'), _('Peach')),
(_('Vine'), _('Vine')),
)

tree_type = models.CharField(
verbose_name=_('Tree of type'),
choices=TYPE_OF_TREES,
max_length=13,
)

number_of_tree = models.IntegerField(
verbose_name=_('Number of tree'),
default=1,
)

tree_height = models.DecimalField(
verbose_name=_('Average tree height'),
decimal_places=1,
max_digits=3,
)

picture = models.ImageField(upload_to='static/trees', blank=True,
null=True)

def __str__(self):
return (f"{self.pk}, " +
f"{self.tree_type}, " +
f"{self.number_of_tree}")

@staticmethod
def valid_tree_types():
"""
This class method returns a list of valid address
types
"""
return [k for k, v in Tree.TYPE_OF_TREES]


class HarvestMonth(models.Model):
class Meta:
verbose_name_plural = _('Harvest Months')
unique_together = ('tree', 'harvest_month')

tree = models.ForeignKey(
Tree,
models.CASCADE,
related_name=_('harvest_months'),
)

MONTHS = (
(_('January'), _('January')),
(_('February'), _('February')),
(_('March'), _('March')),
(_('April'), _('April')),
(_('May'), _('May')),
(_('June'), _('June')),
(_('July'), _('July')),
(_('August'), _('August')),
(_('September'), _('September')),
(_('October'), _('October')),
(_('November'), _('November')),
(_('December'), _('December')),
)

harvest_month = models.CharField(
choices=MONTHS,
verbose_name=_('Harvest month'),
max_length=9,
)

def __str__(self):
return f'{self.harvest_month}'

@staticmethod
def valid_months():
"""
This class method returns a list of valid address
types
"""
return [k for k, v in HarvestMonth.MONTHS]
Loading

0 comments on commit f946667

Please sign in to comment.