def cria_testes(verb):
    global cache, nome_tb, letra_tb, colunas, diags
    inicializa(True)
    # Identificador de usuários e lista de poltronas de cada pedido de compra:
    lista_cupsf = \
      [
        ( "C-00000001", "U-00000001", "Amanda Almeida",  "45.246.235-2",   True, ),
        ( "C-00000002", "U-00000001", "Basílio Barros",  "234.764.987-23", True, ),
        ( "C-00000003", "U-00000002", "Carlos Costa",    "76.863.987-5",   True, ),
        ( "C-00000004", "U-00000002", "Diego Dias",      "654.987.098-09", False,),
        ( "C-00000005", "U-00000002", "Romario Silva",   "122.787.038-05", False,),
        ( "C-00000006", "U-00000001", "Fabio Santos",    "555.957.058-05", True, ),
        ( "C-00000007", "U-00000001", "Renato Augusto",  "111.227.338-03", False,),
        ( "C-00000008", "U-00000001", "Carlos Tevez",    "666.967.698-06", True, ),
        ( "C-00000009", "U-00000002", "André Santos",    "554.181.018-01", False,),
        ( "C-00000010", "U-00000002", "Victor Cantillo", "444.955.085-08", True, ),
      ]
    for id_cpr_esp, id_cliente, nome_pass, doc_pass, comprando in lista_cupsf:
        cliente = usuario.busca_por_identificador(id_cliente)

        cpr = cria(cliente, nome_pass, doc_pass)
        assert cpr != None and type(cpr) is compra.Objeto_Compra
        id_cpr = compra.obtem_identificador(cpr)
        if not comprando: compra.fecha(cpr)

        # Paranóia:
        assert id_cpr == id_cpr_esp
        cliente_1 = compra.obtem_cliente(cpr)
        id_cliente_1 = usuario.obtem_identificador(cliente_1)
        assert id_cliente_1 == id_cliente

        if verb:
            sys.stderr.write("compra %s de %s criada\n" % (id_cpr, id_cliente))
    return
Beispiel #2
0
def pode_trocar(usr, pol):
  global cache, nome_tb, letra_tb, colunas, diags

  if usr == None or pol == None: return False

  assert type(usr) is usuario.Objeto_Usuario
  assert type(pol) is poltrona.Objeto_Poltrona
  
  # A poltrona {pol} está reservada a alguma compra?
  id_cpr = poltrona.obtem_atributo(pol, 'id_compra'); 
  if id_cpr == None: return False
  
  # A compra {cpr} ainda está aberta?
  cpr = compra.busca_por_identificador(id_cpr)
  assert cpr != None # Paranóia.
  if compra.obtem_atributo(cpr, 'status') != 'comprando': return False

  # O trecho da poltrona {pol} ainda não foi encerrado?
  id_trc_pol = poltrona.obtem_atributo(pol, 'id_trecho');
  trc_pol = None if id_trc_pol == None else trecho.busca_por_identificador(id_trc_pol)
  assert trc_pol != None # Paranóia.
  if trecho.obtem_atributo(trc_pol, 'encerrado'): return False
  
  # O usuário tem direito de excluir e comprar nessa compra?
  dono = (compra.obtem_cliente(cpr) == usr)
  if not dono: return False
  
  # Pode trocar, parece:
  return True
def gera(cpr, ver, id_carrinho):

    id_cpr = compra.obtem_identificador(cpr)
    usr = compra.obtem_cliente(cpr)
    id_usr = usuario.obtem_identificador(usr)
    atrs_compra = compra.obtem_atributos(cpr)
    preco_tot = compra.calcula_preco(cpr)
    nome_pass = atrs_compra['nome_pass']
    doc_pass = atrs_compra['doc_pass']

    ids_poltronas = poltrona.busca_por_compra(cpr)
    num_poltronas = len(ids_poltronas)

    icone_carrinho = "<b>&#128722;</b>" if id_cpr == id_carrinho else ""

    # !!! Definir um estilo decente para os campos? Ou definir fora do {html_table}? !!!
    ht_carrinho = icone_carrinho
    ht_cpr = id_cpr
    ht_usr = id_usr
    ht_num_poltronas = str(num_poltronas)
    ht_preco_tot = str(preco_tot)
    ht_nome_pass = nome_pass
    ht_doc_pass = doc_pass

    campos = [
        ht_carrinho, ht_cpr, ht_usr, ht_num_poltronas, ht_nome_pass,
        ht_doc_pass, ht_preco_tot
    ]

    if ver:
        ht_ver = html_botao_simples.gera("Ver", "ver_compra",
                                         {'id_compra': id_cpr}, "#22ff22")
        campos.append(ht_ver)

    return campos
def gera(ids_poltronas, usr, carr):

    id_trc = None  # Identificador do trecho comum, ou None.

    admin = False if usr == None else usuario.obtem_atributo(
        usr, 'administrador')
    fazer_checkin = admin  # Por enquanto.
    embarcar = admin  #Por enquanto

    if admin or usr == None:
        assert carr == None  # Administrador e não-logado não tem carrinho.
    id_carr = None if carr == None else compra.obtem_identificador(carr)

    # Gera a linha de os cabeçalhos das colunas
    linha_cab = html_resumo_de_poltrona_de_trecho.gera_cabecalho(fazer_checkin)
    assert type(linha_cab) is list or type(linha_cab) is tuple  # Paranóia.

    # Gera as linhas da tabela.
    linhas = [].copy()
    for id_poltrona in ids_poltronas:
        pol = poltrona.busca_por_identificador(id_poltrona)

        # Obtem dados da poltrona:
        assert pol != None
        id_trc_pol = poltrona.obtem_atributo(pol, 'id_trecho')
        id_cpr_pol = poltrona.obtem_atributo(pol, 'id_compra')
        cpr_pol = None if id_cpr_pol == None else compra.busca_por_identificador(
            id_cpr_pol)
        usr_pol = None if cpr_pol == None else compra.obtem_cliente(cpr_pol)

        # Verifica se o trecho é o mesmo para todas as poltronas:
        if id_trc != None: assert id_trc_pol == id_trc
        id_trc = id_trc_pol

        # Decide que botões vai ter:
        alterar = admin
        comprar = (carr != None) and poltrona.pode_comprar(usr, pol, carr)
        excluir = (cpr_pol != None) and (usr_pol
                                         == usr) and poltrona.pode_excluir(
                                             usr, pol)

        # Gera os campos da linha:
        linha = html_resumo_de_poltrona_de_trecho.gera(pol, alterar, comprar,
                                                       excluir, fazer_checkin,
                                                       embarcar)
        assert type(linha) is list or type(linha) is tuple  # Paranóia.
        linhas.append(linha)

    ht_tabela = html_table.gera(linhas, linha_cab)
    ht_legenda = html_resumo_de_poltrona_de_trecho.gera_legenda(fazer_checkin)
    ht_res = ht_tabela + ht_legenda
    return ht_res
def verifica_compra(rotulo, cpr, ident, cliente, status, nome_pass, doc_pass):
    """Testes básicos de consistência do objeto {cpr} da classe {Objeto_Compra}, dados
  {ident} e {atrs} esperados."""
    global ok_global

    sys.stderr.write("%s\n" % ("-" * 70))
    sys.stderr.write("verificando compra %s\n" % rotulo)
    atrs = {
        'cliente': cliente,
        'status': status,
        'nome_pass': nome_pass,
        'doc_pass': doc_pass
    }
    ok = compra.verifica(cpr, ident, atrs)

    if cpr != None and type(cpr) is compra.Objeto_Compra:

        sys.stderr.write("testando {obtem_cliente()}:\n")
        usr1 = compra.obtem_cliente(cpr)
        if usr1 != cliente:
            aviso_prog(
                "retornou " + str(usr1) + ", deveria ter retornado " +
                str(cliente), True)
            ok = False

        sys.stderr.write("testando {obtem_status()}:\n")
        status1 = compra.obtem_status(cpr)
        if status1 != status:
            aviso_prog(
                "retornou " + str(status1) + ", deveria ter retornado " +
                str(status), True)
            ok = False

        # erro na implementação de poltrona
        # sys.stderr.write("testando {obtem_poltronas()}:\n")
        # itens1 = compra.obtem_poltronas(cpr)
        # if itens1 != usr:
        #   aviso_prog("retornou " + str(itens1) + ", deveria ter retornado " + str(usr),True)
        #   ok = False

    if not ok:
        aviso_prog("teste falhou", True)
        ok_global = False

    sys.stderr.write("%s\n" % ("-" * 70))
    return
Beispiel #6
0
def processa(ses, args):

  # Obtem o dono da sessão {ses}:
  usr_ses = None if ses == None else sessao.obtem_usuario(ses)
  assert usr_ses != None # Usuário não logado não deveria ter acesso a este comando.
  admin = False if usr_ses == None else usuario.obtem_atributo(usr_ses, 'administrador')
  carr = None if ses == None else sessao.obtem_carrinho(ses) # Carrinho de compras da sessão.

  # Obtem a poltrona a excluir:
  id_pol = args['id_poltrona']
  pol = None if id_pol == None else poltrona.busca_por_identificador(id_pol)
  assert pol != None # A poltrona deve estar identificada em {args}.
  del args['id_poltrona']
  
  # Obtem a compra de onde excluir:
  id_cpr_pol = poltrona.obtem_atributo(pol, 'id_compra')
  cpr_pol = None if id_cpr_pol == None else compra.busca_por_identificador(id_cpr_pol)
  assert cpr_pol != None # A poltrona não pode estar livre.
  
  # Obtem o dono da compra:
  usr_pol = compra.obtem_cliente(cpr_pol)
  assert usr_pol != None # Paranoia.
  
  # Verifica permissão:
  assert admin or (usr_pol == usr_ses) # Outro usuário não deveria ter acesso a este comando.

  try:
    # Ao definir {id_compra} como {None}, estamos excluindo a poltrona
    poltrona.muda_atributos(pol, {'id_compra': None})

    if (not admin) and (cpr_pol != carr):
      # Mudamos o carrinho:
      sessao.muda_atributos(ses, {'carrinho': cpr_pol})
      aviso = ("Seu carrinho agora é a compra %s" % id_cpr_pol)
    else:
      aviso = None

    # Gera a página de retorno:
    pag = html_pag_compra.gera(ses, cpr_pol, None, aviso)
  except ErroAtrib as ex:
    erros = ex[0]
    # Mostra a página da poltrona com mesmos args e erro:
    pag = html_pag_compra.gera(ses, cpr_pol, args, aviso)
  return pag
def testa_nome_passageiro_null():
    # Valores originais
    id_cpr = 'C-00000001'
    cpr = compra.busca_por_identificador(id_cpr)
    usr = compra.obtem_cliente(cpr)
    id_usr = usuario.obtem_identificador(usr)
    status = compra.obtem_atributo(cpr, 'status')
    nome_pass_org = compra.obtem_atributo(cpr, 'nome_pass')

    # Novos valores
    args = {'id_compra': id_cpr, 'id_usr': id_usr, 'status': status}

    testa("NoPass", ses, args)

    # Valores atualizados
    cpr_mod = compra.busca_por_identificador('C-00000001')
    nome_pass_mod = compra.obtem_atributo(cpr_mod, 'nome_pass')

    assert nome_pass_mod == nome_pass_org, "Compra não atualizada"
Beispiel #8
0
def processa(ses, args):

    # Validações, por via das dúvidas:
    # Falhas são erros de programação e não do usuário.
    assert ses != None  # Deveria acontecer.
    assert sessao.aberta(ses)  # Deveria acontecer.

    usr = sessao.obtem_usuario(ses)
    assert usr != None  # Deveria acontecer.

    # Obtém id da compra a ver
    id_cpr = args['id_compra'] if 'id_compra' in args else None
    assert id_cpr != None  # Paranóia (formulário deve incluir sempre).
    del args['id_compra']
    cpr = compra.busca_por_identificador(id_cpr)
    assert cpr != None  # Paranóia.

    # O dono da sessão pode examinar essa compra?
    autorizado = (compra.obtem_cliente(cpr)
                  == usr) or sessao.eh_administrador(ses)
    assert autorizado  # Paranóia (cliente não deveria ter acesso a compras de outros).

    pag = html_pag_compra.gera(ses, cpr, None, None)
    return pag
Beispiel #9
0
def gera(ses, pol, atrs, erros):
    # Obtem dados da sessão e seu usuário:
    usr_ses = None if ses == None else sessao.obtem_usuario(ses)
    admin = sessao.eh_administrador(ses)
    carr = None if (ses == None) or admin else sessao.obtem_carrinho(ses)

    # Obtem dados correntes da poltrona:
    assert pol != None, "poltrona deve ser especificada"
    assert type(pol) is poltrona.Objeto_Poltrona
    id_pol = poltrona.obtem_identificador(pol)
    assert id_pol != None  # Paranóia.

    # Completa {atrs} com atributos correntes de {pol}:
    if atrs == None: atrs = {}.copy()  # Por via das dúvidas.
    atrs_pol = poltrona.obtem_atributos(pol)
    assert atrs_pol != None  # Paranóia
    for ch, val in atrs_pol.items():
        if not ch in atrs: atrs[ch] = val

    # Obtem compra {cpr} da poltrona, se houver:
    id_cpr = poltrona.obtem_atributo(pol, 'id_compra')
    cpr = None if id_cpr == None else compra.busca_por_identificador(id_cpr)
    cpr_aberta = False if cpr == None else compra.obtem_status(
        cpr) == 'comprando'
    usr_cpr = None if cpr == None else compra.obtem_cliente(cpr)

    # Obtem trecho {trc} da poltrona:
    id_trc = poltrona.obtem_atributo(pol, 'id_trecho')
    assert id_trc != None  # Paranóia.
    trc = trecho.busca_por_identificador(id_trc)
    assert trc != None  # Paranóia.
    encerrado = trecho.obtem_atributo(trc, 'encerrado')

    # Gera botões da página:
    ht_submit = ""
    # Tem botão "Alterar" para alterar dados?
    if admin:
        ht_submit += html_botao_submit.gera("Alterar", "alterar_poltrona",
                                            None, "#ff0000")

    # Tem botão "Excluir" para excluir a poltrona de {cpr}?
    if poltrona.pode_excluir(usr_ses, pol):
        ht_submit += html_botao_simples.gera("Excluir", "excluir_poltrona",
                                             {'id_poltrona': id_pol},
                                             "#ff4400")

    # Tem botão "Comprar" para comprar a poltrona?
    if poltrona.pode_comprar(usr_ses, pol, carr):
        ht_submit += html_botao_simples.gera("Comprar", "comprar_poltrona",
                                             {'id_poltrona': id_pol},
                                             "#ff4400")

    # Tem botão "Trocar" para trocar a poltrona?
    if poltrona.pode_trocar(usr_ses, pol):
        ht_submit += html_botao_simples.gera("Trocar", "trocar_poltrona",
                                             {'id_poltrona': id_pol},
                                             "#ff4400")

    # Botão de cancelar alteração:
    if admin:
        ht_submit += html_botao_simples.gera("Cancelar", "principal", None,
                                             "#00ff00")

    ht_conteudo = html_form_dados_de_poltrona.gera(id_pol, atrs, admin,
                                                   ht_submit)
    pag = html_pag_generica.gera(ses, ht_conteudo, erros)
    return pag
Beispiel #10
0
def gera(ses, trc, atrs, erros):
    # Obtem usuário da sessão, determina privilégios:
    usr_ses = None if ses == None else sessao.obtem_usuario(ses)
    admin = sessao.eh_administrador(ses)

    if atrs == None: atrs = {}.copy()  # Por via das dúvidas.

    # Botões de acão:
    ht_submit = ""
    if trc == None:
        # Acrescentando novo trecho:
        id_trc = None
        novo = True
        # O submit é "Acrescentar":
        ht_submit += html_botao_submit.gera("Acrescentar",
                                            "acrescentar_trecho", None,
                                            "#ff0000")
    else:
        # Visualização/alteração de trecho existente:
        assert type(trc) is trecho.Objeto_Trecho
        novo = False

        id_trc = trecho.obtem_identificador(trc)
        assert id_trc != None  # Paranóia.

        # Completa {atrs} com atributos de {trc}:
        atrs_trc = trecho.obtem_atributos(trc)
        assert atrs_trc != None  # Paranóia
        for ch, val in atrs_trc.items():
            if not ch in atrs: atrs[ch] = val

        # Botoes de ação:
        if admin:
            # O submit é "Alterar":
            ht_submit += html_botao_submit.gera("Alterar", "alterar_trecho",
                                                None, "#ff0000")
            # Tem tamém botão "Clonar":
            ht_submit += html_botao_simples.gera("Clonar", "clonar_trecho",
                                                 {'id_trecho': id_trc},
                                                 "#ff0000")

    # Constrói formulário com dados do trecho:
    ht_dados_trecho = html_form_dados_de_trecho.gera(id_trc, atrs, admin,
                                                     ht_submit)

    # Constrói a lista de poltronas do trecho:
    if novo:
        ht_dados_poltronas = ""
    else:
        # Formata a lista de poltronas:
        ids_pols_todas = poltrona.busca_por_trecho(trc)
        if admin:
            # Mostra todas as poltronas do trecho:
            ids_pols_ver = ids_pols_todas
        else:
            # Mostra só as poltronas disponíveis ou reservadas para compras do usuário {usr}:
            trc_encerrado = atrs_trc['encerrado']
            ids_pols_ver = [].copy()
            for id_pol in ids_pols_todas:
                assert id_pol != None  # Paranóia.
                pol = poltrona.busca_por_identificador(id_pol)
                assert pol != None  # Paranóia.
                id_cpr_pol = poltrona.obtem_atributo(pol, 'id_compra')
                cpr_pol = None if id_cpr_pol == None else compra.busca_por_identificador(
                    id_cpr_pol)
                usr_pol = None if cpr_pol == None else compra.obtem_cliente(
                    cpr_pol)
                # Verifica relevância de {pol} para o usuário:
                livre = (cpr_pol == None)
                if (livre and (not trc_encerrado)) or ((usr_ses != None) and
                                                       (usr_pol == usr_ses)):
                    ids_pols_ver.append(id_pol)

        if len(ids_pols_ver) == 0:
            # Não há poltronas a mostrar.
            estilo_aviso = "color:red;font-size:20;"
            ht_dados_poltronas = "<br/>" + html_span.gera(
                estilo_aviso, "Não há poltronas disponíveis")
        else:
            # Formata a lista de poltronas:
            fazer_checkin = admin  # Deve ter botão de "Checkin" em cada poltrona?
            # sys.stderr.write(" ids_pols = %s\n" % str(ids_pols))
            # sys.stderr.write(" id_trc = %s\n" % str(id_trc))

            carr = None if ses == None else sessao.obtem_carrinho(ses)
            ht_dados_poltronas = html_lista_de_poltronas_de_trecho.gera(
                ids_pols_ver, usr_ses, carr)

    # Botão "Voltar":
    ht_bt_cancel = html_botao_simples.gera("Voltar", 'principal', None,
                                           "#ff2200")

    # Monta a página:
    ht_conteudo = \
      ht_dados_trecho + "<br/>" +  \
      ht_dados_poltronas + "<br/>" +  \
      ht_bt_cancel

    pagina = html_pag_generica.gera(ses, ht_conteudo, erros)
    return pagina
Beispiel #11
0
    modulo = comando_excluir_poltrona
    funcao = modulo.processa
    frag = False  # {True} se for apenas um fragmento HTML, {False} se for página completa.
    pretty = False  # Se {True}, formata HTML para legibilidate (mas introduz brancos nos textos).
    testa_gera_html(modulo, funcao, rotulo, frag, pretty, *args)


# Sessao de usuário comum e poltrona desse usuário:
ses_com1 = sessao.busca_por_identificador("S-00000003")
usr_com1 = sessao.obtem_usuario(ses_com1)
assert not usuario.obtem_atributo(usr_com1, 'administrador')

id_cpr_com1 = "C-00000003"
cpr_com1 = compra.busca_por_identificador(id_cpr_com1)
assert compra.obtem_cliente(cpr_com1) == usr_com1
id_pol_com1 = "A-00000008"
pol_com1 = poltrona.busca_por_identificador(id_pol_com1)
assert poltrona.obtem_atributo(pol_com1, "id_compra") == id_cpr_com1

testa("com1-com1", ses_com1, {'id_poltrona': id_pol_com1})

# Sessao de administrador e poltrona de outro usuário:
ses_adm3 = sessao.busca_por_identificador("S-00000004")
usr_adm3 = sessao.obtem_usuario(ses_adm3)
assert usuario.obtem_atributo(usr_adm3, 'administrador')

id_cpr_com2 = "C-00000001"
cpr_com2 = compra.busca_por_identificador(id_cpr_com2)
usr_com2 = compra.obtem_cliente(cpr_com2)
assert not usuario.obtem_atributo(usr_com2, 'administrador')
Beispiel #12
0
def gera(ses, cpr, atrs, erros):

    # Validação dos parâmetros:
    assert ses != None  # Paranóia (cliente deslogado não deve poder ver compra nenhuma).
    assert sessao.aberta(ses)  # Paranóia.
    usr_ses = sessao.obtem_usuario(ses)
    assert usr_ses != None  # Paranóia.
    admin = usuario.obtem_atributo(usr_ses, 'administrador')
    carr = None if admin or ses == None else sessao.obtem_carrinho(ses)

    if atrs == None: atrs = {}.copy()  # Por via das dúvidas.

    # Botões de acão:
    ht_submit = ""
    ht_bt_def_carr = ""
    ht_bt_cancel = ""
    args_bt = {'id_compra': id_cpr}

    if cpr == None:
        # Nova compra:
        assert not admin  # Paranóia (administrador não deve poder criar novas compras).
        id_cpr = None
        novo = True
        titulo = "Nova compra"
    else:
        assert type(cpr) is compra.Objeto_Compra
        usr_cpr = compra.obtem_cliente(cpr)
        assert usr_cpr != None  # Paranóia.
        assert admin or (
            usr_ses == usr_cpr
        )  # Paranóia (cliente comum só pode ver compras suas).

        id_cpr = compra.obtem_identificador(cpr)
        assert id_cpr != None  # Paranóia.

        # Título da página:
        if admin:
            titulo = f"Compra {id_compra}"
        elif cpr == carr:
            titulo = "Seu carrinho de compras"
        else:
            titulo = f"Sua compra {id_compra}"
            ht_bt_def_carr = html_botao_simples.gera("Definir como carrinho",
                                                     "definir_carrinho",
                                                     args_bt, "#44ff00")

        # Completa {atrs} com atributos de {cpr}:
        atrs_cpr = compra.obtem_atributos(cpr)
        assert atrs_cpr != None  # Paranóia
        for ch, val in atrs_cpr.items():
            if not ch in atrs: atrs[ch] = val

        # Botoes de ação:
        # O submit é "Alterar":
        ht_submit += html_botao_submit.gera("Alterar", "alterar_compra", None,
                                            "#ff0000")
        if not admin and (compra.obtem_status(cpr) == 'comprando'):
            # Tem botão submit de "Finalizar compra" que aplica alterações:
            ht_submit += html_botao_submit.gera("Finalizar",
                                                "finalizar_compra", None,
                                                "#55ff00")
            ht_bt_cancel = html_botao_simples.gera("Continuar comprando",
                                                   'principal', None,
                                                   "#ff2200")
        else:
            ht_bt_cancel = html_botao_simples.gera("Voltar", 'principal', None,
                                                   "#ff2200")

    ht_titulo = "<h2>" + titulo + "</h2>"

    # Constrói formulário com dados da compra:
    ht_dados_da_compra = html_form_dados_de_compra.gera(
        id_cpr, atrs, admin, ht_submit)

    # Constrói a lista de poltronas da compra:
    if novo:
        ht_dados_das_poltronas = ""
    else:
        ids_pols = poltrona.busca_por_compra(cpr)

        if len(ids_pols) == 0:
            # Não há poltronas a mostrar.
            estilo_aviso = "color:red;font-size:20;"
            ht_dados_das_poltronas = "<br/>" + html_span.gera(
                estilo_aviso, "Não há poltronas disponíveis")
        else:
            ht_dados_das_poltronas = html_lista_de_poltronas_de_compra.gera(
                ids_pols, usr_ses, carr)

        # Verifica tempos de baldeação:
        poltronas_invalidas = compra.verificar_baldeacao(cpr)
        if erros is None: erros = [].copy()
        for id_poltrona in poltronas_invalidas:
            erros.append(f'Poltrona sem tempo para baldeação: {id_poltrona}')

    ht_conteudo = \
      ht_titulo + "\n" + \
      ht_dados_da_compra + "<br/>\n" + \
      ht_bt_def_carr + "\n" + \
      ht_bt_cancel + "<br/>\n" + \
      ht_dados_das_poltronas

    pag = html_pag_generica.gera(ses, ht_conteudo, erros)
    return pag
Beispiel #13
0
def gera(cpr, editavel, texto_bt, comando_bt):

    # Obtem atributos a mostrar:

    valores = {}.copy()
    id_cpr = compra.obtem_identificador(cpr)
    atrs_cpr = compra.obtem_atributos(cpr)

    # Atributos da compra em si
    valores['id_cpr'] = id_cpr
    valores['status'] = atrs_cpr['status']
    valores['nome_pass'] = atrs_cpr['nome_pass']
    valores['doc_pass'] = atrs_cpr['doc_pass']
    valores['preco_tot'] = ("%.2f" % compra.calcula_preco(cpr))
    # valores['pagamento'] = atrs_cpr['pagamento']

    # Cliente que está montando ou montou a compra:
    usr = compra.obtem_cliente(cpr)
    valores['id_usr'] = usuario.obtem_identificador(usr)
    atrs_usr = usuario.obtem_atributos(usr)
    valores['nome_usr'] = atrs_usr['nome']

    # Bilhetes da compra:
    ids_pols = compra.obtem_poltronas(cpr)
    num_trechos = len(ids_pols)
    valores['n_trechos'] = str(num_trechos)

    if (num_trechos >= 1):
        # Obtém origem, data, e hora de partida do primeiro trecho:
        pol_ini = poltrona.busca_por_identificador(ids_pols[0])
        id_trc_ini = poltrona.obtem_atributo(pol_ini, 'id_trecho')
        trc_ini = trecho.busca_por_identificador(id_trc_ini)
        origem = trecho.obtem_atributo(trc_ini, 'origem')
        dh_partida = trecho.obtem_dia_e_hora_de_partida(trc_ini)
        valores['partida'] = origem + " " + dh_partida

        # Obtém destino, data, e hora de chegada do último trecho:
        pol_fin = poltrona.busca_por_identificador(ids_pols[-1])
        id_trc_fin = poltrona.obtem_atributo(pol_fin, 'id_trecho')
        trc_fin = trecho.busca_por_identificador(id_trc_fin)
        destino = trecho.obtem_atributo(trc_fin, 'destino')
        dh_chegada = trecho.obtem_dia_e_hora_de_chegada(trc_fin)
        valores['chegada'] = destino + " " + dh_chegada

    # Linhas para {html_table.gera}:
    linhas = (
        html_cpr_campo("Compra", 'id_cpr', valores, 'text', None, False),
        html_cpr_campo("Cliente", 'id_usr', valores, 'text', None, False),
        html_cpr_campo("Nome do cliente", 'nome_usr', valores, 'text', None,
                       False),
        html_cpr_campo("Nome do passageiro", 'nome_pass', valores, 'text',
                       "Fulano da Silva", editavel),
        html_cpr_campo("Documento do passageiro", 'doc_pass', valores, 'text',
                       "123.456.789-10", editavel),
        html_cpr_campo("Número de trechos", 'n_trechos', valores, 'text', None,
                       False),
        html_cpr_campo("Preço total", 'preco_tot', valores, 'text', None,
                       False),
        html_cpr_campo("Estado", 'status', valores, 'text', None, False),
        html_cpr_campo("Partida", 'partida', valores, 'text', None, False),
        html_cpr_campo("Chegada", 'chegada', valores, 'text', None, False),
    )
    ht_campos = html_table.gera(linhas, ["", ""])

    # Botões:
    if editavel:
        args_submit = {
            'id_compra': id_cpr
        }  # Argumentos adicionais para submissão.
        ht_submit = html_botao_submit.gera(texto_bt, comando_bt, args_submit,
                                           "#44ff44")
        ht_campos += "<br/>" + ht_submit

    return html_form.gera(ht_campos)
# Um cliente comum:
usrC_id = "U-00000001"
usrC = usuario.busca_por_identificador(usrC_id)
assert not usuario.obtem_atributo(usrC, 'administrador')

# Um administrador:
usrA_id = "U-00000003"
usrA = usuario.busca_por_identificador(usrA_id)
assert usuario.obtem_atributo(usrA, 'administrador')

# Uma compra em aberto do cliente 1:
cprC_id = "C-00000001"
cprC = compra.busca_por_identificador(cprC_id)
assert compra.obtem_status(cprC) == 'comprando'
assert compra.obtem_cliente(cprC) == usrC

# Uma compra fechada:
cprF_id = "C-00000004"
cprF = compra.busca_por_identificador(cprF_id)
assert compra.obtem_status(cprF) != 'comprando'

# Sessão do cliente 1:
sesC = sessao.busca_por_identificador("S-00000001")
assert sessao.obtem_usuario(sesC) == usrC

# Sessão de outro cliente comum:
sesO = sessao.busca_por_identificador("S-00000003")
assert sessao.obtem_usuario(sesO) != None
assert sessao.obtem_usuario(sesO) != usrC