pets/visao/frames/frame_adocao.py

232 lines
8.6 KiB
Python

import tkinter as tk
from tkinter import ttk, messagebox
from persistencia.excecoes import EntidadeNaoEncontradaException
from modelo.adocao import Adocao
from modelo.item_adocao import ItemAdocao
from visao.componentes.dialogo_nova_adocao import DialogoNovaAdocao
from visao.componentes.dialogo_editar_adocao import DialogoEditarAdocao
class FrameAdocao(tk.Frame):
def __init__(self, master=None, bd=None):
super().__init__(master, bg="#1e1e1e")
self.bd = bd
self._criar_layout()
self.popular_treeview()
def _criar_layout(self):
# Título da seção
titulo_label = tk.Label(
self,
text="GERENCIAR ADOÇÕES",
font=("Arial", 24, "bold"),
bg="#1e1e1e",
fg="white"
)
titulo_label.pack(pady=20)
# Frame de busca
busca_frame = tk.Frame(self, bg="#1e1e1e")
busca_frame.pack(pady=5, padx=20, fill="x")
tk.Label(busca_frame, text="Buscar por ID, Adotante ou Pet:", bg="#1e1e1e", fg="white").pack(side="left", padx=(0, 5))
self.entry_busca = tk.Entry(busca_frame, bg="#2c2c2c", fg="white", insertbackground="white", width=40)
self.entry_busca.pack(side="left", fill="x", expand=True)
self.entry_busca.bind("<Return>", lambda event: self._realizar_busca())
btn_buscar = tk.Button(busca_frame, text="Buscar", command=self._realizar_busca, bg="#1f6aa5", fg="white", relief="flat")
btn_buscar.pack(side="left", padx=5)
btn_limpar = tk.Button(busca_frame, text="Limpar", command=self._limpar_busca, bg="#555555", fg="white", relief="flat")
btn_limpar.pack(side="left", padx=5)
# Estilo da Treeview
style = ttk.Style()
style.theme_use("default")
style.configure("Treeview",
background="#2c2c2c",
foreground="white",
rowheight=25,
fieldbackground="#2c2c2c",
bordercolor="#2c2c2c",
borderwidth=0)
style.map('Treeview', background=[('selected', '#1f6aa5')])
style.configure("Treeview.Heading",
background="#2c2c2c",
foreground="white",
font=("Arial", 12, "bold"),
relief="flat")
style.map("Treeview.Heading",
background=[('active', '#3c3c3c')])
tree_container = tk.Frame(self, bg="#1e1e1e")
tree_container.pack(pady=10, padx=20, fill="both", expand=True)
# Configuração da Treeview para um modo hierárquico
self.tree = ttk.Treeview(tree_container, columns=("data",), show="tree headings")
# Coluna #0 (a árvore)
self.tree.heading("#0", text="Detalhes da Adoção", anchor="w")
self.tree.column("#0", anchor="w", stretch=tk.YES, minwidth=250)
# Coluna 'data'
self.tree.heading("data", text="Data da Adoção")
self.tree.column("data", width=150, anchor="center", stretch=tk.NO)
scrollbar = ttk.Scrollbar(tree_container, orient="vertical", command=self.tree.yview)
self.tree.configure(yscrollcommand=scrollbar.set)
self.tree.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")
# Frame para os botões de ação
botoes_frame = tk.Frame(self, bg="#1e1e1e")
botoes_frame.pack(pady=10, padx=20, fill="x")
# Botão Nova Adoção
btn_adicionar = tk.Button(
botoes_frame,
text="Nova Adoção",
command=self.nova_adocao,
bg="#4CAF50",
fg="white",
font=("Arial", 12),
relief="flat",
padx=10,
pady=5
)
btn_adicionar.pack(side="left", padx=5)
btn_alterar = tk.Button(
botoes_frame,
text="Alterar",
command=self.alterar_adocao,
bg="#ffc107",
fg="white",
font=("Arial", 12),
relief="flat",
padx=10,
pady=5
)
btn_alterar.pack(side="left", padx=5)
def popular_treeview(self, lista_adocoes=None):
# Limpa a árvore
for i in self.tree.get_children():
self.tree.delete(i)
if lista_adocoes is None:
lista_adocoes = self.bd.adocoes.listar_todos()
# Popula com os dados de adoções do banco de dados
for adocao in lista_adocoes:
# Nó pai para a adoção
adocao_node = self.tree.insert(
"", "end",
iid=f"adocao_{adocao.id}",
text=f"Adoção ID: {adocao.id}",
open=True
)
# Nó filho para o adotante
self.tree.insert(adocao_node, "end", text=f"Adotante: {adocao.adotante.nome}")
# Nó "pasta" para os pets
pets_node = self.tree.insert(adocao_node, "end", text="Pets Adotados", open=True)
# Nós filhos para cada pet adotado
for item in adocao.itens:
self.tree.insert(
pets_node, "end",
text=f"{item.pet.nome} ({item.pet.especie})",
values=(item.data,)
)
def nova_adocao(self):
dialog = DialogoNovaAdocao(self, self.bd)
self.wait_window(dialog)
if dialog.result:
pessoa = dialog.result["pessoa"]
pets = dialog.result["pets"]
data = dialog.result["data"]
try:
proximo_id = self.bd.obter_proximo_id_adocao()
nova_adocao = Adocao(proximo_id, pessoa)
for pet in pets:
item = ItemAdocao(pet, data)
nova_adocao.adicionar_item(item)
self.bd.adocoes.inserir(nova_adocao)
self.popular_treeview()
messagebox.showinfo("Sucesso", "Adoção registrada com sucesso.")
except Exception as e:
messagebox.showerror("Erro", f"Ocorreu um erro ao registrar a adoção:\n{e}")
def _obter_id_adocao_selecionada(self):
"""Obtém o ID da adoção a partir do item selecionado na Treeview."""
selecionado = self.tree.selection()
if not selecionado:
messagebox.showwarning("Aviso", "Por favor, selecione uma adoção.")
return None
item_id = selecionado[0]
# O iid do nó pai da adoção é 'adocao_ID'
if not item_id.startswith("adocao_"):
# Se um item filho for selecionado, encontra o pai
item_id = self.tree.parent(item_id)
if not item_id.startswith("adocao_"):
item_id = self.tree.parent(item_id)
try:
return int(item_id.split('_')[1])
except (IndexError, ValueError):
return None
def alterar_adocao(self):
id_adocao = self._obter_id_adocao_selecionada()
if id_adocao is None:
return
try:
adocao_atual = self.bd.adocoes.buscar_por_id(id_adocao)
dialog = DialogoEditarAdocao(self, self.bd, adocao_atual)
self.wait_window(dialog)
if dialog.result:
# Atualiza os dados da adoção
adocao_atual.adotante = dialog.result["pessoa"]
adocao_atual.itens.clear() # Limpa os pets antigos
for pet in dialog.result["pets"]:
item = ItemAdocao(pet, dialog.result["data"])
adocao_atual.adicionar_item(item)
self.bd.adocoes.alterar(adocao_atual.id, adocao_atual)
self.popular_treeview()
messagebox.showinfo("Sucesso", "Adoção alterada com sucesso.")
except EntidadeNaoEncontradaException as e:
messagebox.showerror("Erro", f"Não foi possível alterar: {e}\nA lista será atualizada.")
self.popular_treeview()
def _realizar_busca(self):
termo_busca = self.entry_busca.get().strip().lower()
if not termo_busca:
self.popular_treeview()
return
todas_adocoes = self.bd.adocoes.listar_todos()
resultados = [
adocao for adocao in todas_adocoes if
termo_busca in str(adocao.id) or
termo_busca in adocao.adotante.nome.lower() or
any(termo_busca in item.pet.nome.lower() or termo_busca in item.pet.especie.lower() for item in adocao.itens)
]
self.popular_treeview(resultados)
def _limpar_busca(self):
self.entry_busca.delete(0, tk.END)
self.popular_treeview()