Commit fe2d0e91 authored by Hypsug0's avatar Hypsug0
Browse files

feat: Add links to session

parent fe975364
from django.db import models
from django.utils.translation import ugettext_lazy as _
# Create your models here.
class TypeLink(models.Model):
id_type_link = models.AutoField(primary_key=True, db_index=True)
label = models.CharField(
verbose_name=_("Type de lien"), max_length=255, db_index=True, unique=True, null=False
)
desc = models.TextField(verbose_name=_("Description"), null=True, blank=True)
class Links(models.Model):
id_link = models.AutoField(primary_key=True, db_index=True)
link = models.URLField(verbose_name=_("Lien internet (URL)"), null=False)
desc = models.TextField(verbose_name=_("Description"), null=True, blank=True)
......@@ -2018,4 +2018,20 @@
<field name="category" type="CharField">-</field>
<field name="label" type="CharField">Autres (préciser en commentaires)</field>
</object>
<object model="dicts.linktype" pk="1">
<field name="code" type="CharField">vc_session</field>
<field name="label" type="CharField">[Vigie-Chiro] Session</field>
</object>
<object model="dicts.linktype" pk="2">
<field name="code" type="CharField">document</field>
<field name="label" type="CharField">Document en ligne</field>
</object>
<object model="dicts.linktype" pk="3">
<field name="code" type="CharField">blog</field>
<field name="label" type="CharField">Blog</field>
</object>
<object model="dicts.linktype" pk="4">
<field name="code" type="CharField">other</field>
<field name="label" type="CharField">Autre</field>
</object>
</django-objects>
\ No newline at end of file
from django.contrib.gis.db import models
from django.utils.translation import ugettext_lazy as _
from django.db import models
from django.utils.translation import ugettext_lazy as _
# Create your models here.
......@@ -274,13 +273,25 @@ class TreeBecoming(models.Model):
return self.descr
class Meta:
verbose_name_plural = "ionnaire des devenirs des arbres"
verbose_name_plural = "Dictionnaire des devenirs des arbres"
class LinkType(models.Model):
"""Types d'hyperliens"""
id = models.AutoField(primary_key=True)
code = models.CharField(max_length=20, verbose_name=_("Code du type de lien"))
label = models.CharField(max_length=50, verbose_name=_("Description"))
def __str__(self):
return self.label
class Meta:
verbose_name_plural = "Dictionnaire des types de hyperliens"
class Contact(models.Model):
"""
ionnaire des types de contacts
"""
"""Dictionnaire des types de contacts"""
id = models.IntegerField(primary_key=True)
code = models.CharField(max_length=6, verbose_name=_("Code du contact"))
......@@ -392,9 +403,7 @@ class PropertyDomain(models.Model):
class CountPrecision(models.Model):
id = models.IntegerField(primary_key=True)
contact = models.CharField(
max_length=5, verbose_name=_("type de contacts"), default="0"
)
contact = models.CharField(max_length=5, verbose_name=_("type de contacts"), default="0")
code = models.CharField(max_length=10)
descr = models.CharField(max_length=50)
......@@ -420,9 +429,7 @@ class TypeDevice(models.Model):
class CountUnit(models.Model):
id = models.IntegerField(primary_key=True)
contact = models.CharField(
max_length=5, verbose_name=_("type de contacts"), default="0"
)
contact = models.CharField(max_length=5, verbose_name=_("type de contacts"), default="0")
code = models.CharField(max_length=10)
descr = models.CharField(max_length=50)
......@@ -621,9 +628,7 @@ class BiomDent(models.Model):
class PlaceManagementAction(models.Model):
id = models.IntegerField(primary_key=True)
code = models.CharField(max_length=5, verbose_name=_("Code des actions de gestion"))
category = models.CharField(
max_length=100, verbose_name=_("Catégorie d'action de gestion")
)
category = models.CharField(max_length=100, verbose_name=_("Catégorie d'action de gestion"))
label = models.CharField(max_length=250, verbose_name=_("Action de gestion"))
def __str__(self):
......@@ -640,15 +645,11 @@ class LandCoverCLC(models.Model):
label_lev3 = models.CharField(
max_length=150, verbose_name=_("Libelle Corine Land Cover (niv3)")
)
code_lev2 = models.CharField(
max_length=3, verbose_name=_("Code Corine Land Cover (niv2)")
)
code_lev2 = models.CharField(max_length=3, verbose_name=_("Code Corine Land Cover (niv2)"))
label_lev2 = models.CharField(
max_length=150, verbose_name=_("Libelle Corine Land Cover (niv2)")
)
code_lev1 = models.CharField(
max_length=3, verbose_name=_("Code Corine Land Cover (niv1)")
)
code_lev1 = models.CharField(max_length=3, verbose_name=_("Code Corine Land Cover (niv1)"))
label_lev1 = models.CharField(
max_length=150, verbose_name=_("Libelle Corine Land Cover (niv1)")
)
......
......@@ -11,7 +11,7 @@ from django.utils.translation import ugettext_lazy as _
from leaflet.forms.widgets import LeafletWidget
from core.forms import DangerAccordionGroup, InfoAccordionGroup, PrimaryAccordionGroup
from dicts.models import CountPrecision, CountUnit, Method, TypeDevice
from dicts.models import CountPrecision, CountUnit, LinkType, Method, TypeDevice
from management.models import Transmitter
from .models import (
......@@ -24,6 +24,7 @@ from .models import (
Place,
PlaceManagement,
Session,
SessionLink,
Sighting,
Tree,
TreeGite,
......@@ -1037,6 +1038,60 @@ class DeviceForm(forms.ModelForm):
self.fields["type"].queryset = TypeDevice.objects.filter(contact=contact)
class SessionLinkForm(forms.ModelForm):
class Meta:
model = SessionLink
fields = ("type_link", "link", "comment")
error_messages = {
NON_FIELD_ERRORS: {
"unique_together": "%(model_name)s's %(field_labels)s are not unique."
}
}
def __init__(self, *args, **kwargs):
self.helper = FormHelper()
self.helper.form_method = "post"
self.helper.form_action = "submit"
self.helper.layout = Layout(
Row(
Column(
Submit("submit", _("Enregistrer"), css_class="btn-primary btn-sm"),
Button(
"cancel",
_("Annuler"),
css_class="btn-warning btn-sm",
onclick="history.go(-1)",
),
css_class="col-lg-12 btn-group",
role="button",
)
),
Accordion(
PrimaryAccordionGroup(
"Informations",
Row(Column("type_link", css_class="col-lg-12")),
Row(Column("link", css_class="col-lg-12")),
Row(Column("comment", css_class="col-lg-12")),
)
),
Row(
Column(
Submit("submit", _("Enregistrer"), css_class="btn-primary btn-sm"),
Button(
"cancel",
_("Annuler"),
css_class="btn-warning btn-sm",
onclick="history.go(-1)",
),
css_class="col-lg-12 btn-group",
role="button",
)
),
)
super(SessionLinkForm, self).__init__(*args, **kwargs)
class SightingForm(forms.ModelForm):
class Meta:
model = Sighting
......
......@@ -100,11 +100,6 @@ class MetaPlace(gismodels.Model):
related_name="metaplace_modifier",
on_delete=models.SET_NULL,
)
links = models.ManyToManyField(
"core.Links",
related_name="metaplace_related",
related_query_name="metaplaces",
)
def __str__(self):
return "%s ∙ %s" % (self.name, self.type)
......@@ -245,11 +240,6 @@ class Place(models.Model):
verbose_name="Plan du site et/ou topo de la cavité",
)
comment = models.TextField(blank=True, null=True, verbose_name=_("Commentaire"))
links = models.ManyToManyField(
"core.Links",
related_name="place_related",
related_query_name="places",
)
other_imported_data = models.TextField(
blank=True, null=True, verbose_name=_("Autres données importées")
)
......@@ -357,11 +347,6 @@ class PlaceManagement(models.Model):
"Si vous voulez charger plusieurs fichiers, créez une archive avec un logiciel de compression comme 7zip"
),
)
links = models.ManyToManyField(
"core.Links",
related_name="place_management_related",
related_query_name="place_managements",
)
bdsource = models.CharField(max_length=100, blank=True, null=True)
id_bdsource = models.CharField(max_length=100, blank=True, null=True)
extra_data = JSONField(blank=True, null=True)
......@@ -860,11 +845,6 @@ class Session(models.Model):
# null=True,
# )
comment = models.TextField(blank=True, null=True, verbose_name=_("Commentaire"))
links = models.ManyToManyField(
"core.Links",
related_name="session_related",
related_query_name="sessions",
)
bdsource = models.CharField(max_length=100, blank=True, null=True)
id_bdsource = models.TextField(blank=True, null=True)
extra_data = JSONField(blank=True, null=True)
......@@ -918,6 +898,32 @@ class Session(models.Model):
unique_together = ["place", "contact", "date_start"]
class SessionLink(models.Model):
id_session_link = models.AutoField(verbose_name=_("id unique"), primary_key=True)
type_link = models.ForeignKey(
"dicts.LinkType", on_delete=models.DO_NOTHING, verbose_name=_("Type de lien")
)
link = models.URLField(null=False, verbose_name=_("Hyperlien"), help_text=_("http(s)://..."))
comment = models.CharField(
max_length=500, null=True, blank=True, verbose_name=_("Commentaire")
)
session = models.ForeignKey(
Session,
on_delete=models.CASCADE,
related_name="session_link_related",
related_query_name="session_links",
)
class Meta:
unique_together = [["link", "session"]]
def __str__(self):
return f"{self.type_link.label}{self.link}"
def get_absolute_url(self):
return reverse("sights:session_detail", kwargs={"pk": self.session.pk})
class Sighting(models.Model):
id_sighting = models.AutoField(_("id unique"), primary_key=True)
uuid = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
......
from django.urls import include, path
from django.contrib.auth.decorators import login_required
from django.urls import include, path
from django.views.generic import TemplateView
from sights.session.views import (
DeviceCreate,
DeviceDelete,
DeviceUpdate,
SessionChangePlaceUpdate,
SessionCreate,
SessionDetail,
SessionUpdate,
SessionDelete,
SessionDetail,
SessionLinkCreate,
SessionLinkDelete,
SessionLinkUpdate,
SessionMyList,
SessionChangePlaceUpdate,
DeviceCreate,
DeviceUpdate,
DeviceDelete,
SessionUpdate,
)
urlpatterns = [
# Session relative URLS
path("place/<int:pk>/session/add", SessionCreate.as_view(), name="session_create",),
path("session/<int:pk>/detail", SessionDetail.as_view(), name="session_detail",),
path("session/<int:pk>/update", SessionUpdate.as_view(), name="session_update",),
path(
"place/<int:pk>/session/add",
SessionCreate.as_view(),
name="session_create",
),
path(
"session/<int:pk>/detail",
SessionDetail.as_view(),
name="session_detail",
),
path(
"session/<int:pk>/update",
SessionUpdate.as_view(),
name="session_update",
),
path(
"session/<int:pk>/change_place",
SessionChangePlaceUpdate.as_view(),
name="sessionchangeplace_update",
),
path("session/<int:pk>/delete", SessionDelete.as_view(), name="session_delete",),
path(
"session/<int:pk>/delete",
SessionDelete.as_view(),
name="session_delete",
),
# Device relative URLS
path("session/<int:pk>/device/add", DeviceCreate.as_view(), name="device_create",),
path(
"session/<int:pk>/device/add",
DeviceCreate.as_view(),
name="device_create",
),
path("device/<int:pk>/update", DeviceUpdate.as_view(), name="device_update"),
path("device/<int:pk>/delete", DeviceDelete.as_view(), name="device_delete"),
path(
"session/<int:pk>/link/add",
SessionLinkCreate.as_view(),
name="sessionlink_create",
),
path("sessionlink/<int:pk>/update", SessionLinkUpdate.as_view(), name="sessionlink_update"),
path("sessionlink/<int:pk>/delete", SessionLinkDelete.as_view(), name="sessionlink_delete"),
]
......@@ -15,26 +15,11 @@ from django.views.generic.edit import CreateView, DeleteView, UpdateView
from django_tables2 import SingleTableView
from core import js
from ..forms import (
SessionChangePlaceForm,
SessionForm,
DeviceForm,
)
from ..mixins import (
SessionEditAuthMixin,
SessionViewAuthMixin,
SightingEditAuthMixin,
)
from ..models import (
Session,
Device,
Sighting,
)
from ..tables import (
SessionTable,
SessionDeviceTable,
SessionSightingTable,
)
from ..forms import DeviceForm, SessionChangePlaceForm, SessionForm, SessionLinkForm
from ..mixins import SessionEditAuthMixin, SessionViewAuthMixin, SightingEditAuthMixin
from ..models import Device, Session, SessionLink, Sighting
from ..tables import SessionDeviceTable, SessionSightingTable, SessionTable
IMAGE_FILE_TYPES = ["png", "jpg", "jpeg"]
DOCUMENT_FILE_TYPES = ["doc", "docx", "odt", "pdf"]
......@@ -152,9 +137,7 @@ class SessionDelete(SessionEditAuthMixin, DeleteView):
context = super(SessionDelete, self).get_context_data(**kwargs)
context["icon"] = "fa fa-fw fa-trash"
context["title"] = _("Suppression d'une session")
context["message_alert"] = _(
"Êtes-vous certain de vouloir supprimer la session"
)
context["message_alert"] = _("Êtes-vous certain de vouloir supprimer la session")
return context
......@@ -175,9 +158,7 @@ class SessionDetail(SessionViewAuthMixin, DetailView):
# Rendu des observations
context["sightingicon"] = "fa fa-eye fa-fw"
context["sightingtitle"] = _("Observations")
context["sightingcount"] = (
Sighting.objects.filter(session=pk).distinct().count()
)
context["sightingcount"] = Sighting.objects.filter(session=pk).distinct().count()
context["sightingtable"] = SessionSightingTable(
Sighting.objects.filter(session=pk).distinct().order_by("-timestamp_update")
)
......@@ -291,15 +272,76 @@ class DeviceDelete(SightingEditAuthMixin, DeleteView):
template_name = "confirm_delete.html"
def get_success_url(self):
return reverse_lazy(
"sights:session_detail", kwargs={"pk": self.object.session_id}
)
return reverse_lazy("sights:session_detail", kwargs={"pk": self.object.session_id})
def get_context_data(self, **kwargs):
context = super(DeviceDelete, self).get_context_data(**kwargs)
context["icon"] = "fa fa-fw fa-trash"
context["title"] = _("Suppression d'une dispositif d'échantillonage")
context["message_alert"] = _(
"Êtes-vous certain de vouloir supprimer le dispositif"
)
context["message_alert"] = _("Êtes-vous certain de vouloir supprimer le dispositif")
return context
class SessionLinkCreate(LoginRequiredMixin, CreateView):
model = SessionLink
form_class = SessionLinkForm
template_name = "normal_form.html"
# def get(self, request, *args, **kwargs):
# session = Session.objects.get(id_session=self.kwargs.get('pk'))
# self.form.fields['type'].queryset = TypeDevice.objects.filter(contact=session.contact.code)
# return super(DeviceCreate, self).get(request, *args, **kwargs)
def get_form_kwargs(self):
kwargs = super(SessionLinkCreate, self).get_form_kwargs()
session_id = self.kwargs.get("pk")
return kwargs
def form_valid(self, form):
form.instance.created_by = self.request.user
form.instance.session_id = self.kwargs.get("pk")
return super(SessionLinkCreate, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(SessionLinkCreate, self).get_context_data(**kwargs)
context["icon"] = "fi-link"
context["title"] = _("Ajout d'un lien")
context["js"] = ""
return context
class SessionLinkUpdate(SightingEditAuthMixin, UpdateView):
model = SessionLink
form_class = SessionLinkForm
template_name = "normal_form.html"
def get_form_kwargs(self):
kwargs = super(SessionLinkUpdate, self).get_form_kwargs()
session_id = self.object.session_id
return kwargs
def form_valid(self, form):
form.instance.updated_by = self.request.user
return super(SessionLinkUpdate, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(SessionLinkUpdate, self).get_context_data(**kwargs)
context["icon"] = "fi-link"
context["title"] = _("Modification d'un lien")
context["js"] = ""
return context
class SessionLinkDelete(SightingEditAuthMixin, DeleteView):
model = SessionLink
template_name = "confirm_delete.html"
def get_success_url(self):
return reverse_lazy("sights:session_detail", kwargs={"pk": self.object.session_id})
def get_context_data(self, **kwargs):
context = super(SessionLinkDelete, self).get_context_data(**kwargs)
context["icon"] = "fa fa-fw fa-trash"
context["title"] = _("Suppression d'une lien")
context["message_alert"] = _("Êtes-vous certain de vouloir supprimer le lien")
return context
......@@ -107,6 +107,26 @@
{% if object.study %}{{ object.study }}{% else %} Session non-attribuée à une étude {% endif %}
</div>
</div>
<div class="col-lg-12">
<label>Liens</label> <a href="{% url 'sights:sessionlink_create' pk=object.pk %}"
class="btn btn-xs btn-primary pull-right"><i class="fa fa-fw fa-plus"></i><span class="hidden-xs"> Ajouter</span></a>
<div class="well well-sm">
{% if object.session_link_related.count > 0%}
{% for link in object.session_link_related.all %}
<div class="btn-group btn-group-xs">
<a class="text-info" href="{% url 'sights:sessionlink_update' pk=link.pk %}" title="Editer"><i class="fa fa-fw fa-edit"></i></a>
<a class="text-danger" href="{% url 'sights:sessionlink_delete' pk=link.pk %}" title="Modifier" target="_blank"><i class="fa fa-fw fa-trash"></i></a>
</div>
<strong>{{link.type_link}}</strong>&nbsp;:&nbsp;<a href="{{link.link}}" target="_blank" data-toggle="tooltip" title="{{link.comment}}">{{link.link}}</a><br>
{% endfor %}
{% else %} - {% endif %}
</div>
</div>
{% if object.is_confidential %}
<div class="col-lg-12">
<div class="alert alert-danger" role="alert">
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment