def pode_comprar(usr, pol, cpr): global cache, nome_tb, letra_tb, colunas, diags if cpr == None or pol == None or cpr == None: return False assert type(usr) is usuario.Objeto_Usuario assert type(pol) is poltrona.Objeto_Poltrona assert type(cpr) is compra.Objeto_Compra # A compra {cpr} ainda está aberta? if compra.obtem_atributo(cpr, 'status') != 'comprando': return False # A poltrona {pol} está livre? id_cpr_pol = poltrona.obtem_atributo(pol, 'id_compra'); if id_cpr_pol != None: return False # O trecho da poltrona {pol} ainda está disponível? 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 # Há incompatibilidade de horários com as poltronas já em {cpr}? if not compra.trecho_eh_compativel(cpr, trc_pol): return False # Pode comprar, parece: return True
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(ses, rot, erros): ver_roteiro = False # Já estamos vendo o roteiro. campos_resumo = html_resumo_de_roteiro.gera(rot, ver_roteiro) ht_resumo = "".join(str(campos_resumo)) # ??? EXPANDIR COMO {html_pag_ver_compra} alterar_trcs = False # Não deve ter botões de "Alterar". ht_trechos = html_lista_de_trechos.gera(rot, alterar_trcs) ht_conteudo = ht_resumo + "<br/>" + ht_trechos ids_trechos = roteiro.obtem_identificadores_de_trechos(rot) ids_trechos_txt = ",".join(ids_trechos) # verifica se todos os trechos estao disponivels roteiro_disponivel = True for id_trc in ids_trechos: trc = trecho.busca_por_identificador(id_trc) roteiro_disponivel = roteiro_disponivel and not trecho.obtem_atributo(trc, 'encerrado') if roteiro_disponivel: atrs_comprar = {'ids_trechos': ids_trechos_txt} ht_comprar = html_botao_simples.gera("Comprar", "comprar_roteiro", atrs_comprar, "#22ff22") ht_conteudo += "<br/>" + ht_comprar pag = html_pag_generica.gera(ses, ht_conteudo, erros) return pag
def verificar_disponibilidade(trc): global cache, nome_tb, letra_tb, colunas, diags assert type(trc) is trecho.Objeto_Trecho encerrado = trecho.obtem_atributo(trc, 'encerrado') num_poltronas_livres = trecho.numero_de_poltronas_livres(trc) return (not encerrado) and num_poltronas_livres > 0
def testa_atualiza_atributo_com_sucesso(): args = {'id_trecho': "T-00000001", 'destino': 'POA'} testa("Suc", ses, args) updated_trecho = trecho.busca_por_identificador("T-00000001") assert trecho.obtem_atributo(updated_trecho, "destino") == 'POA', "Trecho não atualizado"
def testa_encerra_trecho(): args = {'id_trecho': "T-00000001"} # Executa comando de teste testa("Suc", ses, args) # Valida se teste funcionou trc = trecho.busca_por_identificador("T-00000001") # Verifica se alterou: assert trecho.obtem_atributo(trc, 'encerrado'), "Não encerrou o trecho"
def processa(ses, args): # Usuário deve estar logado para iniciar um pedido de compra if ses == None: pag = html_pag_mensagem_de_erro.gera( ses, ["Voce deve estar logado para comprar um roteiro!"]) return pag cpr = sessao.obtem_carrinho(ses) if cpr == None: # Novo carrinho associada ao usuario compra.cria(ses.cliente, ses.cliente.nome_pass, ses.cliente.doc_pass) # Recupera os objetos trechos para verificar poltronas ids_trechos = args['ids_trechos'].split(',') obj_trechos = [] for id in ids_trechos: obj_trechos.append(trecho.busca_por_identificador(id)) # Verifica e inclui poltronas na compra for trc in obj_trechos: # Verifica se o trecho possui pelo menos uma poltrona livre if trecho.numero_de_poltronas_livres(trc) < 1: pag = html_pag_mensagem_de_erro.gera(ses, [ "Nao tem mais poltronas livres no trecho {} :(".format( trecho.obtem_atributo(trc, "codigo")) ]) return pag # Obtem lista de poltronas livres para comparacao do melhor preco id_pol_livres = poltrona.lista_livres(trc) melhor_preco = math.inf id_melhor_preco = None for id_pol in id_pol_livres: pol = poltrona.busca_por_identificador(id_pol) preco_pol = poltrona.obtem_atributo(pol, "preco") # Atualiza melhor preco, assim como seu id if preco_pol < melhor_preco: melhor_preco = preco_pol id_melhor_preco = id_pol # Adiciona a poltrona ao carrinho comando_comprar_poltrona.processa(ses, {'id_poltrona': id_melhor_preco}) pag = comando_ver_carrinho.processa(ses, None) return pag
def obtem_resumo(rot): resumo = {}.copy() trecho_inicial = rot[0] trecho_final = rot[-1] resumo['origem'] = trecho.obtem_atributo(trecho_inicial, 'origem') resumo['dia_partida'] = trecho.obtem_atributo(trecho_inicial, 'dia_partida') resumo['hora_partida'] = trecho.obtem_atributo(trecho_inicial, 'hora_partida') resumo['destino'] = trecho.obtem_atributo(trecho_final, 'destino') resumo['dia_chegada'] = trecho.obtem_atributo(trecho_final, 'dia_chegada') resumo['hora_chegada'] = trecho.obtem_atributo(trecho_final, 'hora_chegada') resumo['num_escalas'] = len(rot) - 1 resumo['preco_min'] = 0.00 # !!! CALCULAR !!! return resumo
def poltronas_abertas(usr): id_usr = usuario.obtem_identificador(usr) abertas_usr = [].copy() ids_compras = compra.busca_por_cliente(id_usr) for id_cpr in ids_compras: cpr = compra.busca_por_identificador(id_cpr) assert cpr != None # Paranóia. # Pega o id das poltronas de cada uma dessas compras ids_poltronas = compra.obtem_poltronas(cpr) for id_pol in ids_poltronas: # Para cada um desses ids pega o objeto da poltrona pol = poltrona.busca_por_identificador(id_pol) assert pol != None # Paranóia. assert poltrona.obtem_atributo(pol, 'id_compra') == id_cpr # Paranóia. # Verifica se o trecho não foi encerrado id_trc = poltrona.obtem_atributo(pol, 'id_trecho') trc = trecho.busca_por_identificador(id_trc) if not trecho.obtem_atributo(trc, 'encerrado'): abertas_usr.append(pol) return abertas_usr
# Sessao de teste de administrador: ses_adm = sessao.busca_por_identificador("S-00000004") assert ses_adm != None assert sessao.eh_administrador(ses_adm) # Usuario administrador de teste: usr_adm = sessao.obtem_usuario(ses_adm) assert usr_adm != None usr_adm_id = usuario.obtem_identificador(usr_adm) usr_adm_atrs = usuario.obtem_atributos(usr_adm) # Trechos de teste (somente id): trc1_id = "T-00000001" # Não encerrado. trc1 = trecho.busca_por_identificador(trc1_id) assert not trecho.obtem_atributo(trc1, 'encerrado') trc6_id = "T-00000006" # Encerrado. trc6 = trecho.busca_por_identificador(trc6_id) assert trecho.obtem_atributo(trc6, 'encerrado') # ---------------------------------------------------------------------- # Atributos para criação de novo trecho: atrs_nov = { 'codigo': 'AZ 3344', 'origem': 'GRU', 'destino': 'RAO', 'dia_partida': '2020-05-02', 'dia_chegada': '2020-05-02' }
def obtem_origem_destino(pol): id_trc = obtem_atributo(pol, 'id_trecho'); trc = trecho.busca_por_identificador(id_trc); origem = trecho.obtem_atributo(trc, 'origem') destino = trecho.obtem_atributo(trc, 'destino') return origem, destino
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
def descobre_todos_rec(origem, data_min, prefixo, destino, data_max, soh_disponiveis): """Função auxiliar da função {descobre_todos}. O parâmetro {prefixo} é o roteiro parcial que atualmente esta sendo montado. Se não for uma lista vazia, deve ser um roteiro válido que começa em {origem}, não antes de {data_min}. A função calcula recursivamente todos as extensões válidas do {prefixo} que saem do aeroporto onde este termina e terminam em {destino}, e devolve uma lista de todos esses roteiros. Para ser válido, um roteiro não pode terminar depois de {data_max}, e cada trecho além do primeiro deve sair do mesmo aeroporto onde o trecho anterior chegou, com intervalo de tempo suficiente para a baldeação. As datas devem ter o formato "aaaa-mm-dd HH:MM UTC". """ debug = True # Pega o último trecho do prefixo: trc_prev = None if len(prefixo) == 0 else prefixo[-1]; if debug: sys.stderr.write(" " * len(prefixo)) sys.stderr.write("trc_prev = %s\n" % trecho.mostra(trc_prev)) assert (trc_prev == None) or (type(trc_prev) is trecho.Objeto_Trecho) # Pega o aeroporto final do {prefixo} etapa = origem if trc_prev == None else trecho.obtem_atributo(trc_prev, 'destino') if etapa == destino: # Este prefixo é uma slução e não adianta tentar estendê-lo: return [ prefixo ] rots = [].copy() # Os roteiros encontrados que começam com {prefixo}. # Pega todos os trechos que saem de {etapa}: for id_trc_prox in trecho.busca_por_origem(etapa): trc_prox = trecho.busca_por_identificador(id_trc_prox) assert trc_prox != None # Paranóia. # Verifica tempo. Este é o teste que impede recursão infinita. if trc_prev != None: # Verifica se há tempo suficiente para a baldeação: dt_sai_ok = trecho.horarios_sao_compativeis(trc_prev, trc_prox) else: # Verifica se {trc_prox} não sai antes da data mínima de partide: data_sai = trecho.obtem_dia_e_hora_de_chegada(trc_prox) dt_sai_ok = (data_sai >= data_min) if not dt_sai_ok: continue if soh_disponiveis: # Verifica se este trecho está não encerrado para compra: disp = trecho.verificar_disponibilidade(trc_prox) if not disp: continue # Verifica se este trecho termina antes da data limite: data_chg = trecho.obtem_dia_e_hora_de_partida(trc_prox) data_chg_ok = (data_chg <= data_max) if not data_chg_ok: continue # Emenda este trecho no prefixo e busca recursivamente: prefixo1 = prefixo + [ trc_prox ] rots1 = descobre_todos_rec(origem, data_min, prefixo1, destino, data_max, soh_disponiveis) rots += rots1 # Esgotou todas as possiveis extensoes do {prefixo}: return rots
def obtem_dia_e_hora_de_chegada(trc): global cache, nome_tb, letra_tb, colunas, diags assert type(trc) is trecho.Objeto_Trecho dia = trecho.obtem_atributo(trc, 'dia_chegada') hora = trecho.obtem_atributo(trc, 'hora_chegada') return dia + " " + hora + " UTC"
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)