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("", 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()