Erro ao tentar fazer um código

Estou tentando fazer esse código mas está dando erro, poderiam me ajudar.
import tkinter as tk
from tkinter import ttk, messagebox
import sqlite3

class AplicativoVendas:
    def __init__(self, janela, conexao):
        self.janela = janela
        self.janela.title("Estven")

        self.conexao = conexao

        # Configurações de estilo de texto
        self.estilo_texto = ('Arial', 14, 'bold')
        self.cor_texto = 'blue'

        # Adicionando o texto principal
        self.label_principal = tk.Label(janela, text="Estven", font=self.estilo_texto, fg=self.cor_texto)
        self.label_principal.pack(pady=20)

        # Adicionando botões
        self.botao_estoque = tk.Button(janela, text="Estoque", command=self.abrir_estoque)
        self.botao_estoque.pack(pady=10)

        self.botao_venda = tk.Button(janela, text="Venda", command=self.abrir_venda)
        self.botao_venda.pack(pady=10)

        self.botao_relatorios = tk.Button(janela, text="Relatórios", command=self.abrir_relatorios)
        self.botao_relatorios.pack(pady=10)

    def abrir_estoque(self):
        JanelaEstoque(self.janela, self.conexao)

    def abrir_venda(self):
        JanelaVenda(self.janela, self.conexao)

    def abrir_relatorios(self):
        messagebox.showinfo("Aviso", "Abrir tela de relatórios")

class JanelaEstoque:
    def __init__(self, janela_pai, conexao):
        self.janela_estoque = tk.Toplevel(janela_pai)
        self.janela_estoque.title("Estoque")
        self.conexao = conexao

        # Verificar se a tabela "estoque" existe, e criar se necessário
        cursor = self.conexao.cursor()
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS itens_venda (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                venda_id INTEGER NOT NULL,
                produto_id INTEGER NOT NULL,
                quantidade INTEGER NOT NULL,
                valor_unitario REAL NOT NULL,
                FOREIGN KEY (venda_id) REFERENCES vendas(id),
                FOREIGN KEY (produto_id) REFERENCES estoque(id)
            )
        ''')
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS vendas (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                valor_total REAL NOT NULL,
                forma_pagamento TEXT NOT NULL
            )
        ''')
        self.conexao.commit()

        # Configuração da Treeview para exibir a lista de produtos
        self.treeview = ttk.Treeview(self.janela_estoque, columns=('ID', 'Nome', 'Quantidade', 'Valor Unitário', 'Valor Venda', 'Tipo'))
        self.treeview.heading('ID', text='ID')
        self.treeview.heading('Nome', text='Nome')
        self.treeview.heading('Quantidade', text='Quantidade')
        self.treeview.heading('Valor Unitário', text='Valor Unitário')
        self.treeview.heading('Valor Venda', text='Valor Venda')
        self.treeview.heading('Tipo', text='Tipo')
        self.treeview.pack(padx=10, pady=10)

        # Adicionar botões
        self.botao_novo = tk.Button(self.janela_estoque, text="Novo", command=self.novo_produto)
        self.botao_novo.pack(pady=5)

        self.botao_editar = tk.Button(self.janela_estoque, text="Editar", command=self.editar_produto)
        self.botao_editar.pack(pady=5)

        self.botao_excluir = tk.Button(self.janela_estoque, text="Excluir", command=self.excluir_produto)
        self.botao_excluir.pack(pady=5)

        self.botao_voltar = tk.Button(self.janela_estoque, text="Voltar", command=self.janela_estoque.destroy)
        self.botao_voltar.pack(pady=5)

        # Adicionar entrada de busca
        self.entry_busca = tk.Entry(self.janela_estoque)
        self.entry_busca.pack(pady=5)

        # Adicionar botão de busca
        self.botao_busca = tk.Button(self.janela_estoque, text="Buscar", command=self.buscar_produto)
        self.botao_busca.pack(pady=5)

        # Preencher a Treeview com dados do banco de dados
        self.carregar_dados()

        # Configurar a função de clique duplo na Treeview
        self.treeview.bind("<Double-1>", self.editar_produto)

    def buscar_produto(self):
        termo_busca = self.entry_busca.get().lower()

        # Limpar dados existentes na Treeview
        for item in self.treeview.get_children():
            self.treeview.delete(item)

        cursor = self.conexao.cursor()
        cursor.execute("SELECT * FROM estoque")
        rows = cursor.fetchall()

        for row in rows:
            if termo_busca in str(row).lower():
                self.treeview.insert('', 'end', values=row)

    def carregar_dados(self):
        # Limpar dados existentes na Treeview
        for item in self.treeview.get_children():
            self.treeview.delete(item)

        cursor = self.conexao.cursor()
        cursor.execute("SELECT * FROM estoque")
        rows = cursor.fetchall()

        for row in rows:
            self.treeview.insert('', 'end', values=row)

    def novo_produto(self):
        JanelaNovoProduto(self.janela_estoque, self.conexao, self.carregar_dados)

    def editar_produto(self, event=None):
        item_selecionado = self.treeview.selection()
        if item_selecionado:
            id_produto = self.treeview.item(item_selecionado)['values'][0]
            JanelaEditarProduto(self.janela_estoque, self.conexao, self.carregar_dados, id_produto)
        else:
            messagebox.showwarning("Aviso", "Selecione um produto para editar.")

    def excluir_produto(self):
        item_selecionado = self.treeview.selection()
        if item_selecionado:
            confirmacao = messagebox.askyesno("Confirmar Exclusão", "Tem certeza que deseja excluir este produto?")
            if confirmacao:
                id_produto = self.treeview.item(item_selecionado)['values'][0]
                self.excluir_produto_do_banco(id_produto)
                self.carregar_dados()
        else:
            messagebox.showwarning("Aviso", "Selecione um produto para excluir.")

    def excluir_produto_do_banco(self, id_produto):
        cursor = self.conexao.cursor()
        cursor.execute("DELETE FROM estoque WHERE id=?", (id_produto,))
        self.conexao.commit()

class JanelaVenda:
    def __init__(self, janela_principal, conexao):
        self.janela_venda = tk.Toplevel(janela_principal)
        self.janela_venda.title("Venda")
        self.conexao = conexao

        # Configurar a Treeview para exibir a lista de produtos para venda
        self.treeview_venda = ttk.Treeview(self.janela_venda, columns=('ID', 'Nome', 'Quantidade', 'Valor Unitário', 'Valor Venda', 'Tipo'))
        self.treeview_venda.heading('ID', text='ID')
        self.treeview_venda.heading('Nome', text='Nome')
        self.treeview_venda.heading('Quantidade', text='Quantidade')
        self.treeview_venda.heading('Valor Unitário', text='Valor Unitário')
        self.treeview_venda.heading('Valor Venda', text='Valor Venda')
        self.treeview_venda.heading('Tipo', text='Tipo')
        self.treeview_venda.pack(padx=10, pady=10)

        # Adicionar campo de pesquisa
        self.entry_pesquisa = tk.Entry(self.janela_venda)
        self.entry_pesquisa.pack(side=tk.LEFT, padx=5)

        self.botao_pesquisar = tk.Button(self.janela_venda, text="Pesquisar", command=self.pesquisar_produto)
        self.botao_pesquisar.pack(side=tk.LEFT, padx=5)

        # Adicionar campo de quantidade ao lado do botão "Adicionar ao Carrinho"
        self.entry_quantidade_carrinho = tk.Entry(self.janela_venda)
        self.label_quantidade_carrinho = tk.Label(self.janela_venda, text="Quantidade:")
        self.entry_quantidade_carrinho.pack(side=tk.LEFT, padx=5)
        self.label_quantidade_carrinho.pack(side=tk.LEFT, padx=5)

        # Adicionar botão "Adicionar ao Carrinho"
        self.botao_adicionar_carrinho = tk.Button(self.janela_venda, text="Adicionar ao Carrinho", command=self.adicionar_ao_carrinho)
        self.botao_adicionar_carrinho.pack(pady=10)

        # Adicionar botão "Visualizar Carrinho"
        self.botao_visualizar_carrinho = tk.Button(self.janela_venda, text="Visualizar Carrinho", command=self.visualizar_carrinho)
        self.botao_visualizar_carrinho.pack(pady=10)

        # Inicializar lista para armazenar itens do carrinho
        self.carrinho = []

    def adicionar_ao_carrinho(self):
        item_selecionado = self.treeview_venda.selection()
        if item_selecionado:
            id_produto = self.treeview_venda.item(item_selecionado)['values'][0]
            nome_produto = self.treeview_venda.item(item_selecionado)['values'][1]
            quantidade_disponivel = self.treeview_venda.item(item_selecionado)['values'][2]
            valor_venda = self.treeview_venda.item(item_selecionado)['values'][4]

            try:
                quantidade_digitada = int(self.entry_quantidade_carrinho.get())
                if quantidade_digitada > 0 and quantidade_digitada <= quantidade_disponivel:
                    # Lógica para adicionar ao carrinho
                    produto = {'id': id_produto, 'nome': nome_produto, 'quantidade': quantidade_digitada}
                    self.carrinho.append(produto)
                    messagebox.showinfo("Adicionado ao Carrinho",
                                        f"{quantidade_digitada} unidades de '{nome_produto}' foram adicionadas ao carrinho.")
                else:
                    messagebox.showwarning("Aviso",
                                           f"Quantidade indisponível para '{nome_produto}'. Estoque atual: {quantidade_disponivel}.")
            except ValueError:
                messagebox.showwarning("Aviso", "Por favor, insira uma quantidade válida.")
        else:
            messagebox.showwarning("Aviso", "Selecione um produto para adicionar ao carrinho.")

    def visualizar_carrinho(self):
        nova_janela_carrinho = tk.Toplevel(self.janela_venda)
        nova_janela_carrinho.title("Carrinho de Compras")

        # Criar Treeview para exibir itens no carrinho
        treeview_carrinho = ttk.Treeview(nova_janela_carrinho, columns=('Produto', 'Quantidade', 'Valor Venda'))
        treeview_carrinho.heading('Produto', text='Produto')
        treeview_carrinho.heading('Quantidade', text='Quantidade')
        treeview_carrinho.heading('Valor Venda', text='Valor Venda')
        treeview_carrinho.pack(padx=10, pady=10)

        # Adicionar coluna para mostrar o valor total
        treeview_carrinho["columns"] = (
        'Produto', 'Quantidade', 'Valor Venda', 'Valor Total')  # Adicione 'Valor Total' à lista de colunas
        treeview_carrinho.heading('Produto', text='Produto')
        treeview_carrinho.heading('Quantidade', text='Quantidade')
        treeview_carrinho.heading('Valor Venda', text='Valor Venda')
        treeview_carrinho.heading('Valor Total', text='Valor Total')  # Adicione a coluna 'Valor Total'
        treeview_carrinho.column('Produto', anchor='center', width=150)
        treeview_carrinho.column('Quantidade', anchor='center', width=80)
        treeview_carrinho.column('Valor Venda', anchor='center', width=100)
        treeview_carrinho.column('Valor Total', anchor='center', width=100)

        # Preencher Treeview com itens do carrinho
        valor_total = 0  # Inicializar o valor total
        for item in self.carrinho:
            # Recuperar informações adicionais do produto (incluindo Valor Venda)
            cursor = self.conexao.cursor()
            cursor.execute("SELECT nome, valor_venda FROM estoque WHERE id=?", (item['id'],))
            produto_info = cursor.fetchone()

            if produto_info:
                nome_produto, valor_venda = produto_info
                valor_total_item = item['quantidade'] * valor_venda
                valor_total += valor_total_item
                treeview_carrinho.insert('', 'end',
                                         values=(nome_produto, item['quantidade'], valor_venda, valor_total_item))

        # Adicionar rótulo para mostrar o valor total
        label_valor_total = tk.Label(nova_janela_carrinho, text=f'Valor Total: R${valor_total:.2f}')
        label_valor_total.pack(pady=10)

        # Adicionar campo para selecionar a forma de pagamento
        label_forma_pagamento = tk.Label(nova_janela_carrinho, text="Forma de Pagamento:")
        label_forma_pagamento.pack(pady=5)

        forma_pagamento_var = tk.StringVar()
        entry_forma_pagamento = ttk.Combobox(nova_janela_carrinho, textvariable=forma_pagamento_var,
                                             values=['Dinheiro', 'Cartão', 'PIX'])
        entry_forma_pagamento.pack(pady=5)
        entry_forma_pagamento.set('Dinheiro')  # Padrão para 'Dinheiro'

        # Adicionar botão para concluir a venda
        botao_concluir_venda = tk.Button(nova_janela_carrinho, text="Concluir Venda",
                                         command=lambda: self.concluir_venda(forma_pagamento_var.get(),
                                                                             nova_janela_carrinho))
        botao_concluir_venda.pack(pady=10)

    def concluir_venda(self, forma_pagamento):
        if not self.carrinho:
            messagebox.showwarning("Aviso", "Carrinho vazio. Adicione itens ao carrinho antes de concluir a venda.")
            return

        # Calcular o valor total da venda
        valor_total = sum(item['quantidade'] * item['valor_venda'] for item in self.carrinho)

        # Registrar a venda no banco de dados
        cursor = self.conexao.cursor()
        cursor.execute("INSERT INTO vendas (valor_total, forma_pagamento) VALUES (?, ?)",
                       (valor_total, forma_pagamento))
        venda_id = cursor.lastrowid  # Recuperar o ID da venda recém-inserida

        # Atualizar o estoque e registrar os itens vendidos
        for item in self.carrinho:
            cursor.execute("UPDATE estoque SET quantidade=quantidade-? WHERE id=?", (item['quantidade'], item['id']))
            cursor.execute("INSERT INTO vendas (valor_total, forma_pagamento) VALUES (?, ?)",
                           (round(valor_total, 2), forma_pagamento))

        # Limpar o carrinho após a venda
        self.carrinho = []

        # Commit das alterações no banco de dados
        self.conexao.commit()

        # Exemplo: mostrar uma mensagem informando que a venda foi concluída
        messagebox.showinfo("Venda Concluída",
                            f"A venda foi concluída. Forma de Pagamento: {forma_pagamento}. Valor Total: R${valor_total:.2f}")

        # Fechar a janela de visualização do carrinho
        nova_janela_carrinho.destroy()

    def pesquisar_produto(self):
        termo_pesquisa = self.entry_pesquisa.get().lower()

        # Limpar dados existentes na Treeview
        for item in self.treeview_venda.get_children():
            self.treeview_venda.delete(item)

        cursor = self.conexao.cursor()
        cursor.execute("SELECT * FROM estoque")
        rows = cursor.fetchall()

        for row in rows:
            if termo_pesquisa in str(row).lower():
                self.treeview_venda.insert('', 'end', values=row)


    def realizar_venda(self):
        item_selecionado = self.treeview_venda.selection()
        if item_selecionado:
            id_produto = self.treeview_venda.item(item_selecionado)['values'][0]
            nome_produto = self.treeview_venda.item(item_selecionado)['values'][1]
            quantidade_disponivel = self.treeview_venda.item(item_selecionado)['values'][2]
            valor_venda = self.treeview_venda.item(item_selecionado)['values'][4]

            # Perguntar ao usuário a quantidade a ser vendida
            quantidade_vendida = simpledialog.askinteger("Quantidade", f"Quantidade de '{nome_produto}' a ser vendida:",
                                                         minvalue=1, maxvalue=quantidade_disponivel)

            if quantidade_vendida:
                # Atualizar quantidade em estoque
                nova_quantidade = quantidade_disponivel - quantidade_vendida
                cursor = self.conexao.cursor()
                cursor.execute("UPDATE estoque SET quantidade=? WHERE id=?", (nova_quantidade, id_produto))
                self.conexao.commit()

                messagebox.showinfo("Venda Realizada", f"{quantidade_vendida} unidades de '{nome_produto}' foram vendidas.")
                self.janela_venda.destroy()
            else:
                messagebox.showwarning("Aviso", "Quantidade inválida.")
        else:
            messagebox.showwarning("Aviso", "Selecione um produto para realizar a venda.")

class JanelaNovoProduto:
    def __init__(self, janela_pai, conexao, callback_atualizar):
        self.janela_novo_produto = tk.Toplevel(janela_pai)
        self.janela_novo_produto.title("Novo Produto")
        self.conexao = conexao
        self.callback_atualizar = callback_atualizar

        # Adicionando campos de entrada e rótulos
        tk.Label(self.janela_novo_produto, text="Nome:").pack(pady=5)
        self.entry_nome = tk.Entry(self.janela_novo_produto)
        self.entry_nome.pack(pady=5)

        tk.Label(self.janela_novo_produto, text="Quantidade:").pack(pady=5)
        self.entry_quantidade = tk.Entry(self.janela_novo_produto)
        self.entry_quantidade.pack(pady=5)

        tk.Label(self.janela_novo_produto, text="Valor Unitário:").pack(pady=5)
        self.entry_valor_unitario = tk.Entry(self.janela_novo_produto)
        self.entry_valor_unitario.pack(pady=5)

        tk.Label(self.janela_novo_produto, text="Valor Venda:").pack(pady=5)
        self.entry_valor_venda = tk.Entry(self.janela_novo_produto)
        self.entry_valor_venda.pack(pady=5)

        tk.Label(self.janela_novo_produto, text="Tipo:").pack(pady=5)
        self.tipo_var = tk.StringVar()
        self.entry_tipo = ttk.Combobox(self.janela_novo_produto, textvariable=self.tipo_var, values=['Unitário', 'Pacote'])
        self.entry_tipo.pack(pady=5)

        # Adicionando botão de salvar
        self.botao_salvar = tk.Button(self.janela_novo_produto, text="Salvar", command=self.salvar_produto)
        self.botao_salvar.pack(pady=10)

    def salvar_produto(self):
        nome = self.entry_nome.get()
        quantidade = self.entry_quantidade.get()
        valor_unitario = self.entry_valor_unitario.get()
        valor_venda = self.entry_valor_venda.get()
        tipo = self.tipo_var.get()

        if nome and quantidade and valor_unitario and valor_venda and tipo:
            try:
                quantidade = int(quantidade)
                valor_unitario = float(valor_unitario.replace(',', '.'))  # Substituir ',' por '.' para tratar valores fracionados
                valor_venda = float(valor_venda.replace(',', '.'))  # Substituir ',' por '.' para tratar valores fracionados
                cursor = self.conexao.cursor()
                cursor.execute("INSERT INTO estoque (nome, quantidade, valor_unitario, valor_venda, tipo) VALUES (?, ?, ?, ?, ?)",
                               (nome, quantidade, valor_unitario, valor_venda, tipo))
                self.conexao.commit()
                messagebox.showinfo("Sucesso", "Produto adicionado com sucesso.")
                self.janela_novo_produto.destroy()
                self.callback_atualizar()
            except ValueError:
                messagebox.showerror("Erro", "Por favor, insira valores numéricos válidos.")
        else:
            messagebox.showwarning("Aviso", "Por favor, preencha todos os campos.")

class JanelaEditarProduto(JanelaNovoProduto):
    def __init__(self, janela_pai, conexao, callback_atualizar, id_produto):
        super().__init__(janela_pai, conexao, callback_atualizar)
        self.janela_novo_produto.title("Editar Produto")
        self.id_produto = id_produto

        # Preencher os campos com os dados do produto selecionado
        cursor = self.conexao.cursor()
        cursor.execute("SELECT * FROM estoque WHERE id=?", (id_produto,))
        produto = cursor.fetchone()

        if produto:
            self.entry_nome.insert(0, produto[1])
            self.entry_quantidade.insert(0, produto[2])
            self.entry_valor_unitario.insert(0, produto[3])
            self.entry_valor_venda.insert(0, produto[4])
            self.tipo_var.set(produto[5])
        else:
            messagebox.showwarning("Aviso", "Produto não encontrado.")

    def salvar_produto(self):
        nome = self.entry_nome.get()
        quantidade = self.entry_quantidade.get()
        valor_unitario = self.entry_valor_unitario.get()
        valor_venda = self.entry_valor_venda.get()
        tipo = self.tipo_var.get()

        if nome and quantidade and valor_unitario and valor_venda and tipo:
            try:
                quantidade = int(quantidade)
                valor_unitario = float(valor_unitario.replace(',', '.'))  # Substituir ',' por '.' para tratar valores fracionados
                valor_venda = float(valor_venda.replace(',', '.'))  # Substituir ',' por '.' para tratar valores fracionados
                cursor = self.conexao.cursor()
                cursor.execute("UPDATE estoque SET nome=?, quantidade=?, valor_unitario=?, valor_venda=?, tipo=? WHERE id=?",
                               (nome, quantidade, valor_unitario, valor_venda, tipo, self.id_produto))
                self.conexao.commit()
                messagebox.showinfo("Sucesso", "Produto atualizado com sucesso.")
                self.janela_novo_produto.destroy()
                self.callback_atualizar()
            except ValueError:
                messagebox.showerror("Erro", "Por favor, insira valores numéricos válidos.")
        else:
            messagebox.showwarning("Aviso", "Por favor, preencha todos os campos.")

if __name__ == "__main__":
    conexao_banco = sqlite3.connect("estoque.db")

    janela_principal = tk.Tk()
    app = AplicativoVendas(janela_principal, conexao_banco)
    janela_principal.mainloop()

    # Fechar a conexão com o banco de dados ao encerrar o programa
    conexao_banco.close()

Está dando esse erro: Exception in Tkinter callback
Traceback (most recent call last):
File “C:\Users\danil\AppData\Local\Programs\Python\Python311\Lib\tkinter_init_.py”, line 1948, in call
return self.func(*args)
^^^^^^^^^^^^^^^^
File “C:\Users\danil\Desktop\Projeto Aplicativo Loja\teste.py”, line 276, in
command=lambda: self.concluir_venda(forma_pagamento_var.get(),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: JanelaVenda.concluir_venda() takes 2 positional arguments but 3 were given

On lines 276-277 you have:

self.concluir_venda(forma_pagamento_var.get(), nova_janela_carrinho)

That’s 2 arguments being passed to a method. When the method is called, it’s passed self and the arguments, which is a total of 3 here.

On line 280 you have:

def concluir_venda(self, forma_pagamento):

That’s self plus 1 other argument, which is a total of 2 aguments.

It looks like you forgot that you are also passing nova_janela_carrinho to the method.