Ir para conteúdo
Fórum Script Brasil

Frank K Hosaka

Membros
  • Total de itens

    1.622
  • Registro em

  • Última visita

Tudo que Frank K Hosaka postou

  1. O JavaScript é o único programa que eu conheço que é capaz de atualizar a página onde ele está, através do comando location.reload( ), e isso eu consegui no código PHP. O Laravel é outra história, qualquer solicitação que você faz precisa usar a ferramenta @csrf. Mas o @csrf só é usado com o marcador <form>, e não queria sair da página porque isso ia ser um grande desastre. Copiei o código JavaScript do PHP no Laravel, e obtive o erro 419, esse é o famoso erro da ausência do csrf. O Copilot pediu para criar um comando <meta> que gera o crsf e também pedir para o JavaScript encaminhar o crsf adiante. E deu certo. Eu não sou bom com o JavaScript, mas quando consigo fazer o JavaScript trabalhar para mim, eu fico feliz da vida: arquivo resources > views > nfCFOPview.blade.php <meta name="csrf-token" content="{{ csrf_token() }}"> @include('menuView') <script> btMenu.innerHTML='NF Fornecedor CFOP';document.title="NF Fornecedor CFOP" function getCsrfToken() { return document.querySelector('meta[name="csrf-token"]').getAttribute('content'); } function atualizar(cfop, codprod) { var xmlhttp = new XMLHttpRequest(); var url = "nfCFOPatualizar"; var formData = new FormData(); formData.append('cfop', cfop); formData.append('codprod', codprod); formData.append('_token',getCsrfToken()) xmlhttp.open("POST", url, true); xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4) { console.log("Estado da requisição: " + xmlhttp.readyState); if (xmlhttp.status == 200) { location.reload(); } else { alert("Erro na requisição: " + xmlhttp.status); } } }; xmlhttp.send(formData); } </script> <div class="flex"> <div class="w-[50px] text-right">Cforn</div> <div class="w-[50px] text-right">Cod</div> <div class="w-[378px] ml-2">Produto</div> <div class="w-[50px] text-right">CFOP</div> <div class="w-[100px] text-right">NCM</div> </div> <?php foreach($previa as $p): ?> <div class="flex odd:bg-gray-200"> <div class="w-[50px] text-right"><?=$p->codforn?></div> <div class="w-[50px] text-right"><?=$p->codprod?></div> <div class="w-[378px] ml-2 truncate"><?=$p->prod?></div> <div class="<?=$p->class?>" onclick="atualizar(<?=$p->cfop?>,<?=$p->codprod?>)"> <?=$p->cfop?> </div> <div class="<?=$p->class2?>"><?=$p->ncm?></div> </div> <?php endforeach; ?>
  2. Frank K Hosaka

    CFOP

    Semana passada a Bling me orientou que existe no menu de configurações a rotina para Nota Fiscal > Natureza da Operação, onde podem ser definidas as regras de tributação, e assim definir uma CFOP para cada produto de acordo com a NCM. O MySQL me informou que eu tenho atualmente 256 NCM dentro da tbprod, o problema é saber quem tem substituição tributária e quem não tem. A Secretaria da Fazenda tem o regulamento do ICMS bem como planilhas que definem os produtos que tem substituição tributária, mas aquilo é bem difícil de entender e trabalhar. A minha saída é olhar cada nota fiscal do fornecedor e corrigir o banco de dados. Na tbprod eu criei o campo string cfop, e defini para todas elas 5405. A seguir criei uma rotina em PHP para olhar a nota do fornecedor no formato xml, comparar os dados com a tbprod, e assim corrigir o que for necessário: arquivo nf.php <?php class NF { function CFOP() { return view('nfArquivo',['action'=>'?NF.CFOPselecionado']); } function CFOPatualizar() { $cfop = $_POST['cfop']; $codprod = $_POST['codprod']; (new Conn)->update("tbprod set cfop='$cfop' where codprod = $codprod"); } function CFOPselecionado() { (new Conn)->delete("tbnf"); (new Conn)->exec("alter table tbnf auto_increment = 1"); $nfe=simplexml_load_file($_FILES['arquivo']['tmp_name']); $itens=$nfe->NFe->infNFe->det; $nNF = (float)$nfe->NFe->infNFe->ide->nNF; $xNome = (string)$nfe->NFe->infNFe->emit->xNome; $nome = explode(" ", $xNome)[0]; $codp = (new Conn)->select("codp from tbpessoa where pessoa like '%$nome%'")[0]->codp; foreach ($itens as $item){ // no campo codforn uso a primeira letra para identificar o fornecedor $codforn = (string)$item->prod->cProd; $criterio= strtolower($nome[0].$codforn); $consulta = (new Conn)->select("* from tbprod where codforn like '%$criterio%' "); $codprod = 'null'; if (count($consulta) == 1) { $codprod = $consulta[0]->codprod; } if (count($consulta) > 1) { $consulta2 = (new Conn)->select("* from tbprod where codforn like '%$criterio' "); if(count($consulta2) == 1){ $codprod = $consulta2[0]->codprod; } else { echo "existem vários produtos com codforn com o critério $criterio"; foreach($consulta as $c) { echo "<br>".$c->codprod." ".$c->prod; } exit; } } if (count($consulta)==0) { echo "nenhum produto encontrado com o critério $criterio"; exit; } $produto = substr((string)$item->prod->xProd,0,79); $cfop = (string)$item->prod->CFOP; if($cfop==6101 || $cfop==6102 || $cfop==5101) { $cfop=5102; } if($cfop==6401 || $cfop==6402 || $cfop==5401) { $cfop=5405; } $class=($cfop == $consulta[0]->cfop) ? "w-[50px] text-right" : "w-[50px] text-red-500 text-right"; $ncm = (string)$item->prod->NCM; $class2=($ncm == $consulta[0]->cf) ? "w-[100px] text-right" : "w-[100px] text-red-500 text-right"; (new Conn)->insert("tbnf (codforn,codprod,prod,cfop,codp,ncm,class,class2) values ($codforn,$codprod,'$produto','$cfop',$codp,'$ncm','$class','$class2')"); } $previa=(new Conn)->select("* from tbnf"); $_SESSION['vetor']=['nNF' => $nNF,'xNome' => $xNome, 'codp' => $codp]; return view('nfCFOPView',['previa'=>$previa,'nNF' => $nNF,'xNome' => $xNome, 'codp' => $codp]); } } arquivo nfArquivo.php <?php require 'menuView.php' ?> <script>btmenu.innerHTML="Nota do Fornecedor";document.title="Nota do Fornecedor"</script> <div class=mb-3> <form method=post enctype="multipart/form-data" action="<?=$action?>"> <label for=arquivo class=form-label>Escolha o arquivo XML</label> <input type=file name=arquivo class=form-control id=formfile required onchange=submit()> </form> </div> arquivo nfCFOPview.php <?php include('menuView.php'); ?> <script> btMenu.innerHTML='NF Fornecedor CFOP';document.title="NF Fornecedor CFOP" function atualizar(cfop, codprod) { var xmlhttp = new XMLHttpRequest(); var url = "?NF.CFOPatualizar"; var formData = new FormData(); formData.append('cfop', cfop); formData.append('codprod', codprod); xmlhttp.open("POST", url, true); xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4) { console.log("Estado da requisição: " + xmlhttp.readyState); if (xmlhttp.status == 200) { location.reload(); } else { alert("Erro na requisição: " + xmlhttp.status); } } }; xmlhttp.send(formData); } </script> <div class="flex"> <div class="w-[50px] text-right">Cforn</div> <div class="w-[50px] text-right">Cod</div> <div class="w-[448px] ml-2">Produto</div> <div class="w-[50px] text-right">CFOP</div> <div class="w-[100px] text-right">NCM</div> </div> <?php foreach($previa as $p): ?> <div class="flex odd:bg-gray-200"> <div class="w-[50px] text-right"><?=$p->codforn?></div> <div class="w-[50px] text-right"><?=$p->codprod?></div> <div class="w-[448px] ml-2 truncate"><?=$p->prod?></div> <div class="<?=$p->class?>" onclick="atualizar(<?=$p->cfop?>,<?=$p->codprod?>)"> <?=$p->cfop?> </div> <div class="<?=$p->class2?>"><?=$p->ncm?></div> </div> <?php endforeach; ?>
  3. Eu ouvi dizer que os bancos trabalham com muitos técnicos de informação, mas eu não conheço nenhum em particular. Eu aconselho a pegar uma pessoa real e ver a história particular dele, principalmente quanto que ele ganha. Eu fiz o estudo da programação por conta própria. Quem me ajudou a ter noção de programação foi o recurso da macro encontrado dentro da planilha Excel. Além da macro, o Excel oferece Visual Basic for Aplications. O tutorial deles é de amargar, fiz vários testes e experimentei várias frustrações. Em 2020, eu vi um vídeo bacana do professor Guanabara, ele me ensinou a instalar o servidor WampServe. Levei dois meses para instalar no meu notebook, depois de ver e ler várias matérias espalhadas na internet. Depois que eu consegui instalar o servidor, eu ganhei de brinde o MySQL e o PHP. Levei mais dois meses para mexer com ele. Enfim, comecei o meu projeto chamado orçamento, e eu sofri muito porque não sabia nada de HTML e nem de JavaScript. Finalmente chegou 2024, e surgiu o Copilot da Microsoft. Ele me ajudou a programar melhor, dominar principalmente o espinhoso capítulo do CSS. Enfim, eu já sei como escrever "olá mundo" na tela do celular, eu consegui hospedar o meu código na Hostinger, o plano inicial é de R$ 10,00 por mês, só que não dá para usar o programa npm e nem node. Logo, ao invés de assinar um curso, por que você não conversa com o Copilot? Aqui o endereço: www.copilot.com. A página está em inglês, mas você pode usar a gramática portuguesa, comece assim: olá Copilot, eu não sei nada de programação, por onde eu começo?
  4. Recebi a resposta da Bling, ainda não tive tempo de verificar, mas acho oportuno publicar a resposta aqui, uma vez que é o nome da Bling é que está em jogo: Atendente: Maria M. Mensagem: Bom dia, tudo bem? Espero que sim! Temos como criar regras por produtos, NCM e grupo de produtos. Na natureza de operação, você poderá criar regras tributárias para diferentes produtos. Para isso, siga os passos descritos abaixo: Passo 1: Posicione o mouse sobre o ícone da engrenagem > Todas as configurações > Notas fiscais > Naturezas de operação Passo 2: Clique sobre a natureza desejada Passo 3: Em Regras de Tributação, clique sobre a regra que deseja alterar ou em '+ Adicionar regra' para adicionar uma nova regra Passo 4: Clicando sobre a opção 'Qualquer produto', selecione uma das opções: • Produto • NCM • Grupo de Produtos Exemplo em anexo: https://prnt.sc/y0t0BUfWpWEj E preencha o campo ao lado com a informação: Caso tenha selecionado a opção 'Produto', informe o nome do produto cadastrado, e selecione-o. Caso tenha selecionado a opção 'NCM', informe o NCM do produto e selecione-o. Caso tenha selecionado a opção 'Grupo de Produtos', informe o nome do grupo cadastrado, e selecione-o. Clique aqui para verificar mais sobre o grupo de produtos OBS: Caso deseje adicionar mais de um produto, basta clicar na opção 'Adicionar outro item', para produtos que compartilharão das mesmas regras tributárias. Em seguida, preencha os dados tributários conforme orientado por sua contabilidade. Ao finalizar as alterações, clique em 'Salvar'. Em seguida, salve a natureza. Assim, após a configuração das regras por produto, a informação e tributos serão informados automaticamente nas notas com essa natureza de operação selecionada. Para saber quais informações preencher, seria somente com a contabilidade. Em caso de dúvidas, sigo a disposição! -- Atenciosamente, Eduarda M. - Suporte Bling (54) 3771-7278
  5. Eu sou do tempo que se emitia a Nota Fiscal na mão, eu tinha que ter o cuidado na hora de preencher a Natureza da Operação, e em seguida registrava a NF no Livro de Saída. Hoje é 2025, tudo é moderno, você não usa mais a caneta e o papel de carbono para emitir, basta um teclado. O máximo que eu consegui fazer com o PHP é montar um orçamento, mas eu não sou capaz de fazer um código que emita uma nota fiscal. Eu contratei a Bling, e hoje ela cobra R$ 70,00 por mês para emitir a Nota Fiscal do tipo NFCe. Uso a Bling para importar o orçamento que fiz no PHP, e de lá eu emito a NFCe. Tudo parece fácil e tudo parece mágica, me faz acreditar que os R$ 70,00 é uma pechincha. A NFCe é gravado na Secretaria da Fazenda, tudo parece tranquilo. Só que eu pedi o Registro de Saída do serviço contábil, e eu cai de costa. Todas as NFCe foram registrados como 5.102 venda a não contribuinte, quando tem muito produto que eu vendo e que foram previamente tributados pelo ICMS antecipado, ou seja, eu esperava que o livro mostrasse um monte de CFOP 5.405 e um pouco de 5.102. Eu pedi socorro para o Copilot e a resposta dele é bem imprecisa, indica vários vídeos do YouTube que são mais imprecisas. A Inteligência Artificial ainda não está preparada para entender o Regulamento do ICMS e ensinar como emitir a Nota Fiscal. Estou muito tranquilo com o meu programa Orçamento que não emite Nota Fiscal. O que me deixa apavorado é a Bling emitir a Nota Fiscal sem nenhum contador ou fiscal da Secretaria da Fazenda para homologar o serviço que eu pago: de que adianta pagar R$ 70,00 para emitir a Nota Fiscal com a natureza da operação errada? Eu não posso exigir muito do Copilot, pois ele é um serviço gratuito. Mas quem está pagando um serviço melhor que o Copilot, por favor, pergunte a ele se é possível saber se uma Nota Fiscal foi emitida corretamente, principalmente no tópico Natureza da Operação. Grato.
  6. Eu tenho um projeto chamado orçamento que estou desenvolvendo desde 1999, eu uso o código PHP e o código Laravel, ambos têm a mesma lógica e a mesma imagem, menos o formulário do login. O formulário do Laravel é capaz de preencher toda a tela do celular, no modo retrato, e isso eu não consegui no código PHP. Você pode traduzir o código PHP em Laravel, o contrário é impossível. Por exemplo, o Laravel não deixa você submeter um formulário se não usar o recurso Blade @csrf, já o PHP não tem esse recurso. A minha única saída foi tentar copiar o código HTML produzido pelo Laravel e copiar no PHP. Eu nunca imaginei que fosse possível ver o código fonte no navegador do celular, mas hoje o Copilot me deu a dica de modificar a barra de endereço de "https://frank.com" para "view-source:https://frank.com", e assim consegui ver o código HTML no celular. Selecionei tudo, copiei num bloco do Google Keep, e no notebook eu copiei o código para o Visual Studio, e assim consegui criar o código PHP que faz a mesma mágica que o Laravel: arquivo loginView.php <meta name="viewport" content="width=device-width, initial-scale=1"> <script src="https://cdn.tailwindcss.com"></script> <script>document.title="Login"</script> <div class="min-h-screen flex flex-col sm:justify-center items-center pt-6 sm:pt-0 bg-gray-100"> <div class="text-2xl">Projeto Classe</div> <div class="w-full sm:max-w-md mt-6 px-6 py-4 bg-white shadow-md overflow-hidden sm:rounded-lg"> <form method="POST" action="?Login.menu"> <div> <label class="block font-medium text-sm text-gray-700" for="email"> Email </label> <input class="px-2 border rounded-md shadow-sm mt-2 focus:outline-blue-700" id="email" type="email" name="email" required="required" autofocus autocomplete="username"> </div> <!-- Password --> <div class="mt-4"> <label class="block font-medium text-sm text-gray-700" for="password"> Senha </label> <input class="px-2 border rounded-md shadow-sm block mt-1 focus:outline-blue-700" id="password" type="password" name="password" required="required" autocomplete="current-password"> </div> <button type="submit" class="px-2 mt-4 rounded-lg text-gray-500 font-semibold hover:bg-gray-200"> Entrar </button> </form> </div> </div>
  7. Eu não sei mexer no servidor, mas passei a sua questão para o Copilot e ele respondeu: Esse erro ocorre porque a função nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation foi introduzida na versão 1.50.0 do nghttp2, mas parece que a versão do php_curl.dll que você está usando ainda está vinculada a uma versão anterior do nghttp2. Para resolver isso, você pode tentar atualizar a biblioteca nghttp2 para a versão mais recente ou verificar se há uma versão atualizada do php_curl.dll que corresponda à versão do PHP que você está usando. Aqui estão alguns passos que podem ajudar: Atualize o Apache: Às vezes, atualizar o Apache para a versão mais recente pode resolver problemas de compatibilidade. No Laragon, você pode fazer isso clicando com o botão direito no ícone do Apache e selecionando a versão mais recente disponível2. Verifique a versão do nghttp2.dll: Certifique-se de que o arquivo nghttp2.dll esteja presente na mesma pasta que o php_curl.dll ou em um local que esteja no caminho do sistema (PATH). Atualize o PHP e suas extensões: Certifique-se de que todas as extensões PHP e bibliotecas estejam atualizadas para a versão mais recente compatível com o seu PHP. Se essas soluções não resolverem o problema, você pode considerar desativar temporariamente a extensão curl para ver se o erro persiste. No entanto, isso pode afetar o funcionamento de algumas funcionalidades do seu site.
  8. Consultei o Copilot, e ele montou o seguinte código VBA: Sub VerificarPlanilhas() Dim wsCaixa As Worksheet Dim wsRH As Worksheet Dim rngCaixa As Range Dim rngRH As Range Dim celCaixa As Range Dim celRH As Range Dim cpfCaixa As String Dim cpfRH As String Dim valorCaixa As Double Dim valorRH As Double Dim encontrado As Boolean ' Definir as planilhas Set wsCaixa = ThisWorkbook.Sheets("Caixa") Set wsRH = ThisWorkbook.Sheets("RH") ' Definir os intervalos de dados Set rngCaixa = wsCaixa.Range("A2", wsCaixa.Cells(wsCaixa.Rows.Count, 1).End(xlUp)) Set rngRH = wsRH.Range("A2", wsRH.Cells(wsRH.Rows.Count, 1).End(xlUp)) ' Limpar formatação de cor existente rngCaixa.Interior.ColorIndex = xlNone rngRH.Interior.ColorIndex = xlNone ' Verificar CPFs na planilha Caixa For Each celCaixa In rngCaixa cpfCaixa = celCaixa.Value valorCaixa = celCaixa.Offset(0, 1).Value encontrado = False For Each celRH In rngRH If celRH.Value = cpfCaixa Then encontrado = True valorRH = celRH.Offset(0, 1).Value If valorCaixa <> valorRH Then celCaixa.Interior.Color = RGB(255, 255, 0) ' Amarelo celCaixa.Offset(0, 1).Interior.Color = RGB(255, 255, 0) ' Amarelo celRH.Interior.Color = RGB(255, 255, 0) ' Amarelo celRH.Offset(0, 1).Interior.Color = RGB(255, 255, 0) ' Amarelo End If Exit For End If Next celRH If Not encontrado Then celCaixa.Interior.Color = RGB(0, 255, 0) ' Verde celCaixa.Offset(0, 1).Interior.Color = RGB(0, 255, 0) ' Verde End If Next celCaixa ' Verificar CPFs na planilha RH For Each celRH In rngRH cpfRH = celRH.Value encontrado = False For Each celCaixa In rngCaixa If celCaixa.Value = cpfRH Then encontrado = True Exit For End If Next celCaixa If Not encontrado Then celRH.Interior.Color = RGB(255, 0, 0) ' Vermelho celRH.Offset(0, 1).Interior.Color = RGB(255, 0, 0) ' Vermelho End If Next celRH MsgBox "Verificação concluída!" End Sub O código funciona, mas apresentou resultado diferente no caso da Vilma - renda mensal R$ 101,27. Foi pintado de amarelo por constar nas duas planilhas mas com valores divergentes. O critério é muito vago, se a Vilma retirou do caixa R$ 10,00; R$ 10,00; R$ 10,00, e a planilha do RH constar apenas um registro de R$ 10,00, o código não será capaz de pintar coisa alguma.
  9. Desde ontem é que eu percebi que não consigo enxergar todo o plano de contas no celular, modo paisagem. Fazendo vários testes, descobri que o problema está aqui: <div class="hidden fixed ml-4 top-15 border-4 border-gray-400 rounded" id="myModal"> Ao invés do fixed, usei absolute, e assim consigo rolar o plano de contas até o fim no modo paisagem, e também consigo rolar para o lado no modo retrato, no celular. A dica <div class="overflow-x-auto">Lançamentos</div> ajuda a mostrar a maior parte do plano de contas, mas não todo.
  10. Estou usando o ambiente Laravel, HTML <div> e o CSS Tailwind para as visualizações caberem no meu celular Note 10 no modo paisagem. No começo, eu me atrapalhei na hora de usar o Tailwind com o marcador <table>, e assim eu me aventurei com o marcador <div>. O grande problema que eu enfrentei é alinhar a <div>cabecalho</div> com a <div>dados</div>. Só na semana passada é que eu aprendi que só é possível alinhar duas <div> se elas tiverem exatamente o mesmo tamanho. Outro problema é colorir a <div>cabecalho</div>, aqui eu apelei para a improvisação: se <div class="odd:bg-gray-200"> não der certo, então mudar para <div class="even:bg-gray-200">. O Copilot tem várias sugestões para resolver esse tipo de problema, mas eu sinceramente prefiro o velho método da tentativa e erro, claro que o meu método não é lógico, mas é o melhor atalho que eu encontrei para renderizar a página no meu celular no modo paisagem o mais rápido que eu puder. É a famosa política de que os fins justificam os meios: arquivo resources > views > diarioHistorico.blade.php @include('menuView') // define entre outras coisas body {width:630px} <script>btMenu.innerHTML = 'Histórico';document.title = 'Histórico'</script> <div class="flex font-semibold odd:bg-gray-200"> <div class="w-[70px]">Dia</div> <div class="w-[50px] text-right">Lcto</div> <div class="w-[50px] text-right">CtaD</div> <div class="w-[50px] text-right">CtaC</div> <div class="w-[80px] text-right">Valor</div> <div class="w-[328px] ml-2">Histórico</div> </div> @foreach($hist as $h) <div class="flex odd:bg-gray-200"> <div class="w-[70px]">{{dbr($h->dia)}}</div> <div class="w-[50px] text-right"> <a href='diarioEdita?docto={{$h->docto}}' class="text-gray-500 font-semibold"> {{$h->lcto}} </a> </div> <div class="w-[50px] text-right">{{$h->contad}}</div> <div class="w-[50px] text-right">{{$h->contac}}</div> <div class="w-[80px] text-right">{{dec($h->valor)}}</div> <div class="w-[328px] ml-2">{{$h->hist}}</div> </div> @endforeach
  11. Ontem, eu tentei fazer um lançamento contábil pelo celular (no modo paisagem), mas na hora de eu chamar o plano de contas percebi que não consegui rolar o plano de contas para baixo, e assim eu vi que é impossível fazer o lançamento contábil pelo celular. Eu não tive escolha, mandei todo o meu código PHP para o Copilot e pedi ajuda. O código tem duas grandes partes. A <div> do plano de contas. E a <div> do lançamento contábil. O Copilot alterou o meu código, acrescentando <div class="overflow-x-auto"> em torno do <div> do lançamento contábil. Isso não faz o menor sentido para mim, mas isso deu certo no celular, conseguir rolar o plano de contas para baixo. arquivo diarioLcto.php <?php include('menuView.php') ?> <script src="https://cdn.tailwindcss.com"></script> <style> input[type="date"]::-webkit-calendar-picker-indicator { display: none} </style> <script> btMenu.innerHTML='<?=$btnMenu?>' document.title='<?=$btnMenu?>' var idControle,Descricao function ir(controle,destino) { idControle=controle Descricao=destino myModal.classList.remove('hidden') } function voltar(texto) { controle=document.getElementById(idControle) destino=document.getElementById(Descricao) controle.value=texto.substr(0,3) tamanho=texto.strlen destino.innerHTML=texto.substr(4,tamanho) myModal.classList.add('hidden') } function fechar() { myModal.classList.add('hidden') } </script> <div class="hidden fixed ml-4 top-15 border-4 border-gray-400 rounded overflow-y-auto max-h-screen" id="myModal"> <?php foreach($ativo as $key=>$row): ?> <div class="flex"> <div class="w-[300px] pl-2 <?= $key%2==0 ? 'bg-gray-300' : 'bg-white' ?>"> <a onclick="voltar(this.innerHTML)"><?=$row->conta." ".$row->descricao?></a> </div> <?php if($key<$contaPassivo): ?> <div class="flex w-[300px] <?= $key%2==0 ? 'bg-gray-300' : 'bg-white' ?>"> <a onclick="voltar(this.innerHTML)"><?=$passivo[$key]->conta." ".$passivo[$key]->descricao?></a> <?php if($passivo[$key]->conta==415): ?> <a onclick=fechar() class=ml-[100px]>Fechar</a> <?php endif; ?> </div> <?php endif; ?> </div> <?php endforeach; ?> </div> <div class="overflow-x-auto"> <?php if(count($produtos)): ?> <div class="flex even:bg-gray-200"> <div style=width:100px class=text-right>Cod</div> <div style=width:400px class=ml-2>Produto</div> <div style=width:50px class=text-right>Qt</div> <div style=width:50px class=text-right>Un</div> <div style=width:100px class=text-right>Total</div> </div> <?php foreach($produtos as $prod): ?> <div class="flex even:bg-gray-200"> <div class="w-[100px] text-right text-gray-500 font-semibold"> <a href="?Produto.alterarItem.<?=$prod->id?>"> <?=$prod->codprod?> </a> </div> <div class="w-[400px] ml-2"><?=$prod->prod?></div> <div class="w-[50px] text-right"><?=virgula($prod->qt)?></div> <div class="w-[50px] text-right"> <a href="?Produto.excluir.<?=$prod->id?>"> <?=$prod->un?> </a> </div> <div class="w-[100px] text-right"><?=dec($prod->custototal)?></div> </div> <?php endforeach; ?> <div class="flex even:bg-gray-200"> <div class='w-[100px] text-right'> <?=date('d/m/y',strtotime($produtos[0]->dia))?> </div> <div class="w-[500px] flex ml-2 white-space-nowrap"> <form method=post action="?Diario.produto"> <input type=submit name=produto value='Produto' class="mr-[10px] text-gray-500 font-semibold py-0 px-1 bg-transparent rounded-lg"> <?php if($somaProdutos!==0): ?> <a href=?Diario.pessoa class="text-gray-500 font-semibold"> <?=$produtos[0]->pessoa?> </a> <?php endif; ?> </form> </div> <div class="w-[200px] text-end font-semibold"><?=dec($somaProdutos)?></div> </div> <?php else: if($btnMenu!=="Novo Lançamento"): ?> <div class="w-[400px] ml-2"> <form method=post action="?Diario.produto"> <input type=submit name=produto value='Produto' class="text-gray-500 font-semibold hover:bg-gray-200 p-1 rounded-lg"> </form> </div> <?php endif; endif; ?> </div> <form action='<?=$comando?>' method="post" class="container rounded-lg mx-auto border border-gray-200 mt-4"> <?php if($btnMenu=="Edita Lançamento"): ?> <div class="py-2"> <a href="?Diario.cria.<?=$consulta->lcto?>" class="text-gray-500 font-semibold"> Acrescentar no lançamento <?=$consulta->lcto?></a> </div> <?php endif; ?> <div class="flex items-center bg-gray-200 mt-3 h-[35px] rounded-lg"> <label for=dia class="block ml-2 mr-14">Dia</label> <input type="date" name="dia" id=dia value=<?=$consulta->dia?> class='w-[90px] text-gray-500 font-semibold bg-transparent border-none rounded-lg p-1 py-0 text-right focus:ring-1 focus:ring-blue-700 focus:outline-none' onclick=this.showPicker()> </div> <div class="flex items-center mt-1"> <label for=lcto class="block ml-2 mr-16">Lçto</label> <input name=lcto id=lcto value='<?=$consulta->lcto?>' size=4 class='border-none rounded-lg text-gray-500 font-semibold p-1 py-0 text-right bg-transparent'> </div> <div class="flex items-center bg-gray-200 mt-1 h-[35px] rounded-lg"> <label for=contad class="block ml-2 mr-10">ContaD</label> <input name=contad id=contad value='<?=$consulta->contad?>' size=4 onclick="ir(this.id,'DescD')" autocomplete=off class='border-none bg-transparent text-gray-500 font-semibold rounded-lg p-1 py-0 text-right focus:ring-1 focus:ring-blue-700 focus:outline-none'> <span id="DescD" class="ml-4 "></span> </div> <div class="flex items-center mt-1"> <label for=contac class="block ml-2 mr-10">ContaC</label> <input name=contac id=contac value='<?=$consulta->contac?>' size=4 onclick="ir(this.id,'DescC')" autocomplete=off class='border-none text-gray-500 font-semibold rounded-lg p-1 py-0 text-right bg-transparent focus:ring-1 focus:ring-blue-700 focus:outline-none'> <span id="DescC" class="ml-4"></span> </div> <div class="flex items-center bg-gray-200 mt-1 mb-1 h-[35px] rounded-lg"> <label for=valor class="block ml-2 mr-12 text-gray-900">Valor</label> <input name=valor id=valor value='<?=dec($consulta->valor)?>' autocomplete="off" class='border-none text-gray-500 font-semibold bg-transparent rounded-lg p-1 py-0 text-right focus:ring-1 focus:ring-blue-700 focus:outline-none' size=5> </div> <div class="flex items-center mt-1 mb-3"> <label for=hist class="block ml-2 mr-3 text-gray-900">Histórico</label> <input name=hist id=hist value='<?=$consulta->hist?>' autocomplete="off" class='border-none text-gray-500 font-semibold rounded-lg p-1 py-0 bg-transparent focus:ring-1 focus:ring-blue-700 focus:outine:none' size=47 > <input type="hidden" name="docto" value="<?=$consulta->docto?>"> <input type="submit" value="Confirmar" class="border-none text-gray-500 font-semibold hover:bg-gray-200 p-1 py-0 ml-2 rounded"> </div> </form>
  12. A minha função apuração não funciona, então eu pedi ajuda para o Copilot. Mas ele não conseguiu resolver o problema. Na segunda tentativa, o Copilot foi bem mais esperto, ele criou uma rotina para calcular o último ano, se ele não estiver lá, então a função pede a gentileza de incluir o último ano no vetor da apuração: arquivo balancete.php <?php class balancete { function apuracao() { $primeiroDia = (new Conn)->select('dia from tbdiario order by dia')[0]->dia; $ultimoDia = (new Conn)->select('dia from tbdiario order by dia desc')[0]->dia; $anos = []; while (strtotime($primeiroDia) <= strtotime($ultimoDia)) { $anos[] = date('Y', strtotime($primeiroDia)); $data = new DateTime($primeiroDia); $primeiroDia = date_modify($data, '+1 year')->format('Y-m-d'); } $ultimoAno=date('Y',strtotime($ultimoDia)); if(!in_array($ultimoAno,$anos)) { $anos[] = $ultimoAno; } rsort($anos); $meses = ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez']; return view('balanceteApuracao', ['anos' => $anos, 'meses' => $meses]); } }
  13. arquivo appView.php <!DOCTYPE html> <html lang="en"> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"> </script> <script src="https://cdn.tailwindcss.com"></script> <style> @media (min-width: 768px) { .geral {width: 700px; margin: auto; font-size: 16px} } @media (max-width: 767px) { body {width: 630px; margin: auto; font-size: 16px} } @media (min-width: 768px) and (max-width:1024px) { body {width:700px;margin: auto; font-size: 16px}} input[type="date"]::-webkit-calendar-picker-indicator {display: none} summary { list-style:none } </style> <title>Projeto Classe</title> <body class=geral> Esse código é uma tremenda aberração. Eu não queria criar a classe "geral" para formatar o laptop, mas esse é o único jeito que eu encontrei para centralizar a renderização no meio da tela. Se eu escrever body no lugar do .geral, tudo fica encostado na esquerda. Apesar do código não respeitar a lógica, consegui definir o body do celular para 630px e do tablet para 700 px. A minha intuição me diz que o mais sensato é esquecer o laptop, o tablet e o celular, e montar todo o código baseado numa só classe, assim <body class="w-[630px] m-auto"> no jargão da Tailwind. O duro é ter que mexer num monte de views que foram projetados para 700 pixels.
  14. O PHP.ini está error_reporting=E_ALL, ou seja, é para considerar todo tipo de erro como acontece na Hostinger. O único jeito é ter paciência, e empurrar a vida com a barriga. Feliz Ano Novo.
  15. Eu olhei o arquivo php.ini [apache module] e lá eu vi error_reporting = E_ALL. O mistério ainda continua.
  16. Frank K Hosaka

    Erro no código

    Simplifiquei o código, e só consegui salvar o xlsx com a ajuda do parâmetro FileFormat: Sub teste() Dim ws As Worksheet Dim Filename As String Set ws = ActiveSheet Filename = ThisWorkbook.Path & "\Venda de veículos.xlsx" On Error GoTo ErrorHandler ws.SaveAs Filename:=Filename, FileFormat:=xlOpenXMLWorkbook MsgBox "Arquivo salvo com sucesso como " & Filename Exit Sub ErrorHandler: MsgBox "Erro ao salvar o arquivo: " & Err.Description End Sub
  17. O <input type="file"> produz um quadro com a frase "Escolha o arquivo" e ali adiante outra mensagem "nenhum arquivo selecionado". O Copilot me passou uma dica de como esconder a segunda parte do marcador, mas ele escondeu todo o input, no lugar colocou um botão personalizado, e acrescentou um código em JavaScript. Eu achei a dica do Copilot muito trabalhoso, então decidi improvisar por conta própria, usando apenas o Tailwind. Não ficou bom, dá para ver que se trata de gambiarra: <?php include 'menuView.php'; ?> <script>btmenu.innerHTML="Nota Faltante";document.title="Nota Faltante"</script> <script src="https://cdn.tailwindcss.com"></script> <div> <form method="post" enctype="multipart/form-data" action="?Bling.faltanteSelecionado"> <div class="flex"> <input type="file" name="pasta" class="w-[133px] font-semibold" onchange=submit()> <div class="font-semibold bg-gray-200 border-t-2 border-r-2 border-b-2 border-black px-1">zipado da Bling</div> </div> </form> </div>
  18. Hoje eu usei o cdn da Tailwind no Laravel, e ele funcionou tanto no notebook bem como no Hostinger, só o JavaScript reclamou que eu não deveria usar o cdn. arquivo route > web.php Route::view('/','index'); arquivo reources > views > index.blade.php <!-- esse arquivo pode ser testado no PHP, mas se não mudar o nome do arquivo, terá que executar localhost/index.blade --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.tailwindcss.com"></script> <body class="w-[500px] m-0 m-auto"> <table class="table table-striped"><!-- tabela zebrada com Bootstrap --> <tr><th class="ml-2">Coluna 1<th>Coluna2 <tr><td>2<td>2 <tr><td>3<td>4 </table> <table class="min-w-full"><!-- tabela zebrada com Tailwind --> <tr class="bg-gray-200"><th>Coluna 1<th>Coluna2 <?php for($i=1;$i<=10;$i++): ?> <tr class="odd:bg-gray-200"><td><?=$i?><td><?=$i?> <?php endfor; ?> </table>
  19. Eu consultei o Copilot, e ele disse que é possível o PERL executar uma macro do Microsoft Access. Ou seja, se a sua consulta funciona no Microsoft Access, você precisa transformar essa consulta numa macro e pedir para o PERL executar a macro: #!/usr/bin/perl use strict; use warnings; use Win32::OLE; # Caminho para o arquivo .mdb my $caminho = 'C:/caminho/para/seu/arquivo.mdb'; # Inicializa o objeto Access my $access = Win32::OLE->new('Access.Application', 'Quit') or die "Não foi possível iniciar o Access: $!"; # Abre o banco de dados my $banco = $access->OpenCurrentDatabase($caminho) or die "Não foi possível abrir o banco de dados: " . $access->LastError(); # Executa a subroutine $banco->RunMacro('NomeDaSubroutine'); # Fecha o banco de dados e o Access $banco->CloseCurrentDatabase(); $access->Quit; Acho que o mais sensato é criar a função calc_idade2 no ambiente do PERL, ou seja, você estuda a fonte original do Access e depois codifica na gramática do PERL. O máximo que dá para fazer com as conexões ODBC é acessar informações contidas nas tabelas e não todos os recursos do Microsoft Access.
  20. Ontem, eu pedi para a Hostinger usar o PHP 8.4, pois eu não vi nenhum problema aqui no Notebook. Hoje eu aprendi que o Notebook é uma coisa, mas o Hostinger é coisa totalmente diferente. Aqui no Notebook, o seguinte comando gera um arquivo CSV: fputcsv($arquivo, $dados[0]); Mas o PHP 8.4 do Hostinger é diferente, ele reclama que o comando está depreciado e que preciso colocar os parâmetros do $escape, assim: fputcsv($arquivo, $dados[0],',','"','\\'); Eu consegui os parâmetros graças ao Copilot. O meu programa orçamento não gera e nem tem credencial para emitir uma NFC-e, o máximo que eu consegui fazer é montar um pedido nos moldes da Bling, depois vou na Bling, importo o pedido, e em seguida emito a NFC-e. O mais comum é o Cupom Fiscal, mas em São Paulo, você precisa do SAT para autenticar o cupom. Já o NFC-e é a antiga NF Série D, na versão eletrônica, e ele não precisa do SAT para ser autenticado e a Bling não tem uma versão para emitir o Cupom Fiscal. A Bling tem rotina para gerar pedido, mas achei oportuno fazer um Orçamento em PHP para facilitar na hora de usar o tablet ou celular: <?php class Orcamento { function apagarBling($pedido) { (new Conn)->update("tbpedido set bling=null where ped=$pedido"); return $this->inicio($pedido); } function bling($pedido) { $pBling=$_GET['pBling']; $verificar=(new Conn)->select("count(bling) as contagem from tbpedido where bling=$pBling")[0]->contagem; if($verificar) { echo "<h1>Pedido Bling $pBling já foi criado. <a href=?Orcamento.inicio>Voltar</a></h1>"; exit; } (new Conn)->update("tbpedido set bling=$pBling where ped=$pedido"); $contato="Consumidor Final"; $itens=(new Conn)->select("* from tbhistped where ped=$pedido"); $previa=(new Conn)->select("sum(subtotal) as soma from tbhistped where subtotal < 0 and ped=$pedido")[0]->soma; $desconto=$previa ? abs($previa) : 0; $total=(new Conn)->select("total from tbpedido where ped=$pedido")[0]->total; $data=date('d/m/Y',strtotime((new Conn)->select("dia from tbpedido where ped = $pedido")[0]->dia)); $dados = array( array("Número pedido","Nome Comprador","Data","CPF/CNPJ Comprador","Endereço Comprador", "Bairro Comprador","Número Comprador","Complemento Comprador","CEP Comprador","Cidade Comprador", "UF Comprador","Telefone Comprador","Celular Comprador","E-mail Comprador","Produto", "SKU","Un","Quantidade","Valor Unitário","Valor Total", "Total Pedido","Valor Frete Pedido","Valor Desconto Pedido","Outras despesas","Nome Entrega", "Endereço Entrega","Número Entrega","Complemento Entrega","Cidade Entrega","UF Entrega", "CEP Entrega","Bairro Entrega","Transportadora","Serviço","Tipo Frete", "Observações","Qtd Parcela","Data Prevista","Vendedor","Forma Pagamento", "ID Forma Pagamento")); foreach($itens as $item) { if($item->subtotal>0) { $dados[]=array($pBling,$contato,$data,null,null, null,null,null,null,null, null,null,null,null,null, $item->codprod,$item->un,$item->qt,$item->unitario,$item->subtotal, $total,null,$desconto,null,null, null,null,null,null,null, null,null,null,null,null, null,1,$data,null,1, 0); } } $arquivo = fopen("$pBling.csv", "w"); fputcsv($arquivo, $dados[0],',','"','\\'); foreach ($dados as $linha) { if ($linha != $dados[0]) { fputcsv($arquivo, $linha,',','"','\\'); } } fclose($arquivo); if (file_exists("$pBling.csv")) { header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=' . basename("$pBling.csv")); header('Content-Length: ' . filesize("$pBling.csv")); readfile("$pBling.csv"); unlink("$pBling.csv"); } } function confirmar() { $ped=$_POST['ped']; if(!empty($_POST['dinheiro'])) { $dinheiro=str_replace(',','.',$_POST['dinheiro']); $troco=str_replace(',','.',$_POST['troco']); } else { $dinheiro=0; $troco=0; } if(isset($_POST['cartao'])){$cartao=1;} else {$cartao=0;} if(isset($_POST['pix'])){$pix=1;} else {$pix=0;} if(!empty($_POST['parcial'])) { if($dinheiro!==0) { echo "<script>location.replace('orcamento.php')></script>";exit; } $dinheiro=$_POST['parcial']; $troco=0; } $horavenda=date('Y-m-d H:i'); (new Conn)->update("tbpedido set horavenda='$horavenda',dinheiro=$dinheiro, troco=$troco,cartao=$cartao,pix=$pix where ped=$ped"); return $this->inicio(); } function corrigir($ped) { (new Conn)->update("tbpedido set horavenda=null,horavenda=null,dinheiro=null, troco=null,cartao=0,pix=0 where ped=$ped"); return $this->inicio(); } function excluir($id) { $ped=$_GET['pedido']; (new Conn)->delete("tbhistped where id=$id"); $novoTotal=(new Conn)->select("sum(subtotal) as soma from tbhistped where ped=$ped")[0]->soma; if($novoTotal==null) { $novoTotal='null'; } (new Conn)->update("tbpedido set total=$novoTotal where ped=$ped"); return $this->inicio($ped); } function historicoOrc($hist) { $where=""; if($hist) { $ped=$_SESSION['referencia']+$hist; $where="where ped <= $ped"; } $pedidos=(new Conn)->select("* from tbpedido left join tbpessoa on tbpedido.codp = tbpessoa.codp $where order by ped desc limit 20"); $_SESSION['referencia']=$pedidos[0]->ped; return view('orcamentoHist',['pedidos'=>$pedidos]); } function inicio($pedido = null) { $prod=(new Conn)->select("* from tbprod order by prod"); $maquina=strpos($_SERVER['HTTP_USER_AGENT'],"Windows"); $hoje=date('Y-m-d'); $where=""; if($pedido) { $where="where ped=$pedido"; $vr['codprod']=(isset($_SESSION['codprod'])) ? $_SESSION['codprod'] : null; if($vr['codprod']) { $codprod=$vr['codprod']; $produto=(new Conn)->select("* from tbprod where codprod=$codprod")[0]; $vr['prod']=$produto->prod; $vr['un']=$produto->un; $custo=$produto->custo; $margem=$produto->marg; $vr['preço']=pvenda($custo,$margem); } else { unset($_SESSION['codprod']); $vr=['ped'=>'','diaped'=>$hoje,'totalped'=>'','codp'=>'','pessoa'=>'', 'end'=>'','cnpj'=>'','tel'=>'','nota'=>'','codprod'=>'','un'=>'', 'prod'=>null,'preço'=>'','horavenda'=>'','bling'=>'']; } } $ped=(new Conn)->select("* from tbpedido $where order by ped desc")[0]; $vr['ped']=$ped->ped; $_SESSION['ped']=$ped->ped; $vr['diaped']=$ped->dia; $vr['horavenda']=$ped->horavenda; $vendido=($ped->horavenda) ? true : false; $vr['totalped']=$ped->total; $vr['bling']=$ped->bling; $vr['codp']=$ped->codp; if(isset($_SESSION['codp'])) { $vr['codp']=$_SESSION['codp']; unset($_SESSION['codp']); } if($vr['codp']) { $pessoa=(new Conn)->select("* from tbpessoa where codp=". $vr['codp'])[0]; $vr['pessoa']=$pessoa->pessoa; $vr['end']=$pessoa->end; $vr['cnpj']=$pessoa->cnpj; $vr['tel']=$pessoa->tel; $vr['nota']=$pessoa->nota; } $histped=(new Conn)->select("tbhistped.id,tbhistped.ped, tbhistped.codprod, tbhistped.qt as qt, tbhistped.unitario as unitario, tbhistped.subtotal, tbprod.prod as prod, tbprod.un as un from tbhistped inner join tbprod on tbhistped.codprod = tbprod.codprod and tbhistped.ped = $ped->ped order by tbhistped.id"); return view('orcamentoView',['vr'=>$vr,'histped'=>$histped,'prod'=>$prod, 'maquina'=>$maquina,'vendido'=>$vendido]); } function menu() { unset($_SESSION['codprod']); unset($_SESSION['codp']); unset($_SESSION['pessoa']); return $this->inicio(); } function novo() { $pedido=(new Conn)->select("* from tbpedido order by ped desc")[0]; $ped=$pedido->ped; $total=$pedido->total; if($total!==null) { $ped++; $dia=date('Y-m-d'); (new Conn)->insert("tbpedido (dia,ped) values ('$dia',$ped)"); } return header("location:?Orcamento.inicio.$ped"); } function pedido($pedido) { $_SESSION['ped']=$pedido; return $this->inicio($pedido); } function pessoa($pedido) { $_SESSION['end']="?Orcamento.pessoaSelecionada.$pedido"; if(isset($_GET['codp'])){ $codp=$_GET['codp']; return header("location:?pessoa.inicio.$codp"); } return header("location:?Pessoa.inicio"); } function pessoaSelecionada($pedido) { $codp=$_SESSION['codp']; (new Conn)->update("tbpedido set codp = $codp where ped=$pedido"); return $this->inicio($pedido); } function produto() { $pedido=$_SESSION['ped']; $_SESSION['end']="?Orcamento.inicio.$pedido"; $produto=str_replace(" ","%",$_POST['produto']); $tamanho=strlen($produto); $posicao=strpos($produto,":"); if($posicao==0) { if($produto!=="") { $_SESSION['criterio']="where prod like '%$produto%' order by prod"; } return header("location:?Produto.inicio"); } $_SESSION['codprod']=substr($produto,$posicao+1,$tamanho-$posicao); return $this->inicio($_SESSION['ped']); } function qt() { $qt=deca($_POST['qt']); $codprod=$_SESSION['codprod']; unset($_SESSION['codprod']); if($qt==0 || $qt=='') { return $this->inicio(); } $produto=(new Conn)->select("* from tbprod where codprod=$codprod")[0]; $ped=$_SESSION['ped']; $un=$produto->un; $custo=$produto->custo; $margem=$produto->marg; $unitario=pvenda($custo,$margem); $subtotal=$qt*$unitario; (new Conn)->insert("tbhistped (ped,codprod,un,unitario,subtotal,qt) values ($ped,$codprod,'$un',$unitario,$subtotal,$qt)"); $novoTotal=(new Conn)->select("sum(subtotal) as soma from tbhistped where ped=$ped")[0]->soma; (new Conn)->update("tbpedido set total=$novoTotal where ped=$ped"); return $this->inicio($ped); } }
  21. Durante quatro horas fiz vários testes para ver o que eu fiz de errado no código PHP, mas não consegui encontrar nada. Até que eu fui tentar fazer diretamente no terminal, no Workbench MySQL: update tbnf set custoanterior=15.8, e o MySQL reclamou que os dados estavam truncados. Mudei o tipo do campo de float para double para int, mas nada disso resolveu. Finalmente decidi estudar toda a tabela, e dentro do campo codprod encontrei algo assim <b>Ver</ b>, isso é uma gambiarra HTML que eu coloquei dentro de um campo tipo varchar. O Copilot me explicou que o varchar é só para texto puro e que não pode usar o marcador HTML. Para corrigir o problema, ele sugeriu mudar o tipo do campo para TEXT. Eu imaginei que o problema era a consulta, mas acabei descobrindo que a tabela é que estava detonada, algo parecido com o PHP, se você abre um bloco {, o PHP não faz nada se você não fechar o bloco com }. Resumindo, VARCHAR e TEXT é quase a mesma coisa, você só não pode usar marcador HTML no VARCHAR. Agora eu entendo porque é tão difícil estudar o banco de dados.
  22. Frank K Hosaka

    O $epsilon

    Hoje apareceu uma nota fiscal fora do estado, onde eu tive que calcular o ICMS substituição tributária e o ICMS diferencial de alíquota. Eu fiz o cálculo usando o Excel, e também codifiquei o código no PHP para calcular a mesma coisa. Deu uma diferença de R$ 0,01. O Copilot me ofereceu quatro dicas que não funcionaram. Então, ele apresentou o $epsilon. O Copilot é engenhoso! <?php echo round(76.25*0.18-9.15,2) . "<br>"; echo number_format(76.25*0.18-9.15,2,'.','') . "<br>"; bcscale(2); $parte1=bcmul('76.25','0.18'); echo bcsub($parte1,'9.15') . "<br>"; $parte1 = 76.25 * 0.18; $parte2 = $parte1 - 9.15; echo number_format($parte2,2,'.','') . "<br>"; $epsilon = 0.00001; $valor=76.25*0.18-9.15; echo round($valor + $epsilon,2);
  23. Eu raramente uso chave externa, pois eu não sei qual a categoria do produto. Aconselho a fazer o mesmo, não crie a chave externa. Mas se você sabe a categoria do produto, e você tem chave externa para ela, você é obrigado a incluir a categoria do produto, toda vez que for incluir um produto, assim: CREATE DEFINER=`root`@`localhost` PROCEDURE `testandoNulo`() BEGIN DROP TABLE IF EXISTS tb_produtos; DROP TABLE IF EXISTS tb_categoria; CREATE TABLE tb_categoria ( id_categoria INT(11) PRIMARY KEY AUTO_INCREMENT NOT NULL, desc_categoria VARCHAR(255) NOT NULL ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; INSERT INTO tb_categoria (desc_categoria) VALUES ('Produtos que envolvem dispositivos eletrônicos e inovações tecnológicas.'), ('Roupas e acessórios que seguem tendências de estilo e design.'), ('Produtos e tratamentos para cuidados pessoais e estética.'); CREATE TABLE tb_produtos ( id_produtos INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT, desc_produtos VARCHAR(255) NOT NULL, valor DECIMAL(10,2), id_categorias INT(11) NOT NULL, CONSTRAINT fk_id_categoria FOREIGN KEY (id_categorias) REFERENCES tb_categoria(id_categoria) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; INSERT INTO tb_produtos (desc_produtos, valor, id_categorias) VALUES ('Dispositivo portátil que combina funções de telefone, computador e câmera em um único aparelho.', 600, 1), ('Peça de roupa feminina que cobre o corpo desde os ombros até a parte inferior das pernas.', 80, 2), ('Produto cosmético usado para manter a pele hidratada e suave.', 30, 3); END
  24. CREATE DEFINER=`root`@`localhost` PROCEDURE `calcular_notas`() BEGIN DROP TABLE IF EXISTS aluno; DROP TABLE IF EXISTS resposta; DROP TABLE IF EXISTS gabarito; CREATE TABLE `aluno` ( `id` int NOT NULL AUTO_INCREMENT, `nome` varchar(80) COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; CREATE TABLE `resposta` ( `Id` int NOT NULL AUTO_INCREMENT, `Aluno_id` int DEFAULT NULL, `Questao` int DEFAULT NULL, `Resposta` varchar(45) DEFAULT NULL, PRIMARY KEY (`Id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; CREATE TABLE `gabarito` ( `Id` int NOT NULL AUTO_INCREMENT, `Questao` int DEFAULT NULL, `Solucao` varchar(45) DEFAULT NULL, PRIMARY KEY (`Id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; INSERT INTO aluno (Nome) values ('João'),('José'),('Lucas'); INSERT INTO resposta (Aluno_Id,Questao,Resposta) values (1,1,'A'),(1,2,'D'),(1,3,'E'),(1,4,'C'),(1,5,'B'), (2,1,'C'),(2,2,'E'),(2,3,'E'),(2,4,'C'),(2,5,'A'),(3,1,'B'),(3,2,'D'),(3,3,'A'),(3,4,'A'),(3,5,'A'); INSERT INTO gabarito (Questao, Solucao) VALUES (1, 'C'),(2, 'D'),(3, 'E'),(4,'C'),(5,'A'); SELECT r.Aluno_Id, a.Nome, COUNT(*) AS acertos FROM resposta r JOIN gabarito g ON r.Questao = g.Questao JOIN aluno a ON a.id = r.Aluno_id WHERE r.Resposta = g.Solucao GROUP BY r.Aluno_Id; END
  25. Eu acho bem bacana o roteador do Laravel, e eu pensei fazer o mesmo no PHP. O Copilot sugeriu criar o arquivo .htaccess: RewriteEngine On RewriteRule ^([^/]+)/?$ index.php [L] No teste que eu fiz no Hostinger, não precisei do arquivo .htaccess O meu roteador ficou assim: <?php class Teste { function teste() {echo "olá mundo!";} function beleza($alfa = null) { if($alfa){echo $alfa;} else {echo "o mundo e belo";} } } $request = $_SERVER['REQUEST_URI']; $script_name = $_SERVER['SCRIPT_NAME']; $base = str_replace(basename($script_name), '', $script_name); $path = str_replace($base, '', $request); $path = trim($path, '/'); if(strpos($path,'?')===false){$path .= '?';} list($before,$after)=explode('?',$path,2); $rota=['teste'=>'Teste.teste','beleza'=>'Teste.beleza']; $segmentos=explode('.',$rota[$before]); $nomeControle=$segmentos[0]; $metodo=$segmentos[1]; $parametro=$after ?? null; (new $nomeControle())->$metodo($parametro); ?> Ele funcionou quando escrevi localhost/astudy/teste, localhost/astudy/beleza, localhost/astudy/beleza?variavel=15
×
×
  • Criar Novo...