From 053304f5598293529b371644aba0bd5f37e9fba1 Mon Sep 17 00:00:00 2001 From: Emersonjsc Date: Mon, 7 Jul 2025 00:19:26 -0300 Subject: [PATCH] Tratamento de erros --- visao/componentes/dialogo_editar_adocao.py | 26 +++++++- visao/componentes/dialogo_nova_adocao.py | 13 ++-- visao/frames/frame_adocao.py | 72 +++++++++++++++++++++- visao/frames/frame_pessoa.py | 24 +++++--- visao/frames/frame_pet.py | 36 ++++++----- 5 files changed, 143 insertions(+), 28 deletions(-) diff --git a/visao/componentes/dialogo_editar_adocao.py b/visao/componentes/dialogo_editar_adocao.py index 0a40d1f..01b7f9c 100644 --- a/visao/componentes/dialogo_editar_adocao.py +++ b/visao/componentes/dialogo_editar_adocao.py @@ -77,4 +77,28 @@ class DialogoEditarAdocao(tk.Toplevel): self.listbox_pets.selection_set(i) if self.adocao_atual.itens: - self.entry_data.insert(0, self.adocao_atual.itens[0].data) \ No newline at end of file + self.entry_data.insert(0, self.adocao_atual.itens[0].data) + + def _on_ok(self): + idx_pessoa = self.combo_pessoas.current() + if idx_pessoa == -1: + messagebox.showerror("Erro", "Por favor, selecione um adotante.", parent=self) + return + + indices_pets = self.listbox_pets.curselection() + if not indices_pets: + messagebox.showerror("Erro", "Por favor, selecione pelo menos um pet.", parent=self) + return + + data_str = self.entry_data.get() + try: + datetime.strptime(data_str, "%d-%m-%Y") + except ValueError: + messagebox.showerror("Erro de Formato", "A data deve estar no formato DD/MM/AAAA.", parent=self) + return + + pessoa_selecionada = self.pessoas[idx_pessoa] + pets_selecionados = [self.pets[i] for i in indices_pets] + + self.result = {"pessoa": pessoa_selecionada, "pets": pets_selecionados, "data": data_str} + self.destroy() \ No newline at end of file diff --git a/visao/componentes/dialogo_nova_adocao.py b/visao/componentes/dialogo_nova_adocao.py index a55d48e..647abde 100644 --- a/visao/componentes/dialogo_nova_adocao.py +++ b/visao/componentes/dialogo_nova_adocao.py @@ -50,9 +50,9 @@ class DialogoNovaAdocao(tk.Toplevel): scrollbar.pack(side="right", fill="y") # Data - tk.Label(main_frame, text="Data da Adoção (DD-MM-AAAA):", bg="#1e1e1e", fg="white").pack(anchor="w") + tk.Label(main_frame, text="Data da Adoção (DD/MM/AAAA):", bg="#1e1e1e", fg="white").pack(anchor="w") self.entry_data = tk.Entry(main_frame, bg="#2c2c2c", fg="white", insertbackground="white") - self.entry_data.insert(0, datetime.now().strftime("%d-%m-%Y")) + self.entry_data.insert(0, datetime.now().strftime("%d/%m/%Y")) self.entry_data.pack(fill="x", pady=(0, 20)) # Botões @@ -76,10 +76,15 @@ class DialogoNovaAdocao(tk.Toplevel): messagebox.showerror("Erro", "Por favor, selecione pelo menos um pet.", parent=self) return - data = self.entry_data.get() + data_str = self.entry_data.get() + try: + datetime.strptime(data_str, "%d-%m-%Y") + except ValueError: + messagebox.showerror("Erro de Formato", "A data deve estar no formato DD-MM-AAAA.", parent=self) + return pessoa_selecionada = self.pessoas[idx_pessoa] pets_selecionados = [self.pets[i] for i in indices_pets] - self.result = {"pessoa": pessoa_selecionada, "pets": pets_selecionados, "data": data} + self.result = {"pessoa": pessoa_selecionada, "pets": pets_selecionados, "data": data_str} self.destroy() \ No newline at end of file diff --git a/visao/frames/frame_adocao.py b/visao/frames/frame_adocao.py index 170f08b..0468c22 100644 --- a/visao/frames/frame_adocao.py +++ b/visao/frames/frame_adocao.py @@ -1,9 +1,10 @@ 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): @@ -14,6 +15,7 @@ class FrameAdocao(tk.Frame): self.popular_treeview() def _criar_layout(self): + # Título da seção titulo_label = tk.Label( self, text="GERENCIAR ADOÇÕES", @@ -23,6 +25,7 @@ class FrameAdocao(tk.Frame): ) titulo_label.pack(pady=20) + # Frame de busca busca_frame = tk.Frame(self, bg="#1e1e1e") busca_frame.pack(pady=5, padx=20, fill="x") @@ -60,8 +63,10 @@ class FrameAdocao(tk.Frame): 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) @@ -79,6 +84,7 @@ class FrameAdocao(tk.Frame): 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", @@ -92,13 +98,29 @@ class FrameAdocao(tk.Frame): ) 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( @@ -108,10 +130,13 @@ class FrameAdocao(tk.Frame): 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", @@ -142,6 +167,51 @@ class FrameAdocao(tk.Frame): 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: diff --git a/visao/frames/frame_pessoa.py b/visao/frames/frame_pessoa.py index 528746a..9c8498a 100644 --- a/visao/frames/frame_pessoa.py +++ b/visao/frames/frame_pessoa.py @@ -152,12 +152,16 @@ class FramePessoas(tk.Frame): ) if novo_nome and novo_nome.strip() and novo_nome.strip() != nome_atual: - pessoa = self.bd.pessoas.buscar_por_id(id_pessoa) - if pessoa: - pessoa.nome = novo_nome.strip() - self.bd.pessoas.alterar(pessoa.id, pessoa) + try: + pessoa = self.bd.pessoas.buscar_por_id(id_pessoa) + if pessoa: + pessoa.nome = novo_nome.strip() + self.bd.pessoas.alterar(pessoa.id, pessoa) + self.popular_treeview() + messagebox.showinfo("Sucesso", "Pessoa 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() - messagebox.showinfo("Sucesso", "Pessoa alterada com sucesso.") def apagar_pessoa(self): selecionado = self.tree.selection() @@ -168,9 +172,13 @@ class FramePessoas(tk.Frame): item = self.tree.item(selecionado[0]) id_pessoa, nome_pessoa = item['values'] if messagebox.askyesno("Confirmar", f"Tem certeza que deseja apagar '{nome_pessoa}'?"): - self.bd.pessoas.remover(id_pessoa) - self.popular_treeview() - messagebox.showinfo("Sucesso", "Pessoa apagada com sucesso.") + try: + self.bd.pessoas.remover(id_pessoa) + self.popular_treeview() + messagebox.showinfo("Sucesso", "Pessoa apagada com sucesso.") + except EntidadeNaoEncontradaException as e: + messagebox.showerror("Erro", f"Não foi possível apagar: {e}\nA lista será atualizada.") + self.popular_treeview() def _realizar_busca(self): termo_busca = self.entry_busca.get().strip().lower() diff --git a/visao/frames/frame_pet.py b/visao/frames/frame_pet.py index 01f8097..6df41f0 100644 --- a/visao/frames/frame_pet.py +++ b/visao/frames/frame_pet.py @@ -152,20 +152,24 @@ class FramePet(tk.Frame): item = self.tree.item(selecionado[0]) id_pet, _, _ = item['values'] - pet_atual = self.bd.pets.buscar_por_id(id_pet) - if not pet_atual: - messagebox.showerror("Erro", "Pet não encontrado no banco de dados.") - return + try: + pet_atual = self.bd.pets.buscar_por_id(id_pet) + if not pet_atual: + messagebox.showerror("Erro", "Pet não encontrado no banco de dados.") + return - dialog = DialogoEditarPet(self, pet_atual) - self.wait_window(dialog) + dialog = DialogoEditarPet(self, pet_atual) + self.wait_window(dialog) - if dialog.result: - pet_atual.nome = dialog.result["nome"] - pet_atual.especie = dialog.result["especie"] - self.bd.pets.alterar(pet_atual.id, pet_atual) + if dialog.result: + pet_atual.nome = dialog.result["nome"] + pet_atual.especie = dialog.result["especie"] + self.bd.pets.alterar(pet_atual.id, pet_atual) + self.popular_treeview() + messagebox.showinfo("Sucesso", "Pet alterado com sucesso.") + except EntidadeNaoEncontradaException as e: + messagebox.showerror("Erro", f"Não foi possível alterar: {e}\nA lista será atualizada.") self.popular_treeview() - messagebox.showinfo("Sucesso", "Pet alterado com sucesso.") def apagar_pet(self): selecionado = self.tree.selection() @@ -176,9 +180,13 @@ class FramePet(tk.Frame): item = self.tree.item(selecionado[0]) id_pet, nome_pet, _ = item['values'] # Ignora a espécie, que agora está na treeview if messagebox.askyesno("Confirmar", f"Tem certeza que deseja apagar '{nome_pet}'?"): - self.bd.pets.remover(id_pet) - self.popular_treeview() - messagebox.showinfo("Sucesso", "Pet apagada com sucesso.") + try: + self.bd.pets.remover(id_pet) + self.popular_treeview() + messagebox.showinfo("Sucesso", "Pet apagada com sucesso.") + except EntidadeNaoEncontradaException as e: + messagebox.showerror("Erro", f"Não foi possível apagar: {e}\nA lista será atualizada.") + self.popular_treeview() def _realizar_busca(self): termo_busca = self.entry_busca.get().strip().lower()