code refactoring (#12412)
gitea/passerelle-montpellier-encombrants/pipeline/head This commit looks good Details

This commit is contained in:
Serghei Mihai 2023-05-09 14:42:45 +02:00
parent 53c31986fd
commit 28d11bc31b
11 changed files with 132 additions and 169 deletions

View File

@ -1,29 +0,0 @@
# passerelle-montpellier-encombrants
# Copyright (C) 2015 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import django.apps
class AppConfig(django.apps.AppConfig):
name = 'passerelle_montpellier_encombrants'
def get_after_urls(self):
from . import urls
return urls.urlpatterns
default_app_config = 'passerelle_montpellier_encombrants.AppConfig'

View File

@ -14,10 +14,14 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import datetime
from django.db import models from django.db import models
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from passerelle.base.models import BaseResource from passerelle.base.models import BaseResource
from passerelle.utils.api import endpoint
from .utils import get_sector
class EncombrantsManagement(BaseResource): class EncombrantsManagement(BaseResource):
@ -26,20 +30,34 @@ class EncombrantsManagement(BaseResource):
class Meta: class Meta:
verbose_name = 'Gestion des encombrants Montpellier' verbose_name = 'Gestion des encombrants Montpellier'
@classmethod manager_view_template_name = 'passerelle_montpellier_encombrants/detail.html'
def get_icon_class(cls):
return 'ressources'
@classmethod @endpoint(
def get_verbose_name(cls): perm='can_access',
return cls._meta.verbose_name pattern=r'^(?P<insee>\w+)$',
parameters={
def get_absolute_url(self): 'adresse': {'description': _('Address')},
return reverse('montpellier-encombrants-view', kwargs={'slug': self.slug}) 'limit': {'description': _('Results number limit')},
},
@classmethod )
def get_add_url(cls): def available(self, request, insee, adresse=None, limit=None):
return reverse('montpellier-encombrants-add') sector = get_sector(insee, adresse)
if sector:
if datetime.datetime.today().weekday() == 4:
tomorrow = datetime.datetime.today() + datetime.timedelta(days=3)
elif datetime.datetime.today().weekday() == 5:
tomorrow = datetime.datetime.today() + datetime.timedelta(days=2)
else:
tomorrow = datetime.datetime.today() + datetime.timedelta(days=1)
collect_days = sector.collectday_set.filter(date__gt=tomorrow).order_by('date')
else:
collect_days = []
result = [
{'id': x.date.strftime('%Y-%m-%d'), 'text': x.date.strftime('%d/%m/%Y')} for x in collect_days
]
if limit is not None and limit.isnumeric():
result = result[: int(limit)]
return {'data': result}
class Sector(models.Model): class Sector(models.Model):
@ -50,6 +68,14 @@ class Sector(models.Model):
class Meta: class Meta:
verbose_name = _('Sector') verbose_name = _('Sector')
@classmethod
def get_verbose_name(cls):
return cls._meta.verbose_name
@property
def title(self):
return self
def __str__(self): def __str__(self):
communes = Commune.objects.filter(sector=self) communes = Commune.objects.filter(sector=self)
if not communes: if not communes:
@ -62,6 +88,17 @@ class Commune(models.Model):
insee = models.CharField(max_length=10, blank=False, verbose_name=_('INSEE Code')) insee = models.CharField(max_length=10, blank=False, verbose_name=_('INSEE Code'))
sector = models.ForeignKey(Sector, verbose_name=_('Sector'), on_delete=models.CASCADE) sector = models.ForeignKey(Sector, verbose_name=_('Sector'), on_delete=models.CASCADE)
class Meta:
verbose_name = _('Commune')
@classmethod
def get_verbose_name(cls):
return cls._meta.verbose_name
@property
def title(self):
return self
def __str__(self): def __str__(self):
return '%s (%s)' % (self.name, self.insee) return '%s (%s)' % (self.name, self.insee)
@ -78,6 +115,17 @@ class CollectDay(models.Model):
sector = models.ForeignKey(Sector, verbose_name=_('Sector'), on_delete=models.CASCADE) sector = models.ForeignKey(Sector, verbose_name=_('Sector'), on_delete=models.CASCADE)
date = models.DateField(verbose_name=_('Date')) date = models.DateField(verbose_name=_('Date'))
class Meta:
verbose_name = _('Collect day')
@classmethod
def get_verbose_name(cls):
return cls._meta.verbose_name
@property
def title(self):
return self
class Meta: class Meta:
ordering = ['date'] ordering = ['date']
unique_together = ('sector', 'date') unique_together = ('sector', 'date')

View File

@ -1,8 +0,0 @@
{% extends "passerelle/manage.html" %}
{% block breadcrumb %}
{{ block.super }}
{% if object.id %}
<a href="{{object.get_absolute_url}}">{{ object.title }}</a>
{% endif %}
{% endblock %}

View File

@ -1,6 +1,11 @@
{% extends "passerelle_montpellier_encombrants/base.html" %} {% extends "passerelle_montpellier_encombrants/detail.html" %}
{% load i18n %} {% load i18n %}
{% block breadcrumb %}
{{ block.super }}
<a href="{{object.get_absolute_url}}">{{ object.title }}</a>
{% endblock %}
{% block appbar %} {% block appbar %}
<h2>{% trans 'Collect Days' %}</h2> <h2>{% trans 'Collect Days' %}</h2>
<a rel="popup" href="{% url 'montpellier-encombrants-collectday-add' %}">{% trans 'New' %}</a> <a rel="popup" href="{% url 'montpellier-encombrants-collectday-add' %}">{% trans 'New' %}</a>

View File

@ -1,6 +1,11 @@
{% extends "passerelle_montpellier_encombrants/base.html" %} {% extends "passerelle_montpellier_encombrants/detail.html" %}
{% load i18n %} {% load i18n %}
{% block breadcrumb %}
{{ block.super }}
<a href="{{object.get_absolute_url}}">{{ object.title }}</a>
{% endblock %}
{% block appbar %} {% block appbar %}
<h2>{% trans 'Communes' %}</h2> <h2>{% trans 'Communes' %}</h2>
<a rel="popup" href="{% url 'montpellier-encombrants-commune-add' %}">{% trans 'New' %}</a> <a rel="popup" href="{% url 'montpellier-encombrants-commune-add' %}">{% trans 'New' %}</a>

View File

@ -1,14 +1,6 @@
{% extends "passerelle/manage/service_view.html" %} {% extends "passerelle/manage/service_view.html" %}
{% load i18n passerelle %} {% load i18n passerelle %}
{% block endpoints %}
<ul>
<li>{% trans 'Listing available days:' %} <a href="{% url 'montpellier-encombrants-available-days' slug=object.slug insee=34088 %}"
>{{ site_base_uri }}{% url 'montpellier-encombrants-view' slug=object.slug %}available/<i>&lt;insee&gt;</i></a></li>
</ul>
{% endblock %}
{% block description %} {% block description %}
{% if perms.passerelle_montpellier_encombrants.change_passerelle_montpellier_encombrants %} {% if perms.passerelle_montpellier_encombrants.change_passerelle_montpellier_encombrants %}
<div> <div>
@ -19,15 +11,6 @@
<li><a href="{% url 'montpellier-encombrants-commune-listing' %}">{% trans 'Communes' %}</a></li> <li><a href="{% url 'montpellier-encombrants-commune-listing' %}">{% trans 'Communes' %}</a></li>
<li><a href="{% url 'montpellier-encombrants-collectday-listing' %}">{% trans 'Collect Days' %}</a></li> <li><a href="{% url 'montpellier-encombrants-collectday-listing' %}">{% trans 'Collect Days' %}</a></li>
</ul> </ul>
</div> </div>
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block security %}
<p>
{% trans 'Accessing the listings is open, but posting requests is limited to the following API users:' %}
</p>
{% access_rights_table resource=object permission='can_post_request' %}
{% endblock %}

View File

@ -1,6 +1,12 @@
{% extends "passerelle_montpellier_encombrants/base.html" %} {% extends "passerelle_montpellier_encombrants/detail.html" %}
{% load i18n %} {% load i18n %}
{% block breadcrumb %}
{{ block.super }}
<a href="{{object.get_absolute_url}}">{{ object.title }}</a>
{% endblock %}
{% block appbar %} {% block appbar %}
<h2>{% trans 'Sectors' %}</h2> <h2>{% trans 'Sectors' %}</h2>
<a rel="popup" href="{% url 'montpellier-encombrants-sector-add' %}">{% trans 'New' %}</a> <a rel="popup" href="{% url 'montpellier-encombrants-sector-add' %}">{% trans 'New' %}</a>

View File

@ -20,31 +20,7 @@ from passerelle.urls_utils import app_enabled, decorated_includes, required
from .views import * from .views import *
public_urlpatterns = [
re_path(
r'^(?P<slug>[\w,-]+)/$',
EncombrantsManagementDetailView.as_view(),
name='montpellier-encombrants-view',
),
re_path(
r'^(?P<slug>[\w,-]+)/available/(?P<insee>\d+)$',
AvailableDaysView.as_view(),
name='montpellier-encombrants-available-days',
),
]
management_urlpatterns = [ management_urlpatterns = [
path('add', EncombrantsManagementCreateView.as_view(), name='montpellier-encombrants-add'),
re_path(
r'^(?P<slug>[\w,-]+)/edit$',
EncombrantsManagementUpdateView.as_view(),
name='montpellier-encombrants-edit',
),
re_path(
r'^(?P<slug>[\w,-]+)/delete$',
EncombrantsManagementDeleteView.as_view(),
name='montpellier-encombrants-delete',
),
path('sectors/', SectorListView.as_view(), name='montpellier-encombrants-sector-listing'), path('sectors/', SectorListView.as_view(), name='montpellier-encombrants-sector-listing'),
path('sectors/add', SectorCreateView.as_view(), name='montpellier-encombrants-sector-add'), path('sectors/add', SectorCreateView.as_view(), name='montpellier-encombrants-sector-add'),
re_path( re_path(
@ -85,14 +61,3 @@ management_urlpatterns = [
name='montpellier-encombrants-collectday-remove', name='montpellier-encombrants-collectday-remove',
), ),
] ]
urlpatterns = required(
app_enabled('passerelle_montpellier_encombrants'),
[
re_path(r'^montpellier-encombrants/', include(public_urlpatterns)),
re_path(
r'^manage/montpellier-encombrants/',
decorated_includes(login_required, include(management_urlpatterns)),
),
],
)

View File

@ -23,7 +23,6 @@ from django.core.mail import EmailMessage
from django.template.loader import get_template from django.template.loader import get_template
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from .models import Commune
from .ods import Workbook from .ods import Workbook
prefix_map = { prefix_map = {
@ -73,6 +72,8 @@ def prefix_cleanup(name):
def get_sector(insee, address=None): def get_sector(insee, address=None):
from .models import Commune
communes = Commune.objects.filter(insee=insee) communes = Commune.objects.filter(insee=insee)
for commune in communes: for commune in communes:
streets = commune.street_set.all() streets = commune.street_set.all()

View File

@ -36,31 +36,6 @@ from .models import CollectDay, Commune, EncombrantsManagement, Sector, Street
from .utils import get_sector, prefix_cleanup from .utils import get_sector, prefix_cleanup
class EncombrantsManagementDetailView(DetailView):
model = EncombrantsManagement
template_name = 'passerelle_montpellier_encombrants/detail.html'
class EncombrantsManagementCreateView(CreateView):
model = EncombrantsManagement
form_class = EncombrantsManagementForm
template_name = 'passerelle/manage/service_form.html'
class EncombrantsManagementUpdateView(UpdateView):
model = EncombrantsManagement
form_class = EncombrantsManagementUpdateForm
template_name = 'passerelle/manage/service_form.html'
class EncombrantsManagementDeleteView(DeleteView):
model = EncombrantsManagement
template_name = 'passerelle/manage/service_confirm_delete.html'
def get_success_url(self):
return reverse('manage-home')
class SectorListView(ListView): class SectorListView(ListView):
model = Sector model = Sector
@ -152,30 +127,6 @@ class CollectDayDeleteView(DeleteView):
success_url = reverse_lazy('montpellier-encombrants-collectday-listing') success_url = reverse_lazy('montpellier-encombrants-collectday-listing')
class AvailableDaysView(View, SingleObjectMixin):
model = EncombrantsManagement
def get(self, request, *args, **kwargs):
sector = get_sector(kwargs.get('insee'), request.GET.get('adresse'))
if sector:
if datetime.datetime.today().weekday() == 4:
tomorrow = datetime.datetime.today() + datetime.timedelta(days=3)
elif datetime.datetime.today().weekday() == 5:
tomorrow = datetime.datetime.today() + datetime.timedelta(days=2)
else:
tomorrow = datetime.datetime.today() + datetime.timedelta(days=1)
collect_days = sector.collectday_set.filter(date__gt=tomorrow).order_by('date')
else:
collect_days = []
limit = request.GET.get('limit')
result = [
{'id': x.date.strftime('%Y-%m-%d'), 'text': x.date.strftime('%d/%m/%Y')} for x in collect_days
]
if limit:
result = result[: int(limit)]
return passerelle_utils.response_for_json(request, {'data': result})
class StreetEditView(FormView): class StreetEditView(FormView):
form_class = StreetsForm form_class = StreetsForm
template_name = 'passerelle/manage/service_form.html' template_name = 'passerelle/manage/service_form.html'

View File

@ -2,10 +2,12 @@ import datetime
import json import json
from random import randint from random import randint
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase from django.test import TestCase
from django.test.client import Client from django.test.client import Client
from django.urls import reverse from django.urls import reverse
from django.utils.encoding import force_text from django.utils.encoding import force_text
from passerelle.base.models import AccessRight, ApiUser
from passerelle_montpellier_encombrants.models import ( from passerelle_montpellier_encombrants.models import (
CollectDay, CollectDay,
@ -41,6 +43,11 @@ class EncombrantsTestCase(TestCase):
self.instance = EncombrantsManagement.objects.create( self.instance = EncombrantsManagement.objects.create(
title='montpellier', slug='montpellier', description='encombrants' title='montpellier', slug='montpellier', description='encombrants'
) )
api, _ = ApiUser.objects.get_or_create(username='all', keytype='', key='')
obj_type = ContentType.objects.get_for_model(self.instance)
AccessRight.objects.update_or_create(
codename='can_access', apiuser=api, resource_type=obj_type, resource_pk=self.instance.pk
)
self.now = datetime.datetime.now() self.now = datetime.datetime.now()
for mail, insee, name in ( for mail, insee, name in (
('cournonsec@montpellier3m.fr', '34087', 'Cournonsec'), ('cournonsec@montpellier3m.fr', '34087', 'Cournonsec'),
@ -59,14 +66,18 @@ class EncombrantsTestCase(TestCase):
for commune in Commune.objects.all(): for commune in Commune.objects.all():
r = self.client.get( r = self.client.get(
reverse( reverse(
'montpellier-encombrants-available-days', 'generic-endpoint',
kwargs={'slug': self.instance.slug, 'insee': commune.insee}, kwargs={
'connector': 'passerelle-montpellier-encombrants',
'endpoint': 'available',
'slug': self.instance.slug,
'rest': commune.insee,
},
) )
) )
data = json.loads(force_text(r.content)) data = json.loads(force_text(r.content))
def test_collectdays_in_communes_with_street(self): def test_collectdays_in_communes_with_street(self):
maurin_sector = Sector.objects.create(contact_email='maurin@montpellier3m.fr') maurin_sector = Sector.objects.create(contact_email='maurin@montpellier3m.fr')
maurin_commune = Commune.objects.create(sector=maurin_sector, name='Maurin', insee='34970') maurin_commune = Commune.objects.create(sector=maurin_sector, name='Maurin', insee='34970')
@ -81,8 +92,13 @@ class EncombrantsTestCase(TestCase):
# Maurin # Maurin
r = self.client.get( r = self.client.get(
reverse( reverse(
'montpellier-encombrants-available-days', 'generic-endpoint',
kwargs={'slug': self.instance.slug, 'insee': '34970'}, kwargs={
'connector': 'passerelle-montpellier-encombrants',
'endpoint': 'available',
'slug': self.instance.slug,
'rest': '34970',
},
), ),
{'adresse': 'PLAN DU MAS DE SARDAN'}, {'adresse': 'PLAN DU MAS DE SARDAN'},
) )
@ -95,8 +111,13 @@ class EncombrantsTestCase(TestCase):
r = self.client.get( r = self.client.get(
reverse( reverse(
'montpellier-encombrants-available-days', 'generic-endpoint',
kwargs={'slug': self.instance.slug, 'insee': '34970'}, kwargs={
'connector': 'passerelle-montpellier-encombrants',
'endpoint': 'available',
'slug': self.instance.slug,
'rest': '34970',
},
), ),
{'adresse': 'ROUTE DEPARTEMENTALE 172'}, {'adresse': 'ROUTE DEPARTEMENTALE 172'},
) )
@ -107,8 +128,13 @@ class EncombrantsTestCase(TestCase):
r = self.client.get( r = self.client.get(
reverse( reverse(
'montpellier-encombrants-available-days', 'generic-endpoint',
kwargs={'slug': self.instance.slug, 'insee': '34970'}, kwargs={
'connector': 'passerelle-montpellier-encombrants',
'endpoint': 'available',
'slug': self.instance.slug,
'rest': '34970',
},
), ),
{'adresse': 'ROUTE DEPARTEMENTALE 172'}, {'adresse': 'ROUTE DEPARTEMENTALE 172'},
) )
@ -118,8 +144,13 @@ class EncombrantsTestCase(TestCase):
def test_collectdays_nonexisting_street(self): def test_collectdays_nonexisting_street(self):
r = self.client.get( r = self.client.get(
reverse( reverse(
'montpellier-encombrants-available-days', 'generic-endpoint',
kwargs={'slug': self.instance.slug, 'insee': '34970'}, kwargs={
'connector': 'passerelle-montpellier-encombrants',
'endpoint': 'available',
'slug': self.instance.slug,
'rest': '34970',
},
), ),
{'adresse': 'Nonexisting street'}, {'adresse': 'Nonexisting street'},
) )
@ -137,8 +168,13 @@ class EncombrantsTestCase(TestCase):
r = self.client.get( r = self.client.get(
reverse( reverse(
'montpellier-encombrants-available-days', 'generic-endpoint',
kwargs={'slug': self.instance.slug, 'insee': '34970'}, kwargs={
'connector': 'passerelle-montpellier-encombrants',
'endpoint': 'available',
'slug': self.instance.slug,
'rest': '34970',
},
), ),
{'adresse': 'route departementale 172'}, {'adresse': 'route departementale 172'},
) )