
Frank K Hosaka
Membros-
Total de itens
1.590 -
Registro em
-
Última visita
Frank K Hosaka's Achievements
0
Reputação
-
Pegando o nome de um arquivo zipado (Simples Nacional)
pergunta respondeu ao Frank K Hosaka de Frank K Hosaka em PHP
A seguir a listagem completa: arquivo app > Models > tbrendabruta.php <?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class tbrendabruta extends Model { use HasFactory; protected $table="tbrendabruta"; protected $fillable=['apuracao','renda']; const UPDATED_AT=null; const CREATED_AT=null; } ?> arquivo app > Livewire > Simples.php <?php namespace App\Livewire; use App\Models\tbrendabruta; use Carbon\Carbon; use DOMDocument; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.app',['titulo'=>'Estimativa do Simples'])] class Simples extends Component { protected $listeners=['verArquivo']; public $aliquota=7.3, $reducao=5940, $efetiva; // 2a. faixa da tabela do simples no comércio public $comST,$grupos,$modal, $notasFiscais = [],$nfCanceladas = []; public $notasCanceladas,$primeiraNota,$receitasAnteriores,$renda12; public $semST,$somaTotal,$totalDeNotas,$ultimaNota; public $CST,$SST,$TT; public $apuracao,$proxApuracao,$venda; function incluir() { tbrendabruta::create(['apuracao'=>$this->proxApuracao,'renda'=>$this->venda]); $this->modal=true; } function verArquivo($arquivo) { $this->modal=false; $this->apuracao=tbrendabruta::max('apuracao'); $previa=Carbon::createFromFormat('Ym',$this->apuracao); $this->proxApuracao=$previa->addMonth()->format('Ym'); $arquivo=substr($arquivo,0,-4); $diretorio="C:/Users/Frank/Downloads/".$arquivo; $contaArquivos=count(scandir($diretorio))-2; $nfces = scandir($diretorio); $this->notasCanceladas=0; $this->somaTotal=0; $this->comST=0; $this->semST=0; foreach($nfces as $nfce) { if($nfce !== '.' && $nfce !=='..' ) { if(strpos($nfce,'-can') !== false) { $this->nfCanceladas[] = intval(substr($nfce,28,6)); $this->notasCanceladas++; continue; } $numeroNota=intval(substr($nfce,28,6)); if(in_array($numeroNota,$this->nfCanceladas)) { continue; } $this->notasFiscais[]=$numeroNota; $dom = new DOMDocument(); $dom->load("$diretorio/$nfce"); $nfe=$dom->documentElement; if($nfe->getElementsByTagName('vNF')->item(0)) { $somaNF=$nfe->getElementsByTagName('vNF')->item(0)->nodeValue; $this->somaTotal+=$somaNF; $produtos=$nfe->getElementsByTagName('prod'); foreach($produtos as $p) { $cfop=$p->getElementsByTagName('CFOP')->item(0)->nodeValue; $vProd=$p->getElementsByTagName('vProd')->item(0)->nodeValue; $vDesc=0; if($p->getElementsByTagName('vDesc')->item(0)) { $vDesc=$p->getElementsByTagName('vDesc')->item(0)->nodeValue; } if($cfop==5405) { $this->comST += $vProd - $vDesc; } else { $this->semST += $vProd - $vDesc; } } } } } sort($this->notasFiscais); $this->primeiraNota=intval($this->notasFiscais[0]); $this->ultimaNota=intval($this->notasFiscais[$contaArquivos-1]); $this->totalDeNotas=count($this->notasFiscais); $this->receitasAnteriores = tbrendabruta::orderBy('id','desc') ->skip(1)->take(12)->get(); $this->renda12=array_reduce($this->receitasAnteriores->toArray(),function($total,$r) { return $total + $r['renda']; },0); $this->grupos=array_chunk($this->receitasAnteriores->toArray(),3); $this->efetiva=round((($this->renda12*$this->aliquota/100-$this->reducao)/$this->renda12)*100,4); $this->CST=round($this->comST*$this->efetiva/100*(1-34/100),2); $this->SST=round($this->semST*$this->efetiva/100,2); $this->TT=$this->CST+$this->SST; } function mount() { $this->modal=true; } } ?> arquivo resources > views > livewire > simples.blade.php <div> <div class="mt-5"></div> @if($modal) <flux:input type="file" wire:model="zip" label="Escolha um arquivo zipado da Bling já descompactado" onchange="arquivo=event.target.files[0].name; Livewire.dispatch('verArquivo',[arquivo])" /> @else <div class=font-semibold>Estimativa do Simples Nacional {{ $apuracao }}</div> <div class="flex items-center"> Próxima Apuração {{ $proxApuracao }} <div class="w-[200px] ml-2"> <flux:input wire:model="venda" wire:change="incluir" size=xs placeholder="valor da venda"/> </div> </div> <div class=flex> <div>Total de Notas</div> <div class="ml-2">{{$totalDeNotas}}</div> </div> <div class=flex> <div>Notas Canceladas</div> <div class="ml-2 text-right mr-2">{{$notasCanceladas.": ";}}</div> @foreach($nfCanceladas as $n) {{ $n." "}} @endforeach </div> <div class=flex> <div>Primeira Nota</div> <div class="text-right ml-2 font-semibold">{{$primeiraNota}}</div> <div class="ml-5">Última Nota</div> <div class="text-right ml-5 font-semibold">{{$ultimaNota}}</div> </div> @foreach($grupos as $grupo) <div class='flex'> @foreach($grupo as $r) <div class="w-[40px] font-semibold">{{$r['apuracao']}}</div> <div class="w-[100px] text-right mr-5">{{dec($r['renda'])}}</div> @endforeach </div> @endforeach <div class="flex"> <div class="mr-5">Renda 12 meses:</div> <div class="font-semibold">{{dec($renda12)}}</div> </div> <div class="flex"> <div class="w-[130px]">Alíquota Efetiva</div> <div class="w-[320px]">{{"(".dec($renda12)." x ".virgula($aliquota). " % - ".dec($reducao).") / ".dec($renda12)}}</div> <div class="w-[10px]">{{" = "}}</div> <div class="w-[80px] text-right font-semibold">{{ virgula($efetiva)." %" }} </div> </div> <div class=flex> <div class="w-[70px]">Com ST</div> <div class="w-[100px] text-right">{{dec($comST)}}</div> <div class="ml-1 w-[160px]">{{ " x ".virgula($efetiva)." % x (1 - 34%)"}}</div> <div class="w-[10px]">=</div> <div class="w-[100px] font-semibold text-right">{{ dec($CST) }}</div> </div> <div class=flex> <div class="w-[70px]">Sem ST</div> <div class="w-[100px] text-right">{{dec($semST)}}</div> <div class="ml-1 w-[160px]">{{ " x ".virgula($efetiva)." %"}}</div> <div class="w-[10px]">=</div> <div class="w-[100px] font-semibold text-right">{{ dec($SST) }}</div> </div> <div class=flex> <div class="w-[70px]">Total</div> <div class="w-[100px] text-right">{{dec($somaTotal)}}</div> <div class="ml-1 w-[160px]"></div> <div class="w-[10px]">{{ " " }}</div> <div class="w-[100px] font-semibold text-right text-red-700">{{ dec($TT) }}</div> </div> @endif </div> -
O tutorial do Livewire afirma que é fácil fazer upload, mas eu só recebi a mensagem de que o upload falhou, no caso do arquivo zipado. Mas eu vi que o <input type=file> pegou o nome do arquivo selecionado. Com a ajuda do Copilot, consegui pegar o nome do arquivo e mandar para o Livewire: arquivo app > Livewire > Simples.php <?php namespace App\Livewire; use Livewire\Component; class Simples extends Component { protected $listeners=['verArquivo']; public function verArquivo($arquivo) { dd($arquivo); } } arquivo resources > views > livewire > simples.blade.php <flux:input type="file" onchange="arquivo=event.target.files[0].name; Livewire.dispatch('verArquivo',[arquivo])" /> Apesar do código ser bem pequeno, isso é resultado de várias tentativas e erros. Foi muita sorte o código JavaScript funcionar, a lista do Copilot era bem maior. Já o Livewire.dispatch, esse deu muito trabalho, a ideia de colocar colchete em torno da variável que contém o nome do arquivo foi pura tentativa erro, não sei como usar o comando dispatch, mas nesse caso, deu certo. Claro que o nome do arquivo não ajuda muito, mas eu espero explorar o diretório que tem o mesmo nome do arquivo zipado. O PHP, o Laravel e o Livewire não gostam de arquivos zipados, mas para trabalhar com arquivo xml, eles não reclamam.
-
O orçamento é apenas uma equação do primeiro grau, onde orçamento = quantidade x preço. O PHP e o Laravel permitem pegar o valor do <input name=quantidade> e passar para a variável $quantidade através do recurso do <form>. Já o Livewire elimina o transtorno do <form> usando apenas <input wire:model=quantidade>. Isso é bem engenhoso. O problema é o preço. No PHP e no Laravel, eu tive que criar dois módulos, o orçamento e o produto. Para não perder as informações do orçamento eu usei a variável global session(['pedido'=>$pedido]), e assim eu pulava do módulo orçamento para o módulo produto. E no módulo produto, eu usei a variável global session(['codprod'=>$codprod]) e assim voltava para o módulo do orçamento para fazer o resto do serviço. A variável global é uma mão na roda, o problema são os outros módulos, e eu estou enfrentando um monte de problema de lógica. A minha ideia é acabar com a variável global, e usar o Livewire para carregar o orçamento e o produto ao mesmo tempo no navegador, a minha ideia é fazer do produto um modal do orçamento, e assim que o usuário selecionar o produto, ele usa o comando dispatch( ) para enviar o código do produto para o orçamento, e o orçamento usa o recurso do ouvinte ("listener") para pegar o código do produto para terminar a equação. Falar é fácil, codificar são outros quinhentos. Aqui só fiz o esboço.
-
O Livewire é a soma de três arquivos: o componente, o layout e o encaixe, os dois últimos usam o CSS Tailwind. Eu comecei a estudar o Laravel em 2022, mas em 2025 é que consegui dominar melhor porque eu consegui decorar um pouco a sintaxe do Tailwind. Só é possível mexer com o Tailwind com a ajuda do Copilot. Para contornar o problema do Tailwind é que inventaram o <flux>, ele é um componente do HTML que já vem pré-formatado, você não precisa do Copilot para desenhar um <input>. Mas para o Tailwind, o Livewire e o Flux funcionarem, o seu arquivo layout deve seguir essa diretriz: arquivo resources > views > components > teste.blade.php <!DOCTYPE html> <title>{{ $title }}</title> @vite(['resources/css/app.css', 'resources/js/app.js']) @livewireScripts @fluxAppearance <body> <flux:main> {{ $slot }} </flux:main> @fluxScripts </body> arquivo app > Livewire > Lteste.php <?php namespace App\Livewire; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.teste',['title'=>'Teste'])] class Lteste extends Component { } ?> arquivo resources > views > livewire > lteste.blade.php <div> <flux:modal.trigger name="edit-profile"> <flux:button>Edit profile</flux:button> </flux:modal.trigger> <flux:modal name="edit-profile" class="md:w-96"> <div class="space-y-6"> <div> <flux:heading size="lg">Update profile</flux:heading> <flux:text class="mt-2">Make changes to your personal details.</flux:text> </div> <flux:input label="Name" placeholder="Your name" /> <flux:input label="Date of birth" type="date" /> <div class="flex"> <flux:spacer /> <flux:button type="submit" variant="primary">Save changes</flux:button> </div> </div> </flux:modal> </div> arquivo routes > web.php <?php use App\Livewire\Lteste; Route::middleware(['auth','verified'])->group(function() { Route::get('lteste',Lteste::class)->name('lteste'); } ?>
-
Há muito tempo, eu consegui esse código para criar o arquivo csv no PHP e no Laravel <?php // listagem parcial class Orcamento extends Controller { function bling(Request $request) { // rotina para criar $dados $arquivo = fopen("$request->pBling.csv", "w"); fputcsv($arquivo, $dados[0]); foreach ($dados as $linha) { if ($linha != $dados[0]) { fputcsv($arquivo, $linha); } } fclose($arquivo); if (file_exists("$request->pBling.csv")) { header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=' . basename("$request->pBling.csv")); header('Content-Length: ' . filesize("$request->pBling.csv")); readfile("$request->pBling.csv"); unlink("$request->pBling.csv"); } } Mas esse código não funciona no Livewire. Depois de pesquisar o Livewire, o Laravel, o Copilot e um monte de tentativa e erro, cheguei nesse código: arquivo app > Livewire > Lorcamento.php <?php namespace App\Livewire; use App\Models\tbhistped; use App\Models\tbpedido; use App\Models\tbpessoa; use App\Models\tbprod; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.app',['titulo'=>'Orçamento'])] class Lorcamento extends Component { public $bling,$histped,$mensagem,$modal,$modal2; public $pedido,$pessoa,$procPed,$prod,$qt,$vendido,$vr=[]; // listagem parcial function gerarBling() { $this->modal = false; $this->modal2 = false; $pedido = $this->pedido; $pBling = $this->bling; tbpedido::where('ped',$pedido)->update(['bling'=>$pBling]); $contato="Consumidor Final"; $itens=tbhistped::where('ped',$pedido)->get(); $previa=tbhistped::where('ped',$pedido)->where('subtotal','<',0) ->sum('subtotal'); $desconto=$previa ? abs($previa) : 0; $total=tbpedido::where('ped',$pedido)->value('total'); $data=date('d/m/Y',strtotime(tbpedido::where('ped',$pedido)->value('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); } } $path=storage_path(); $arquivo = fopen($path.$pBling.".csv", "w+"); fputcsv($arquivo, $dados[0]); foreach ($dados as $linha) { if ($linha != $dados[0]) { fputcsv($arquivo, $linha); } } fclose($arquivo); return response()->download($path.$pBling.".csv","$pBling.csv") ->deleteFileAfterSend(true); } } Esse código funciona tanto no Windows quanto no Hostinger. Mas dessa vez eu tive a curiosidade de saber onde exatamente o Laravel cria o arquivo csv. Do jeito que eu fiz, o Laravel cria o arquivo no diretório raíz, e eu chamei o arquivo de 1234.csv, já o Laravel muda o nome para storage1234.csv. Na hora de fazer o download, ele desce com o nome 1234.csv. Eu não sei se posso ou não usar o diretório raiz, mas é assim que estou trabalhando. Aqui no Windows, eu consegui criar o arquivo na pasta Storage, mas lá na Hostinger eu não tenho a menor ideia de como fazer isso.
-
Tudo indica que o Livewire é a versão PHP do Ajax. Eu não consegui trabalhar com o Ajax, mas eu estou conseguindo me entrosar com o Livewire. Em homenagem ao Livewire, eu criei um código PHP que tenta imitar a mágica que ele faz: arquivo teste.php <?php class Teste { public $mensagem, $renda, $view; function visao() { $this->view = " <div>$this->mensagem</div> <form method=post> <input name=renda onchange=submit() placeholder=$this->renda> </form> a sua renda é de $this->renda "; echo $this->view; } function __construct() { $this->renda=$_POST['renda'] ?? null; $this->mensagem="Qual a sua renda?"; $this->visao(); } } new Teste;
-
Finalmente, consegui um modal semi-transparente
pergunta respondeu ao Frank K Hosaka de Frank K Hosaka em PHP
Fiz um ajuste para o modal informar ou solicitar informação do usuário. Ele funciona no notebook, não ficou nada legal no celular e não tenho um tablet para testar: arquivo resources > views > livewire > lorcamento.blade.php <div> @if($modal) <div class="fixed inset-0 flex items-center justify-center" style="background-color: rgba(0, 0, 0, 0.5)"> <div class="bg-white p-6 rounded shadow-lg"> <h2 class="text-lg font-semibold">Mensagem</h2> <p class="mt-2 text-gray-700 text-xl whitespace-nowrap">{{$mensagem}}</p> @if($modal2) <flux:input wire:model="bling" wire:change="gerarBling" /> @endif <flux:button wire:click="fecharModal" class="mt-2"> Fechar </flux:button> </div> </div> @endif <!-- listagem parcial --> </div> arquivo app > Livewire > Lorcamento.php <?php namespace App\Livewire; use App\Models\tbhistped; use App\Models\tbpedido; use App\Models\tbpessoa; use App\Models\tbprod; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.app',['titulo'=>'Orçamento'])] class Lorcamento extends Component { public $bling,$histped,$mensagem,$modal,$modal2; public $pedido,$pessoa,$procPed,$prod,$qt,$vendido,$vr=[]; function apagarBling($pedido) { tbpedido::where('ped',$pedido)->update(['bling'=>null]); $this->montarPedido($pedido); } function blingar($vendido=null) { if(is_null($vendido)) { $this->mensagem="O pedido Bling só pode ser criado depois de registrar a venda"; $this->modal=true; } else { $this->mensagem="Número do pedido Bling"; $this->modal=true; $this->modal2=true; } } function blingProximo() { $numeros=tbpedido::whereNotNull('bling')->orderBy('bling')->get(); $intervalos=[]; $inicio=$fim=$numeros[0]->bling; foreach($numeros as $numero) { if($numero->bling == $fim || $numero->bling == $fim + 1) { $fim=$numero->bling; } else { $intervalos[]=($inicio==$fim) ? $inicio : "$inicio-$fim"; $inicio=$fim=$numero->bling; } } $intervalos[]=($inicio==$fim) ? $inicio : "$inicio-$fim"; $this->mensagem="Pedidos já utilizados: "; foreach($intervalos as $key => $i) { $this->mensagem .= $i; if($key===array_key_last($intervalos)) { $this->mensagem .= "."; } else { $this->mensagem .= ","; } } $this->modal=true; } function fecharModal() { $this->modal=false; $this->modal2=false; } // listagem parcial } -
Hoje eu reclamei com o Copilot que a classe "bg-opacity-50" do Tailwind não funciona comigo, assim ele sugeriu utilizar um CSS clássico com um style inline: arquivo resources > views > lorcamento.blade.php (listagem parcial) @if($modal) <div class="fixed inset-0 flex items-center justify-center" style="background-color: rgba(0, 0, 0, 0.5)"> <div class="bg-white p-6 rounded shadow-lg w-96"> <h2 class="text-lg font-semibold">Mensagem</h2> <p class="mt-2 text-gray-700 text-xl">{{$mensagem}}</p> <flux:button wire:click="fecharModal" class="mt-4"> Fechar </flux:button> </div> </div> @endif arquivo app > Livewire > Lorcamento.php (listagem parcial) <?php // ... function bling($pedido,$vendido=null) { if(is_null($vendido)) { $this->mensagem="O pedido Bling só pode ser criado depois de registrar a venda"; $this->modal=true; } } function fecharModal() { $this->modal=false; }
-
A Bling tem um serviço que pega os dados atuais do MySQL através de arquivos CSV e atualiza o cadastro de produtos. O problema é que isso acaba saindo caro porque cada atualização acaba aumentando o espaço ocupado no armazenamento de dados. A minha saída foi atualizar os produtos na Bling na unha. Ou seja, eu não mando um arquivo csv, eu pego o CSV da Bling e depois eu comparo com o MySQL. Quando são poucos registros para atualizar, é fácil selecionar, copiar e colar. Mas hoje eu tive que enfrentar um monte de atualização, e pedi socorro para o Copilot, perguntei se ele sabia se o JavaScript é capaz de transferir os dados que foram clicados para a área de transferência, isso reduziu 50% o meu serviço de edição: arquivo resources > views > lbling-diferenca.blade.php <div> <script> function copiar(elemento) { conteudo=elemento.innerText || elemento.textContent navigator.clipboard.writeText(conteudo) elemento.parentElement.style.display="none" } </script> <div class="font-semibold flex"> <div class=w-[100px]>Código</div> <div class=w-[100px]>Campo</div> <div class=w-[100px]>MySQL</div> <div class=w-[100px]>Bling</div> </div> <div class=flex> <div class=w-[100px]></div> <div class=w-[100px]>Produtos</div> <div class=w-[100px]>{{ $contaProduto }}</div> <div class=w-[100px]>{{ $contaProdBling }}</div> </div> @foreach($dif as $d) @foreach($d as $v) @if(array_keys($v)[0]=="Codigo") @php $codigo=array_values($v)[0]; @endphp @else @if(array_keys($v)[0]!=="Descricao") <div class="flex"> <div class=w-[100px]>{{$codigo}}</div> <div class=w-[100px]>{{array_keys($v)[0]}}</div> <div class=w-[100px] onclick=copiar(this)> <pre class="font-sans"><?=array_values($v)[0]?></pre> </div> <div class=w-[100px]> <pre class="font-sans"><?=array_values($v)[1]?></pre> </div> </div> @else <div class=flex> <div class=w-[100px]>{{$codigo}}</div> <div class=w-[100px]>{{array_keys($v)[0]}}</div> <div class=w-[100px] onclick=copiar(this)> <pre class="font-sans"><?=array_values($v)[0]?></pre> </div> </div> <div class=flex> <div class=w-[200px]></div> <div class=w-[100px] onclick=copiar(this)> <pre class="font-sans"><?=array_values($v)[1]?></pre> </div> </div> @endif @endif @endforeach @endforeach </div> arquivo app > Livewire > LblingDiferenca.php <?php namespace App\Livewire; use App\Models\tbprod; use App\Models\tbprodbling; use Illuminate\Support\Facades\DB; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.app',['titulo'=>'Diferença na Bling'])] class LblingDiferenca extends Component { public $contaProdBling, $contaProduto, $dif=[]; function mount() { DB::table('tbprodbling')->truncate(); $arquivos=$_FILES['arquivos']; foreach($arquivos['tmp_name'] as $arquivo) { $dados=file($arquivo); foreach($dados as $linha) { $campos=explode(';',$linha); if(aspas($campos[1])!=="Código") { $codprod=intval(trim(aspas($campos[1]))); $un=aspas($campos[3]); $prod=aspas($campos[2]); $custo=deca(aspas($campos[11])); $codbar=trim(aspas($campos[19])); $cf=deca(aspas($campos[4])); $venda=deca(aspas($campos[6])); tbprodbling::create(['codprod'=>$codprod,'un'=>$un, 'prod'=>$prod,'custo'=>$custo,'codbar'=>$codbar, 'cf'=>$cf,'venda'=>$venda]); } } } $produto=tbprod::where('loc','<>','a24')->get(); $prodBling=tbprodbling::all(); $this->contaProduto=count($produto); $this->contaProdBling=count($prodBling); if($this->contaProdBling>$this->contaProduto) { $prod=$produto->pluck('codprod'); $pBling=$prodBling->pluck('codprod'); $difs=$pBling->diff($prod); foreach($difs as $d) { echo "problema no codprod $d na Bling <br>"; } dd('parada total'); } foreach($produto as $key=>$pr) { $codprod=$pr->codprod; $previa=tbprodBling::where('codprod',$codprod)->get(); if(count($previa)==0) { $this->dif[$key][]=['Codigo'=>$codprod]; $this->dif[$key][]=['Incluir'=>$codprod,'Incluir2'=>'Incluir']; } else { $a=tbprodBling::where('codprod',$codprod)->first(); $un=($pr->un==$a->un) ? 1 : 0; $prod=($pr->prod==$a->prod) ? 1 : 0; $custo=($pr->custo==$a->custo) ? 1 : 0; $codbar=($pr->codbar==$a->codbar) ? 1 : 0; $cf=($pr->cf==$a->cf) ? 1 : 0; $venda=($pr->venda==$a->venda) ? 1 : 0; if($un.$prod.$custo.$codbar.$cf.$venda !== '111111') { $this->dif[$key][]=['Codigo'=>$pr->codprod,'Codigo2'=>$a->codprod]; if($pr->prod!==$a->prod) { $this->dif[$key][]=['Descricao'=>$pr->prod,'Descricao2'=>$a->prod]; } if($pr->custo!==$a->custo) { if($pr->custo || $a->custo<>0) { $this->dif[$key][]=['Custo'=>$pr->custo,'Custo2'=>$a->custo]; } } if($pr->codbar!=$a->codbar) { $this->dif[$key][]=['Codigo de Barra'=>$pr->codbar,'Codigo de Barra2'=>$a->codbar]; } if($pr->cf!==$a->cf) { if($pr->cf || $a->cf) { $this->dif[$key][]=['NCM'=>$pr->cf,'NCM2'=>$a->cf]; } } if($pr->venda!==$a->venda) { $this->dif[$key][]=['Venda'=>$pr->venda,'Venda2'=>$a->venda]; } if($pr->un!==$a->un) { $this->dif[$key][]=['Un'=>$pr->un,'Un2'=>$a->un]; } } } } } }
-
Hoje eu vi que o meu irmão Jorge tentou alterar centenas de descrição de produtos na tentativa de tornar a leitura mais fácil para ele. Eu achei a ideia dele muito boa, e eu perguntei para o Copilot como eu faço para o HTML respeitar os espaços adicionais que o usuário tenta acrescentar na descrição do produto. O Copilot sugeriu eu usar caracteres invisíveis mas que não seja a barra de espaço. Eu fiquei bastante indignado, é muito difícil apertar a barra de espaço, imagine mexer com várias teclas ao mesmo tempo para incluir um caractere invisível. Mas eu lembrei do marcador <pre></pre>, eu uso bastante na hora de fazer depuração dos meus códigos. Pensei, o que me impede de usar esses marcadores no meu código? E assim eu testei: <?php foreach($produtos as $prod): ?> <pre class="font-sans"><?=$prod->prod?></pre> <?php endforeach; ?> E não é que deu certo! Agora, todos os espaços que o meu irmão colocou na descrição vão aparecer na tela da Web!
-
Código não traz os dados para alteração e exclusão
pergunta respondeu ao PaiDeLaura de Frank K Hosaka em VBA
Tem muito serviço por aqui, mas fiz o teste com a rotina cmdAlterar_Click( ), tentando fazer o comando funcionar, e ficou assim (simplifiquei bastante para testar a lógica): Acredito que o comando exit do está no lugar correto, assim sobrou dois comandos para verificar, o If not validated ... e o call cmdLimpar, mas isso é bastante serviço, e isso vai além do escopo de qualquer fórum. A minha sugestão é testar um código de cada vez, tipo Cell(1,1)="olá mundo", e vai acrescentando um novo recurso de cada vez. Private Sub cmdAlterar_Click() Dim linha As Long Dim encontrado As Boolean linha = 2 ' Começar da linha 2 With Sheets("AgendaEventos") Do While .Cells(linha, 1).Value <> "" If .Cells(linha, 1).Value = Me.txtNumOficio.Text Then .Cells(linha, 2).Value = Me.txtEvento.Text encontrado = True End If linha = linha + 1 Loop End With If encontrado Then MsgBox "Registro alterado com sucesso!", vbInformation Else MsgBox "Número de Ofício não encontrado para alteração!", vbExclamation End If End Sub -
Não consegui usar Livewire.dispatch( ) dentro do JavaScript [Resolvido]
pergunta respondeu ao Frank K Hosaka de Frank K Hosaka em PHP
Encontrei a resposta nessa mensagem: https://github.com/livewire/livewire/pull/8226 Adaptando ao meu código, ficou assim: arquivo app > Livewire > Lcontrolid.php <?php namespace App\Livewire; use App\Models\tbpedido; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.app',['titulo'=>'Imprimir Pedido'])] class Lcontrolid extends Component { public $itens,$modal,$ped; protected $listeners=['voltar'=>'voltar']; function mount($pedido) { $this->ped=$pedido; $this->itens=tbpedido::where('tbpedido.ped',$pedido) ->join('tbhistped','tbpedido.ped','=','tbhistped.ped') ->join('tbprod','tbprod.codprod','=','tbhistped.codprod')->get(); $num_rows=count($this->itens); if($num_rows==0) { $this->modal=true; } session(['ocultar'=>true]); } function voltar() { session()->forget('ocultar'); redirect("/lorcamento/$this->ped"); } } arquivo resources > views > livewire > lcontrolid.blade.php <div> @if($modal) Não há nada para imprimir @else <table> <tr class=fw-semibold><td colspan=7>Quitanda do Frank Corporation <tr class=fw-semibold><td colspan=7>Pedido {{$itens[0]->ped}} de {{dbr($itens[0]->dia)}} @foreach($itens as $item) <tr><td colspan=7>{{$item->prod}} <tr><td class=text-end>{{$item->qt}} <td class=text-end>{{$item->un}} <td class=px-2>x<td class=text-end>{{dec($item->unitario)}} <td class=px-2>=<td class=text-end>{{dec($item->subtotal)}} @endforeach <tr class=fw-semibold><td>Total<td><td><td><td><td class=text-end>{{dec($itens[0]->total)}} @endif @script <script> window.print() window.onafterprint = function() { setTimeout(()=>{$wire.$dispatch('voltar')}) // location.replace('/lorcamento/{{$ped}}') } </script> @endscript </div> -
O Livewire não consegue fazer o serviço de impressão. Quem faz isso é o bom e velho JavaScript. O problema é como o JavaScript vai devolver o comando para o Livewire. Há vários tutoriais na internet, recomendando a usar o Livewire.dispatch("voltar") dentro do JavaScript e um protected $listeners=["voltar"=>"voltar"] dentro do componente, mas isso não deu certo comigo, eu tive que apelar para a velha gambiarra, eu pedi para o JavaScript voltar para o orçamento. arquivo app > Livewire > Lcontrolid.php <?php namespace App\Livewire; use App\Models\tbpedido; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.app',['titulo'=>'Imprimir Pedido'])] class Lcontrolid extends Component { public $itens,$modal,$ped; function mount($pedido) { $this->ped=$pedido; $this->itens=tbpedido::where('tbpedido.ped',$pedido) ->join('tbhistped','tbpedido.ped','=','tbhistped.ped') ->join('tbprod','tbprod.codprod','=','tbhistped.codprod')->get(); $num_rows=count($this->itens); if($num_rows==0) { $this->modal=true; } session(['ocultar'=>true]); } } arquivo resources > views > livewire > lcontrolid.blade.php <div> @if($modal) Não há nada para imprimir @else <table> <tr class=fw-semibold><td colspan=7>Quitanda do Frank Corporation <tr class=fw-semibold><td colspan=7>Pedido {{$itens[0]->ped}} de {{dbr($itens[0]->dia)}} @foreach($itens as $item) <tr><td colspan=7>{{$item->prod}} <tr><td class=text-end>{{$item->qt}} <td class=text-end>{{$item->un}} <td class=px-2>x<td class=text-end>{{dec($item->unitario)}} <td>=<td class=text-end>{{dec($item->subtotal)}} @endforeach <tr class=fw-semibold><td>Total<td><td><td><td><td class=text-end>{{dec($itens[0]->total)}} @endif <script> window.print() window.onafterprint = function() { location.replace('/lorcamento/{{$ped}}') } </script> </div>
-
duvida por que meu codigo não esta recebendo os dados POST no controller
pergunta respondeu ao Braz Mendes de Frank K Hosaka em PHP
É porque você esqueceu de definir a rota do <form> através da propriedade action. A sintaxe correta é <form method=post action=controller.add> O problema é como o conteúdo do <input> vai chegar até aquela classe, isso vai depender do roteador. Eu tenho um código php que trabalha com a instancia de classe, e assim eu defino o action assim: <form method=post action=?controller.add>, ele força o navegador a jogar tudo para o arquivo index.php e de lá o roteador vai procurar a classe e o método correspondente. Enfim o roteador é um capítulo bem espinhoso que você precisa dominar antes de usar o <form> Mas essa fase já passou para mim. Eu não preciso mais usar o <form> para mandar o conteúdo do <input> para a variável $titulo, tem um rapaz que inventou o Livewire no Laravel, ele inventou o <input wire:model='titulo'>, assim que você dá o enter a variável $titulo já está definido. É uma mágica surpreendente! -
Lá em 2022 eu vi matéria de como o Laravel passa parâmetros de uma Blade para o Controller, só que eu não entendi nada, e improvisei assim <a href=orcamento?apagar=1>Orçamento</a> Isso deu certo até mesmo com o Livewire. Mas aqui em 2025, eu conto com o Copilot e com ele me aventurei a definir os parâmetros dentro do Route, agora com o paradigma do Livewire: Route::get('lorcamento/{pedido?}/{apagar?}',Lorcamento::class)->name('lorcamento'); Tentei mudar isso, mas o Copilot disse que não dá, essa é a sintaxe do Laravel. O que eu gostei é do ponto de interrogação, ele torna o parâmetro opcional. Eu defini o menu do orçamento, dentro do resources > views > components > layouts > app.blade.php <a class="block px-4 py-2 hover:bg-gray-200" href="{{ route('lorcamento',['apagar'=>1])}}"> Orçamento </a> E finalmente o componente ficou assim: function mount($pedido=null,$apagar=null) { $this->montarPedido($pedido,$apagar); } Note que o nome do parâmetro é exatamente igual ao que foi definido no Route, só que ele usa o prefixo $. O meu sonho é acabar com os parâmetros com a ajuda do Livewire, e definir o Route assim: Route::get('lorcamento',Lorcamento::class)->name('lorcamento'); Mas até esse dia chegar, preciso eliminar um monte de gambiarra que inventei na rotina do orçamento. Todos eles foram para o Liveware, só precisei adaptar aqui e ali. Foi isso que me fez gostar bastante do Liveware, ele é muito mais flexível que o Laravel.