Advertisement
MizunoBrasil

Controle de Pagamento Diarista Código Python exe Windows

Sep 5th, 2024
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.73 KB | None | 0 0
  1. # Compilar com pyinstaller --windowed --hidden-import babel.numbers --hidden-import babel.localedata nome_do_arquivo.py
  2.  
  3. import tkinter as tk
  4. from tkinter import ttk, messagebox, simpledialog, filedialog
  5. from tkcalendar import Calendar
  6. from threading import Thread
  7. import sqlite3
  8. from reportlab.lib.pagesizes import letter
  9. from reportlab.pdfgen import canvas
  10. import locale
  11. from datetime import datetime
  12. from PIL import Image
  13. import os
  14.  
  15. class CalendarApp:
  16.     def __init__(self, root):
  17.         self.root = root
  18.         self.root.title("Pagamentos Luzia")
  19.         self.center_window(400, 650)
  20.  
  21.         self.selected_dates = []
  22.         self.db_name = 'pagamentos-diarista.db'
  23.  
  24.         # Conectar ao banco de dados
  25.         self.conn = sqlite3.connect(self.db_name)
  26.         self.cursor = self.conn.cursor()
  27.         self.create_table()
  28.  
  29.         # Cria o calendário
  30.         self.cal = Calendar(root, selectmode="day", year=2024, month=8, day=31, date_pattern='dd/mm/yyyy')
  31.         self.cal.pack(pady=20)
  32.  
  33.         # Cria o botão para marcar a data
  34.         mark_button = ttk.Button(root, text="Marcar Data", command=self.mark_date)
  35.         mark_button.pack(pady=10)
  36.  
  37.         # Label para mostrar as datas marcadas
  38.         self.label = ttk.Label(root, text="Datas Marcadas:")
  39.         self.label.pack(pady=10)
  40.  
  41.         self.dates_text = tk.Text(root, height=10, width=40)
  42.         self.dates_text.pack(pady=10)
  43.         self.load_dates()
  44.  
  45.         # Botão para finalizar e calcular o valor total
  46.         finish_button = ttk.Button(root, text="Finalizar Marcação", command=self.finalize_dates)
  47.         finish_button.pack(pady=10)
  48.  
  49.         # Botão para gerar PDF
  50.         pdf_button = ttk.Button(root, text="Gerar PDF", command=self.generate_pdf_with_image)
  51.         pdf_button.pack(pady=10)
  52.  
  53.         # Botão para apagar banco de dados
  54.         clear_button = ttk.Button(root, text="Apagar Banco de Dados", command=self.clear_database)
  55.         clear_button.pack(pady=10)
  56.  
  57.     def create_table(self):
  58.         self.cursor.execute('''CREATE TABLE IF NOT EXISTS datas (
  59.                                id INTEGER PRIMARY KEY,
  60.                                data TEXT,
  61.                                valor REAL)''')
  62.         self.conn.commit()
  63.  
  64.     def mark_date(self):
  65.         selected = self.cal.get_date()
  66.  
  67.         if selected not in self.selected_dates:
  68.             try:
  69.                 # Pede ao usuário para informar o valor da marcação
  70.                 value = float(simpledialog.askstring("Valor", "Informe o valor para a data marcada (em R$):"))
  71.                 self.selected_dates.append((selected, value))
  72.                 self.cursor.execute("INSERT INTO datas (data, valor) VALUES (?, ?)", (selected, value))
  73.                 self.conn.commit()
  74.                 self.dates_text.insert(tk.END, f"{selected} - R${value:.2f}\n")
  75.             except ValueError:
  76.                 messagebox.showerror("Erro", "Por favor, insira um valor válido.")
  77.  
  78.     def load_dates(self):
  79.         self.cursor.execute("SELECT data, valor FROM datas")
  80.         rows = self.cursor.fetchall()
  81.         for row in rows:
  82.             date, value = row
  83.             self.dates_text.insert(tk.END, f"{date} - R${value:.2f}\n")
  84.             self.selected_dates.append((date, value))
  85.  
  86.     def finalize_dates(self):
  87.         total_value = sum(value for _, value in self.selected_dates)
  88.         selected_dates_str = "\n".join([f"{date} - R${value:.2f}" for date, value in self.selected_dates])
  89.         messagebox.showinfo("Finalização", f"Datas selecionadas:\n{selected_dates_str}\n\nValor total: R${total_value:.2f}")
  90.  
  91.     def generate_pdf_with_image(self):
  92.         if not self.selected_dates:
  93.             messagebox.showerror("Erro", "Nenhuma data foi marcada.")
  94.             return
  95.  
  96.         # Solicitar que o usuário selecione uma imagem para ser adicionada ao PDF
  97.         img_path = filedialog.askopenfilename(filetypes=[("Image files", "*.jpg;*.jpeg;*.png")])
  98.         if not img_path:
  99.             messagebox.showerror("Erro", "Nenhuma imagem foi selecionada.")
  100.             return
  101.  
  102.         # Usar uma thread para gerar o PDF e evitar travamento da interface
  103.         thread = Thread(target=self.process_pdf_generation, args=(img_path,))
  104.         thread.start()
  105.  
  106.     def process_pdf_generation(self, img_path):
  107.         try:
  108.             # Definir a localidade para Português do Brasil
  109.             locale.setlocale(locale.LC_TIME, 'pt_BR.utf8')
  110.  
  111.             # Obtendo o nome do mês e o ano da primeira data marcada no calendário
  112.             first_selected_date = self.selected_dates[0][0]
  113.             first_selected_date_obj = datetime.strptime(first_selected_date, '%d/%m/%Y')
  114.             selected_month = first_selected_date_obj.strftime("%B").capitalize()
  115.             selected_year = first_selected_date_obj.strftime("%Y")
  116.  
  117.             # Adicionar o dia, mês, ano, hora, minuto e segundo ao nome do arquivo para torná-lo único
  118.             current_time = datetime.now().strftime('%d-%m-%Y-%H-%M-%S')
  119.             pdf_filename = f"pagamento-luzia-{selected_month}-{selected_year}-{current_time}.pdf"
  120.  
  121.             c = canvas.Canvas(pdf_filename, pagesize=letter)
  122.  
  123.             # Configura o tamanho da fonte
  124.             font_size = 14
  125.             c.setFont("Helvetica", font_size)
  126.  
  127.             # Título com o mês e ano baseados na primeira data marcada
  128.             title = f"Pagamentos Luzia - {selected_month} de {selected_year}"
  129.             c.drawString(100, 780, title)
  130.  
  131.             # Subtítulo "Datas"
  132.             c.drawString(100, 750, "Datas:")
  133.  
  134.             y_position = 730
  135.             for date, value in self.selected_dates:
  136.                 c.drawString(100, y_position, f"{date} - R${value:.2f}")
  137.                 y_position -= 20
  138.  
  139.             total_value = sum(value for _, value in self.selected_dates)
  140.             c.drawString(100, y_position - 20, f"Valor Total: R${total_value:.2f}")
  141.  
  142.             # Adicionar a linha "Pagamento realizado através do PIX na chave [numero]." 7 linhas abaixo do "Valor Total"
  143.             payment_info_y_position = y_position - 20 - (7 * 20)
  144.             c.drawString(100, payment_info_y_position, "Pagamento realizado através do PIX na chave 31xxxxxxx.")
  145.  
  146.             # Adicionar o rodapé na parte inferior da página com a data e o nome do arquivo em itálico (somente na primeira página)
  147.             footer_y_position = 50  # Próximo ao final da página
  148.             footer_text_2 = f"Arquivo {pdf_filename} gerado em {datetime.now().strftime('%d/%m/%Y')}"
  149.  
  150.             # Muda o x_position para 10 para alinhar à esquerda
  151.             c.setFont("Helvetica-Oblique", font_size)  # Muda a fonte para itálico
  152.             c.drawString(10, footer_y_position, footer_text_2)
  153.  
  154.             # Finalizar a primeira página do PDF
  155.             c.showPage()
  156.  
  157.             # Criar uma nova página para a imagem
  158.             # Carregar a imagem e ajustar a proporção para caber na página
  159.             image = Image.open(img_path)
  160.             image_width, image_height = image.size
  161.             page_width, page_height = letter
  162.  
  163.             # Calculando a escala mantendo a proporção
  164.             ratio = min(page_width / image_width, page_height / image_height)
  165.             new_width = image_width * ratio
  166.             new_height = image_height * ratio
  167.  
  168.             # Centralizando a imagem na página
  169.             x_position = (page_width - new_width) / 2
  170.             y_position_image = (page_height - new_height) / 2
  171.  
  172.             # Desenhar a imagem na nova página
  173.             c.drawImage(img_path, x_position, y_position_image, new_width, new_height)
  174.  
  175.             c.save()
  176.             messagebox.showinfo("PDF Gerado", f"PDF gerado com sucesso: {pdf_filename}")
  177.  
  178.         except Exception as e:
  179.             messagebox.showerror("Erro", f"Ocorreu um erro: {str(e)}")
  180.  
  181.     def clear_database(self):
  182.         # Confirmação antes de apagar o banco de dados
  183.         response = messagebox.askyesno("Confirmação", "Tem certeza que deseja apagar todas as datas?")
  184.         if response:  # Se o usuário confirmar
  185.             self.cursor.execute("DELETE FROM datas")
  186.             self.conn.commit()
  187.             self.selected_dates.clear()
  188.             self.dates_text.delete(1.0, tk.END)
  189.             messagebox.showinfo("Banco de Dados", "Todas as datas foram apagadas com sucesso.")
  190.  
  191.     def center_window(self, width, height):
  192.         screen_width = self.root.winfo_screenwidth()
  193.         screen_height = self.root.winfo_screenheight()
  194.  
  195.         x = int((screen_width / 2) - (width / 2))
  196.         y = int((screen_height / 2) - (height / 2))
  197.  
  198.         self.root.geometry(f'{width}x{height}+{x}+{y}')
  199.  
  200.     def __del__(self):
  201.         self.conn.close()
  202.  
  203. if __name__ == "__main__":
  204.     root = tk.Tk()
  205.     app = CalendarApp(root)
  206.     root.mainloop()
  207.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement