Refatoração do back-end de animais e lotes

O back-end dos animais e lotes agora possui uma estrutura mais organizada e visualmente clara, é desejável  que as outras entidades sigam a mesma lógica.
This commit is contained in:
Eberton committed 2026-05-24 18:31:14 -03:00
1 parent 9374bfd71b
commit ae0483ddf1
18 files changed
+134 -130

No files matched your search

@@ -2,5 +2,5 @@
{% csrf_token %} {% csrf_token %}
{{ form }} {{ form }}
<button class="btn-primary" type="submit">Salvar</button> <button class="btn-primary" type="submit">Salvar</button>
<a href="{{ return_url }}" class="btn-simple">Cancelar</a> <a href="{{ return_url }}" class="btn-primary">Cancelar</a>
</form> </form>
+1 -1
View File
@@ -28,7 +28,7 @@
{% csrf_token %} {% csrf_token %}
{{ form }} {{ form }}
{% if fail_login %} {% if fail_login %}
<p class="login-fail"><i class="fa-solid fa-circle-exclamation"></i> Login ou senha incorretos</p> <p class="login-fail"><i class="fa-solid fa-circle-exclamation"></i> Usuário ou senha incorretos</p>
{% endif %} {% endif %}
<button type="submit">Entrar <i class="fa-solid fa-right-to-bracket"></i></button> <button type="submit">Entrar <i class="fa-solid fa-right-to-bracket"></i></button>
<p>Não possui cadastro? <a href="{% url 'entities:user:user_signin' %}">Solicite acesso</a>.</p> <p>Não possui cadastro? <a href="{% url 'entities:user:user_signin' %}">Solicite acesso</a>.</p>
+69 -76
View File
@@ -1,4 +1,4 @@
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse from django.urls import reverse
from django.db.models import Prefetch from django.db.models import Prefetch
@@ -6,10 +6,24 @@ from ..models import Animal, Batch
from ..forms import AnimalCreateForm, AnimalEditForm, BatchForm from ..forms import AnimalCreateForm, AnimalEditForm, BatchForm
from entities.models import Farm from entities.models import Farm
# Local utility functions
def _get_selected_farm_id(request):
return request.session['selected_farm_id']
def get_selected_farm(request): def _get_selected_farm(request):
return Farm.objects.get(id=request.session['selected_farm_id']) return Farm.objects.get(id=_get_selected_farm_id(request))
def _get_animal_by_id(request, animal_id):
return get_object_or_404(Animal, pk=animal_id, farm_id=_get_selected_farm_id(request))
def _get_farms_active_animals(request):
return Animal.objects.filter(
farm=_get_selected_farm_id(request),
is_active=True
)
def _get_batch_by_id(request, batch_id):
return get_object_or_404(Batch, pk=batch_id, is_active=True)
# Animal Services # Animal Services
def get_animal_new_context(): def get_animal_new_context():
@@ -26,7 +40,7 @@ def get_animal_new_context():
def create_animal(request): def create_animal(request):
form = AnimalCreateForm(request.POST) form = AnimalCreateForm(request.POST)
selected_farm = get_selected_farm(request) selected_farm = _get_selected_farm(request)
if form.is_valid(): if form.is_valid():
animal = form.save(commit=False) animal = form.save(commit=False)
@@ -36,10 +50,9 @@ def create_animal(request):
return False return False
def get_animal_update_context(request, animal_id):
def update_animal(request, animal_id): animal = _get_animal_by_id(request, animal_id)
farm_id = request.session['selected_farm_id'] form = AnimalEditForm(instance=animal)
animal = get_object_or_404(Animal, pk=animal_id, farm_id=farm_id)
context = {} context = {}
context['title'] = 'Editar animal' context['title'] = 'Editar animal'
@@ -48,39 +61,39 @@ def update_animal(request, animal_id):
kwargs={'animal_id': animal.pk} kwargs={'animal_id': animal.pk}
) )
context['return_url'] = reverse('entities:animal:animal_list') context['return_url'] = reverse('entities:animal:animal_list')
context['form'] = form
if request.method == 'GET': return context
form = AnimalEditForm(instance=animal)
elif request.method == 'POST': def update_animal(request, animal_id):
animal = _get_animal_by_id(request, animal_id)
form = AnimalEditForm(request.POST, instance=animal) form = AnimalEditForm(request.POST, instance=animal)
if form.is_valid(): if form.is_valid():
form.save() form.save()
return {'redirect': 'entities:animal:animal_list'} return True
context['form'] = form return False
return {'context': context} def get_animal_delete_context(request, animal_id):
animal = _get_animal_by_id(request, animal_id)
context = {}
context['description'] = f"Excluir registro de animal {animal.identifier}"
context['positive_url'] = reverse('entities:animal:animal_delete', kwargs={'animal_id': animal_id})
context['negative_url'] = reverse('entities:animal:animal_list')
return context
def delete_animal(request, animal_id): def delete_animal(request, animal_id):
farm_id = request.session['selected_farm_id'] animal = _get_animal_by_id(request, animal_id)
animal = get_object_or_404(Animal, pk=animal_id, farm_id=farm_id)
animal.is_active = False animal.is_active = False
animal.save() animal.save()
# Batch Services # Batch Services
def create_batch(request): def get_batch_new_context(request):
selected_farm = get_selected_farm(request)
if request.method == 'GET':
form = BatchForm() form = BatchForm()
form.fields['animals'].queryset = Animal.objects.filter( form.fields['animals'].queryset = _get_farms_active_animals(request)
farm=selected_farm,
is_active=True
)
context = { context = {
'title': 'Novo Lote', 'title': 'Novo Lote',
@@ -89,9 +102,9 @@ def create_batch(request):
'return_url': reverse('entities:animal:batch_list') 'return_url': reverse('entities:animal:batch_list')
} }
return {'context': context} return context
elif request.method == 'POST': def create_batch(request):
form = BatchForm(request.POST) form = BatchForm(request.POST)
if form.is_valid(): if form.is_valid():
@@ -99,76 +112,56 @@ def create_batch(request):
batch.save() batch.save()
form.save_m2m() form.save_m2m()
return {'redirect': 'entities:animal:batch_list'} return True
form.fields['animals'].queryset = Animal.objects.filter( return False
farm=selected_farm,
is_active=True
)
context = { def get_batch_update_context(request, batch_id):
'title': 'Novo Lote', batch_old = _get_batch_by_id(request, batch_id)
'form': form, form = BatchForm(instance=batch_old)
'action_url': reverse('entities:animal:batch_create'), form.fields['animals'].queryset = _get_farms_active_animals(request)
'return_url': reverse('entities:animal:batch_list')
}
return {'context': context}
def update_batch(request, batch_id):
batch_old = get_object_or_404(Batch, pk=batch_id, is_active=True)
selected_farm = get_selected_farm(request)
context = { context = {
'title': f'Editar Lote {batch_old.identifier}', 'title': f'Editar Lote {batch_old.identifier}',
'return_url': reverse('entities:animal:batch_list') 'return_url': reverse('entities:animal:batch_list'),
} 'action_url': reverse(
if request.method == 'GET':
form = BatchForm(instance=batch_old)
form.fields['animals'].queryset = Animal.objects.filter(
farm=selected_farm,
is_active=True
)
context['action_url'] = reverse(
'entities:animal:batch_update', 'entities:animal:batch_update',
kwargs={'batch_id': batch_old.pk} kwargs={'batch_id': batch_old.pk}
) ),
'form': form
}
elif request.method == 'POST': return context
def update_batch(request, batch_id):
form = BatchForm(request.POST) form = BatchForm(request.POST)
batch_old = _get_batch_by_id(request, batch_id)
if form.is_valid(): if form.is_valid():
batch_new = form.save(commit=False)
batch_new.is_active = True
batch_old.is_active = False batch_old.is_active = False
batch_old.save() batch_old.save()
batch_new = form.save(commit=False)
batch_new.is_active = True
batch_new.save() batch_new.save()
form.instance = batch_new
form.save_m2m() form.save_m2m()
return {'redirect': 'entities:animal:batch_list'} return True
form.fields['animals'].queryset = Animal.objects.filter( return False
farm=selected_farm,
is_active=True
)
context['action_url'] = reverse( def get_batch_delete_context(request, batch_id):
'entities:animal:batch_update', batch = _get_batch_by_id(request, batch_id)
kwargs={'batch_id': batch_old.pk} context = {}
) context['description'] = f"Excluir registro do lote {batch.identifier}"
context['positive_url'] = reverse('entities:animal:batch_delete', kwargs={'batch_id': batch_id})
context['negative_url'] = reverse('entities:animal:batch_list')
context['form'] = form return context
return {'context': context} def delete_batch(request, batch_id):
batch = _get_batch_by_id(request, batch_id)
def delete_batch(batch_id):
batch = get_object_or_404(Batch, pk=batch_id, is_active=True)
batch.is_active = False batch.is_active = False
batch.save() batch.save()
@@ -77,7 +77,9 @@
} }
/* NEW BUTTON */ /* NEW BUTTON */
.entity_search > a { .new-entity-button {
cursor: pointer;
user-select: none;
height: 32px; height: 32px;
padding: 0 var(--space-md); padding: 0 var(--space-md);
background: var(--color-success); background: var(--color-success);
@@ -91,7 +93,7 @@
transition: background var(--transition-speed); transition: background var(--transition-speed);
} }
.entity_search > a:hover { .new-entity-button:hover {
background: var(--color-success); background: var(--color-success);
opacity: 0.85; opacity: 0.85;
} }
@@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'base_modal.html' %}
{% load static %} {% load static %}
{% block extra_css %} {% block extra_css %}
@@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'base_modal.html' %}
{% load static %} {% load static %}
{% block extra_css %} {% block extra_css %}
@@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'base_modal.html' %}
{% load static %} {% load static %}
{% block extra_css %} {% block extra_css %}
@@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'base_modal.html' %}
{% load static %} {% load static %}
{% block extra_css %} {% block extra_css %}
@@ -9,7 +9,7 @@
{% block content %} {% block content %}
<h1>{{ title }}</h1> <h1>{{ title }}</h1>
{% block before_table %} {% endblock %} {% block before_table %}{% endblock %}
<div class="entity_search"> <div class="entity_search">
<p>Busca geral</p> <p>Busca geral</p>
@@ -27,11 +27,7 @@
<i class="fa-solid fa-magnifying-glass"></i> <i class="fa-solid fa-magnifying-glass"></i>
</button> </button>
</form> </form>
<a class="new-entity-button" hx-get="{% url create_url %}" hx-swap="beforeend" hx-target="body">Novo <i class="fa-solid fa-plus"></i></a>
<!-- New -->
<a href="{% url create_url %}">
Novo <i class="fa-solid fa-plus"></i>
</a>
</div> </div>
{% if not object_list %} {% if not object_list %}
@@ -57,19 +53,14 @@
<!-- Update --> <!-- Update -->
<td> <td>
<a href="{% url edit_url obj.id %}"> <a class="entity-update" hx-get="{% url edit_url obj.id %}" hx-swap="beforeend" hx-target="body">
<i class="fa-solid fa-pen-to-square"></i> <i class="fa-solid fa-pen-to-square"></i>
</a> </a>
</td> </td>
<!-- Delete --> <!-- Delete -->
<td> <td>
<form method="POST" action="{% url delete_url obj.id %}"> <a class="entity-delete" hx-get="{% url delete_url obj.id %}" hx-swap="beforeend" hx-target="body"><i class="fa-solid fa-trash"></i></a>
{% csrf_token %}
<button type="submit" class="btn-icon-trash">
<i class="fa-solid fa-trash"></i>
</button>
</form>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
@@ -101,6 +92,6 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
{% block after_table %} {% endblock %} {% block after_table %}{% endblock %}
{% endblock %} {% endblock %}
@@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'base_modal.html' %}
{% load static %} {% load static %}
{% block extra_css %} {% block extra_css %}
@@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'base_modal.html' %}
{% load static %} {% load static %}
{% block extra_css %} {% block extra_css %}
@@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'base_modal.html' %}
{% load static %} {% load static %}
{% block extra_css %} {% block extra_css %}
@@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'base_modal.html' %}
{% load static %} {% load static %}
{% block extra_css %} {% block extra_css %}
@@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'base_modal.html' %}
{% load static %} {% load static %}
{% block extra_css %} {% block extra_css %}
@@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'base_modal.html' %}
{% load static %} {% load static %}
{% block extra_css %} {% block extra_css %}
@@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'base_modal.html' %}
{% load static %} {% load static %}
{% block extra_css %} {% block extra_css %}
@@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'base_modal.html' %}
{% load static %} {% load static %}
{% block extra_css %} {% block extra_css %}
+42 -24
View File
@@ -7,58 +7,76 @@ from ..services import animal as services
# Animal Views # Animal Views
@farm_required @farm_required
def animal_new(request): def animal_new(request):
if request.method == 'GET':
context = services.get_animal_new_context() context = services.get_animal_new_context()
if request.method == 'GET':
return render(request, 'animal/animal_new.html', context) return render(request, 'animal/animal_new.html', context)
elif request.method == 'POST': if request.method == 'POST':
success = services.create_animal(request) if services.create_animal(request):
if success:
return redirect('entities:animal:animal_list') return redirect('entities:animal:animal_list')
context['error'] = "Não foi possível registrar o animal"
return redirect('entities:animal:animal_create') return render(request, 'animal/animal_new.html', context)
@farm_required @farm_required
def animal_update(request, animal_id): def animal_update(request, animal_id):
result = services.update_animal(request, animal_id) context = services.get_animal_update_context(request, animal_id)
if request.method == 'GET':
return render(request, 'animal/animal_update.html', context)
if result.get('redirect'): if request.method == 'POST':
return redirect(result['redirect']) if services.update_animal(request, animal_id):
return redirect('entities:animal:animal_list')
return render(request, 'animal/animal_update.html', result['context']) context['error'] = "Não foi possível editar o animal"
return render(request, 'animal/animal_update.html', context)
@farm_required @farm_required
@require_http_methods(["POST"])
def animal_delete(request, animal_id): def animal_delete(request, animal_id):
if request.method == 'GET':
context = services.get_animal_delete_context(request, animal_id)
return render(request, 'confirmation_popup.html', context)
if request.method == 'POST':
services.delete_animal(request, animal_id) services.delete_animal(request, animal_id)
return redirect('entities:animal:animal_list') return redirect('entities:animal:animal_list')
# Batch Views # Batch Views
@farm_required @farm_required
def batch_new(request): def batch_new(request):
result = services.create_batch(request) context = services.get_batch_new_context(request)
if request.method == 'GET':
return render(request, 'batch/batch_new.html', context)
if result.get('redirect'): if request.method == 'POST':
return redirect(result['redirect']) if services.create_batch(request):
return redirect('entities:animal:batch_list')
return render(request, 'batch/batch_new.html', result['context']) context['error'] = "Não foi possível criar o lote"
return render(request, 'batch/batch_new.html', context)
@farm_required @farm_required
def batch_update(request, batch_id): def batch_update(request, batch_id):
result = services.update_batch(request, batch_id) context = services.get_batch_update_context(request, batch_id)
if request.method == 'GET':
return render(request, 'batch/batch_update.html', context)
if result.get('redirect'): if request.method == 'POST':
return redirect(result['redirect']) if services.update_batch(request, batch_id):
return redirect('entities:animal:batch_list')
return render(request, 'batch/batch_update.html', result['context']) context['error'] = "Não foi possível editar o lote"
return render(request, 'batch/batch_update.html', context)
@farm_required @farm_required
@require_http_methods(["POST"])
def batch_delete(request, batch_id): def batch_delete(request, batch_id):
services.delete_batch(batch_id) if request.method == 'GET':
context = services.get_batch_delete_context(request, batch_id)
return render(request, 'confirmation_popup.html', context)
if request.method == 'POST':
services.delete_batch(request, batch_id)
return redirect('entities:animal:batch_list') return redirect('entities:animal:batch_list')