Entities BaseListView
Criado uma ListView base e utilizada como padrão para exibir os registros cadastrados
This commit is contained in:
1 parent
24650484f1
commit
d3883669f3
31 files changed
+661
-515
No files matched your search
@@ -0,0 +1 @@
|
||||
404 not found
|
||||
@@ -1,48 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'css/layout/entity_home.css' %}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="entity_title">
|
||||
<h1>{{entity_name}}</h1>
|
||||
<form method="GET" action="{{entity_home_url}}" class="form_entity_search">
|
||||
{% if filter_query %}
|
||||
<a href="{{entity_home_url}}" class="btn-clear-filter">{{filter_query}}<i class="fa-solid fa-xmark"></i></a>
|
||||
{% endif %}
|
||||
<label for="entity_search">Buscar</label>
|
||||
<input type="text" name="entity_search" required>
|
||||
<button type="submit"><i class="fa-solid fa-magnifying-glass"></i></button>
|
||||
</form>
|
||||
<a href="{{entity_new_url}}">Novo <i class="fa-solid fa-plus"></i></a>
|
||||
</div>
|
||||
{% if not entities %}
|
||||
<p>Nenhum registro encontrado.</p>
|
||||
{% else %}
|
||||
<table>
|
||||
<tr>
|
||||
<th>Identificador</th>
|
||||
<th>Idade</th>
|
||||
<th>Peso</th>
|
||||
<th>Editar</th>
|
||||
<th>Excluir</th>
|
||||
</tr>
|
||||
{% for entity in entities %}
|
||||
<tr>
|
||||
<td>{{ animal.identifier }}</td>
|
||||
<td>{{ animal.age }}</td>
|
||||
<td>{{ animal.weight }} Kg</td>
|
||||
<td><a href="{% url 'entities:animal:animal_update' animal.id %}"><i class="fa-solid fa-pen-to-square"></i></a></td>
|
||||
<td>
|
||||
<form method="POST" action="{% url 'entities:animal:animal_delete' animal.id %}">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn-icon-trash"><i class="fa-solid fa-trash"></i></button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
<form method="post" action="{% url 'entities:user:farm_set_post' %}" class="navbar-farm-selector w33">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="next" value="{{ request.get_full_path }}">
|
||||
<input type="hidden" name="next" value="{{ request.path }}">
|
||||
<select name="farm_id" onchange="this.form.submit()">
|
||||
{% for farm in farms %}
|
||||
<option value="{{ farm.id }}" {% if farm.id == SELECTED_FARM.id %}selected{% endif %}>
|
||||
|
||||
@@ -12,32 +12,32 @@
|
||||
|
||||
<li class="sidebar-header">REGISTROS</li>
|
||||
|
||||
<li class="{% if request.resolver_match.url_name not in 'rotation_home, rotation_new, rotation_delete' %}highlight-hover{% endif %}">
|
||||
<a href="{% url 'entities:rotation:rotation_home' %}" class="sidebar-link {% if request.resolver_match.url_name in 'rotation_home, rotation_new, rotation_delete' %}active{% endif %}"><i class="fa-solid fa-arrows-spin"></i> Movimentações</a>
|
||||
<li class="{% if request.resolver_match.url_name not in 'rotation_home, rotation_create, rotation_delete' %}highlight-hover{% endif %}">
|
||||
<a href="{% url 'entities:rotation:rotation_home' %}" class="sidebar-link {% if request.resolver_match.url_name in 'rotation_home, rotation_create, rotation_delete' %}active{% endif %}"><i class="fa-solid fa-arrows-spin"></i> Movimentações</a>
|
||||
</li>
|
||||
|
||||
<li class="sidebar-header">CADASTROS</li>
|
||||
|
||||
<li class="{% if request.resolver_match.url_name not in 'animal_home, animal_new, animal_update, animal_delete' %}highlight-hover{% endif %}">
|
||||
<a href="{% url 'entities:animal:animal_home' %}" class="sidebar-link {% if request.resolver_match.url_name in 'animal_home, animal_new, animal_update, animal_delete' %}active{% endif %}"><i class="fa-solid fa-cow"></i> Animais</a>
|
||||
<li class="{% if request.resolver_match.url_name not in 'animal_list, animal_create, animal_update, animal_delete' %}highlight-hover{% endif %}">
|
||||
<a href="{% url 'entities:animal:animal_list' %}" class="sidebar-link {% if request.resolver_match.url_name in 'animal_list, animal_create, animal_update, animal_delete' %}active{% endif %}"><i class="fa-solid fa-cow"></i> Animais</a>
|
||||
</li>
|
||||
|
||||
<li class="{% if request.resolver_match.url_name not in 'batch_home, batch_new, batch_update, batch_delete' %}highlight-hover{% endif %}">
|
||||
<a href="{% url 'entities:animal:batch_home' %}" class="sidebar-link {% if request.resolver_match.url_name in 'batch_home, batch_new, batch_update, batch_delete' %}active{% endif %}"><i class="fa-solid fa-layer-group"></i> Lotes</a>
|
||||
<li class="{% if request.resolver_match.url_name not in 'batch_list, batch_create, batch_update, batch_delete' %}highlight-hover{% endif %}">
|
||||
<a href="{% url 'entities:animal:batch_list' %}" class="sidebar-link {% if request.resolver_match.url_name in 'batch_list, batch_create, batch_update, batch_delete' %}active{% endif %}"><i class="fa-solid fa-layer-group"></i> Lotes</a>
|
||||
</li>
|
||||
|
||||
<li class="{% if request.resolver_match.url_name not in 'paddock_home, paddock_new, paddock_update, paddock_delete' %}highlight-hover{% endif %}">
|
||||
<a href="{% url 'entities:farm:paddock_home' %}" class="sidebar-link {% if request.resolver_match.url_name in 'paddock_home, paddock_new, paddock_update, paddock_delete' %}active{% endif %}"><i class="fa-solid fa-leaf"></i> Piquetes</a>
|
||||
<li class="{% if request.resolver_match.url_name not in 'paddock_list, paddock_create, paddock_update, paddock_delete' %}highlight-hover{% endif %}">
|
||||
<a href="{% url 'entities:farm:paddock_list' %}" class="sidebar-link {% if request.resolver_match.url_name in 'paddock_list, paddock_create, paddock_update, paddock_delete' %}active{% endif %}"><i class="fa-solid fa-leaf"></i> Piquetes</a>
|
||||
</li>
|
||||
|
||||
<li class="{% if request.resolver_match.url_name not in 'paddock_group_home, paddock_group_new, paddock_group_update, paddock_group_delete' %}highlight-hover{% endif %}">
|
||||
<a href="{% url 'entities:farm:paddock_group_home' %}" class="sidebar-link {% if request.resolver_match.url_name in 'paddock_group_home, paddock_group_new, paddock_group_update, paddock_group_delete' %}active{% endif %}"><i class="fa-solid fa-layer-group"></i> Blocos</a>
|
||||
<li class="{% if request.resolver_match.url_name not in 'paddock_group_list, paddock_group_create, paddock_group_update, paddock_group_delete' %}highlight-hover{% endif %}">
|
||||
<a href="{% url 'entities:farm:paddock_group_list' %}" class="sidebar-link {% if request.resolver_match.url_name in 'paddock_group_list, paddock_group_create, paddock_group_update, paddock_group_delete' %}active{% endif %}"><i class="fa-solid fa-layer-group"></i> Blocos</a>
|
||||
</li>
|
||||
|
||||
<li class="sidebar-header">CONFIGURAÇÔES</li>
|
||||
|
||||
<li class="{% if request.resolver_match.url_name not in 'farm_home, farm_new, farm_update, farm_delete' %}highlight-hover{% endif %}">
|
||||
<a href="{% url 'entities:farm:farm_home' %}" class="sidebar-link {% if request.resolver_match.url_name in 'farm_home, farm_new, farm_update, farm_delete' %}active{% endif %}"><i class="fa-solid fa-gear"></i> Fazenda</a>
|
||||
<li class="{% if request.resolver_match.url_name not in 'farm_home, farm_create, farm_update, farm_delete' %}highlight-hover{% endif %}">
|
||||
<a href="{% url 'entities:farm:farm_home' %}" class="sidebar-link {% if request.resolver_match.url_name in 'farm_home, farm_create, farm_update, farm_delete' %}active{% endif %}"><i class="fa-solid fa-gear"></i> Fazenda</a>
|
||||
</li>
|
||||
{% if user.is_staff or user.is_superuser %}
|
||||
<li class="{% if request.resolver_match.url_name not in 'admin' %}highlight-hover{% endif %}">
|
||||
|
||||
File renamed without changes.
@@ -0,0 +1,22 @@
|
||||
from django import template
|
||||
|
||||
register = template.Library()
|
||||
|
||||
"""
|
||||
Allows dinamic access to object attributes in templates.
|
||||
Exemple:
|
||||
{{ obj|get_attr:"name" }}
|
||||
"""
|
||||
@register.filter
|
||||
def get_attr(obj, attr):
|
||||
try:
|
||||
value = getattr(obj, attr)
|
||||
|
||||
if callable(value):
|
||||
value = value()
|
||||
|
||||
# If none, return empty string to avoid displaying "None" in the template
|
||||
return value if value is not None else ""
|
||||
|
||||
except Exception:
|
||||
return ""
|
||||
@@ -12,39 +12,14 @@ def get_selected_farm(request):
|
||||
|
||||
|
||||
# Animal Services
|
||||
def get_animal_home_context(request):
|
||||
selected_farm = get_selected_farm(request)
|
||||
|
||||
context = {}
|
||||
context['title'] = 'Animais'
|
||||
context['farm'] = selected_farm
|
||||
|
||||
animals = Animal.objects.filter(
|
||||
farm=selected_farm,
|
||||
is_active=True
|
||||
)
|
||||
|
||||
filter_query = request.GET.get('animal_search')
|
||||
|
||||
if filter_query:
|
||||
context['filter_query'] = filter_query
|
||||
animals = animals.filter(
|
||||
identifier__icontains=filter_query
|
||||
)
|
||||
|
||||
context['animals'] = animals
|
||||
|
||||
return context
|
||||
|
||||
|
||||
def get_animal_new_context():
|
||||
form = AnimalCreateForm()
|
||||
|
||||
context = {}
|
||||
context['title'] = 'Novo animal'
|
||||
context['form'] = form
|
||||
context['action_url'] = reverse('entities:animal:animal_new')
|
||||
context['return_url'] = reverse('entities:animal:animal_home')
|
||||
context['action_url'] = reverse('entities:animal:animal_create')
|
||||
context['return_url'] = reverse('entities:animal:animal_list')
|
||||
|
||||
return context
|
||||
|
||||
@@ -72,7 +47,7 @@ def update_animal(request, animal_id):
|
||||
'entities:animal:animal_update',
|
||||
kwargs={'animal_id': animal.pk}
|
||||
)
|
||||
context['return_url'] = reverse('entities:animal:animal_home')
|
||||
context['return_url'] = reverse('entities:animal:animal_list')
|
||||
|
||||
if request.method == 'GET':
|
||||
form = AnimalEditForm(instance=animal)
|
||||
@@ -82,7 +57,7 @@ def update_animal(request, animal_id):
|
||||
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return {'redirect': 'entities:animal:animal_home'}
|
||||
return {'redirect': 'entities:animal:animal_list'}
|
||||
|
||||
context['form'] = form
|
||||
|
||||
@@ -97,34 +72,6 @@ def delete_animal(request, animal_id):
|
||||
|
||||
|
||||
# Batch Services
|
||||
|
||||
def get_batch_home_context(request):
|
||||
selected_farm = get_selected_farm(request)
|
||||
|
||||
context = {}
|
||||
context['title'] = 'Lotes'
|
||||
context['farm'] = selected_farm
|
||||
|
||||
all_batches = Batch.objects.filter(
|
||||
batchanimal__animal__farm=selected_farm,
|
||||
is_active=True
|
||||
).distinct().prefetch_related(
|
||||
Prefetch('animals', queryset=Animal.objects.filter(is_active=True))
|
||||
)
|
||||
|
||||
filter_query = request.GET.get('batch_search')
|
||||
|
||||
if filter_query:
|
||||
context['filter_query'] = filter_query
|
||||
all_batches = all_batches.filter(
|
||||
identifier__icontains=filter_query
|
||||
)
|
||||
|
||||
context['batches'] = all_batches
|
||||
|
||||
return context
|
||||
|
||||
|
||||
def create_batch(request):
|
||||
selected_farm = get_selected_farm(request)
|
||||
|
||||
@@ -138,8 +85,8 @@ def create_batch(request):
|
||||
context = {
|
||||
'title': 'Novo Lote',
|
||||
'form': form,
|
||||
'action_url': reverse('entities:animal:batch_new'),
|
||||
'return_url': reverse('entities:animal:batch_home')
|
||||
'action_url': reverse('entities:animal:batch_create'),
|
||||
'return_url': reverse('entities:animal:batch_list')
|
||||
}
|
||||
|
||||
return {'context': context}
|
||||
@@ -152,7 +99,7 @@ def create_batch(request):
|
||||
batch.save()
|
||||
form.save_m2m()
|
||||
|
||||
return {'redirect': 'entities:animal:batch_home'}
|
||||
return {'redirect': 'entities:animal:batch_list'}
|
||||
|
||||
form.fields['animals'].queryset = Animal.objects.filter(
|
||||
farm=selected_farm,
|
||||
@@ -162,8 +109,8 @@ def create_batch(request):
|
||||
context = {
|
||||
'title': 'Novo Lote',
|
||||
'form': form,
|
||||
'action_url': reverse('entities:animal:batch_new'),
|
||||
'return_url': reverse('entities:animal:batch_home')
|
||||
'action_url': reverse('entities:animal:batch_create'),
|
||||
'return_url': reverse('entities:animal:batch_list')
|
||||
}
|
||||
|
||||
return {'context': context}
|
||||
@@ -175,7 +122,7 @@ def update_batch(request, batch_id):
|
||||
|
||||
context = {
|
||||
'title': f'Editar Lote {batch_old.identifier}',
|
||||
'return_url': reverse('entities:animal:batch_home')
|
||||
'return_url': reverse('entities:animal:batch_list')
|
||||
}
|
||||
|
||||
if request.method == 'GET':
|
||||
@@ -204,7 +151,7 @@ def update_batch(request, batch_id):
|
||||
batch_new.save()
|
||||
form.save_m2m()
|
||||
|
||||
return {'redirect': 'entities:animal:batch_home'}
|
||||
return {'redirect': 'entities:animal:batch_list'}
|
||||
|
||||
form.fields['animals'].queryset = Animal.objects.filter(
|
||||
farm=selected_farm,
|
||||
|
||||
@@ -33,8 +33,8 @@ def get_farm_new_context():
|
||||
context = {}
|
||||
context['title'] = 'Nova fazenda'
|
||||
context['form'] = form
|
||||
context['action_url'] = reverse('entities:farm:farm_new')
|
||||
context['return_url'] = reverse('entities:farm:farm_home')
|
||||
context['action_url'] = reverse('entities:farm:farm_create')
|
||||
context['return_url'] = reverse('entities:farm:farm_list')
|
||||
|
||||
return context
|
||||
|
||||
@@ -60,7 +60,7 @@ def update_farm(request, farm_id):
|
||||
'entities:farm:farm_update',
|
||||
kwargs={'farm_id': farm.pk}
|
||||
)
|
||||
context['return_url'] = reverse('entities:farm:farm_home')
|
||||
context['return_url'] = reverse('entities:farm:farm_list')
|
||||
|
||||
if request.method == 'GET':
|
||||
form = FarmEditForm(instance=farm)
|
||||
@@ -70,7 +70,7 @@ def update_farm(request, farm_id):
|
||||
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return {'redirect': 'entities:farm:farm_home'}
|
||||
return {'redirect': 'entities:farm:farm_list'}
|
||||
|
||||
context['form'] = form
|
||||
|
||||
@@ -84,32 +84,6 @@ def delete_farm(farm_id):
|
||||
|
||||
|
||||
# Paddock Services
|
||||
|
||||
def get_paddock_home_context(request):
|
||||
selected_farm = get_selected_farm(request)
|
||||
|
||||
context = {}
|
||||
context['title'] = 'Piquete'
|
||||
context['farm'] = selected_farm
|
||||
|
||||
all_paddocks = Paddock.objects.filter(
|
||||
farm=selected_farm,
|
||||
is_active=True
|
||||
)
|
||||
|
||||
filter_query = request.GET.get('paddock_search')
|
||||
|
||||
if filter_query:
|
||||
context['filter_query'] = filter_query
|
||||
all_paddocks = all_paddocks.filter(
|
||||
identifier__icontains=filter_query
|
||||
)
|
||||
|
||||
context['paddocks'] = all_paddocks
|
||||
|
||||
return context
|
||||
|
||||
|
||||
def create_paddock(request):
|
||||
selected_farm = get_selected_farm(request)
|
||||
|
||||
@@ -119,8 +93,8 @@ def create_paddock(request):
|
||||
context = {
|
||||
'title': 'Novo Piquete',
|
||||
'form': form,
|
||||
'action_url': reverse('entities:farm:paddock_new'),
|
||||
'return_url': reverse('entities:farm:paddock_home')
|
||||
'action_url': reverse('entities:farm:paddock_create'),
|
||||
'return_url': reverse('entities:farm:paddock_list')
|
||||
}
|
||||
|
||||
return {'context': context}
|
||||
@@ -133,13 +107,13 @@ def create_paddock(request):
|
||||
paddock.farm = selected_farm
|
||||
paddock.save()
|
||||
|
||||
return {'redirect': 'entities:farm:paddock_home'}
|
||||
return {'redirect': 'entities:farm:paddock_list'}
|
||||
|
||||
context = {
|
||||
'title': 'Novo Piquete',
|
||||
'form': form,
|
||||
'action_url': reverse('entities:farm:paddock_new'),
|
||||
'return_url': reverse('entities:farm:paddock_home')
|
||||
'action_url': reverse('entities:farm:paddock_create'),
|
||||
'return_url': reverse('entities:farm:paddock_list')
|
||||
}
|
||||
|
||||
return {'context': context}
|
||||
@@ -155,7 +129,7 @@ def update_paddock(request, paddock_id):
|
||||
'entities:farm:paddock_update',
|
||||
kwargs={'paddock_id': paddock.pk}
|
||||
)
|
||||
context['return_url'] = reverse('entities:farm:paddock_home')
|
||||
context['return_url'] = reverse('entities:farm:paddock_list')
|
||||
|
||||
if request.method == 'GET':
|
||||
form = PaddockEditForm(instance=paddock)
|
||||
@@ -165,7 +139,7 @@ def update_paddock(request, paddock_id):
|
||||
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return {'redirect': 'entities:farm:paddock_home'}
|
||||
return {'redirect': 'entities:farm:paddock_list'}
|
||||
|
||||
context['form'] = form
|
||||
|
||||
@@ -179,34 +153,6 @@ def delete_paddock(paddock_id):
|
||||
|
||||
|
||||
# Paddock Group Services
|
||||
|
||||
def get_paddock_group_home_context(request):
|
||||
selected_farm = get_selected_farm(request)
|
||||
|
||||
context = {}
|
||||
context['title'] = 'Blocos'
|
||||
context['farm'] = selected_farm
|
||||
|
||||
all_paddock_groups = PaddockGroup.objects.filter(
|
||||
paddocks__farm=selected_farm,
|
||||
is_active=True
|
||||
).distinct().prefetch_related(
|
||||
Prefetch('paddocks', queryset=Paddock.objects.filter(is_active=True))
|
||||
)
|
||||
|
||||
filter_query = request.GET.get('paddock_group_search')
|
||||
|
||||
if filter_query:
|
||||
context['filter_query'] = filter_query
|
||||
all_paddock_groups = all_paddock_groups.filter(
|
||||
identifier__icontains=filter_query
|
||||
)
|
||||
|
||||
context['paddock_groups'] = all_paddock_groups
|
||||
|
||||
return context
|
||||
|
||||
|
||||
def create_paddock_group(request):
|
||||
selected_farm = get_selected_farm(request)
|
||||
|
||||
@@ -224,7 +170,7 @@ def create_paddock_group(request):
|
||||
paddock_group = form.save(commit=False)
|
||||
paddock_group.save()
|
||||
|
||||
return {'redirect': 'entities:farm:paddock_group_home'}
|
||||
return {'redirect': 'entities:farm:paddock_group_list'}
|
||||
|
||||
form.fields['paddocks'].queryset = Paddock.objects.filter(
|
||||
farm=selected_farm,
|
||||
@@ -234,8 +180,8 @@ def create_paddock_group(request):
|
||||
context = {
|
||||
'title': 'Novo Bloco',
|
||||
'form': form,
|
||||
'action_url': reverse('entities:farm:paddock_group_new'),
|
||||
'return_url': reverse('entities:farm:paddock_group_home')
|
||||
'action_url': reverse('entities:farm:paddock_group_create'),
|
||||
'return_url': reverse('entities:farm:paddock_group_list')
|
||||
}
|
||||
|
||||
return {'context': context}
|
||||
@@ -247,7 +193,7 @@ def update_paddock_group(request, paddock_group_id):
|
||||
|
||||
context = {
|
||||
'title': f'Editar Lote {paddock_group.identifier}',
|
||||
'return_url': reverse('entities:farm:paddock_group_home')
|
||||
'return_url': reverse('entities:farm:paddock_group_list')
|
||||
}
|
||||
|
||||
if request.method == 'GET':
|
||||
@@ -270,7 +216,7 @@ def update_paddock_group(request, paddock_group_id):
|
||||
paddock_group = form.save()
|
||||
paddock_group.save()
|
||||
|
||||
return {'redirect': 'entities:farm:paddock_group_home'}
|
||||
return {'redirect': 'entities:farm:paddock_group_list'}
|
||||
|
||||
form.fields['paddocks'].queryset = Paddock.objects.filter(
|
||||
farm=selected_farm,
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
/* PAGE HEADER */
|
||||
.entity_search {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-md);
|
||||
margin-bottom: var(--space-lg);
|
||||
margin-top: var(--space-lg);
|
||||
}
|
||||
|
||||
.entity_search h1 {
|
||||
font-size: var(--font-xl);
|
||||
color: var(--color-text-dark);
|
||||
margin: 0;
|
||||
margin-right: var(--space-lg);
|
||||
}
|
||||
|
||||
/* SEARCH FORM */
|
||||
.entity_search form {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-xs);
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.entity_search form label {
|
||||
font-size: var(--font-sm);
|
||||
color: var(--color-text-dark);
|
||||
}
|
||||
|
||||
/* Input com altura igual ao botão */
|
||||
.entity_search form input {
|
||||
height: 32px;
|
||||
padding: 0 var(--space-sm);
|
||||
font-size: var(--font-sm);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--border-radius-sm);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.entity_search form input:focus {
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
|
||||
/* Botão buscar */
|
||||
.entity_search form button {
|
||||
height: 32px;
|
||||
padding: 0 var(--space-sm);
|
||||
border: none;
|
||||
border-radius: var(--border-radius-sm);
|
||||
background: var(--color-primary);
|
||||
color: var(--color-text-light);
|
||||
cursor: pointer;
|
||||
transition: background var(--transition-speed);
|
||||
}
|
||||
|
||||
.entity_search form button:hover {
|
||||
background: var(--color-secondary);
|
||||
}
|
||||
|
||||
/* CLEAR FILTER */
|
||||
.btn-clear-filter {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
height: 32px;
|
||||
padding: 0 var(--space-sm);
|
||||
background: var(--color-danger-light);
|
||||
color: var(--color-danger);
|
||||
border-radius: var(--border-radius-sm);
|
||||
text-decoration: none;
|
||||
font-size: var(--font-sm);
|
||||
}
|
||||
|
||||
.btn-clear-filter:hover {
|
||||
background: var(--color-danger);
|
||||
color: var(--color-text-light);
|
||||
}
|
||||
|
||||
/* NEW BUTTON */
|
||||
.entity_search > a {
|
||||
height: 32px;
|
||||
padding: 0 var(--space-md);
|
||||
background: var(--color-success);
|
||||
color: var(--color-text-light);
|
||||
border-radius: var(--border-radius-sm);
|
||||
text-decoration: none;
|
||||
font-size: var(--font-sm);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-xs);
|
||||
transition: background var(--transition-speed);
|
||||
}
|
||||
|
||||
.entity_search > a:hover {
|
||||
background: var(--color-success);
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
/* TABLE */
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
background: var(--color-bg-white);
|
||||
border-radius: var(--border-radius-sm);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
table th {
|
||||
text-align: left;
|
||||
padding: var(--space-xs) var(--space-sm);
|
||||
font-size: var(--font-md);
|
||||
background: var(--color-bg-dark);
|
||||
color: var(--color-text-light);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
table td {
|
||||
padding: var(--space-xs);
|
||||
font-size: var(--font-md);
|
||||
border-bottom: 1px solid var(--color-border-subtle);
|
||||
}
|
||||
|
||||
table tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
table tbody tr:hover {
|
||||
background: var(--color-bg-light);
|
||||
}
|
||||
|
||||
/* Fixed width on the last two colluns */
|
||||
td:last-child,
|
||||
th:last-child {
|
||||
width: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
td:nth-last-child(2),
|
||||
th:nth-last-child(2) {
|
||||
width: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
td, th {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* ACTION ICONS */
|
||||
table a {
|
||||
color: var(--color-primary);
|
||||
transition: color var(--transition-speed);
|
||||
}
|
||||
|
||||
table a:hover {
|
||||
color: var(--color-secondary);
|
||||
}
|
||||
|
||||
/* DELETE BUTTON */
|
||||
.btn-icon-trash {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--color-danger);
|
||||
cursor: pointer;
|
||||
transition: color var(--transition-speed);
|
||||
}
|
||||
|
||||
.btn-icon-trash:hover {
|
||||
color: var(--color-danger);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
/* PAGINATION */
|
||||
.pagination {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
align-items: center;
|
||||
margin-top: var(--space-lg);
|
||||
font-size: var(--font-sm);
|
||||
}
|
||||
|
||||
.pagination .left {
|
||||
justify-self: end;
|
||||
display: flex;
|
||||
gap: var(--space-xs);
|
||||
}
|
||||
|
||||
.pagination .center {
|
||||
justify-self: center;
|
||||
white-space: nowrap;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.pagination .right {
|
||||
justify-self: start;
|
||||
display: flex;
|
||||
gap: var(--space-xs);
|
||||
}
|
||||
|
||||
.pagination a {
|
||||
padding: 3px 7px;
|
||||
background: var(--color-bg-light);
|
||||
border-radius: var(--border-radius-sm);
|
||||
text-decoration: none;
|
||||
color: var(--color-text-dark);
|
||||
transition: all var(--transition-speed);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<div class="active_rotaiton_card">
|
||||
<h4>Movimentação {rotation.id}</h4>
|
||||
<p>Lote {lote.name} atualmente no piquete {paddock.number} a {rotation.duration} atrás</p>
|
||||
<p>var = {{var}}</p>
|
||||
<a href="#vermais">Ver mais</a>
|
||||
</div>
|
||||
@@ -1,48 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'animal/css/animal.css' %}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="animal_title">
|
||||
<h1>Animais</h1>
|
||||
<form method="GET" action="{% url 'entities:animal:animal_home' %}" class="form_animal_search">
|
||||
{% if filter_query %}
|
||||
<a href="{% url 'entities:animal:animal_home' %}" class="btn-clear-filter">{{filter_query}}<i class="fa-solid fa-xmark"></i></a>
|
||||
{% endif %}
|
||||
<label for="animal_search">Buscar</label>
|
||||
<input type="text" name="animal_search" required>
|
||||
<button type="submit"><i class="fa-solid fa-magnifying-glass"></i></button>
|
||||
</form>
|
||||
<a href="{% url 'entities:animal:animal_new' %}">Novo <i class="fa-solid fa-plus"></i></a>
|
||||
</div>
|
||||
{% if not animals %}
|
||||
<p>Nenhum animal encontrado.</p>
|
||||
{% else %}
|
||||
<table>
|
||||
<tr>
|
||||
<th>Identificador</th>
|
||||
<th>Idade</th>
|
||||
<th>Peso</th>
|
||||
<th>Editar</th>
|
||||
<th>Excluir</th>
|
||||
</tr>
|
||||
{% for animal in animals %}
|
||||
<tr>
|
||||
<td>{{ animal.identifier }}</td>
|
||||
<td>{{ animal.age }}</td>
|
||||
<td>{{ animal.weight }} Kg</td>
|
||||
<td><a href="{% url 'entities:animal:animal_update' animal.id %}"><i class="fa-solid fa-pen-to-square"></i></a></td>
|
||||
<td>
|
||||
<form method="POST" action="{% url 'entities:animal:animal_delete' animal.id %}">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn-icon-trash"><i class="fa-solid fa-trash"></i></button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -1,48 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'animal/css/batch.css' %}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="batch_title">
|
||||
<h1>Lotes</h1>
|
||||
<form method="GET" action="{% url 'entities:animal:batch_home' %}" class="form_batch_search">
|
||||
{% if filter_query %}
|
||||
<a href="{% url 'entities:animal:batch_home' %}" class="btn-clear-filter">{{filter_query}}<i class="fa-solid fa-xmark"></i></a>
|
||||
{% endif %}
|
||||
<label for="batch_search">Buscar</label>
|
||||
<input type="text" name="batch_search" required>
|
||||
<button type="submit"><i class="fa-solid fa-magnifying-glass"></i></button>
|
||||
</form>
|
||||
<a href="{% url 'entities:animal:batch_new' %}">Novo <i class="fa-solid fa-plus"></i></a>
|
||||
</div>
|
||||
{% if not batches %}
|
||||
<p>Nenhum lote encontrado.</p>
|
||||
{% else %}
|
||||
<table>
|
||||
<tr>
|
||||
<th>Identificador</th>
|
||||
<th>Categoria animal</th>
|
||||
<th>Tipo de lote</th>
|
||||
<th>Editar</th>
|
||||
<th>Excluir</th>
|
||||
</tr>
|
||||
{% for batch in batches %}
|
||||
<tr>
|
||||
<td>{{ batch.identifier }}</td>
|
||||
<td>{{ batch.animal_category }}</td>
|
||||
<td>{{ batch.batch_type }} Kg</td>
|
||||
<td><a href="{% url 'entities:animal:batch_update' batch.id %}"><i class="fa-solid fa-pen-to-square"></i></a></td>
|
||||
<td>
|
||||
<form method="POST" action="{% url 'entities:animal:batch_delete' batch.id %}">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn-icon-trash"><i class="fa-solid fa-trash"></i></button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,106 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
{% load custom_tags %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'layout/entity_list.css' %}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ title }}</h1>
|
||||
|
||||
{% block before_table %} {% endblock %}
|
||||
|
||||
<div class="entity_search">
|
||||
<p>Busca geral</p>
|
||||
<!-- Search -->
|
||||
<form method="GET" action="{% url list_url %}">
|
||||
{% if query %}
|
||||
<a href="{% url list_url %}" class="btn-clear-filter">
|
||||
{{ query }} <i class="fa-solid fa-xmark"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<label for="search">Buscar</label>
|
||||
<input type="text" name="q" value="{{ query }}" required>
|
||||
<button type="submit">
|
||||
<i class="fa-solid fa-magnifying-glass"></i>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- New -->
|
||||
<a href="{% url create_url %}">
|
||||
Novo <i class="fa-solid fa-plus"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{% if not object_list %}
|
||||
<p>Nenhum registro encontrado.</p>
|
||||
{% else %}
|
||||
{% block table %}
|
||||
<table>
|
||||
<tr>
|
||||
{% for col in columns %}
|
||||
<th>{{ col.label }}</th>
|
||||
{% endfor %}
|
||||
<th>Editar</th>
|
||||
<th>Excluir</th>
|
||||
</tr>
|
||||
|
||||
{% for obj in object_list %}
|
||||
<tr>
|
||||
{% for col in columns %}
|
||||
<td>
|
||||
{{ obj|get_attr:col.field }}
|
||||
</td>
|
||||
{% endfor %}
|
||||
|
||||
<!-- Update -->
|
||||
<td>
|
||||
<a href="{% url edit_url obj.id %}">
|
||||
<i class="fa-solid fa-pen-to-square"></i>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<!-- Delete -->
|
||||
<td>
|
||||
<form method="POST" action="{% url delete_url obj.id %}">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn-icon-trash">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
<!-- Pagination -->
|
||||
{% if is_paginated %}
|
||||
<div class="pagination">
|
||||
<div class="left">
|
||||
{% if page_obj.has_previous %}
|
||||
<a href="?page=1&q={{ query }}"><i class="fa-solid fa-angles-left"></i></a>
|
||||
<a href="?page={{ page_obj.previous_page_number }}&q={{ query }}"><i class="fa-solid fa-angle-left"></i></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
|
||||
<span class="center">
|
||||
Página {{ page_obj.number }} de {{ page_obj.paginator.num_pages }}
|
||||
</span>
|
||||
|
||||
<div class="right">
|
||||
{% if page_obj.has_next %}
|
||||
<a href="?page={{ page_obj.next_page_number }}&q={{ query }}"><i class="fa-solid fa-angle-right"></i></a>
|
||||
<a href="?page={{ page_obj.paginator.num_pages }}&q={{ query }}"><i class="fa-solid fa-angles-right"></i></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% block after_table %} {% endblock %}
|
||||
|
||||
{% endblock %}
|
||||
@@ -16,7 +16,7 @@
|
||||
<input type="text" name="farm_search" required>
|
||||
<button type="submit"><i class="fa-solid fa-magnifying-glass"></i></button>
|
||||
</form>
|
||||
<a href="{% url 'entities:farm:farm_new' %}">Novo <i class="fa-solid fa-plus"></i></a>
|
||||
<a href="{% url 'entities:farm:farm_create' %}">Novo <i class="fa-solid fa-plus"></i></a>
|
||||
</div>
|
||||
{% if not farms %}
|
||||
<p>Nenhuma fazenda encontrado.</p>
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'farm/css/paddock.css' %}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="paddock_title">
|
||||
<h1>Piquetes</h1>
|
||||
|
||||
<form method="GET" action="{% url 'entities:farm:paddock_home' %}" class="form_paddock_search">
|
||||
{% if filter_query %}
|
||||
<a href="{% url 'entities:farm:paddock_home' %}" class="btn-clear-filter">
|
||||
{{filter_query}}<i class="fa-solid fa-xmark"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<label for="paddock_search">Buscar</label>
|
||||
<input type="text" name="paddock_search" required>
|
||||
|
||||
<button type="submit">
|
||||
<i class="fa-solid fa-magnifying-glass"></i>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<a href="{% url 'entities:farm:paddock_new' %}">
|
||||
Novo <i class="fa-solid fa-plus"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{% if not paddocks %}
|
||||
<p>Nenhum piquete encontrado.</p>
|
||||
{% else %}
|
||||
<table>
|
||||
<tr>
|
||||
<th>Número</th>
|
||||
<th>Área</th>
|
||||
<th>Capacidade</th>
|
||||
<th>Ocupado</th>
|
||||
<th>Bloco</th>
|
||||
<th>Editar</th>
|
||||
<th>Excluir</th>
|
||||
</tr>
|
||||
|
||||
{% for paddock in paddocks %}
|
||||
<tr>
|
||||
<td>{{ paddock.paddock_number }}</td>
|
||||
<td>{{ paddock.area }} ha</td>
|
||||
<td>{{ paddock.load_capacity }}</td>
|
||||
<td>
|
||||
{% if paddock.occupied %}
|
||||
Sim
|
||||
{% else %}
|
||||
Não
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if paddock.paddock_group %}
|
||||
{{ paddock.paddock_group.identifier }}
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="{% url 'entities:farm:paddock_update' paddock.id %}">
|
||||
<i class="fa-solid fa-pen-to-square"></i>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<form method="POST" action="{% url 'entities:farm:paddock_delete' paddock.id %}">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn-icon-trash">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -1,76 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'farm/css/paddock_group.css' %}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="paddock_group_title">
|
||||
<h1>Blocos</h1>
|
||||
|
||||
<form method="GET" action="{% url 'entities:farm:paddock_group_home' %}" class="form_paddock_group_search">
|
||||
{% if filter_query %}
|
||||
<a href="{% url 'entities:farm:paddock_group_home' %}" class="btn-clear-filter">
|
||||
{{filter_query}}<i class="fa-solid fa-xmark"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<label for="paddock_group_search">Buscar</label>
|
||||
<input type="text" name="paddock_group_search" required>
|
||||
|
||||
<button type="submit">
|
||||
<i class="fa-solid fa-magnifying-glass"></i>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<a href="{% url 'entities:farm:paddock_group_new' %}">
|
||||
Novo <i class="fa-solid fa-plus"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{% if not paddock_groups %}
|
||||
<p>Nenhum bloco encontrado.</p>
|
||||
{% else %}
|
||||
<table>
|
||||
<tr>
|
||||
<th>Identificador</th>
|
||||
<th>Descrição</th>
|
||||
<th>Piquetes</th>
|
||||
<th>Editar</th>
|
||||
<th>Excluir</th>
|
||||
</tr>
|
||||
|
||||
{% for group in paddock_groups %}
|
||||
<tr>
|
||||
<td>{{ group.identifier }}</td>
|
||||
<td>{{ group.description }}</td>
|
||||
|
||||
<td>
|
||||
{% for paddock in group.paddocks.all %}
|
||||
{{ paddock.paddock_number }}{% if not forloop.last %}, {% endif %}
|
||||
{% empty %}
|
||||
-
|
||||
{% endfor %}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="{% url 'entities:farm:paddock_group_update' group.id %}">
|
||||
<i class="fa-solid fa-pen-to-square"></i>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<form method="POST" action="{% url 'entities:farm:paddock_group_delete' group.id %}">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn-icon-trash">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -1,10 +1,37 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
{% extends 'entity_list.html' %}
|
||||
{% load custom_tags %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'farm/css/home.css' %}">
|
||||
{% block before_table %}
|
||||
<p>Essas informações aparecem antes da tabela apenas para a tela de movimentações</p>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
Home - Rotation
|
||||
{% endblock %}
|
||||
{% block table %}
|
||||
<table>
|
||||
<tr>
|
||||
{% for col in columns %}
|
||||
<th>{{ col.label }}</th>
|
||||
{% endfor %}
|
||||
<th>Excluir</th>
|
||||
</tr>
|
||||
|
||||
{% for obj in object_list %}
|
||||
<tr>
|
||||
{% for col in columns %}
|
||||
<td>
|
||||
{{ obj|get_attr:col.field }}
|
||||
</td>
|
||||
{% endfor %}
|
||||
|
||||
<!-- Delete -->
|
||||
<td>
|
||||
<form method="POST" action="{% url delete_url obj.id %}">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn-icon-trash">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
@@ -1,17 +1,18 @@
|
||||
from django.urls import path
|
||||
from ..views import animal as views
|
||||
from ..views import AnimalListView, BatchListView
|
||||
|
||||
app_name = 'animal'
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.animal_home, name='animal_home'),
|
||||
path('batch/', views.batch_home, name='batch_home'),
|
||||
path('list/', AnimalListView.as_view(), name='animal_list'),
|
||||
path('batch/list/', BatchListView.as_view(), name='batch_list'),
|
||||
|
||||
path('new/', views.animal_new, name='animal_new'),
|
||||
path('new/', views.animal_new, name='animal_create'),
|
||||
path('update/<int:animal_id>', views.animal_update, name='animal_update'),
|
||||
path('delete/<int:animal_id>', views.animal_delete, name='animal_delete'),
|
||||
|
||||
path('batch/new/', views.batch_new, name='batch_new'),
|
||||
path('batch/new/', views.batch_new, name='batch_create'),
|
||||
path('batch/update/<int:batch_id>', views.batch_update, name='batch_update'),
|
||||
path('batch/delete/<int:batch_id>', views.batch_delete, name='batch_delete'),
|
||||
]
|
||||
@@ -1,22 +1,23 @@
|
||||
from django.urls import path
|
||||
from ..views import farm as views
|
||||
from ..views import PaddockListView, PaddockGroupListView
|
||||
|
||||
app_name = 'farm'
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.farm_home, name='farm_home'),
|
||||
path('paddock/', views.paddock_home, name='paddock_home'),
|
||||
path("paddock/group/", views.paddock_group_home, name="paddock_group_home"),
|
||||
path('paddock/list/', PaddockListView.as_view(), name='paddock_list'),
|
||||
path('paddock/group/list/', PaddockGroupListView.as_view(), name='paddock_group_list'),
|
||||
|
||||
path('new/', views.farm_new, name='farm_new'),
|
||||
path('new/', views.farm_new, name='farm_create'),
|
||||
path('update/<int:farm_id>', views.farm_update, name='farm_update'),
|
||||
path('delete/<int:farm_id>', views.farm_delete, name='farm_delete'),
|
||||
|
||||
path('paddock/new/', views.paddock_new, name='paddock_new'),
|
||||
path('paddock/new/', views.paddock_new, name='paddock_create'),
|
||||
path('paddock/update/<int:paddock_id>', views.paddock_update, name='paddock_update'),
|
||||
path('paddock/delete/<int:paddock_id>', views.paddock_delete, name='paddock_delete'),
|
||||
|
||||
path('paddock_group/new/', views.paddock_group_new, name='paddock_group_new'),
|
||||
path('paddock_group/new/', views.paddock_group_new, name='paddock_group_create'),
|
||||
path('paddock_group/update/<int:paddock_group_id>', views.paddock_group_update, name='paddock_group_update'),
|
||||
path('paddock_group/delete/<int:paddock_group_id>', views.paddock_group_delete, name='paddock_group_delete'),
|
||||
]
|
||||
@@ -1,14 +1,13 @@
|
||||
from django.urls import path
|
||||
from django.http import HttpResponse
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from ..views import RotationListView
|
||||
|
||||
from ..views import rotation as views
|
||||
|
||||
app_name = 'rotation'
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.rotation_home, name='rotation_home'),
|
||||
path('', RotationListView.as_view(), name='rotation_home'),
|
||||
|
||||
path('new/', views.rotation_new, name='rotation_new'),
|
||||
path('new/', views.rotation_create, name='rotation_create'),
|
||||
path('delete/<int:rotation_id>', views.rotation_delete, name='rotation_delete'),
|
||||
]
|
||||
@@ -1,3 +1,10 @@
|
||||
from .animal import *
|
||||
from .farm import *
|
||||
from .rotation import *
|
||||
from .rotation import *
|
||||
|
||||
from .list.base import BaseListView
|
||||
from .list.animal import AnimalListView
|
||||
from .list.batch import BatchListView
|
||||
from .list.paddock import PaddockListView
|
||||
from .list.paddock_group import PaddockGroupListView
|
||||
from .list.rotation import RotationListView
|
||||
@@ -5,12 +5,6 @@ from core.decorators import farm_required
|
||||
from ..services import animal as services
|
||||
|
||||
# Animal Views
|
||||
@farm_required
|
||||
def animal_home(request):
|
||||
context = services.get_animal_home_context(request)
|
||||
return render(request, 'animal/animal_home.html', context)
|
||||
|
||||
|
||||
@farm_required
|
||||
def animal_new(request):
|
||||
if request.method == 'GET':
|
||||
@@ -20,9 +14,9 @@ def animal_new(request):
|
||||
elif request.method == 'POST':
|
||||
success = services.create_animal(request)
|
||||
if success:
|
||||
return redirect('entities:animal:animal_home')
|
||||
return redirect('entities:animal:animal_list')
|
||||
|
||||
return redirect('entities:animal:animal_new')
|
||||
return redirect('entities:animal:animal_create')
|
||||
|
||||
|
||||
@farm_required
|
||||
@@ -39,16 +33,10 @@ def animal_update(request, animal_id):
|
||||
@require_http_methods(["POST"])
|
||||
def animal_delete(request, animal_id):
|
||||
services.delete_animal(request, animal_id)
|
||||
return redirect('entities:animal:animal_home')
|
||||
return redirect('entities:animal:animal_list')
|
||||
|
||||
|
||||
# Batch Views
|
||||
@farm_required
|
||||
def batch_home(request):
|
||||
context = services.get_batch_home_context(request)
|
||||
return render(request, 'batch/batch_home.html', context)
|
||||
|
||||
|
||||
@farm_required
|
||||
def batch_new(request):
|
||||
result = services.create_batch(request)
|
||||
@@ -73,4 +61,4 @@ def batch_update(request, batch_id):
|
||||
@require_http_methods(["POST"])
|
||||
def batch_delete(request, batch_id):
|
||||
services.delete_batch(batch_id)
|
||||
return redirect('entities:animal:batch_home')
|
||||
return redirect('entities:animal:batch_list')
|
||||
@@ -19,9 +19,9 @@ def farm_new(request):
|
||||
elif request.method == 'POST':
|
||||
success = services.create_farm(request)
|
||||
if success:
|
||||
return redirect('entities:farm:farm_home')
|
||||
return redirect('entities:farm:farm_list')
|
||||
|
||||
return redirect('entities:farm:farm_new')
|
||||
return redirect('entities:farm:farm_create')
|
||||
|
||||
|
||||
|
||||
@@ -39,17 +39,10 @@ def farm_update(request, farm_id):
|
||||
@require_http_methods(["POST"])
|
||||
def farm_delete(request, farm_id):
|
||||
services.delete_farm(request, farm_id)
|
||||
return redirect('entities:farm:farm_home')
|
||||
return redirect('entities:farm:farm_create')
|
||||
|
||||
|
||||
# Paddock Views
|
||||
@farm_required
|
||||
def paddock_home(request):
|
||||
context = {}
|
||||
context['title'] = 'Piquete'
|
||||
return render(request, 'paddock/paddock_home.html', context)
|
||||
|
||||
|
||||
@farm_required
|
||||
def paddock_new(request):
|
||||
if request.method == 'GET':
|
||||
@@ -59,9 +52,9 @@ def paddock_new(request):
|
||||
elif request.method == 'POST':
|
||||
success = services.create_paddock(request)
|
||||
if success:
|
||||
return redirect('entities:farm:paddock_home')
|
||||
return redirect('entities:farm:paddock_list')
|
||||
|
||||
return redirect('entities:farm:paddock_new')
|
||||
return redirect('entities:farm:paddock_create')
|
||||
|
||||
|
||||
|
||||
@@ -79,17 +72,10 @@ def paddock_update(request, paddock_id):
|
||||
@require_http_methods(["POST"])
|
||||
def paddock_delete(request, paddock_id):
|
||||
services.delete_paddock(request, paddock_id)
|
||||
return redirect('entities:farm:paddock_home')
|
||||
return redirect('entities:farm:paddock_list')
|
||||
|
||||
|
||||
# Paddock Group Views
|
||||
@farm_required
|
||||
def paddock_group_home(request):
|
||||
context = {}
|
||||
context['title'] = 'Bloco'
|
||||
return render(request, 'paddock_group/paddock_group_home.html', context)
|
||||
|
||||
|
||||
@farm_required
|
||||
def paddock_group_new(request):
|
||||
if request.method == 'GET':
|
||||
@@ -99,9 +85,9 @@ def paddock_group_new(request):
|
||||
elif request.method == 'POST':
|
||||
success = services.create_paddock_group(request)
|
||||
if success:
|
||||
return redirect('entities:farm:paddock_group_home')
|
||||
return redirect('entities:farm:paddock_group_list')
|
||||
|
||||
return redirect('entities:farm:paddock_group_new')
|
||||
return redirect('entities:farm:paddock_group_create')
|
||||
|
||||
|
||||
|
||||
@@ -119,4 +105,4 @@ def paddock_group_update(request, paddock_group_id):
|
||||
@require_http_methods(["POST"])
|
||||
def paddock_group_delete(request, paddock_group_id):
|
||||
services.delete_paddock_group(request, paddock_group_id)
|
||||
return redirect('entities:farm:paddock_group_home')
|
||||
return redirect('entities:farm:paddock_group_list')
|
||||
@@ -0,0 +1,23 @@
|
||||
from .base import BaseListView
|
||||
from entities.models.animal import Animal
|
||||
|
||||
class AnimalListView(BaseListView):
|
||||
model = Animal
|
||||
|
||||
title = "Animais"
|
||||
|
||||
columns = [
|
||||
{"field": "identifier", "label": "Identificador"},
|
||||
{"field": "age", "label": "Idade"},
|
||||
{"field": "weight", "label": "Peso"},
|
||||
]
|
||||
|
||||
create_url = "entities:animal:animal_create"
|
||||
edit_url = "entities:animal:animal_update"
|
||||
delete_url = "entities:animal:animal_delete"
|
||||
list_url = "entities:animal:animal_list"
|
||||
|
||||
filter_fields = ["identifier"]
|
||||
|
||||
def get_queryset(self):
|
||||
return super().get_queryset().filter(is_active=True, farm=self.selected_farm)
|
||||
@@ -0,0 +1,57 @@
|
||||
from django.views.generic import ListView
|
||||
from django.db.models import Q
|
||||
from entities.models.farm import Farm
|
||||
|
||||
class BaseListView(ListView):
|
||||
template_name = "entity_list.html"
|
||||
paginate_by = 10
|
||||
selected_farm = ""
|
||||
order_by = ["id"]
|
||||
|
||||
# Specific configurations for each entity
|
||||
title = ""
|
||||
columns = []
|
||||
|
||||
create_url = ""
|
||||
edit_url = ""
|
||||
delete_url = ""
|
||||
list_url = ""
|
||||
|
||||
filter_fields = [] # ex: ["identifier", "name"]
|
||||
|
||||
# Acts like a init function - provides the select_farm Farm object to all dependent views
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
farm_id = self.request.session.get('selected_farm_id')
|
||||
self.selected_farm = Farm.objects.filter(id=farm_id).first()
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
# Filter
|
||||
def get_queryset(self):
|
||||
queryset = super().get_queryset()
|
||||
query = self.request.GET.get("q")
|
||||
|
||||
if query and self.filter_fields:
|
||||
q_objects = Q()
|
||||
|
||||
for field in self.filter_fields:
|
||||
q_objects |= Q(**{f"{field}__icontains": query})
|
||||
|
||||
queryset = queryset.filter(q_objects)
|
||||
|
||||
return queryset.order_by(*self.order_by)
|
||||
|
||||
# Context
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
context.update({
|
||||
"title": self.title,
|
||||
"columns": self.columns,
|
||||
"create_url": self.create_url,
|
||||
"edit_url": self.edit_url,
|
||||
"delete_url": self.delete_url,
|
||||
"list_url": self.list_url,
|
||||
"query": self.request.GET.get("q", ""),
|
||||
})
|
||||
|
||||
return context
|
||||
@@ -0,0 +1,35 @@
|
||||
from .base import BaseListView
|
||||
from django.db.models import Prefetch
|
||||
from entities.models.animal import Batch, Animal
|
||||
|
||||
class BatchListView(BaseListView):
|
||||
model = Batch
|
||||
|
||||
title = "Lotes"
|
||||
|
||||
columns = [
|
||||
{"field": "identifier", "label": "Identificador"},
|
||||
{"field": "animal_cathgory", "label": "Categoria"},
|
||||
{"field": "batch_type", "label": "Tipo"},
|
||||
]
|
||||
|
||||
create_url = "entities:animal:batch_create"
|
||||
edit_url = "entities:animal:batch_update"
|
||||
delete_url = "entities:animal:batch_delete"
|
||||
list_url = "entities:animal:batch_list"
|
||||
|
||||
filter_fields = ["identifier"]
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = Batch.objects.filter(
|
||||
batchanimal__animal__farm=self.selected_farm,
|
||||
is_active=True
|
||||
).distinct().prefetch_related(
|
||||
Prefetch('animals', queryset=Animal.objects.filter(is_active=True))
|
||||
)
|
||||
|
||||
query = self.request.GET.get("q")
|
||||
if query:
|
||||
queryset = queryset.filter(identifier__icontains=query)
|
||||
|
||||
return queryset
|
||||
@@ -0,0 +1,24 @@
|
||||
from .base import BaseListView
|
||||
from entities.models.farm import Paddock
|
||||
|
||||
class PaddockListView(BaseListView):
|
||||
model = Paddock
|
||||
|
||||
title = "Piquetes"
|
||||
|
||||
columns = [
|
||||
{"field": "paddock_number", "label": "Número"},
|
||||
{"field": "area", "label": "Área"},
|
||||
{"field": "load_capacity", "label": "Capacidade"},
|
||||
{"field": "occupied", "label": "Ocupado"},
|
||||
]
|
||||
|
||||
create_url = "entities:farm:paddock_group_create"
|
||||
edit_url = "entities:farm:paddock_group_update"
|
||||
delete_url = "entities:farm:paddock_group_delete"
|
||||
list_url = "entities:farm:paddock_group_list"
|
||||
|
||||
filter_fields = ["paddock_number"]
|
||||
|
||||
def get_queryset(self):
|
||||
return super().get_queryset().filter(is_active=True, farm=self.selected_farm)
|
||||
@@ -0,0 +1,35 @@
|
||||
from .base import BaseListView
|
||||
from django.db.models import Prefetch
|
||||
from entities.models.farm import PaddockGroup, Paddock
|
||||
|
||||
class PaddockGroupListView(BaseListView):
|
||||
model = PaddockGroup
|
||||
|
||||
title = "Blocos"
|
||||
|
||||
columns = [
|
||||
{"field": "identifier", "label": "Identificador"},
|
||||
{"field": "description", "label": "Descrição"},
|
||||
]
|
||||
|
||||
create_url = "entities:farm:paddock_group_create"
|
||||
edit_url = "entities:farm:paddock_group_update"
|
||||
delete_url = "entities:farm:paddock_group_delete"
|
||||
list_url = "entities:farm:paddock_group_list"
|
||||
|
||||
filter_fields = ["identifier"]
|
||||
|
||||
def get_queryset(self):
|
||||
|
||||
queryset = PaddockGroup.objects.filter(
|
||||
paddocks__farm=self.selected_farm,
|
||||
is_active=True
|
||||
).distinct().prefetch_related(
|
||||
Prefetch('paddocks', queryset=Paddock.objects.filter(is_active=True))
|
||||
)
|
||||
|
||||
query = self.request.GET.get("q")
|
||||
if query:
|
||||
queryset = queryset.filter(identifier__icontains=query)
|
||||
|
||||
return queryset
|
||||
@@ -0,0 +1,28 @@
|
||||
from .base import BaseListView
|
||||
from entities.models.rotation import Rotation
|
||||
|
||||
class RotationListView(BaseListView):
|
||||
model = Rotation
|
||||
|
||||
template_name = "rotation/rotation_home.html"
|
||||
|
||||
title = "Movimentações"
|
||||
|
||||
columns = [
|
||||
#{"field": "id", "label": "ID"},
|
||||
{"field": "batch", "label": "Lote"},
|
||||
{"field": "paddock", "label": "Piquete"},
|
||||
{"field": "entry_date", "label": "Entrada"},
|
||||
{"field": "exit_date", "label": "Saída"},
|
||||
{"field": "animal_count", "label": "Animais"},
|
||||
{"field": "livestock_unit", "label": "UGM"},
|
||||
]
|
||||
|
||||
create_url = "entities:rotation:rotation_create"
|
||||
delete_url = "entities:rotation:rotation_delete"
|
||||
list_url = "entities:rotation:rotation_home"
|
||||
|
||||
filter_fields = ["id", "batch", "paddock"]
|
||||
|
||||
def get_queryset(self):
|
||||
return super().get_queryset().filter(is_active=True, paddock__farm=self.selected_farm)
|
||||
@@ -1,10 +1,14 @@
|
||||
from django.shortcuts import render
|
||||
from core.decorators import farm_required
|
||||
|
||||
@farm_required
|
||||
def rotation_home(request):
|
||||
return render(request, 'rotation/rotation_home.html')
|
||||
|
||||
def rotation_new(request):
|
||||
@farm_required
|
||||
def rotation_create(request):
|
||||
return render(request, 'rotation/rotation_new.html')
|
||||
|
||||
@farm_required
|
||||
def rotation_delete(request):
|
||||
return render(request, 'rotation/rotation_delete.html')
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
/* HOVER EFFECTS */
|
||||
.highlight-hover:hover {
|
||||
background-color: rgba(255, 255, 255, 0.15);
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(8px);
|
||||
transition: all var(--transition-speed) ease;
|
||||
}
|
||||
Reference in new issue
Block a user