Ir para conteúdo
Fórum Script Brasil

Frank K Hosaka

Membros
  • Total de itens

    1.678
  • Registro em

  • Última visita

Tudo que Frank K Hosaka postou

  1. O meu problema é pior, eu não consigo enxergar o código. Não tem jeito de publicar o código dentro do code << >>?
  2. Bom dia, eu só estou tentando entender a linguagem de objetos, estou bem longe de dominar. O projeto semiLaravel me ensinou muita coisa, como mandar todas as solicitações para o index.php e de lá chamar as classes e objetos. No começo eu só usava o método get. Eu não tenho a menor ideia de como o Laravel consegue centralizar tudo no arquivo web.php, o máximo que eu consegui foi centralizar tudo no index.php. Nessa nova etapa do aprendizado eu tive a aprender a trabalhar com static function, eu ainda não entendi bem o que é. Enfim, eu abandonei o projeto de imitar o Laravel, não vou fazer mais isso, vou usar um novo caminho, onde a prioridade não é mais a elegância e sim a praticidade, e assim eu criei o bd::x($sql,[param1,param2,...), ao invés de eu ter um monte de métodos para tentar abraçar a ideia do CRUD, a ideia é executar o CRUD em um menor número de métodos. O nome disso é tentativa e erro, e vou exibindo os códigos para ver se alguém pode me avaliar e ver quanta besteira estou fazendo.
  3. A última vez que eu vi a classe bd, ele estava ocupando quase 300 linhas, é muita coisa, não vale a pena tentar imitar o Laravel, mas eu aprendi muita coisa, e assim montei uma classe bd com poucos métodos, que não precisa mexer toda vez que aparece uma tarefa nova: arquivo .htaccess RewriteEngine On # Redirecionar tudo para index.php RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php [QSA,L] arquivo index.php <?php require('config.php'); $requestUri = $_SERVER['REQUEST_URI']; $path = substr($requestUri, strlen($basePath)); if ($path == "") { $path = "loginLogin"; } if (!strpos($path, '(')) { $path .= '()'; } if (preg_match('/^([a-z]+)([A-Z][a-zA-Z]*)\((.*)\)$/', $path, $matches)) { $classe = $matches[1]; $metodo = $matches[2]; $argumentos = explode(',', $matches[3]); $argumentos = array_map('urldecode', $argumentos); if (!empty($argumentos[0]) && !empty($argumentos)) { $classe::$metodo(...$argumentos); } else { $classe::$metodo(); } } else { echo "Formato de URL inválido."; } ?> arquivo config.php <?php session_start(); error_reporting(E_ALL); ini_set('display_errors', 1); date_default_timezone_set('America/Sao_Paulo'); $baseDir = $_SERVER['SERVER_NAME'] === 'frank.com' ? $_SERVER['DOCUMENT_ROOT'] : $_SERVER['DOCUMENT_ROOT'].'/chirper/'; $basePath = $_SERVER['SERVER_NAME'] === 'frank.com' ? '/' : '/chirper/'; defined('HOST') || define('HOST', 'localhost'); defined('DBNAME') || define('DBNAME', $baseDir === $_SERVER['DOCUMENT_ROOT'] ? 'Diario' : 'diario'); defined('USER') || define('USER', $baseDir === $_SERVER['DOCUMENT_ROOT'] ? 'Root' : 'root'); defined('PASSWORD') || define('PASSWORD', $baseDir === $_SERVER['DOCUMENT_ROOT'] ? '12345678' : ''); spl_autoload_register(function ($class) { $path = str_replace('\\', DIRECTORY_SEPARATOR, strtolower($class)) . '.php'; if (file_exists($path)) { require $path; } else { echo "classe $class não encontrada"; exit; } }); class bd { private static $bindings = []; private static $initialized = false; private static $query; private static $pdo; static function get() { $stmt = self::getPdo()->prepare(self::$query); if (!empty(self::$bindings)) { foreach (self::$bindings as $key => $value) { $stmt->bindValue(":$key", $value); } } $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_OBJ); self::$query = ''; self::$bindings = []; return $result; } static function get1() { self::$query .= " LIMIT 1"; $stmt = self::getPdo()->prepare(self::$query); if (!empty(self::$bindings)) { foreach (self::$bindings as $key => $value) { $stmt->bindValue(":$key", $value); } } $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_OBJ)[0]; self::$query = ''; self::$bindings = []; return $result; } protected static function getPdo() { self::initialize(); return self::$pdo; } static function getv($column) { $stmt = self::getPdo()->prepare(self::$query); if (!empty(self::$bindings)) { foreach (self::$bindings as $key => $value) { $stmt->bindValue(":$key", $value); } } $stmt->execute(); $result = $stmt->fetch(PDO::FETCH_ASSOC); self::$query = ''; self::$bindings = []; return $result[$column] ?? null; } static function getx() { $stmt = self::getPdo()->prepare(self::$query); if (!empty(self::$bindings)) { foreach (self::$bindings as $key => $value) { $stmt->bindValue(":$key", $value); } } $stmt->execute(); return; } static function initialize() { if (!self::$initialized) { $dsn = 'mysql:host=' . HOST . ';dbname=' . DBNAME; self::$pdo = new PDO($dsn, USER, PASSWORD); self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); self::$initialized = true; } } static function x($sql,$bindings=[]) { self::initialize(); self::$query=$sql; self::$bindings=$bindings; return new static; } } exemplo de comandos: $lctos=bd::x("select * from tbdiario where dia=:dia order by lcto",['dia'=>$dia])->get(); $somaDebito=bd::x("select sum(valor) as soma from tbdiario where dia=:dia and contad>0",['dia'=>$dia])->getv('soma'); bd::x("insert into tbcontacorrente (docto,lcto) values (:dif,:lcto)",['dif'=>$dif,'lcto'=>$lcto])->getx(); bd::x("delete from tbcontacorrente where docto=:docto",['docto'=>$p->docto])->getx(); ou seja, ao invés de criar um método para cada tarefa CRUD Create Read Update Delete, por que não criar um método para todas as tarefas do CRUD?
  4. O Copilot é uma excelente ferramenta, o problema é que ele faz exatamente o que você pede, e agora tenho uma classe bd que ficou enorme, e mesmo assim surge um problema novo que os métodos da classe bd não são capazes de resolver. Esse é o caso do método first, eu precisava do último registro de uma tabela, e o copilot sugeriu alterar o código para self::$orderBy = "ORDER BY ped DESC"; Isso resolve o meu problema no curto prazo, mas lá frente, eu sei que vou precisar ordenar de forma diferente, assim decidi mudar o método por conta própria e eu criei o argumento $opção, e o código ficou assim: static function first($columns = '*', $conditions = [],$opcao = null) { self::initialize(); $table = static::getTableName(); if (is_array($columns)) { $columns = implode(', ', $columns); } $whereClause = ''; self::$bindings = []; if (!empty($conditions)) { foreach ($conditions as $condition) { $field = $condition[0]; $operator = $condition[1]; $value = $condition[2]; if ($operator == 'BETWEEN' && is_array($value)) { $whereClause .= "$field BETWEEN :{$field}_start AND :{$field}_end AND "; self::$bindings["{$field}_start"] = $value[0]; self::$bindings["{$field}_end"] = $value[1]; } else { $whereClause .= "$field $operator :$field AND "; self::$bindings[$field] = $value; } } $whereClause = 'WHERE ' . rtrim($whereClause, ' AND '); } $sql = "SELECT $columns FROM $table $whereClause"; if($opcao) { $sql .= ' '.$opcao; } $sql .= ' LIMIT 1'; $stmt = self::getPdo()->prepare($sql); foreach (self::$bindings as $key => $value) { $stmt->bindValue(":$key", $value); } $stmt->execute(); $result = $stmt->fetch(PDO::FETCH_OBJ); self::$result = $result ? [$result] : []; return $result; } Agora, posso escrever tbpedido::first('*',[],'ORDER BY ped DESC"). É claro que isso está bem longe de parecer com o Eloquent do Laravel, é por isso que dei o nome de semiLaravel ao projeto.
  5. Hoje fiquei o dia todo tentando entender porque o projeto me jogava na tela de login toda vez que eu pedia para executar a rotina do produtoDescontinuar. Tudo indicava que eu sempre perdia a variável global $_SESSION['id'] toda vez que executava esse comando. Isso não fazia o menor sentido, pois eu pedi para o .htaccess jogar todas as solicitações para o index.php, e a primeira tarefa dele é carregar o config.php, onde estava o session_start( ) e assim não há como perder uma sessão. Na base da tentativa e erro, eu mudei o método, ao invés de chamar produto::descontinuar eu chamei de produto:descont, ou seja, o index.php não recebia mais a requisição produtoDescontinuar e sim produtoDescont. O index tem um roteador que separa classe::método( ), e assim tudo voltou a funcionar como eu esperava. A minha tese é que a requisição produtoDescontinuar entrou em conflito com o sistema de arquivos do projeto, um deles se chamava produtoDescontinuar.php, onde estava o formulário onde aguardava o código do produto a descontinuar. Ou seja, na hora que a requisição foi efetivada, o PHP ficou sem saber se abria o arquivo ou jogava tudo no index.php, e acabou decidindo me jogar na tela do login.
  6. https://forum.scriptbrasil.com.br/topic/226896-projeto-semilaravel-versão-em-atualização-28012025-1640/
  7. Eu sou um péssimo professor, pior que o pessoal do YouTube, mas vamos lá. Produto é um nome genérico para qualquer coisa que possa ser trocado por dinheiro. Ninguém faz cadastro de produto, a menos que seja por puro desespero. Então, abra uma nova planilha, dê o nome de produto (tudo em minúsculo). Você olha ao seu redor e você vê porta, laptop, celular. Você digita na célula A1 porta, na célula A2 laptop e na célula A3 celular. Para ver como funciona um formulário do Excel, crie um formulário com uma caixa de texto e um botão, dê um duplo clique no botão e crie o seguinte código: Private Sub CommandButton1_Click() Dim ws As Worksheet Dim nextCell As Range Dim productName As String ' Defina a planilha Set ws = ThisWorkbook.Sheets("produto") ' Obtenha o valor da caixa de texto productName = TextBox1.Value ' Verifique se a caixa de texto não está vazia If productName <> "" Then ' Encontre a próxima célula disponível na coluna A Set nextCell = ws.Cells(ws.Rows.Count, "A").End(xlUp).Offset(1, 0) ' Copie o conteúdo da caixa de texto para a próxima célula disponível nextCell.Value = productName End If End Sub Se você tiver um módulo (se não tiver clique em inserir módulo), e dentro dele crie o seguinte código: Public Sub MeuPrimeiroPrograma() UserForm1.Show End Sub Volte na planilha produto, vá em Desenvolvedor, Macros, e clique em MeuPrimeiroPrograma. Ao invés de você cadastrar o produto na planilha, o formulário é que vai pegar o nome do produto e vai jogar na planilha, escreva maçã e aperte salvar, escreva pera aperte salvar. Viu que bacana? Espero que tenha gostado da aula.
  8. Feliz Ano Novo, Wash, eu simplifiquei o código. Eu só me preocupei em controlar os clientes e os seus assentos, a mensagem original falava de um ônibus, eu reduzi para um fusca, onde nenhum cliente pode selecionar mais de um assento. Mudando de assunto, você consegue ver por aí porque a atualização do "Projeto semiLaravel - atualização" ficou travado? O pessoal viu que é muita bobeira ou o código é que ocupa muito espaço?
  9. O seu código envolve muitos detalhes. Para focar no problema da alocação de clientes para os seus assentos, eu simplifiquei tudo, onde só tenho um pacote que vão levar 3 clientes num fusca, assim: mysql CREATE TABLE cliente ( id INT AUTO_INCREMENT PRIMARY KEY, nome VARCHAR(255) NOT NULL ); INSERT INTO cliente (nome) values ('Frank'),('João'),('Pedro'); CREATE TABLE poltrona ( id INT AUTO_INCREMENT PRIMARY KEY, poltrona INT NOT NULL, pacote VARCHAR(255) NOT NULL, id_cliente INT, FOREIGN KEY (id_cliente) REFERENCES cliente(id) ); arquivo index.php <?php if(isset($_POST['cliente'])) { try { $conn = new PDO('mysql:host=localhost;dbname=teste', 'root', ''); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); if ($_SERVER['REQUEST_METHOD'] == 'POST') { $clienteId = $_POST['cliente']; $poltronaId = $_POST['poltrona']; // Verificar se a poltrona já está reservada $stmt = $conn->prepare("SELECT id_cliente FROM poltrona WHERE poltrona = :poltrona"); $stmt->bindParam(':poltrona', $poltronaId); $stmt->execute(); $result = $stmt->fetch(); if ($result && $result['id_cliente']) { echo "<script>alert('Esta poltrona já está reservada!');</script>"; } else { // Atualizar ou inserir a poltrona com o ID do cliente if ($result) { $stmt = $conn->prepare("UPDATE poltrona SET id_cliente = :id_cliente WHERE poltrona = :poltrona"); } else { $stmt = $conn->prepare("INSERT INTO poltrona (poltrona, id_cliente) VALUES (:poltrona, :id_cliente)"); } $stmt->bindParam(':id_cliente', $clienteId); $stmt->bindParam(':poltrona', $poltronaId); $stmt->execute(); } } } catch (PDOException $e) { echo "Erro: " . $e->getMessage(); } } ?> <!DOCTYPE html> <html lang="pt-BR"> <head> <meta charset="UTF-8"> <title>Reservar Poltrona</title> </head> <body style="width:500px;margin:0 auto;margin-top:50px;"> <h1>Reservar Poltrona</h1> <form method="post"> <label for="cliente">Cliente:</label> <select name="cliente" id="cliente" required> <option value=''>Selecione um cliente</option> <?php // Conectar ao banco de dados e buscar os clientes não reservados $conn = new PDO('mysql:host=localhost;dbname=teste', 'root', ''); $stmt = $conn->query("SELECT id, nome FROM cliente WHERE id NOT IN (SELECT id_cliente FROM poltrona WHERE id_cliente IS NOT NULL)"); while ($row = $stmt->fetch()) { echo "<option value='{$row['id']}'>{$row['nome']}</option>"; } ?> </select><br><br> <label for="poltrona">Poltrona:</label> <select name="poltrona" id="poltrona" required> <option value=''>Selecione uma poltrona</option> <?php // Buscar poltronas disponíveis $stmt = $conn->query("SELECT * FROM poltrona WHERE id_cliente IS NULL"); $poltronasDisponiveis = $stmt->fetchAll(); // mostrar poltronas disponíveis if (empty($poltronasDisponiveis)) { for ($i = 1; $i <= 3; $i++) { $ocupado=$conn->query("SELECT * FROM poltrona WHERE poltrona=$i")->fetchAll(); if(count($ocupado)==0) { echo "<option value='$i'>Poltrona $i</option>"; } } } ?> </select><br><br> <input type="submit" value="Reservar"> </form> <h2>Reservas Feitas</h2> <ul> <?php // Exibir reservas feitas $stmt = $conn->query("SELECT c.nome, p.poltrona FROM poltrona p JOIN cliente c ON p.id_cliente = c.id WHERE p.id_cliente IS NOT NULL"); while ($row = $stmt->fetch()) { echo "<li>Cliente: {$row['nome']}, Poltrona: {$row['poltrona']}</li>"; } ?> </ul> </body> </html>
  10. Na célula a1 tenho Categoria, na célula b1 tenho Foto, na célula c1 tenho Junção. Na célula a2 tenho 1, na célula b2 tenho 1, na célula c2 tenho a função =TEXTO(A2;"00")&"."&TEXTO(B2;"000"), o que dá 01.001 Eu não entendi a função do formulário e do VBA. Se que copiar a fórmula da célula C2 na célula C3, você usa o comando copiar e colar. Se eu entendi tudo errado, tem jeito mostrar o esquema do formulário (tire uma foto com o comando printScreen) e também uma lista do código que está dando problema? Sem ver o código, fica dificil saber o que está acontecendo.
  11. Nessa atualização, eu fiz as modificações para o código rodar tanto no laptop Windows bem como no Hostinger Linux. arquivo .htaccess RewriteEngine On # Redirecionar tudo para index.php RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^ index.php [L] arquivo teste.php <?php class teste { static function Inicio() { $produtos=tbprod::orderBy('prod','ASC')->select('*')->limit(10)->get(); $dia=date('Y-m-d');$contad=101;$contac=101;$valor=0;$hist="nenhum"; $lcto = tbdiario::orderBy('lcto', 'DESC')->select('lcto')->get()[0]->lcto+1; $novo=tbdiario::insert(['dia' => $dia,'lcto'=>$lcto,'contad'=>$contad, 'contac'=>$contac,'valor'=>$valor,'hist'=>$hist]); $lcto=15032; $produtos=tbhistprod::join('tbprod','tbprod.codprod = tbhistprod.codprod') ->join('tbpessoa','tbhistprod.codp=tbpessoa.codp') ->select('*',[['lcto','=',$lcto]])->get(); $somaProdutos=tbhistprod::select(['sum(custototal) as soma'], [['lcto','=',$lcto]])->get()[0]->soma; header("location:testeNovoInicio($somaProdutos)"); // o correto é self::NovoInicio($somaProdutos); aqui o teste é no roteador } static function NovoInicio($somaProdutos) { echo "olá mundo, a soma dos produtos deu"; imprimir($somaProdutos); } } arquivo index.php <?php require('config.php'); $requestUri = $_SERVER['REQUEST_URI']; $path = substr($requestUri, strlen($basePath)); if ($path == "") { // $path = "loginLogin()"; $path="testeInicio()"; } if (preg_match('/^([a-z]+)([A-Z][a-zA-Z]*)\((.*)\)$/', $path, $matches)) { $classe = $matches[1]; $metodo = $matches[2]; $argumentos = explode(',',$matches[3]); $argumentos = array_map('urldecode', $argumentos); if (!empty($argumentos[0] && !empty($argumentos))) { $classe::$metodo(...$argumentos); } else { $classe::$metodo(); } } else { echo "Formato de URL inválido."; } listagem parcial do arquivo config.php <?php session_start(); error_reporting(E_ALL); ini_set('display_errors', 1); date_default_timezone_set('America/Sao_Paulo'); $baseDir = $_SERVER['SERVER_NAME'] === 'frank.com' ? $_SERVER['DOCUMENT_ROOT'] : $_SERVER['DOCUMENT_ROOT'].'/semiLaravel/'; $basePath = $_SERVER['SERVER_NAME'] === 'frank.com' ? '/' : '/semiLaravel/'; defined('HOST') || define('HOST', 'localhost'); defined('DBNAME') || define('DBNAME', $baseDir === $_SERVER['DOCUMENT_ROOT'] ? 'Diario' : 'diario'); defined('USER') || define('USER', $baseDir === $_SERVER['DOCUMENT_ROOT'] ? 'Root' : 'root'); defined('PASSWORD') || define('PASSWORD', $baseDir === $_SERVER['DOCUMENT_ROOT'] ? '12345678' : ''); function imprimir($imprimir) { echo "<pre>"; print_r($imprimir); echo "</pre>"; } spl_autoload_register(function ($class) { $path = str_replace('\\', DIRECTORY_SEPARATOR, strtolower($class)) . '.php'; if (file_exists($path)) { require $path; } else { echo "classe $class não encontrada"; exit; } }); class bd { private static $bindings = []; private static $groupBy = ''; private static $initialized = false; private static $joins = ''; private static $limit = ''; private static $orderBy = ''; private static $pdo; private static $result = []; static function get() { return self::$result; } protected static function getPdo() { self::initialize(); return self::$pdo; } protected static function getTableName() { $reflection = new \ReflectionClass(static::class); return strtolower($reflection->getShortName()); } static function groupBy($columns) { if (is_array($columns)) { $columns = implode(', ', $columns); } self::$groupBy = "GROUP BY $columns"; return new static; } static function initialize() { if (!self::$initialized) { $dsn = 'mysql:host=' . HOST . ';dbname=' . DBNAME; self::$pdo = new PDO($dsn, USER, PASSWORD); self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); self::$initialized = true; } } static function insert($data) { self::initialize(); $table = static::getTableName(); $columns = implode(', ', array_keys($data)); $placeholders = ':' . implode(', :', array_keys($data)); $sql = "INSERT INTO $table ($columns) VALUES ($placeholders)"; $stmt = self::getPdo()->prepare($sql); foreach ($data as $key => $value) { $stmt->bindValue(":$key", $value); } $stmt->execute(); return self::getPdo()->lastInsertId(); } static function join($table, $condition, $type = 'INNER') { self::$joins .= " $type JOIN $table ON $condition"; return new static; } static function limit($limit) { self::$limit = "LIMIT $limit"; return new static; } static function orderBy($column, $direction = 'ASC') { self::$orderBy = "ORDER BY $column $direction"; return new static; } static function select($columns = '*', $conditions = []) { self::initialize(); $table = static::getTableName(); if (is_array($columns)) { $columns = implode(', ', $columns); } $whereClause = ''; self::$bindings = []; if (!empty($conditions) && !empty($conditions[0])) { foreach ($conditions as $condition) { $field = $condition[0]; $operator = $condition[1]; $value = $condition[2]; if ($operator == 'BETWEEN' && is_array($value)) { $whereClause .= "$field BETWEEN :{$field}_start AND :{$field}_end AND "; self::$bindings["{$field}_start"] = $value[0]; self::$bindings["{$field}_end"] = $value[1]; } else { $whereClause .= "$field $operator :$field AND "; self::$bindings[$field] = $value; } } $whereClause = 'WHERE ' . rtrim($whereClause, ' AND '); } $sql = "SELECT $columns FROM $table" . self::$joins . " $whereClause"; if (self::$groupBy) { $sql .= ' ' . self::$groupBy; self::$groupBy = ''; } if (self::$orderBy) { $sql .= ' ' . self::$orderBy; self::$orderBy = ''; } if (self::$limit) { $sql .= ' ' . self::$limit; self::$limit = ''; } $stmt = self::getPdo()->prepare($sql); foreach (self::$bindings as $key => $value) { $stmt->bindValue(":$key", $value); } $stmt->execute(); self::$joins = ''; self::$result = $stmt->fetchAll(PDO::FETCH_OBJ); return new static; } static function update($data, $conditions) { self::initialize(); $table = static::getTableName(); $setClause = ''; foreach ($data as $key => $value) { $setClause .= "$key = :$key, "; } $setClause = rtrim($setClause, ', '); $whereClause = ''; self::$bindings = []; if (!empty($conditions)) { foreach ($conditions as $condition) { $field = $condition[0]; $operator = $condition[1]; $value = $condition[2]; if ($operator == 'BETWEEN' && is_array($value)) { $whereClause .= "$field BETWEEN :{$field}_start AND :{$field}_end AND "; self::$bindings["{$field}_start"] = $value[0]; self::$bindings["{$field}_end"] = $value[1]; } else { $whereClause .= "$field $operator :$field AND "; self::$bindings[$field] = $value; } } $whereClause = 'WHERE ' . rtrim($whereClause, ' AND '); } $sql = "UPDATE $table SET $setClause $whereClause"; $stmt = self::getPdo()->prepare($sql); foreach ($data as $key => $value) { $stmt->bindValue(":$key", $value); } foreach (self::$bindings as $key => $value) { $stmt->bindValue(":$key", $value); } $stmt->execute(); return $stmt->rowCount(); } } class tbconta extends bd { } class tbdiario extends bd { } class tbhistprod extends bd { } class tbpessoa extends bd { } class tbprod extends bd { } class tbusuarios extends bd { }
  12. Hoje o dia foi bem complicado, pedi para o Copilot me ajudar com o operador BETWEEN, e ele introduziu o conceito de depurador, e a partir daí acabei me desentendo com o Copilot. Pensei que o meu problema era a gambiarra que eu fiz no autoload, então decidi tentar introduzir o BETWEEN sem a ajuda do Copilot. O depurador do Copilot é assim: echo $sql. Eu não entendi o que estava acontecendo. Mas mudei o código assim: echo $sql."<br>"; e tudo fez sentido, e foi justamente com a ajuda do depurador é que consegui introduzir o BETWEEN na classe bd. Quanto ao autoload, eu trouxe a versão original. Já a classe das tabelas ficou assim class tbdiario extends bd { }. No meio de tanta confusão, acabei gostando da função getTableName na classe bd, ele é capaz de saber o nome da tabela que foi invocada, e o VS Code não reclama que a classe tabela está ausente. O código seguinte vai executar esse tipo de consulta: $debitos=array_column(tbdiario::groupBy('contad') ->select(['contad','sum(valor) as debito'], [['dia','BETWEEN',[$primeiroDia,$ultimoDia]]]),'debito','contad'); listagem parcial do arquivo config.php spl_autoload_register(function ($class) { $path = str_replace('\\', DIRECTORY_SEPARATOR, strtolower($class)) . '.php'; if (file_exists($path)) { require $path; } else { echo "classe $class não encontrada"; exit; } }); class bd { private static $pdo; private static $initialized = false; private static $orderBy = ''; private static $groupBy = ''; private static $bindings = []; static function initialize() { if (!self::$initialized) { $dsn = 'mysql:host=' . HOST . ';dbname=' . DBNAME; self::$pdo = new PDO($dsn, USER, PASSWORD); self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); self::$initialized = true; } } protected static function getPdo() { self::initialize(); return self::$pdo; } protected static function getTableName() { $reflection = new \ReflectionClass(static::class); return strtolower($reflection->getShortName()); } public static function orderBy($column, $direction = 'ASC') { self::$orderBy = "ORDER BY $column $direction"; return new static; } // Adicionando o método groupBy public static function groupBy($columns) { if (is_array($columns)) { $columns = implode(', ', $columns); } self::$groupBy = "GROUP BY $columns"; return new static; } public static function select($columns = '*', $conditions = []) { self::initialize(); $table = static::getTableName(); if (is_array($columns)) { $columns = implode(', ', $columns); } $whereClause = ''; self::$bindings=[]; if (!empty($conditions)) { foreach ($conditions as $condition) { $field = $condition[0]; $operator = $condition[1]; $value = $condition[2]; if($operator=='BETWEEN' && is_array($value)) { $whereClause .= "$field BETWEEN :{$field}_start AND :{$field}_end AND "; self::$bindings["{$field}_start"] = $value[0]; self::$bindings["{$field}_end"] = $value[1]; } else { $whereClause .= "$field $operator :$field AND "; self::$bindings[$field] = $value; } } $whereClause = 'WHERE ' . rtrim($whereClause, ' AND '); } $sql = "SELECT $columns FROM $table $whereClause"; if (self::$groupBy) { $sql .= ' ' . self::$groupBy; self::$groupBy = ''; // Reset groupBy after use } if (self::$orderBy) { $sql .= ' ' . self::$orderBy; self::$orderBy = ''; // Reset orderBy after use } // echo $sql."<br>"; // depurador $stmt = self::getPdo()->prepare($sql); foreach (self::$bindings as $key => $value) { $stmt->bindValue(":$key", $value); } $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_OBJ); } } class tbconta extends bd { } class tbdiario extends bd { } class tbusuarios extends bd { }
  13. ** estou tentando implantar a condição between, e vejo que a ideia de eliminar a classe tabela está atrapalhando ** O Laravel tem uma pasta chamada Model e dentro dela tem um arquivo para cada tabela na forma de classe. No projeto semiLaravel eu só trabalho no diretório raiz e pensei em eliminar a classe que representa a tabela, passando a tarefa de criar a classe tabela para o autoload, conforme a necessidade do código. Eu não sou capaz de criar um código desse tipo, mas o Copilot sim: ** o grande efeito colateral é a tela do VS Code, ele sempre vai reclamar que a classe tabela não existe ** listagem parcial do config.php <?php spl_autoload_register(function ($class) { $path = str_replace('\\', DIRECTORY_SEPARATOR, strtolower($class)) . '.php'; if (file_exists($path)) { require $path; } else { eval("class $class extends bd {}"); } }); class bd { private static $pdo; private static $initialized = false; private static $orderBy = ''; private static $groupBy = ''; // Adicionando a variável para a cláusula GROUP BY static function initialize() { if (!self::$initialized) { $dsn = 'mysql:host=' . HOST . ';dbname=' . DBNAME; self::$pdo = new PDO($dsn, USER, PASSWORD); self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); self::$initialized = true; } } protected static function getPdo() { self::initialize(); return self::$pdo; } protected static function getTableName() { return strtolower((new \ReflectionClass(static::class))->getShortName()); } public static function orderBy($column, $direction = 'ASC') { self::$orderBy = "ORDER BY $column $direction"; return new static; } // Adicionando o método groupBy public static function groupBy($columns) { if (is_array($columns)) { $columns = implode(', ', $columns); } self::$groupBy = "GROUP BY $columns"; return new static; } public static function select($columns = '*', $conditions = []) { self::initialize(); $table = static::getTableName(); if (is_array($columns)) { $columns = implode(', ', $columns); } $whereClause = ''; if (!empty($conditions)) { foreach ($conditions as $condition) { $field = $condition[0]; $operator = $condition[1]; $value = $condition[2]; $whereClause .= "$field $operator :$field AND "; } $whereClause = 'WHERE ' . rtrim($whereClause, ' AND '); } $sql = "SELECT $columns FROM $table $whereClause"; if (self::$groupBy) { $sql .= ' ' . self::$groupBy; self::$groupBy = ''; // Reset groupBy after use } if (self::$orderBy) { $sql .= ' ' . self::$orderBy; self::$orderBy = ''; // Reset orderBy after use } $stmt = self::getPdo()->prepare($sql); if (!empty($conditions)) { foreach ($conditions as $condition) { $field = $condition[0]; $value = $condition[2]; $stmt->bindValue(":$field", $value); } } $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_OBJ); } }
  14. Para executar esse comando: $debitosAnteriores=array_column(tbdiario::groupBy('contad') ->select(['contad','sum(valor) as debito_anterior'], [['dia','<',$primeiroDia]]),'debito_anterior','contad'); eu precisei alterar a classe bd: listagem parcial de config.php <?php class bd { private static $pdo; private static $initialized = false; private static $orderBy = ''; private static $groupBy = ''; // Adicionando a variável para a cláusula GROUP BY static function initialize() { if (!self::$initialized) { $dsn = 'mysql:host=' . HOST . ';dbname=' . DBNAME; self::$pdo = new PDO($dsn, USER, PASSWORD); self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); self::$initialized = true; } } protected static function getPdo() { self::initialize(); return self::$pdo; } protected static function getTableName() { return ''; // Será implementado na classe filha } public static function orderBy($column, $direction = 'ASC') { self::$orderBy = "ORDER BY $column $direction"; return new static; } // Adicionando o método groupBy public static function groupBy($columns) { if (is_array($columns)) { $columns = implode(', ', $columns); } self::$groupBy = "GROUP BY $columns"; return new static; } public static function select($columns = '*', $conditions = []) { self::initialize(); $table = static::getTableName(); if (is_array($columns)) { $columns = implode(', ', $columns); } $whereClause = ''; if (!empty($conditions)) { foreach ($conditions as $condition) { $field = $condition[0]; $operator = $condition[1]; $value = $condition[2]; $whereClause .= "$field $operator :$field AND "; } $whereClause = 'WHERE ' . rtrim($whereClause, ' AND '); } $sql = "SELECT $columns FROM $table $whereClause"; if (self::$groupBy) { $sql .= ' ' . self::$groupBy; self::$groupBy = ''; // Reset groupBy after use } if (self::$orderBy) { $sql .= ' ' . self::$orderBy; self::$orderBy = ''; // Reset orderBy after use } $stmt = self::getPdo()->prepare($sql); if (!empty($conditions)) { foreach ($conditions as $condition) { $field = $condition[0]; $value = $condition[2]; $stmt->bindValue(":$field", $value); } } $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_OBJ); } } class tbdiario extends bd { protected static function getTableName() { return 'tbdiario'; } } class tbconta extends bd { protected static function getTableName() { return 'tbconta'; } } class tbusuarios extends bd { protected static function getTableName() { return 'tbusuarios';}}
  15. rs é abreviatura de recorset, eu usava isso quando trabalhava com o MS Access dentro do MS Excel, e o código era mais ou menos assim: Sub LerEGravarValoresNoAccess() Dim ws As Worksheet Dim db As Object Dim rs As Object Dim strDBPath As String Dim i As Integer ' Definir a planilha onde os dados estão Set ws = ThisWorkbook.Sheets("NomeDaSuaPlanilha") ' Altere o nome da planilha conforme necessário ' Caminho do banco de dados do Access strDBPath = "C:\Caminho\Para\Seu\BancoDeDados.accdb" ' Altere para o caminho do seu banco de dados ' Abrir conexão com o banco de dados do Access Set db = CreateObject("DAO.DBEngine.120").OpenDatabase(strDBPath) ' Definir o Recordset para a tabela onde os dados serão gravados Set rs = db.OpenRecordset("NomeDaSuaTabela", 2) ' Altere o nome da tabela conforme necessário ' Ler e gravar valores no banco de dados do Access For i = 1 To 3 ' Assumindo que os valores estão nas células A1:A3 e B1:B3 rs.AddNew rs.Fields("Orcamento").Value = ws.Cells(i, 1).Value ' Assumindo que os valores do orçamento estão na coluna A rs.Fields("Valor").Value = ws.Cells(i, 2).Value ' Assumindo que os valores estão na coluna B rs.Update Next i ' Fechar o Recordset e o banco de dados rs.Close db.Close ' Limpar objetos Set rs = Nothing Set db = Nothing End Sub Mas eu não tenho certeza se você está falando do MS Access, pois você só fala em "banco de dados", e assim fica difícil oferecer qualquer tipo de ajuda, eu não sei se você conseguiu conectar o Excel no banco de dados, eu não sei se você sabe usar critério de consulta, e o pior é que também não sei se o formulário tem uma caixa de texto chamado txt_ValorOrcamento, onde qualquer erro de digitação impede que o valor esperado apareça no local esperado.
  16. Estou montando o projeto na base da tentativa e erro, pois eu não entendo nada de lógica. Tenho muita ajuda do Copilot, fico contente quando o código funciona, entender o código, isso sim é uma tarefa difícil. O primeiro problema é do roteador é que eu precisei criar o arquivo .htaccess para mandar todas as solicitações para o arquivo index.php, ele funciona aqui no notebook que usa o Apache. Mas lá no Hostinger, ainda não sei se o código vai funcionar. Eu consegui executar o código do login com a primeira versão do roteador. Mas na hora de testar um novo código que trabalha com datas, o programa travou. O meu roteador foi projetado para executar classe:metodo( ). Tive que mudar tudo, precisei mudar o código para suportar classe:metodo(argumento), ele ficou assim: arquivo index.php <?php require('config.php'); $requestUri = $_SERVER['REQUEST_URI']; $basePath = '/semiLaravel/'; $path = substr($requestUri, strlen($basePath)); if ($path == "") { $path = "loginLogin()"; } // Ajuste a regex para capturar argumentos no formato classeMetodo(arg) if (preg_match('/^([a-z]+)([A-Z][a-zA-Z]*)\((.*)\)$/', $path, $matches)) { $classe = $matches[1]; $metodo = $matches[2]; $argumento = $matches[3]; // Supondo que o método aceita um argumento if (!empty($argumento)) { $classe::$metodo($argumento); } else { $classe::$metodo(); } } else { echo "Formato de URL inválido."; } ?>
  17. O meu código PHP usa um query builder bem simples (PDO->query()), mas na semana passada o Copilot viu o meu código e ele comentou que ele é vulnerável a um ataque do tipo "injeção de SQL", ele sugeriu eu separar a consulta dos parâmetros da consulta. Já que preciso mudar a minha query builder, então que seja mais ou menos no formato do Eloquent, mas hoje o dia foi terrível, eu e o Copilot ficamos o dia todo preso nesse código: if ($lcto) { $btnMenu = "Acrescenta Lançamento"; } else { $lcto = tbdiario::orderBy('lcto', 'DESC')->select('lcto')[0]->lcto+1; } $dia = isset($_SESSION['dia']) ? $_SESSION['dia'] : date('Y-m-d'); $ativo = tbconta::select('*', [['conta', '<', 201]]); O Copilot trabalhou duro, e várias vezes ele reclamou que a minha codificação é uma porcaria; tentei fazer do jeito dele, e não deu certo. Exausto, o Copilot me sugeriu executar uma consulta de cada vez, e para a minha perplexidade, eles funcionam de maneira separada. Eu inverti a ordem da consulta, e o código andou. O Copilot pensou, pensou e pensou e concluiu que o problema era a função orderBy( ). Ele inventou um comando do tipo reset para a função orderBy( ), e agora consigo executar o meu programa do jeito que eu listei. A seguir eu mostro o query builder que eu chamei de semiLaravel. O Laravel coloca todas as classes na pasta Model, no PHP eu não trabalho com nenhuma pasta. No caso do banco de dados, eu joguei tudo dentro do arquivo config.php, assim: listagem parcial do arquivo config.php class bd { private static $pdo; private static $initialized = false; private static $orderBy = ''; static function initialize() { if (!self::$initialized) { $dsn = 'mysql:host=' . HOST . ';dbname=' . DBNAME; self::$pdo = new PDO($dsn, USER, PASSWORD); self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); self::$initialized = true; } } protected static function getPdo() { self::initialize(); return self::$pdo; } protected static function getTableName() { return ''; // Será implementado na classe filha } public static function orderBy($column, $direction = 'ASC') { self::$orderBy = "ORDER BY $column $direction"; return new static; } public static function select($columns = '*', $conditions = []) { self::initialize(); $table = static::getTableName(); if (is_array($columns)) { $columns = implode(', ', $columns); } $whereClause = ''; if (!empty($conditions)) { foreach ($conditions as $condition) { $field = $condition[0]; $operator = $condition[1]; $value = $condition[2]; $whereClause .= "$field $operator :$field AND "; } $whereClause = 'WHERE ' . rtrim($whereClause, ' AND '); } $sql = "SELECT $columns FROM $table $whereClause"; if (self::$orderBy) { $sql .= ' ' . self::$orderBy; self::$orderBy = ''; // Reset orderBy after use } $stmt = self::getPdo()->prepare($sql); if (!empty($conditions)) { foreach ($conditions as $condition) { $field = $condition[0]; $value = $condition[2]; $stmt->bindValue(":$field", $value); } } $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_OBJ); } } class tbdiario extends bd { protected static function getTableName() { return 'tbdiario'; } } class tbconta extends bd { protected static function getTableName() { return 'tbconta'; } } class tbusuarios extends bd { protected static function getTableName() { return 'tbusuarios';}} ?>
  18. Fiz alguns testes, e tive que mudar algumas coisas: arquivo .htaccess RewriteEngine On # Redirecionar tudo para index.php RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^ index.php [L] 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"> </script> <script src="https://cdn.tailwindcss.com"></script> <style> @media (min-width: 768px) { .geral {width: 700px; margin: auto; font-size: 16px; background-color: #f7fafc} } @media (max-width: 767px) { body {width: 630px; margin: auto; font-size: 16px; background-color: #f7fafc} } @media (min-width: 768px) and (max-width:1024px) { body {width:700px;margin: auto; font-size: 16px; background-color: #f7fafc}} input[type="date"]::-webkit-calendar-picker-indicator {display: none} summary { list-style:none } </style> <title>Projeto Classe</title> <body class=geral> arquivo config.php <?php session_start(); error_reporting(E_ALL); ini_set('display_errors', 1); date_default_timezone_set('America/Sao_Paulo'); $baseDir = $_SERVER['SERVER_NAME'] === 'frank.com' ? $_SERVER['DOCUMENT_ROOT'] : $_SERVER['DOCUMENT_ROOT'].'/Frank/'; defined('HOST') || define('HOST', 'localhost'); defined('DBNAME') || define('DBNAME', $baseDir === $_SERVER['DOCUMENT_ROOT'] ? 'Diario' : 'diario'); defined('USER') || define('USER', $baseDir === $_SERVER['DOCUMENT_ROOT'] ? 'Root' : 'root'); defined('PASSWORD') || define('PASSWORD', $baseDir === $_SERVER['DOCUMENT_ROOT'] ? '14061406' : ''); defined('lctoBaixaEstoque') || define('lctoBaixaEstoque',14421); defined('lctoAcertoMais') || define('lctoAcertoMais',14742); defined('lctoAcertoMenos') || define('lctoAcertoMenos',14743); defined('diaAcerto') || define('diaAcerto','2025-01-31'); spl_autoload_register(fn ($class) => require str_replace('\\', DIRECTORY_SEPARATOR, strtolower($class)) . '.php'); function view($arquivo, $array = null){ if (!is_null($array)){ foreach ($array as $var => $value){ ${$var} = $value; } } ob_start(); include $arquivo . ".php"; ob_flush(); } class bd { private static $pdo; private static $initialized = false; public static function initialize() { if (!self::$initialized) { $dsn = 'mysql:host=' . HOST . ';dbname=' . DBNAME; self::$pdo = new PDO($dsn, USER, PASSWORD); self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); self::$initialized = true; } } protected static function getPdo() { self::initialize(); return self::$pdo; } protected static function getTableName() { return ''; // Será implementado na classe filha } public static function select($columns = '*', $conditions = []) { self::initialize(); $table = static::getTableName(); // Construindo a cláusula SELECT if (is_array($columns)) { $columns = implode(', ', $columns); } // Construindo a cláusula WHERE, se houver condições $whereClause = ''; if (!empty($conditions)) { foreach ($conditions as $field => $value) { $whereClause .= "$field = :$field AND "; } $whereClause = 'WHERE ' . rtrim($whereClause, ' AND '); } $sql = "SELECT $columns FROM $table $whereClause"; $stmt = self::getPdo()->prepare($sql); // Vinculando os valores para a cláusula WHERE if (!empty($conditions)) { foreach ($conditions as $field => $value) { $stmt->bindValue(":$field", $value); } } $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_OBJ); } public static function update($conditions, $data) { self::initialize(); $table = static::getTableName(); // Construindo a cláusula SET $setClause = ''; foreach ($data as $field => $value) { $setClause .= "$field = :$field, "; } $setClause = rtrim($setClause, ', '); // Construindo a cláusula WHERE $whereClause = ''; foreach ($conditions as $field => $value) { $whereClause .= "$field = :where_$field AND "; } $whereClause = rtrim($whereClause, ' AND '); $sql = "UPDATE $table SET $setClause WHERE $whereClause"; $stmt = self::getPdo()->prepare($sql); // Vinculando os valores para a cláusula SET foreach ($data as $field => $value) { $stmt->bindValue(":$field", $value); } // Vinculando os valores para a cláusula WHERE foreach ($conditions as $field => $value) { $stmt->bindValue(":where_$field", $value); } $stmt->execute(); } public static function where($field, $operator, $value) { self::initialize(); $table = static::getTableName(); $sql = "SELECT * FROM $table WHERE $field $operator :value"; $stmt = self::getPdo()->prepare($sql); $stmt->bindParam(':value', $value); $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_OBJ); } } class tbusuarios extends bd { protected static function getTableName() { return 'tbusuarios'; } } ?> arquivo index.php <?php require('config.php'); $requestUri = $_SERVER['REQUEST_URI']; $basePath = '/astudy/'; $path = substr($requestUri, strlen($basePath)); $path = $path ? $path : "loginLogin"; if (preg_match('/^([a-z]+)([A-Z].*)$/', $path, $matches)) { $classe = $matches[1]; $metodo = $matches[2]; } $classe::$metodo(); arquivo login.php <?php class Login { public static function alterarSenha() { $mensagem=""; $id=$_SESSION['id']; $email=tbusuarios::select('email',['id'=>$id])[0]->email; return view('loginAlterarSenha',['mensagem'=>$mensagem,'email'=>$email]); } public static function login() { $mensagem=""; $email=""; return view('loginView',['mensagem'=>$mensagem,'email'=>$email]); } public static function menu() { $email=$_POST['email']; $senha=$_POST['password']; $usuario=tbusuarios::where('email','=',$email); if(!$usuario) { $_SESSION['mensagem']="Dados inválidos!"; return view('loginView'); } $confirmar=$usuario[0]->senha; $validaSenha=password_verify($senha,$confirmar); if(!$validaSenha) { $_SESSION['mensagem']="Dados inválidos!"; return view('loginView'); } unset($_SESSION['mensagem']); $_SESSION['id']=$usuario[0]->id; $_SESSION['nome']=$usuario[0]->nome; return view('menuView'); } public static function sair() { session_destroy(); view('loginView',['mensagem'=>""]); } public static function senhaAlterada() { $senhaAlterada=$_POST['senhaAlterada']; $hash=password_hash($senhaAlterada,PASSWORD_BCRYPT,['cost'=>12]); $id=$_SESSION['id']; tbusuarios::update(['id'=>$id],['senha'=>$hash]); return self::login(); } } arquivo loginView.php <?php require('appView.php'); ?> <script>document.title="Login"</script> <div class="mt-[150px] flex justify-center items-center"> <div> <div class="text-2xl">Projeto Classe</div> <div class="w-[630px] sm:max-w-md mt-6 px-6 py-4 bg-white shadow-md overflow-hidden sm:rounded-lg"> <!-- Session Status --> <form method="POST" action="loginMenu"> <div> <label class="block font-medium text-sm text-gray-700" for="email"> Email </label> <input class="w-full px-2 py-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 py-2 border rounded-md shadow-sm block mt-1 w-full 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> </div> arquivo menuView.php <?php include('appView.php'); if (!isset($_SESSION['id']) || !isset($_SESSION['nome'])) { header('Location: loginLogin'); exit(); } ?> <script> window.onload = function() { btDiv.addEventListener('click', function() { dropdownMenu.classList.toggle('hidden'); }); btLogin.addEventListener('click', function() { menuLogin.classList.toggle('hidden'); }); document.addEventListener('click', function(event) { if (!btDiv.contains(event.target) && !btDiv.contains(event.target)) { dropdownMenu.classList.add('hidden'); } if (!btLogin.contains(event.target) && !btLogin.contains(event.target)) { menuLogin.classList.add('hidden'); } }); } </script> <header id="cabecalho" class="bg-white shadow-sm flex p-1 items-center justify-between mb-2"> <div class="flex items-center flex-grow"> <div class="w-[170px] font-semibold">Classe</div> <div class="flex-grow flex justify-center"> <button type="button" id="btDiv" class="inline-flex justify-center w-full px-4 py-1 hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 font-semibold rounded text-gray-500"> <div id="btMenu">Menu</div> <svg class="-mr-1 ml-2 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"> <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a 1 1 0 111.414 1.414l-4 4a 1 1 0 01-1.414 0l-4-4a 1 1 0 010-1.414z" clip-rule="evenodd" /> </svg> </button> <div id="dropdownMenu" class="hidden origin-top-left absolute left-0 mt-2 w-auto rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5"> <?php if ($_SESSION['id'] == 1): ?> <div class="py-1" role="menu" aria-orientation="vertical" aria-labelledby="btMenu"> <a class="block text-gray-500 font-semibold px-4 py-2 hover:bg-gray-200" href="diarioInicio">Diário</a> <a class="block text-gray-500 font-semibold px-4 py-2 hover:bg-gray-200" href="balanceteInicio">Balancete</a> <a class="block text-gray-500 font-semibold px-4 py-2 hover:bg-gray-200" href="pagarInicio">Pagar</a> <a class="block text-gray-500 font-semibold px-4 py-2 hover:bg-gray-200" href="outrosInicio">Outros</a> <?php endif; ?> <a class="block text-gray-500 font-semibold px-4 py-2 hover:bg-gray-200" href="orcamentoMenu">Orçamento</a> <a class="block text-gray-500 font-semibold px-4 py-2 hover:bg-gray-200" href="pessoaInicio">Pessoa</a> <a class="block text-gray-500 font-semibold px-4 py-2 hover:bg-gray-200" href="produtoInicio">Produto</a> <a class="block text-gray-500 font-semibold px-4 py-2 hover:bg-gray-200 whitespace-nowrap" href="vendaInicio">Relatório de Venda</a> <a class="block text-gray-500 font-semibold px-4 py-2 hover:bg-gray-200" href="nfVerxml">Ver XML</a> </div> </div> </div> <div class="flex items-center"> <div class="relative"> <button type="button" id="btLogin" class="inline-flex justify-center w-full px-4 py-1 hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 font-semibold rounded text-gray-500"> <div id="teste"><?=$_SESSION['nome']?></div> <svg class="-mr-1 ml-2 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"> <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a 1 1 0 111.414 1.414l-4 4a 1 1 0 01-1.414 0l-4-4a 1 1 0 010-1.414z" clip-rule="evenodd" /> </svg> </button> <div id="menuLogin" class="hidden origin-top-right absolute right-0 mt-2 w-auto rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5"> <a class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-200" href="loginSair">Sair</a> <a class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-200" href="loginAlterSenha">Mudar Senha</a> </div> </div> </div> </header>
  19. O que eu mais gostei no Laravel foi o Eloquent (ele usa a sintaxe tbdiario::where('lcto',12)->get( )) e o roteador. O problema do roteador web.php é que você precisa criar uma nova rota para cada novo comando. O roteador que inventei não trabalha com um monte de rota, mas trabalha com a sintaxe classeMetodo, assim: arquivo .htaccess RewriteEngine On # Redirecionar tudo para index.php RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^ index.php [L] arquivo bd.php <?php class BD { public static $pdo; private static $initialized = false; public static function initialize() { if (!self::$initialized) { $host = 'localhost'; $dbname = 'diario'; $username = 'root'; $password = ''; $dsn = 'mysql:host=' . $host . ';dbname=' . $dbname; self::$pdo = new PDO($dsn, $username, $password); self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); self::$initialized = true; } } } ?> arquivo diario.php <?php class Diario extends BD { public static function getValor($lcto) { self::initialize(); // Certificando que a inicialização está sendo feita $sql = 'SELECT valor FROM tbdiario WHERE lcto = :lcto'; $stmt = self::$pdo->prepare($sql); $stmt->bindParam(':lcto', $lcto); $stmt->execute(); return $stmt->fetchColumn(); } public static function inicio() { self::initialize(); // Certificando que a inicialização está sendo feita echo "olá mundo<br>"; echo self::getValor(12); } } ?> arquivo index.php <?php spl_autoload_register(fn ($class) => require str_replace('\\', DIRECTORY_SEPARATOR, strtolower($class)) . '.php'); $requestUri = $_SERVER['REQUEST_URI']; $basePath = '/astudy/'; $path = substr($requestUri, strlen($basePath)); if($path=="") { header('location:teste.php'); exit; } if (preg_match('/^([a-z]+)([A-Z].*)$/', $path, $matches)) { $classe = $matches[1]; $metodo = $matches[2]; } $classe::$metodo(); arquivo teste.php <a href=diarioInicio>teste</a>
  20. Encontrei um vídeo no YouTube que ensina como conectar o VBA no WhatsApp versão web, ele usa o comando VBA Shell e SendKeys. O chato é ter que trabalhar com o temporizador, muda de laptop para laptop, mas eu consegui chegar até a caixa de contatos: Sub WhatsApp() Shell "C:\Program Files\Google\Chrome\Application\Chrome.exe" Application.Wait Now + TimeValue("00:00:03") SendKeys "https://web.whatsapp.com/" Application.Wait Now + TimeValue("00:00:03") SendKeys "~" Application.Wait Now + TimeValue("00:00:13") For i = 1 To 10 SendKeys "{TAB}" Application.Wait Now + TimeValue("00:00:02") Next End Sub
  21. O Copilot disse que o Power Automate é capaz de enviar documentos para o WhatsApp, mas você precisa ter uma conta no WhatsApp Business Api, desconfio que o Power Automate não faz parte do Office (que cobra R$ 459,00 por ano) e a API do WhatsApp também não é de graça. Se eu fosse você pegaria um morador de rua e pediria para ele encaminhar cada documento pelo WhatsApp do desktop para o número correspondente, prometendo que você garantiria a pinga no final do serviço. Estava pensando em colocar todos os holerites numa página da empresa, cada um pega o seu. O problema é o safado que vai pegar o holerite do outro e vai reclamar com o patrão que ele ganha bem menos. Nesse caso, iria criptografar o pdf com o CPF do colaborador, mas aí a Adobe quer R$ 100,00 por mês. Isso é um problema difícil de resolver. Boa sorte. Ah, lembrei agora, eu fiz o teste com duas Galaxy da Samsung, ele tem a tecnologia NFC e consegue transferir arquivos entre si, sem precisar usar o Bluetooth ou outro canal de comunicação, tudo por aproximação. Já o iPhone é jogo duro, e tem muito colaborador que tem celular, mas não tem Android nem iOs, e desconfio que o WhatsApp não funciona nesses celulares. Seja qual for a solução, por favor, publique a sua solução, muita gente vai querer saber da sua experiência.
  22. Pelo que eu entendi você quer cadastrar um administrador da tabela admin na tabela users. Para simplificar, a tabela admin só tem um campo chamado nome e o users também. O meu modelo ficou assim: app > Models > User.php <?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; class User extends Authenticatable { use HasFactory, Notifiable; public $timestamps = false; protected $fillable = ['name',]; } app > Models > Admin.php <?php namespace App\Models; class Admin extends User { protected $table="admin"; } app > Http > Controllers > Teste.php <?php namespace App\Http\Controllers; use App\Models\User; use App\Models\Admin; class Teste { function index(){ $admin=Admin::where('id',1)->value('nome'); User::create(['name'=>$admin]); } } Eu gostei do verbo extends no model, eu não preciso mais fazer aquela longa lista de biblioteca que o model precisa usar, mas para pegar uma informação numa tabela e colocar em outra, acho mais fácil jogar o serviço para o Eloquent.
  23. Instalei o selenium, o ChromeDriveManager e o webdriver_manager pelo comando pip install. Eu tive problema com o Service na quarta linha, então o Copilot corrigiu a segunda linha capitalizando a palavra Service. Com outras alterações do Copilot, o código ficou assim: arquivo rascunho.py from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager service = Service(ChromeDriverManager().install()) driver = webdriver.Chrome(service=service) driver.get("https://www.exemplo.com") e a mensagem que recebi foi bem diferente do que você apresentou, quando executei o comando python rascunho.py
  24. Todas as notas fiscais são feitas no formato XML. O Excel é um excelente aplicativo que consegue importar o XML no formato CSV e assim você consegue montar a memória de cálculo para diferença de alíquota de ICMS ou ICMS Substituição Tributária no caso das compras fora do estado de São Paulo. Eu já uso o PHP que tem uma boa ferramenta para importar o XML para a memória do computador (eu já uso uma tabela provisória do MySQL), comparo o novo custo do produto com o velho e atualizo, e em seguida uso todas as informações para dar entrada no estoque. Nem sempre o fornecedor manda o arquivo XML, nesse caso eu peço para o meu irmão tirar uma foto da chave do DANFE, e com essa chave eu vou no portal da Nota Fiscal Eletrônica e peço para fazer o download do arquivo (o portal só autoriza a consulta plena ou o download com o certificado digital da empresa que consta na Nota Fiscal Eletrônica). Estamos em 2025, esse é um mundo totalmente diferente. No meu tempo, a gente ajuntava todas as notas para encaminhar para a contabilidade para fazer a escrituração, apuração e imprimir os livros fiscais. Hoje não. A Contabilidade tem um esquema que consegue puxar todos os xml com o CNJP do cliente. Não sei que mágica é essa, tudo o que sei é que existe uma empresa por trás disso, como eles conseguem fazer esse serviço, isso é um mistério para mim. O que eu mando para a contabilidade são os xml que eu criei para vender. Se você tem PHP, aqui está um código parcial que eu fiz (eu criei um query builder baseado no PDO->query()) e roteador bem simples que passa pelo arquivo index com a sintaxe ?classe.método.argumento): arquivo nf.php <?php class NF { function atualiza() { $previa=(new Conn)->select("* from tbnf"); extract($_SESSION['vetor']); return view('nfView',['previa'=>$previa,'nNF' => $nNF,'xNome' => $xNome, 'codp' => $codp,'vNF' => $vNF,'difAliqICMS' => $difAliqICMS, 'soma'=>$soma,'st'=>$st]); } 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; $consulta = $consulta2; } 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==6403 || $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"); return view('nfCFOPview',['previa'=>$previa,'nNF' => $nNF,'xNome' => $xNome, 'codp' => $codp]); } function custo() { $custoAtual = $_POST['custoAtual']; $codprod = $_POST['codprod']; $margem=(new Conn)->select("marg from tbprod where codprod=$codprod")[0]->marg; $venda=pvenda($custoAtual,$margem); $class="class=text-end"; (new Conn)->update("tbnf set custoanterior=$custoAtual, class='$class' where codprod=$codprod"); (new Conn)->update("tbprod set custo=$custoAtual, venda=$venda where codprod = $codprod"); } function incluir() { $lcto=$_POST['lcto']; $verifica=count((new Conn)->select("* from tbhistprod where lcto=$lcto")); if($verifica){ $mensagem="<h1>Nota já lançada. <a href=?NF.atualiza>Voltar</a></h1>"; return view('mensagemView',['mensagem'=>$mensagem]); } $dia=(new Conn)->select("dia from tbdiario where lcto=$lcto")[0]->dia; $matriz=(new Conn)->select("* from tbnf"); foreach($matriz as $vetor) { (new Conn)->insert("tbhistprod (codprod,dia,qt,custototal,codp,lcto) values ('$vetor->codprod','$dia',$vetor->qt,$vetor->custototal,$vetor->codp,$lcto)"); } return header("location:?Diario.inicio.$dia"); } function inicio() { return view('nfArquivo',['action'=>'?NF.selecionada']); } function qt() { $qt=$_POST['qt']; $id=$_POST['id']; $previa=(new Conn)->select("* from tbnf where id=$id")[0]; $novoClass=$previa->class; $custoAtual=intval($previa->custototal/$qt*100)/100; if($custoAtual!==$previa->custoanterior) { $novoClass="class=\"text-danger text-end\""; } (new Conn)->update("tbnf set class='$novoClass', custoatual=$custoAtual, qt=$qt where id=$id"); return $this->atualiza(); } function selecionada() { (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; $difAliqICMS=0; $st=0; $aliquotaInterna=0.18; foreach ($itens as $item) { if ((float)$item->prod->CFOP == 6102 || (float)$item->prod->CFOP ==6101) { $vBC = (float)$item->imposto->ICMS->ICMS10->vBC; $vBC = $vBC ? $vBC : (float)$item->imposto->ICMS->ICMS00->vBC; $vICMS = (float)$item->imposto->ICMS->ICMS10->vICMS; $vICMS = $vICMS ? $vICMS : (float)$item->imposto->ICMS->ICMS00->vICMS; if((float)$item->prod->NCM == 40169300) { $st += round($vBC*(1.4)*$aliquotaInterna-$vICMS+0.00001,2); // anel de vedação } else { $difAliqICMS += round(($vBC * $aliquotaInterna - $vICMS+0.00001),2); } } } $vNF = (float)$nfe->NFe->infNFe->total->ICMSTot->vNF; $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; $soma=0; 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) { 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); $quantidade = (string)$item->prod->qCom; if (is_numeric($codprod)) { $produtoDobrado = [506, 507, 508, 509, 510, 519, 1768, 1770, 1772]; if (in_array($codprod, $produtoDobrado)) { $quantidade = 2 * $quantidade; } $produtox5=[1798]; if (in_array($codprod,$produtox5 )) { $quantidade = 5 * $quantidade; } $produtoX10 = [2192, 2190,1782,2456]; if (in_array($codprod, $produtoX10)) { $quantidade = 10 * $quantidade; } $produtox12 = [2403,2406,2496,2497,2498,2499]; if (in_array($codprod, $produtox12)) { $quantidade = 12 * $quantidade; } $produtox24 = [2493,2405,2494,2495,2409]; if (in_array($codprod, $produtox24)) { $quantidade = 24 * $quantidade; } } $vICMSST1 = ((float)$item->imposto->ICMS->ICMS10->vICMSST) ? (float)$item->imposto->ICMS->ICMS10->vICMSST : null; $vICMSST2 = ((float)$item->imposto->ICMS->ICMSSN202->vICMSST) ? (float)$item->imposto->ICMS->ICMSSN202->vICMSST : null; $vICMSST = $vICMSST1 ? $vICMSST1 : $vICMSST2; $difAliq = 0; if ((float)$item->prod->CFOP == 6102 || (float)$item->prod->CFOP == 6101){ $vBC = (float)$item->imposto->ICMS->ICMS10->vBC; $vBC = $vBC ? $vBC : (float)$item->imposto->ICMS->ICMS00->vBC; $vICMS = (float)$item->imposto->ICMS->ICMS10->vICMS; $vICMS = $vICMS ? $vICMS : (float)$item->imposto->ICMS->ICMS00->vICMS; if((float)$item->prod->NCM == 40169300) { $difAliq = round($vBC * 1.4 * $aliquotaInterna -$vICMS+0.00001,2); // usando variável $difAliq como st } else { $difAliq = round(($vBC * $aliquotaInterna - $vICMS+0.00001),2); } } $vIPI = (float)$item->imposto->IPI->IPITrib->vIPI ? (float)$item->imposto->IPI->IPITrib->vIPI : 0; $vProd = (string)$item->prod->vProd; $valorTotal = $vProd + $vICMSST + $difAliq + $vIPI; $soma += $valorTotal; $class = "class=text-end"; $custoAtual=0; $custoAnterior=0; if (is_numeric($codprod)) { $custoAtual = intval($valorTotal / $quantidade * 100) / 100; $consulta = (new Conn)->select("custo from tbprod where codprod=$codprod"); $custoAnterior = $consulta[0]->custo; if (abs($custoAnterior - $custoAtual) > 0.02) { $class = "class=\"text-end text-danger\""; } } $produto=str_replace("'","''",$produto); (new Conn)->insert("tbnf (codforn,codprod,prod,qt,custoatual, custoanterior,class,custototal,codp,cfop,class2) values ('$codforn',$codprod,'$produto',$quantidade,$custoAtual, $custoAnterior,'$class',$valorTotal,$codp,'5405','text-right')"); } $previa=(new Conn)->select("* from tbnf"); $_SESSION['vetor']=['nNF' => $nNF,'xNome' => $xNome, 'codp' => $codp,'vNF' => $vNF,'difAliqICMS' => $difAliqICMS, 'soma'=>$soma,'st'=>$st]; return view('nfView',['previa'=>$previa,'nNF' => $nNF,'xNome' => $xNome, 'codp' => $codp,'vNF' => $vNF,'difAliqICMS' => $difAliqICMS, 'soma'=>$soma,'st'=>$st]); } function verXML(){ return view('nfArquivo',['action'=>'?NF.xml']); } function xml(){ $nfe=simplexml_load_file($_FILES['arquivo']['tmp_name']); return imprime($nfe); } } 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 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-[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; ?> arquivo nfView.php <?php include('menuView.php'); ?> <script> btMenu.innerHTML='NF Fornecedor';document.title="NF Fornecedor" function atualizar(custoAtual, custoAnterior, codprod) { var confirma = confirm("Atualizar?\ncusto atual: " + custoAtual + "\ncusto anterior: " + custoAnterior); if (confirma) { var xmlhttp = new XMLHttpRequest(); var url = "?NF.custo"; var formData = new FormData(); formData.append('custoAtual', custoAtual); 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) { // console.log("Status da resposta: " + xmlhttp.status); // alert("Resposta do servidor: " + xmlhttp.responseText); location.replace("?NF.atualiza"); } else { alert("Erro na requisição: " + xmlhttp.status); } } }; xmlhttp.send(formData); } } </script> <table class='table table-striped table-sm'> <tr class=fw-semibold><td colspan=3>NF <?=$nNF." ".substr($xNome,0,10)." codp ".$codp?><td><td><td class=text-end><?=dec($vNF)?> <?php if($difAliqICMS!==0 || $st!==0): ?> <tr class=fw-semibold><td><td><td>Diferença de Alíquota de ICMS<td><td><td class=text-end><?=dec($difAliqICMS)?> <tr class=fw-semibold><td><td><td>Substituição Tributária<td><td><td class=text-end><?=dec($st)?> <tr class=fw-semibold><td><td><td>Total a conferir<td><td><td class=text-end><?=dec($difAliqICMS+$vNF+$st)?> <?php endif; ?> </table> <table class="table table-striped table-sm"> <th style="max-width:50px">Cforn <th style="width:50px text-end">Cod <th style="width:330px">Produto <th class=text-end>Qt <th class=text-end>Custo <th class=text-end>Total <?php foreach($previa as $p): ?> <tr><td style="max-width:80px" class=text-end><?=$p->codforn?> <td style="max-width:50px" class=text-end><?=$p->codprod?> <td style="max-width:330px" class="overflow-hidden" ><?=$p->prod?> <td> <form method=post action=?NF.qt> <input name=qt value='<?=$p->qt?>' class="inv text-end" size='1' onchange=submit()> <input type=hidden name=id value='<?=$p->id?>'> </form> <td <?=$p->class?> onclick="atualizar(<?=$p->custoatual?>,<?=$p->custoanterior?>,<?=$p->codprod?>)"><?=dec($p->custoatual)?> <td class=text-end><?=dec($p->custototal)?> <?php endforeach; ?> <tr class=fw-semibold><td><td><td>Total dos itens<td><td></td><td class=text-end><?=dec($soma)?> </table> <div> Enviar tudo para o banco de dados <form action=?NF.incluir method=post> <input name=lcto placeholder="Número do Lançamento" required> <input type=submit> </form> </div>
  25. Tem jeito de compartilhar o código do arquivo para a gente testar aqui?
×
×
  • Criar Novo...