Ir para conteúdo
Fórum Script Brasil

Pesquisar na Comunidade

Mostrando resultados para as tags ''livewire''.

  • Pesquisar por Tags

    Digite tags separadas por vírgulas
  • Pesquisar por Autor

Tipo de Conteúdo


Fóruns

  • Programação & Desenvolvimento
    • ASP
    • PHP
    • .NET
    • Java
    • C, C++
    • Delphi, Kylix
    • Lógica de Programação
    • Mobile
    • Visual Basic
    • Outras Linguagens de Programação
  • WEB
    • HTML, XHTML, CSS
    • Ajax, JavaScript, XML, DOM
    • Editores
  • Arte & Design
    • Corel Draw
    • Fireworks
    • Flash & ActionScript
    • Photoshop
    • Outros Programas de Arte e Design
  • Sistemas Operacionais
    • Microsoft Windows
    • GNU/Linux
    • Outros Sistemas Operacionais
  • Softwares, Hardwares e Redes
    • Microsoft Office
    • Softwares Livres
    • Outros Softwares
    • Hardware
    • Redes
  • Banco de Dados
    • Access
    • MySQL
    • PostgreSQL
    • SQL Server
    • Demais Bancos
  • Segurança e Malwares
    • Segurança
    • Remoção De Malwares
  • Empregos
    • Vagas Efetivas
    • Vagas para Estágios
    • Oportunidades para Freelances
  • Negócios & Oportunidades
    • Classificados & Serviços
    • Eventos
  • Geral
    • Avaliações de Trabalhos
    • Links
    • Outros Assuntos
    • Entretenimento
  • Script Brasil
    • Novidades e Anúncios Script Brasil
    • Mercado Livre / Mercado Sócios
    • Sugestões e Críticas
    • Apresentações

Encontrar resultados em...

Encontrar resultados que...


Data de Criação

  • Início

    FIM


Data de Atualização

  • Início

    FIM


Filtrar pelo número de...

Data de Registro

  • Início

    FIM


Grupo


AIM


MSN


Website URL


ICQ


Yahoo


Jabber


Skype


Location


Interests

Encontrado 25 registros

  1. Eu não manjo nada de Java Script, assim eu comecei o trabalho com o Copilot. Eu precisava mudar o foco para o topo da página no canto esquerdo, depois de usar o modal no celular. O Copilot deu dezenas de códigos e explicações, mas nenhuma funcionou. O Copilot usa o raciocínio lógico, ele pensa em HTML. Já o meu raciocínio é muito estreito, eu só penso no <div>, assim usei o Java Script na base da tentativa e erro: arquivo resources > views > livewire > diario-lcto.blade.php <div ondblclick="alert('olá mundo')"> etc etc </div> Depois de dezenas de tentativas, esse foi o único que deu certo. Acredito que o Livewire não quer ninguém usando o marcador <script></script> dentro do Blade, assim a minha ideia é esconder o Java Script dentro de um elemento HTML. Eu desisti de ir no topo da tela, então decidi pegar o primeiro controle perto do topo, <input wire:model="dia">, e aprendi com DevTools do Google Chrome que essa sintaxe está errada. Assim resolvi dois problemas de uma só vez assim: <input id="foco" wire:model="dia">. wire:model é um truque de mágica do Livewire, tudo o que você digitar nesse input, ele vai para a variável $dia, ou tudo o que fizer na variável $dia vai aparecer no <input id="foco" wire:model="dia">, sem precisar de nenhum <form>. E o código final ficou assim: <div ondblclick="document.getElementById('foco').focus()"> etc etc </div> O Copilot sugeriu turbinar o Laravel Livewire com Alpine, mas eu disse que sou contra. Se eu levei quatro horas para um código do Java Script funcionar, imagine quanto tempo vou levar para encontrar um erro num gigantesco framework cheio de extensões para todos os lados. É por isso que eu gosto do PHP, o Laravel é formidável mas tenho medo de mexer nele.
  2. Tentei usar o Copilot para localizar o arquivo que define a rota para o usuário que já está logado (ou seja, você fecha o navegador, depois você abre, chama o projeto e, ao invés de ir para o login você acaba no famoso painel do "dashboard"), mas o Copilot ficou preso numa função que verifica a sessão e isso eu não achei, até que ele chegou no web.php e sugeriu isso: <?php use Illuminate\Support\Facades\Auth; Route::get('/', function () { if (Auth::check()) { return Auth::id() == 1 ? redirect()->route('previsao') : redirect()->route('orcamento'); } return redirect()->route('login'); }); A sugestão do Copilot é brilhante, funcional, mas nada óbvio. Eu consegui redirecionar o usuário depois do login, eu só não sei como fazer isso depois que ele estiver logado. Até eu encontrar a sugestão do Copilot, eu fiz essa gambiarra: Route::get('outros/{opcao?}',Outros::class); Route::get('outrosTeste',function(){return redirect('outros/menu');})->name('dashboard'); Ou seja, criei uma rota fictícia, onde o usuário logado vai parar na tela do menu, mas eu queria mesmo uma página para o administrador e outra página para o resto da turma. A solução do Copilot é engenhosa, mas não faço a menor ideia de como ele funciona.
  3. Eu tenho um código mais ou menos assim: blade @foreach($pendencias as $index => $pendencia) @if($pendencia['div1']==1) <div wire:click="mostrar({{$index}})">ola mundo</div> @else // o resto do código <div class="w-[110px] text-right" wire:click="mostrar({{$index}})"> {{ dec($pendencia['debito']) }} </div> // o resto do código @endif @endforeach component function mostrar($indicador) { if($this->pendencias[$indicador]['div1']==0) { return $this->pendencias[$indicador]['div1']=1; } else { return $this->pendencias[$indicador]['div1']=0; } } Esse é o clássico problema do modal. Eu tenho uma lista de pendência, onde aparece o valor da pendência e o nome de quem está me cobrando, só que eu precisava do número do lançamento contábil ou o número da nota fiscal ou qual a parcela que estou pagando, tudo isso dá para colocar num modal. Mas hoje eu pensei em colocar essa informação na mesma linha onde aparece as informações. E deu certo! Esse Livewire é fantástico! A seguir a listagem completa: arquivo resources > views > livewire > pagar.blade.php <div> @if(auth()->user()->id==1) <input wire:model.live="doc1" size="5" autocomplete="off" class="border-none rounded p-2 py-0"> <input wire:model.live="doc2" size="5" autocomplete="off" class="border-none rounded p-2 py-0"> <input type="submit" wire:click="ocultar" value="Ocultar Pendências"> @endif <div class="flex bg-gray-200 mt-2"> <div class="w-[117px] ml-3 text-center">Vencimento</div> <div class="w-[50px] text-right">Docto</div> <div class="w-[110px] text-right">Pendência</div> @if(auth()->user()->id==1) <div class="w-[10px] text-right px-2">R</div> @endif <div class="w-[336px] px-2 border">Pessoa</div> </div> @if(auth()->user()->id==1) @foreach($pendencias as $index => $pendencia) @if($pendencia['div1']==1) <div wire:click="mostrar({{$index}})" class="bg-red-200"> {{"Histórico: Lçto ".$pendencia['lcto']." ".$pendencia['hist']}} </div> @else <div class="even:bg-gray-200"> <div class="flex"> <div class="w-[117px] ml-3 text-right"> <input type=date wire:model.live="pendencias.{{$index}}.vcto" onclick=showPicker() wire:change="atualizaVcto({{$pendencia['docto']}},{{$index}})" class="w-[117px] bg-transparent text-gray-500 font-semibold rounded py-0 border-none"> </div> <div class="w-[50px] text-right"> <div wire:click="selecionarDocto({{$pendencia['docto']}})" class="text-right"> {{ $pendencia['docto'] }} </div> </div> @if($pendencia['debito']) <div class="w-[110px] text-right" wire:click="mostrar({{$index}})"> {{ dec($pendencia['debito']) }} </div> @else <div class="w-[110px] text-right text-red-500" wire:click="mostrar({{$index}})"> {{ dec($pendencia['credito']) }} </div> @endif <div class="w-[10px] px-2"> <input type=checkbox {{$pendencia['restrito']==1 ? 'checked' : ''}} wire:click="restritoDefinir({{$index}})"> </div> <div class="w-[336px] px-2 truncate"> <a class="text-gray-500 font-semibold hover:bg-gray-200" wire:click="selecionarPessoa({{$pendencia['docto']}})"> <?=$pendencia['pessoa']?> </a> </div> </div> </div> @endif @endforeach @endif @if(auth()->user()->id!==1) @foreach($pendencias as $index => $pendencia) @if($pendencia['restrito']==0 && $pendencia['div1']==1) <div wire:click="mostrar({{$index}})" class="bg-red-200"> {{"Histórico: Lçto ".$pendencia['lcto']." ".$pendencia['hist']}} </div> @endif @if($pendencia['restrito']==0 && $pendencia['div1']==0) <div class="even:bg-gray-200"> <div class="flex"> <div class="w-[117px] ml-3 text-right"> <input class="w-[117px] bg-transparent text-gray-500 font-semibold rounded py-0 border-none text-center" value='{{ dbr($pendencia['vcto']) }}'> </div> <div class="w-[50px] text-right"> <div class="text-right">{{ $pendencia['docto'] }}</div> </div> @if($pendencia['debito']) <div class="w-[110px] text-right" wire:click="mostrar({{$index}})"> {{ dec($pendencia['debito']) }} </div> @else <div class="w-[110px] text-right text-red-500" wire:click="mostrar({{$index}})"> {{ dec($pendencia['credito']) }} </div> @endif <div class="w-[346px] px-2 truncate"> <div class="text-gray-500 font-semibold hover:bg-gray-200"> <?=$pendencia['pessoa']?> </div> </div> </div> </div> @endif @endforeach @endif <div class="even:bg-gray-200"> <div class="w-[290px] text-right text-red-500 font-semibold">{{"JK ".dec($jk)}}</div> </div> </div> arquivo app > Livewire > Pagar.php <?php namespace App\Livewire; use App\Models\tbcontacorrente; use App\Models\tbdiario; use App\Models\tbpessoa; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.app',['titulo'=>'Pendências'])] class Pagar extends Component { public $doc1,$doc2,$histAtual,$jk,$lctoAtual,$modal=false,$pendencias=[]; function atualizaVcto($docto,$index) { $vcto=$this->pendencias[$index]['vcto']; tbcontacorrente::where('docto',$docto) ->update(['vcto'=>$vcto]); $this->montaPendencias(); } function fecharModal() { $this->modal=false; } function montaPendencias() { if(request()->input('docto')) { $docto=request()->input('docto'); $codp=session('codp'); tbcontacorrente::where('docto',$docto)->update(['codp'=>$codp]); } $this->pendencias=[]; $contas=tbcontacorrente::where('pgto',0)->orderBy('vcto')->get(); foreach($contas as $conta) { $doc=tbdiario::where('docto',$conta->docto)->first(); $restrito=$conta->restrito; $vcto=$conta->vcto; $docto=$conta->docto; $lcto=$doc->lcto; if($doc->contad==130 || $doc->contad==211) { $debito=$doc->valor; $credito=null; } else { $debito=null; $credito=$doc->valor; } $hist=dbr($doc->dia)." ".$doc->hist; if($conta->codp) { $pessoa=tbpessoa::where('codp',$conta->codp)->value('pessoa'); } else { $pessoa="Selecionar"; } $this->pendencias[]=['vcto'=>$vcto,'docto'=>$docto,'lcto'=>$lcto,'debito'=>$debito, 'credito'=>$credito,'hist'=>$hist,'pessoa'=>$pessoa,'restrito'=>$restrito,'div1'=>0]; } $this->jk=0; foreach ($this->pendencias as $item) { if (isset($item['restrito']) && $item['restrito'] == 0) { $this->jk += $item['credito']; } } } function mostrar($indicador) { if($this->pendencias[$indicador]['div1']==0) { return $this->pendencias[$indicador]['div1']=1; } else { return $this->pendencias[$indicador]['div1']=0; } } function mount() { $pendencias=tbcontacorrente::with('diario')->where('pgto',0)->get(); foreach($pendencias as $p) { $eliminar=($p->diario->contad!==130); $eliminar+=($p->diario->contad!==211); $eliminar+=($p->diario->contac!==130); $eliminar+=($p->diario->contac!==211); if($eliminar==4) { tbcontacorrente::where('docto',$p->docto)->delete(); } } $pendencias=tbcontacorrente::pluck('docto'); $doc1=tbdiario::where('dia','>','2023-12-31')->where('contad',130)->pluck('docto'); $doc2=tbdiario::where('dia','>','2023-12-31')->where('contac',130)->pluck('docto'); $doc3=tbdiario::where('dia','>','2023-12-31')->where('contad',211)->pluck('docto'); $doc4=tbdiario::where('dia','>','2023-12-31')->where('contac',211)->pluck('docto'); $documentos=$doc1->merge($doc2)->merge($doc3)->merge($doc4); $diferenca=$documentos->diff($pendencias); foreach($diferenca as $d) { $lcto=tbdiario::where('docto',$d)->value('lcto'); tbcontacorrente::create(['docto'=>$d,'lcto'=>$lcto,'pgto'=>0]); } $this->montaPendencias(); } function ocultar() { if($this->doc1 !== null) { tbcontacorrente::where('docto',$this->doc1) ->update(['pgto'=>1]); } if($this->doc2 !== null) { tbcontacorrente::where('docto',$this->doc2) ->update(['pgto'=>1]); } $this->doc1=$this->doc2=null; $this->montaPendencias(); } function restritoDefinir($indicador) { $docto=$this->pendencias[$indicador]['docto']; $restricao=$this->pendencias[$indicador]['restrito']; if($restricao==0) { $restricao=1; } else { $restricao=0; } tbcontacorrente::where('docto',$docto) ->update(['restrito'=>$restricao]); $this->montaPendencias(); } function selecionarDocto($docto) { if($this->doc1==null) { $this->doc1 = $docto; } else { if($this->doc2==null) { $this->doc2 = $docto; } } } function selecionarPessoa($docto) { session(['end'=>"pagar?docto=$docto"]); redirect("pessoa"); } }
  4. Frank K Hosaka

    Tofu

    Eu tentei copiar o código de barra de uma conta da Sabesp e colar no meu programa boleto, e apareceu um monte de tofus (retângulos pequenos). Pedi ajuda para o Copilot, ele me deu um monte de dicas para obter apenas os números, mas nenhum deu certo. Perguntei para o Adobe Acrobat quanto custa o serviço de inteligência artificial, e ele disse que o plano mais em conta é de R$ 333,00 por ano. Eu fiquei desesperado, nunca pensei que fosse tão caro copiar uma informação de um arquivo, se bem que o padre José me alertou que o fim dos tempos está cada vez mais próximo. Usei o botão direito do mouse no arquivo da conta da Sabesp, e lá encontrei "Pergunte ao Copilot" além do "Acrobat Reader", e o Copilot conseguiu ler o código de barra. Por enquanto, o Copilot é gratuito. A seguir o meu código Boleto em Livewire: arquivo resources > views > livewire > outros.blade.php (parcial) @if($modal2) <flux:input.group class="mt-5"> <flux:input.group.prefix>código de barra do boleto</flux:input.group.prefix> <flux:input wire:model="boleto" /> </flux:input.group> <flux:input.group class="mt-5"> <flux:input.group.prefix>código de barra do comprovante</flux:input.group.prefix> <flux:input wire:model="comprovante" /> </flux:input.group> <flux:button wire:click="boletos" class="mt-5">Verificar</flux:button> {!! $comparacao !!} <div>{{ $boleto1 }}</div> <div>{{ $comprovante1 }}</div> @endif arquivo app > Livewire > Outros.php (parcial) function boletos() { $this->boleto1=substr(preg_replace('/\D/', '', $this->boleto),0,48); $this->comprovante1=substr(preg_replace('/\D/', '', $this->comprovante),0,48); if($this->boleto1==$this->comprovante1) { $this->comparacao="<p></p>Os códigos de barra são iguais!</p>"; } else { $this->comparacao="<p class='text-red-500'>Os códigos de barra são diferentes</p>"; } }
  5. arquivo app > Livewire > Cartao.php <?php namespace App\Livewire; use App\Models\tbdiario; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.app',['titulo'=>'Conferindo Cartão de Crédito'])] class Cartao extends Component { public $debito,$credito,$lctos=[]; function mount() { $doctos=tbdiario::where('lcto',16386)->get(); foreach($doctos as $d) { $this->lctos[]=['lcto'=>$d->lcto,'docto'=>$d->docto, 'contad'=>$d->contad,'contac'=>$d->contac, 'valor'=>$d->valor,'hist'=>$d->hist,'ticar'=>"flex even:bg-gray-300"]; } $this->debito = array_reduce($this->lctos, function($carry, $item) { if ($item['contad'] > 0) { $carry += $item['valor']; } return $carry; }, 0); $this->credito = array_reduce($this->lctos, function($carry, $item) { if ($item['contac'] > 0) { $carry += $item['valor']; } return $carry; }, 0); usort($this->lctos,function($a,$b) { return $b['valor'] <=> $a['valor']; }); } function ticar($indicador) { $this->lctos[$indicador]['ticar']="flex bg-red-200"; } } arquivo resources > views > livewire > cartao.blade.php <div> <div>Lançamento {{$lctos[0]['lcto']}}</div> <div class="flex bg-gray-300"> <div class=w-[60px]>Docto</div> <div class=w-[60px]>CtaD</div> <div class=w-[60px]>CtaC</div> <div class="w-[100px] text-right">Valor</div> <div class="w-[300px] px-2">Histórico</div> </div> @foreach($lctos as $key=>$l) <div class='{!! $l['ticar'] !!}' wire:click="ticar({{$key}})"> <div class=w-[60px]>{{$l['docto']}}</div> <div class=w-[60px]>{{$l['contad']}}</div> <div class=w-[60px]>{{$l['contac']}}</div> @if($l['contad']) <div class="w-[100px] text-right">{{dec($l['valor'])}}</div> @else <div class="w-[100px] text-right text-red-500">{{dec($l['valor'])}}</div> @endif <div class="W-[300px] px-2">{{$l['hist']}}</div> </div> @endforeach <div class=flex> <div class="w-[180px] text-right">{{dec($debito)}}</div> <div class="w-[100px] text-right text-red-500">{{dec($credito)}}</div> <div class="w-[100px] text-right">{{dec($debito-$credito)}}</div> </div> </div>
  6. Eu tenho um componente chamado Bling, e ele gastava 3 minutos para comparar 3.000 produtos do MySQL com o Bling. Eu usava o MySQL para gravar as informações obtidas do Bling. Ao invés de usar o MySQL, decidi usar um array, mas isso em nada ajudou a melhorar o tempo de resposta. Apresentei o meu código ao Copilot, ele mudou muita coisa, principalmente na hora de indexar um array e o tempo de resposta ficou bem melhor: arquivo app > Livewire > Bling.php <?php namespace App\Livewire; use App\Models\tbprod; use Livewire\Attributes\Layout; use Livewire\Component; use Livewire\WithFileUploads; #[Layout('components.layouts.app',['titulo'=>'Diferença na Bling'])] class Bling extends Component { use WithFileUploads; public $contaProdBling,$contaProduto,$dif=[],$files=[]; public $modal=true,$tbBling=[]; function updatedFiles() { $this->modal=false; foreach($this->files as $arquivo) { $dados=explode(PHP_EOL,$arquivo->get()); foreach($dados as $linha) { if($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])); $this->tbBling[]=['codprod'=>$codprod,'un'=>$un, 'prod'=>$prod,'custo'=>$custo,'codbar'=>$codbar, 'cf'=>$cf,'venda'=>$venda]; } } } } // Criação do índice associativo por codprod $blingIndex = []; foreach ($this->tbBling as $item) { $blingIndex[$item['codprod']] = $item; } // Carrega os produtos do banco (opcionalmente como array) $produto = tbprod::where('loc','<>','a24')->get(); $this->contaProduto = count($produto); $this->contaProdBling = count($this->tbBling); // Verifica diferença de quantidade if ($this->contaProdBling > $this->contaProduto) { $prod = $produto->pluck('codprod'); $pBling = collect(array_column($this->tbBling, 'codprod')); $difs = $pBling->diff($prod); foreach ($difs as $d) { echo "problema no codprod $d na Bling <br>"; } dd('parada total'); // essa rotina não funciona no Laravel, precisa melhorar } // Compara os produtos foreach ($produto as $key => $pr) { $codprod = $pr->codprod; if (!isset($blingIndex[$codprod])) { $this->dif[$key][] = ['Codigo' => $codprod]; $this->dif[$key][] = ['Incluir' => $codprod, 'Incluir2' => 'Incluir']; } else { $a = $blingIndex[$codprod]; $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']]; } } } } } } arquivo resources > views > livewire > bling.blade.php <div> @if($modal) <div class="h-5"></div> <flux:input type="file" wire:model="files" multiple label="Selecione os arquivos de produtos da Bling" /> @else <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 @endif </div>
  7. Dentro do componente Outros.php eu criei uma rotina chamada boletos, para comparar o código de barras do boleto com o código de barra que aparece no comprovante de pagamento. Eu pensei que seria fácil, mas não é. Eu precisei de muita ajuda do Copilot. Para pegar o código de barra no pdf do boleto, eu só selecionei e copiei e colei no meu projeto. Já o código de barra do pdf do comprovante não consegui selecionar e copiar, precisei da ajuda do IA que aparece no programa do Adobe Reader. O espaço que aparece no código de barra do boleto é pura maquiagem, ele não é um espaço de verdade. Já o código de barra do comprovante é bem maior do que você acredita que copiou. E assim, o meu componente Outros.php ficou assim: <?php namespace App\Livewire; use App\Models\tbdiario; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.app',['titulo'=>'Outros Comandos'])] class Outros extends Component { public $baixa,$boleto,$boleto1,$comparacao,$comprovante,$comprovante1,$diaAcerto,$mais,$menos,$modal,$modal2,$modal3=true; public $valorBaixa,$valorMais,$valorMenos,$vetor; function boletos() { $this->boleto1=substr(preg_replace('/\D/', '', $this->boleto),0,47); $this->comprovante1=substr(preg_replace('/\D/','',$this->comprovante),0,47); if($this->boleto1==$this->comprovante1) { $this->comparacao="<p>Os códigos de barra são iguais!</p>"; } else { $this->comparacao="<p class='text-red-500'>Os códigos de barra são diferentes</p>"; } } function mount($opcao=null) { if($opcao=="menu") {$this->modal3=false; return $this->modal=true;} if($opcao=="boleto"){$this->modal3=false; return $this->modal2=true;} // o resto do código } } E o Blade ficou assim: <div> @if($modal) @endif @if($modal2) <flux:input.group class="mt-5"> <flux:input.group.prefix>código de barra do boleto</flux:input.group.prefix> <flux:input wire:model="boleto" /> </flux:input.group> <flux:input.group class="mt-5"> <flux:input.group.prefix>código de barra do comprovante</flux:input.group.prefix> <flux:input wire:model="comprovante" /> </flux:input.group> <flux:button wire:click="boletos" class="mt-5">Verificar</flux:button> {!! $comparacao !!} <div>{{ $boleto }}</div> <div>{{ $comprovante }}</div> <div>{{ strcmp(trim(str_replace(".","",$boleto)),trim(str_replace(".","",$comprovante)))}}</div> <div>{{ $boleto1 }}</div> <div>{{ $comprovante1 }}</div> @endif @if($modal3) <!-- o resto do código --> @endif </div>
  8. Quando você abre o projeto do Laravel, ele vai direto na rotina do login. Mas se você já tiver logado uma vez, a sua chamada para o projeto vai mandar você para o dashboard.blade.php, o painel de controle que vem embutido no Laravel 12. No meu caso, eu defini a rota para o dashboard para o componente chamado menu, que simplesmente não faz nada, ele exibe apenas o layout que defini no arquivo resources > views > components > layouts > app.blade.php. Ao invés de usar um componente que não faz nada decidi usar um componente que faz alguma coisa. Peguei o componente outros.php, e o código do roteador ficou assim: Route::get('outros/{opcao?}',Outros::class); Route::get('outrosTeste',function(){return redirect('outros/menu');})->name('dashboard'); O componente Outros.php ficou assim: class Outros extends Component { public $modal; function mount($opcao=null) { if($opcao=="menu") {return $this->modal=true;} // o resto do código } } E finalmente o Blade: <div> @if($modal) @else <!-- o resto do código --> @endif </div>
  9. Fazer modal no PHP ou no Laravel foi bem difícil para mim, pois eu não tinha nenhuma familiaridade com o JavaScript. Já o Livewire trouxe um novo conceito, onde você divide o HTML em várias partes, e você vai exibindo de acordo com a necessidade. No meu caso, eu dividi o HTML em $modal, $modal2 e $modal3. Dentro do primeiro $modal existem dezenas de "submodais" que são controlados pela variável $comando. $modal2 mostra a nota do fornecedor onde tem quantidade e preço. O $modal3 mostra a mesma nota, mas com o CFOP e o NCM. arquivo app > Livewire > NotaFiscal.php <?php namespace App\Livewire; use App\Models\tbdiario; use App\Models\tbpessoa; use App\Models\tbhistprod; use App\Models\tbprod; use Illuminate\Support\Facades\DB; use Livewire\Attributes\Layout; use Livewire\Component; use Livewire\WithFileUploads; #[Layout('components.layouts.app',['titulo'=>'NF do Fornecedor'])] class NotaFiscal extends Component { use WithFileUploads; public $comando="pegar xml",$criterio,$difAliqICMS,$inativos=[],$indicador,$lcto; public $modal=true,$modal2,$modal3; public $nNF,$opcoes=[],$previa=[],$quant,$soma,$xNome,$XmlFile,$vNF; function updatedXmlFile() { $this->previa=[]; $xmlContent=file_get_contents($this->XmlFile->getRealPath()); $nfe=simplexml_load_string($xmlContent); $itens=$nfe->NFe->infNFe->det; $this->difAliqICMS=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; $this->difAliqICMS += round(($vBC * $aliquotaInterna - $vICMS+0.00001),2); } } $this->vNF = (float)$nfe->NFe->infNFe->total->ICMSTot->vNF; $this->nNF = (string)$nfe->NFe->infNFe->ide->nNF; $this->xNome = (string)$nfe->NFe->infNFe->emit->xNome; $nome = explode(" ", $this->xNome)[0]; $codp = tbpessoa::where('pessoa','like','%'.$nome.'%')->value('codp'); $this->soma=0; foreach ($itens as $item) { $codforn = (string)$item->prod->cProd; $criterio= strtolower($nome[0].$codforn); $consulta = tbprod::where('codforn','like','%'.$criterio.'%')->get(); $cfop = (string)$item->prod->CFOP; $ncm = (string)$item->prod->NCM; if (count($consulta) == 1) { $codprod = $consulta[0]->codprod; if(substr($consulta[0]->cfop,0,1)==0) { $this->inativos[]=$consulta[0]->codprod; } $class=($cfop == substr($consulta[0]->cfop,-4)) ? "w-[50px] text-right" : "w-[50px] text-red-500 text-right"; $class2=($ncm == $consulta[0]->cf) ? "w-[100px] text-right" : "w-[100px] text-red-500 text-right"; } if (count($consulta) > 1) { $consulta2 = tbprod::where('codforn','like','%'.$criterio)->get(); if(count($consulta2) == 1){ $codprod = $consulta2[0]->codprod; $consulta = $consulta2; } else { $codprod = "mult"; } } if (count($consulta)==0) { $codprod = "none"; } $produto = substr((string)$item->prod->xProd,0,79); $quantidade = (float)$item->prod->qCom; if($cfop==6101 || $cfop==6102 || $cfop==5101) { $cfop=5102; } if($cfop==6401 || $cfop==6402 || $cfop==6403 || $cfop==5401 || $cfop==5403 || $cfop==5655) { $cfop=5405; } 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,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; $difAliq = round(($vBC * $aliquotaInterna - $vICMS+0.00001),2); } $vIPI =(isset($item->imposto->IPI->IPITrib->vIPI) && (float)$item->imposto->IPI->IPITrib->vIPI) ? (float)$item->imposto->IPI->IPITrib->vIPI : 0; $vProd = (string)$item->prod->vProd; $valorTotal = $vProd + $vICMSST + $difAliq + $vIPI; $this->soma += $valorTotal; $custoAtual = intval($valorTotal / $quantidade * 100) / 100; $custoAnterior=0; $marg=0; $cclass="w-[70px] text-right"; $nclass="w-[100px] text-right"; $fclass="w-[50px] text-right"; if (is_numeric($codprod)) { $consulta = tbprod::where('codprod',$codprod)->first(); $custoAnterior = $consulta->custo; $marg=$consulta->marg; if (abs($custoAnterior - $custoAtual) > 0.02) { $cclass = 'w-[70px] text-right text-red-500'; } if ($ncm !== $consulta->cf) { $nclass = 'w-[100px] text-right text-red-500'; } if (trim($cfop) !== trim(substr($consulta->cfop,-4))) { $fclass = 'w-[50px] text-right text-red-500'; } } $this->previa[]=['codforn'=>$codforn,'codprod'=>$codprod,'prod'=>$produto, 'qt'=>$quantidade,'custoanterior'=>$custoAnterior,'custoatual'=>$custoAtual, 'custototal'=>$valorTotal, 'fclass'=>$fclass, 'cfop'=>$cfop,'codp'=>$codp,'ncm'=>$ncm,'nclass'=>$nclass,'cclass'=>$cclass, 'marg'=>$marg]; } $this->modal=false; $this->modal2=true; } function atualizarCfop($indicador) { $codprod=$this->previa[$indicador]['codprod']; $cfop=$this->previa[$indicador]['cfop']; DB::table('tbprod')->where('codprod',$codprod) ->update(['cfop' => DB::raw("CONCAT(LEFT(cfop, LENGTH(cfop) - 4), $cfop)")]); $this->previa[$indicador]['fclass']='w-[50px] text-right'; } function atualizarNcm($indicador) { $codprod=$this->previa[$indicador]['codprod']; $ncm=$this->previa[$indicador]['ncm']; tbprod::where('codprod',$codprod)->update(['cf'=>$ncm]); $this->previa[$indicador]['nclass']='w-[100px] text-right'; } function cancelar() { $this->modal=false; } function custo($indicador) { $this->indicador=$indicador; $this->comando="alterar custo"; $this->modal=true; } function custoConfirmado() { $custo=$this->previa[$this->indicador]['custoatual']; $codprod=$this->previa[$this->indicador]['codprod']; $this->previa[$this->indicador]['cclass']="w-[70px] text-right"; tbprod::where('codprod',$codprod)->update(['custo'=>$custo]); $this->modal=false; } function mostrarMais() { if($this->modal2) { $this->modal2=false; $this->modal3=true; } else { $this->modal2=true; $this->modal3=false; } } function multiplo($indicador) { $this->criterio=$this->previa[$indicador]['codforn']; $consulta=tbprod::where('codforn','like',"%$this->criterio")->get(); $this->opcoes=[]; foreach($consulta as $c) { $this->opcoes[]=['indicador'=>$indicador,'codprod'=>$c->codprod,'prod'=>$c->prod]; } $this->modal=true; } function qtDefinir($indicador) { $this->indicador=$indicador; $this->comando="qt"; $this->modal=true; } function qtDefinida() { $quant=$this->quant; $custo=round($this->previa[$this->indicador]['custototal']/$quant,2); $this->previa[$this->indicador]['qt']=$quant; $this->previa[$this->indicador]['custoatual']=$custo; $this->previa[$this->indicador]['cclass']="w-[50px] text-right text-red-500"; $this->modal=false; } function selecionado($chave) { $indicador=$this->opcoes[$chave]['indicador']; $codprod=$this->opcoes[$chave]['codprod']; $this->previa[$indicador]['codprod']=$codprod; $consulta=tbprod::where('codprod',$codprod)->first(); $this->previa[$indicador]['marg']=$consulta->marg; $this->previa[$indicador]['custoanterior']=$consulta->custo; if($this->previa[$indicador]['custoanterior'] !== $this->previa[$indicador]['custoatual']) { $previa[$indicador]['pclass']="w-[50px] text-right text-red-200"; } $this->modal=false; } function transferir() { if(count(tbhistprod::where('lcto',$this->lcto)->get())>0){ $this->comando="transferido"; $this->modal=true; } else { $dia=tbdiario::where('lcto',$this->lcto)->value('dia'); foreach($this->previa as $p) { tbhistprod::create(['codprod'=>$p['codprod'],'dia'=>$dia,'qt'=>$p['qt'], 'custototal'=>$p['custototal'],'codp'=>$p['codp'],'lcto'=>$this->lcto]); } return redirect('ldiario'); } } } arquivo resources > views > livewire > nota-fiscal.blade.php <div> @if($modal) <div class="fixed inset-0 flex items-center justify-center z-10" style="background-color: rgba(243,244,246,0.5)"> <div class="bg-white p-6 rounded shadow-lg"> @if($comando=="pegar xml") <flux:input type="file" wire:model="XmlFile" label="Pegar arquivo xml"/> @endif @if($comando=="escolher produto") @foreach($opcoes as $chave => $o) <flux:button wire:click="selecionado({{$chave}})">{{ $o['codprod']." ".$o['prod'] }} </flux:button> @endforeach <p>Existem muitos produtos com o critério {{$criterio}}. Escolha um.</p> @endif @if($comando=="alterar custo") <div class=w-[300px]> <flux:input.group> <flux:input.group.prefix>Custo Anterior</flux:input.group.prefix> <flux:input value="{{dec($previa[$indicador]['custoanterior'])}}" /> </flux:input.group> <flux:input.group> <flux:input.group.prefix>Custo Atual</flux:input.group.prefix> <flux:input value="{{ dec($previa[$indicador]['custoatual']) }}" /> </flux:input.group> <flux:button wire:click="custoConfirmado">Confirmar</flux:button> </div> @endif @if($comando=="qt") <div class=w-[300px]> <flux:input.group> <flux:input.group.prefix>Definir Quantidade</flux:input.group.prefix> <flux:input wire:model="quant" wire:change="qtDefinida" autofocus autocomplete="off" /> </flux:input.group> <flux:button wire:click="cancelar" class="mt-5">Cancelar</flux:button> </div> @endif @if($comando=="transferido") <div class="text-lg">Documento já transferido anteriormente</div> @endif </div> </div> @endif @if($modal2 || $modal3) @if(count($inativos)) <div class=mt-5>{{ "verificar ".print_r($inativos) }}</div> @endif <div class=flex> <div class=w-[530px]>NF {{ $nNF." ".$xNome }}</div> <div class="w-[100px] text-right">{{ dec($vNF) }}</div> </div> @if($difAliqICMS!==0) <div class="flex"> <div class="w-[530px] text-right">Diferença de Alíquota de ICMS</div> <div class="w-[100px] text-right"><?=dec($difAliqICMS)?></div> </div> <div class="flex"> <div class="w-[530px] text-right">Total a conferir</div> <div class="w-[100px] text-right"><?=dec($difAliqICMS+$vNF)?></div> </div> @endif @if($modal2) <div class="flex even:bg-gray-200"> <div class="w-[70px] text-right">Cforn</div> <div class="w-[50px] text-right">Cod</div> <div class="w-[288px] px-2">Produto</div> <div class="w-[50px] text-right">Mg</div> <div class="w-[50px] text-right">Qt</div> <div class="w-[70px] text-right">Preço</div> <div class="w-[100px] text-right font-semibold" wire:click=mostrarMais>Total</div> </div> @foreach($previa as $key => $p) <div class="flex even:bg-gray-200"> <div class="w-[70px] text-right truncate">{{$p['codforn']}}</div> @if($p['codprod']=="none") <div class="w-[50px] text-right text-red-500">{{$p['codprod']}}</div> @endif @if($p['codprod']=="mult") <div class="w-[50px] text-right text-red-500" wire:click="multiplo({{$key}})"> {{ $p['codprod']}} </div> @endif @if($p['codprod']!=="none" && $p['codprod']!=="mult") <div class="w-[50px] text-right">{{$p['codprod']}}</div> @endif <div class="w-[288px] px-2 truncate">{{$p['prod']}}</div> <div class="w-[50px] text-right">{{$p['marg']}}</div> <div class="w-[50px] text-right" wire:click="qtDefinir({{$key}})">{{$p['qt']}}</div> <div class="{{ $p['cclass']}}" wire:click="custo({{$key}})">{{dec($p['custoatual'])}}</div> <div class="w-[100px] text-right">{{dec($p['custototal'])}}</div> </div> @endforeach @endif @if($modal3) <div class="flex even:bg-gray-200"> <div class="w-[70px] text-right">Cforn</div> <div class="w-[50px] text-right">Cod</div> <div class="w-[358px] px-2">Produto</div> <div class="w-[50px] text-right">CFOP</div> <div class="w-[100px] text-right font-semibold" wire:click="mostrarMais">NCM</div> </div> @foreach($previa as $key => $p) <div class="flex even:bg-gray-200"> <div class="w-[70px] text-right truncate">{{$p['codforn']}}</div> @if($p['codprod']=="none") <div class="w-[50px] text-right text-red-500">{{$p['codprod']}}</div> @endif @if($p['codprod']=="mult") <div class="w-[50px] text-right text-red-500" wire:click="multiplo({{$key}})"> {{ $p['codprod']}} </div> @endif @if($p['codprod']!=="none" && $p['codprod']!=="mult") <div class="w-[50px] text-right">{{$p['codprod']}}</div> @endif <div class="w-[358px] px-2 truncate">{{$p['prod']}}</div> <div class="{{$p['fclass']}}" wire:click="atualizarCfop({{ $key }})"> {{$p['cfop']}} </div> <div class="{{$p['nclass']}}" wire:click="atualizarNcm({{ $key }})"> {{$p['ncm']}} </div> </div> @endforeach @endif <div class=flex> <div class="w-[300px]"> <flux:input.group> <flux:button>Enviar para Lançamento</flux:button> <flux:input wire:model="lcto" wire:change="transferir" /> </flux:input.group> </div> <div class="w-[330px] text-right">{{ dec($soma) }}</div> </div> @endif </div>
  10. É possível gravar numa célula da matriz a informação com a sua formatação (lá no Blade você usa a diretriz {!! ... !!} para recuperar a informação já formatada), o problema é quando você precisar trabalhar só com a informação; assim, a minha sugestão é trabalhar com duas células, uma com a informação e a outra com a formatação correspondente, assim: arquivo app > Livewire > Teste.php <?php namespace App\Livewire; use Livewire\Component; class Teste extends Component { public $previa=[]; function mount() { $dado=dec(12); $this->previa[]=['codigo'=>$dado,'cor1'=>null]; $this->previa[]=['codigo'=>$dado,'cor1'=>null]; $this->previa[]=['codigo'=>$dado,'cor1'=>'text-red-500']; } function mudarCor($indicador){ $cor=$this->previa[$indicador]['cor1']; if($cor==null) { $this->previa[$indicador]['cor1']="text-red-500"; } else { $this->previa[$indicador]['cor1']=null; } } } arquivo teste.blade.php <div> @foreach($previa as $key => $p) <div class="{{$p['cor1']}}" wire:click="mudarCor({{$key}})"> {{$p['codigo']}} </div> @endforeach </div>
  11. O Livewire simplificou bastante o upload, mesmo assim, para cada tipo de arquivo, o procedimento é diferente. O código seguinte faz o upload de até 20 arquivos csv (para um número maior aí vai precisar mexer no WampServ ou ou o servidor que você usar). arquivo app > Livewire > Bling.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; use Livewire\WithFileUploads; #[Layout('components.layouts.app',['titulo'=>'Diferença na Bling'])] class Bling extends Component { use WithFileUploads; public $contaProdBling,$contaProduto,$dif=[],$files=[]; function updatedFiles() { DB::table('tbprodbling')->truncate(); foreach($this->files as $arquivo) { $dados=explode(PHP_EOL,$arquivo->get()); foreach($dados as $linha) { if($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]; } } } } } } arquivo resources > views > livewire > bling.blade.php <div> <flux:input type="file" wire:model="files" multiple /> <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> A seguir o código para fazer o upload de um arquivo xml: arquivo app > Livewire > Cfop.php <?php namespace App\Livewire; use App\Models\tbnf; use App\Models\tbpessoa; use App\Models\tbprod; use Illuminate\Support\Facades\DB; use Livewire\Attributes\Layout; use Livewire\Component; use Livewire\WithFileUploads; #[Layout('components.layouts.app',['titulo'=>'NF CFOP'])] class Cfop extends Component { use WithFileUploads; public $xmlFile,$inativos=[],$nNF,$previa=[],$xNome; function updatedXmlFile() { tbnf::truncate(); DB::statement('alter table tbnf auto_increment=1'); $inativos=[]; $xmlContent=file_get_contents($this->xmlFile->getRealPath()); $nfe=simplexml_load_string($xmlContent); $itens=$nfe->NFe->infNFe->det; $this->nNF = (float)$nfe->NFe->infNFe->ide->nNF; $this->xNome = (string)$nfe->NFe->infNFe->emit->xNome; $nome = explode(" ", $this->xNome)[0]; $codp = tbpessoa::where('pessoa','like','%'.$nome.'%')->value('codp'); foreach ($itens as $item) { $codforn = (string)$item->prod->cProd; $criterio= strtolower($nome[0].$codforn); $consulta = tbprod::where('codforn','like','%'.$criterio.'%')->get(); $codprod = 'null'; if (count($consulta) == 1) { $codprod = $consulta[0]->codprod; } if (count($consulta) > 1) { $consulta2 = tbprod::where('codforn','like','%'.$criterio)->get(); 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==5403 || $cfop==5655) { $cfop=5405; } $class=($cfop == substr($consulta[0]->cfop,-4)) ? "w-[50px] text-right" : "w-[50px] text-red-500 text-right"; if(substr($consulta[0]->cfop,0,1)==0) { $inativos[]=$consulta[0]->codprod; } $ncm = (string)$item->prod->NCM; $class2=($ncm == $consulta[0]->cf) ? "w-[100px] text-right" : "w-[100px] text-red-500 text-right"; tbnf::create(['codforn'=>$codforn,'codprod'=>$codprod,'prod'=>$produto, 'cfop'=>$cfop,'codp'=>$codp,'ncm'=>$ncm,'class'=>$class,'class2'=>$class2]); } $this->previa=tbnf::all(); } function atualizarCfop($cfop,$codprod) { DB::table('tbprod')->where('codprod',$codprod) ->update(['cfop' => DB::raw("CONCAT(LEFT(cfop, LENGTH(cfop) - 4), $cfop)")]); tbnf::where('codprod',$codprod) ->update(['class'=>"w-[50px] text-right"]); $this->previa=tbnf::all(); } function atualizarNcm($codprod,$ncm) { tbprod::where('codprod',$codprod) ->update(['cf'=>$ncm]); tbnf::where('codprod',$codprod) ->update(['class2'=>"w-[100px] text-right"]); $this->previa=tbnf::all(); } } arquivo resources > views > livewire > cfop.blade.php <div> <flux:input type="file" wire:model="xmlFile" /> <div class=mt-5>{{ print_r($inativos) }}</div> <div>NF {{ $nNF." ".$xNome }}</div> <div class="flex bg-gray-200"> <div class="w-[70px] text-right">Cforn</div> <div class="w-[50px] text-right">Cod</div> <div class="w-[358px] px-2">Produto</div> <div class="w-[50px] text-right">CFOP</div> <div class="w-[100px] text-right">NCM</div> </div> @foreach($previa as $p) <div class="flex odd:bg-gray-200"> <div class="w-[70px] text-right truncate"><?=$p->codforn?></div> <div class="w-[50px] text-right"><?=$p->codprod?></div> <div class="w-[358px] px-2 truncate"><?=$p->prod?></div> <div class="{{$p->class}}" wire:click="atualizarCfop({{$p->cfop}},{{$p->codprod}})"> {{$p->cfop}} </div> <div class="{{$p->class2}}" wire:click="atualizarNcm({{$p->codprod}},{{$p->ncm}})"> {{$p->ncm}} </div> </div> @endforeach </div>
  12. Frank K Hosaka

    <flux:button>

    arquivo resources > views > livewire > loutros.blade.php <div> <div class="h-1"></div> <flux:button href='lestoqueBaixar' wire:navigate size="xs" variant="filled">Baixar Estoque</flux:button> <flux:button href="lbalancete/1" size="xs">Criar TBW</flux:button> <flux:button href="lnfArquivo" wire:navigate size="xs" variant="filled">CFOP</flux:button> <flux:button href=lprodutoDescontinuar wire:navigate size="xs">Descontinuar Produto</flux:button> <flux:button href="lnfArquivo" wire:navigate size="xs" variant="filled">Diferença Bling</flux:button> <flux:button href=estoqueDiferenca wire:navigate size="xs">Diferença Estoque</flux:button> <div class="h-1"></div> <flux:button href=lentrada wire:navigate size="xs" variant="filled">Entrada de Produtos</flux:button> <flux:button href=lmegasena wire:navigate size="xs">Mega-Sena</flux:button> <flux:button href=diarioMercado wire:navigate size="xs" variant="filled">Mercado Pago</flux:button> <flux:button href=lnfArquivo wire:navigate size="xs">Nota do Fornecedor</flux:button> <flux:button href="simples" wire:navigate size="xs" variant="filled">Simples</flux:button> <div class=flex> <div class=w-[200px]>session('codp')</div> <div>{{$vetor['codp']}}</div> </div> <div class="flex bg-gray-200"> <div class=w-[200px]>session('codprod')</div> <div>{{$vetor['codprod']}}</div> </div> <div class="flex"> <div class=w-[200px]>session('criterio')</div> <div class=truncate>{{$vetor['criterio']}}</div> </div> <div class="flex bg-gray-200"> <div class=w-[200px]>session('criterioPessoa')</div> <div>{{$vetor['criterioPessoa']}}</div> </div> <div class="flex"> <div class=w-[200px]>session('dia')</div> <div>{{dbr($vetor['dia'])}}</div> </div> <div class="flex bg-gray-200"> <div class=w-[200px]>session('end')</div> <div>{{$vetor['end']}}</div> </div> <div class="flex"> <div class=w-[200px]>session('id')</div> <div>{{$vetor['id']}}</div> </div> <div class="flex bg-gray-200"> <div class=w-[200px]>session('lcto')</div> <div>{{$vetor['lcto']}}</div> </div> <div class="flex"> <div class=w-[200px]>session('pessoa')</div> <div>{{$vetor['pessoa']}}</div> </div> <div class="flex bg-gray-200"> <div class=w-[200px]>env('lctoBaixaEstoque')</div> <div class=w-[100px]>{{$baixa}}</div> <div class='w-[100px] text-red-600 text-right'>{{dec($valorBaixa)}}</div> </div> <div class="flex"> <div class=w-[200px]>env('lctoAcertoMais')</div> <div class=w-[100px]>{{$mais}}</div> <div class='w-[100px] text-red-600 text-right'>{{dec($valorMais)}}</div> </div> <div class="flex bg-gray-200"> <div class=w-[200px]>env('lctoAcertoMenos')</div> <div class=w-[100px]>{{$menos}}</div> <div class='w-[100px] text-red-600 text-right'>{{dec($valorMenos)}}</div> </div> <div class="flex"> <div class=w-[200px]>env('diaAcerto')</div> <div>{{dbr($diaAcerto)}}</div> </div> </div>
  13. O Livewire é basicamente um par de componente e seu Blade correspondente. O Copilot disse que não é possível acessar um método do Livewire pelo roteador, ele disse que o correto é eu invocar o método desejado através do Blade. Eu não gostei da resposta do Copilot, mas com a ajuda dele eu fiz a seguinte gambiarra: arquivo routes > web.php (parcial) <?php use App\Livewire\Lbalancete; Route::middleware(['auth','verified'])->group(function() { Route::get('lbalancete/{opcao?}',Lbalancete::class)->name('lbalancete'); } arquivo resources > views > livewire > loutros.blade.php (parcial) <a href="lbalancete/1" class="text-gray-500 font-semibold">Criar TBW</a> arquivo app > Livewire > Lbalancete.php (parcial) class Lbalancete extends Component { function mount($opcao = null) { if($opcao==1) { $this->tbw() ;} $this->atualizar(); } function tbw() { $ultimoDia=tbdiario::orderBy('dia','desc')->value('dia'); session(['apuracao'=>$ultimoDia]); $balancete=$this->balancete()->balancete; DB::table('tbw')->truncate(); foreach($balancete as $conta) { $inicio=$conta->inicio ?? 'null' ; $debito=$conta->debito ?? 'null '; $credito=$conta->credito ?? 'null'; $fim=$conta->fim ?? 'null'; tbw::create(['conta'=>$conta->conta,'descricao'=>$conta->descricao, 'inicio'=>$inicio,'debito'=>$debito,'credito'=>$credito,'fim'=>$fim]); } session()->forget('apuracao'); return redirect()->to("https://123.456.78.900:8443/phpmyadmin/index.php"); } }
  14. No tempo do PHP e Laravel, eu usei o <form> para fazer uma ponte entre o view e o controller, mas no Livewire acredito que o <form> só serve para usar as regras de validação. Em vários tutoriais do Livewire você vai encontrar coisa do tipo unique:user, ou seja, o Livewire vai procurar a informação na tabela user. No meu caso, o nome da minha tabela é tbusuarios. Mesmo que eu tenho colocado a tabela no model User, o código no Livewire só vai funcionar se eu usar unique:tbusuarios. <?php // Teste.php namespace App\Livewire; use Livewire\Component; class Teste extends Component { public $email; function register() { $data=$this->validate(['email'=>'required|email|unique:tbusuarios']); dd("creating a user with email $this->email"); } } ?> <form wire:submit.prevent="register" class="w-25"> <!-- teste.blade.php --> <div class="h-5"></div> <flux:input wire:model="email" /> <div class="h-5"></div> <flux:button type=submit>Register</flux:button> <div class="h-5"></div> @error('email'){{ $message }}@enderror </form>
  15. Eu tentei testar o código que aparece logo no portal do livewire.laravel.com, ao invés de usar a tabela user, eu usei a tabela de produtos, mas o VS Code disse que encontrou um erro por eu não ter definido a propriedade produto no componente. O VS Code tem razão, o portal do Livewire apresenta um péssimo exemplo de programação, aonde deveria ser @foreach($users as $user), o rapaz escreveu $this->users.
  16. Hoje eu estudei o <wire:loading>, mas nenhum dos exemplos do tutorial funcionou comigo. O único que deu certo foi um que muda a cor de uma opção que foi selecionada: <div wire:click="multiploAtualiza" wire:loading.class="text-red-500" class="text-gray-500 font-semibold"> Atualizar Produtos Vinculados </div>
  17. Apesar do Livewire ser uma extensão do Laravel, aqui eu já considero como um novo recurso do PHP, principalmente para um programador eventual como eu que não conseguiu dominar o JavaScript e principalmente o Ajax. Eu tenho uma rotina que dá entrada no estoque, usando o serviço da digitação. Acredito que a grande maioria dos programadores utiliza o serviço de importação do xml para dar entrada no estoque, mas eu não tenho paciência de esperar e assim eu uso uma cópia da confirmação do pedido do fornecedor. No view, eu tenho três entradas: <input wire:model="codfornec">, <input wire:model="qt"> e <input wire:model="total">. Depois que o usuário fornece os dados, o componente procura na tabela de produtos o registro que contém o codfornec que foi digitado, e se encontrar, ele dá a entrada na tabela histórico do produto. O problema é se o componente não conseguir encontrar, aí o componente solta a mensagem "eu não achei" e fica por isso mesmo. O usuário pode abrir uma nova guia e acertar a tabela de produtos, atualizando ou criando um novo registro. Depois ele volta na guia da entrada de produto, e digita tudo de novo. A lei do menor esforço obriga o usuário a reclamar com o programador que não faz sentido digitar tudo de novo, coisa que já foi digitado antes. E ele tem razão. Eu não sei como resolver isso de maneira lógica, mas improvisei essa gambiarra: Eu criei três variáveis públicas: public $codfornec2, $qt2, $total2, e eles foram definidos quando o componente não encontrar o produto, assim: <?php // ... function item() { // ... $aux=tbprod::where('codforn','like',"%$codforn%")->get(); if (count($aux) == 0) { $this->codforn2=$codforn; $this->qt2=$qt; $this->total2=$total; $this->mensagem="Não existe produto com codforn $codforn"; $this->modal=true; return; } A rotina que fecha o modal anula o conteúdo de $codforn, $qt e $total, e assim o usuário vai ver três caixas vazias que ele não quer digitar. Eu mudei a primeira caixa de entrada: <input wire:model="codforn" wire:click="item">, e o método item no componente ficou assim: <?php // ... function item() { if($this->codforn2) { $codforn=$this->codforn2; $qt=$this->qt2; $total=$this->total2; $this->codforn2=$this->qt2=$this->total2=null; } else { if(is_null($this->codforn)) { return; } $codforn = $this->codforn; $qt = $this->qt; $total = deca($this->total); } Essa gambiarra funciona, o problema é como lembrar o usuário de que é possível recuperar a última digitação só com um clique na primeira caixa.
  18. 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.
  19. 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.
  20. Frank K Hosaka

    O arquivo csv

    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.
  21. 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>
  22. 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.
  23. Antes de conhecer o Livewire, eu usava o POST para atualizar a tela, o Livewire usa ouvintes ('listeners'), que executam tarefas para mudar as propriedades de um componente e assim mudam as informações que estão na tela, logo depois de ouvir a gritaria do dispatch( ). A seguir tenho um componente chamado razão que executa a mudança da apuração e a apuração aparece na forma de modal e assim que o usuário escolhe a nova apuração, a apuração grita "terminei!" e o razão faz o resto do serviço, e tudo isso sem usar o POST. Eu acredito que o listener é uma forma bem inteligente de executar um método dentro de uma classe. O clássico Laravel usava o Route para cada tarefa que você precisava executar dentro de uma classe, no Livewire o Route só serve para dizer aonde está a classe, ou, mais precisamente, o componente. arquivo resources > views > livewire > lrazao.blade.php <div> <div class="flex bg-gray-200"> <div class="w-[50px] text-right mr-2">Lcto</div> <div class="w-[200px]"> @livewire('lbalanceteApuracao') </div> <div class="w-[500px] -ml-3"> <a href="balanceteInicio" class="text-gray-500 font-semibold">{{$razao->conta}} {{$razao->descricao}}</a> </div> </div> <div class="flex font-semibold"> <div class="w-[240px] text-right mr-2">{{dec($razao->inicio)}}</div> <div>Saldo anterior</div> </div> @foreach($lctos as $lcto) @if($lcto->contad==$razao->conta) <div class="flex even:bg-gray-200"> <div class="w-[50px] text-right"> <a href="ldiarioLcto?docto={{$lcto->docto}}" class="text-gray-500 font-semibold">{{$lcto->lcto}}</a> </div> <div class="w-[40px] text-right">{{$lcto->contac}}</div> <div class="w-[50px] text-right"> <a href="balanceteDiario?dia='{{$lcto->dia}}'" class="text-gray-500 font-semibold"> {{date('d/m',strtotime($lcto->dia))}} </a> </div> <div class="w-[100px] text-right mr-2">{{dec($lcto->valor)}}</div> <div class="w-[350px] whitespace-nowrap overflow-auto">{{$lcto->hist}}</div> </div> @endif @if($lcto->contac==$razao->conta) <div class="flex even:bg-gray-200"> <div class="w-[50px] text-right"> <a href="ldiarioLcto?docto={{$lcto->docto}}" class="text-gray-500 font-semibold"> {{$lcto->lcto}} </a> </div> <div class="w-[40px] text-right text-red-500">{{$lcto->contad}}</div> <div class="w-[50px] text-right"> <a href="balanceteDiario?dia={{$lcto->dia}}" class="text-gray-500 font-semibold"> {{date('d/m',strtotime($lcto->dia))}} </a> </div> <div class="w-[100px] text-right text-red-500 mr-2">{{dec($lcto->valor)}}</div> <div class="w-[350px] whitespace-nowrap overflow-auto">{{$lcto->hist}}</div> </div> @endif @endforeach <div class="flex even:bg-gray-200 font-semibold"> <div class="w-[240px] text-right">{{dec($razao->fim)}}</div> <div class="ml-2"> Saldo atual {{dec($razao->debito)}} <span class="text-red-500">{{dec($razao->credito)}}</span> </div> </div> </div> arquivo resources > views > livewire > lbalancete-apuracao.blade.php <div> <div wire:click=alteraModal class="text-gray-500 font-semibold">{{ $apuracao }}</div> @if($modal) <div class="fixed inset-0 flex items-center justify-center"> <div class='bg-white p-6 rounded shadow-lg border-4 border-gray-500'> <div class="text-nowrap">Selecione o período de apuração</div> <select wire:model="ano"> @foreach($anos as $key => $ano) @if($key == 0) <option value="{{ $ano }}" selected>{{ $ano }}</option> @else <option value="{{ $ano }}">{{ $ano }}</option> @endif @endforeach </select> <div class="mt-3"> @foreach($meses as $posicao => $mes) <button class="ml-1 hover:bg-gray-200 text-gray-500 font-bold py-1 rounded" wire:click="apurada({{ $posicao + 1 }})">{{ $mes }}</button> @endforeach </div> </div> @endif </div> arquivo app > Livewire > Lrazao.php <?php namespace App\Livewire; use App\Models\tbdiario; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.app',['titulo'=>'Razão'])] class Lrazao extends Component { public $apuracao, $lctos, $razao; protected $listeners=['razaoAtualizar'=>'atualizar']; function atualizar() { $dia=session('apuracao') ?? date('Y-m-d'); $this->apuracao=apuracao($dia); $primeiroDia=$this->apuracao->primeiroDia; $ultimoDia=$this->apuracao->ultimoDia; $this->lctos=tbdiario::whereBetween('dia',[$primeiroDia,$ultimoDia])->get(); } function mount () { $conta=request()->input('conta') ? request()->input('conta') : session('razao'); $balancete=(new Lbalancete)->balancete()->balancete; $this->razao=array_column($balancete, null, 'conta')[$conta] ?? false; $this->atualizar(); } } ?> arquivo app > Livewire > LbalanceteApuracao.php <?php namespace App\Livewire; use App\Models\tbdiario; use Livewire\Component; class LbalanceteApuracao extends Component { public $ano, $anos=[],$apuracao,$mes,$modal; public $meses=['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez']; public $depuracao; function apurada ($mes) { session(['apuracao'=>$this->ano."-".$mes."-01"]); $dia=session('apuracao'); $this->apuracao=apuracao($dia)->apuracao; $this->modal=false; $this->dispatch('razaoAtualizar'); } function alteraModal () { $this->modal = $this->modal ? false : true; } function mount() { $primeiroAno=substr(tbdiario::orderBy('dia')->value('dia'),0,4); $ultimoAno=substr(tbdiario::orderBy('dia','desc')->value('dia'),0,4); for($i=$ultimoAno;$i>=$primeiroAno;$i--) { $this->anos[]=$i; } $dia=session('apuracao'); $this->ano=date('Y',strtotime($dia)); $this->apuracao=apuracao($dia)->apuracao; } } ?>
  24. O Copilot disse que o Livewire é baseado no Ajax, assim faz sentido quando você definir <input wire:model="pendencias.{{$index}}.vcto">. No começo achei bem estranho, pois eu estava acostumado com coisa do tipo <input value="{{ $pendencias[$index]->vcto }}">. É muito difícil entender o Livewire no começo, só o tempo é que você se familiarizar com a gramática do PHP e a gramática do Java Script Ajax que vem embutido no Livewire. Eu não tenho a menor ideia de como o Livewire conecta uma variável pública com um wire:model, mas na minha rotina de pendências eu precisei de um monte de wire:model para casar com um monte de pendência. Com a ajuda do Copilot, eu consegui isso: arquivo resources > views > livewire > lpgar.blade.php <div> <input wire:model="doc1" size="5" autocomplete="off" class="border-none rounded p-2 py-0"> <input wire:model="doc2" size="5" autocomplete="off" class="border-none rounded p-2 py-0"> <input type="submit" wire:click="ocultar" value="Ocultar Pendências"> <div class="flex bg-gray-200 mt-2"> <div class="w-[117px] ml-3 text-center">Vencimento</div> <div class="w-[50px] text-right">Docto</div> <div class="w-[110px] text-right">Pendência</div> <div class="w-[346px] px-2 border">Pessoa</div> </div> @foreach($pendencias as $index => $pendencia) <div class="even:bg-gray-200"> <div class="flex"> <div class="w-[117px] ml-3 text-right"> <input type=date wire:model="pendencias.{{$index}}.vcto" onclick=showPicker() wire:change="atualizaVcto({{$pendencia['docto']}},{{$index}})" class="w-[117px] bg-transparent text-gray-500 font-semibold rounded py-0 border-none"> </div> <div class="w-[50px] text-right"> <div wire:click="selecionarDocto({{$pendencia['docto']}})" title="Lçto: {{ $pendencias[$index]['lcto'] }}" class="text-right"> {{ $pendencia['docto'] }} </div> </div> @if($pendencia['debito']) <div class="w-[110px] text-right"> <?=dec($pendencia['debito'])?> </div> @else <div class="w-[110px] text-right text-red-500"> <?=dec($pendencia['credito'])?> </div> @endif <div class="w-[346px] px-2 truncate"> <a class="text-gray-500 font-semibold hover:bg-gray-200" wire:click="selecionarPessoa({{$pendencia['docto']}})" title="Histórico: {!!$pendencia['hist']!!}"> <?=$pendencia['pessoa']?> </a> </div> </div> </div> @endforeach </div> Arquivo app > Livewire > Lpagar.php <?php namespace App\Livewire; use App\Models\tbcontacorrente; use App\Models\tbdiario; use App\Models\tbpessoa; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.app',['titulo'=>'Pendências'])] class Lpagar extends Component { public $doc1,$doc2,$pendencias=[]; function atualizaVcto($docto,$index) { $vcto=$this->pendencias[$index]['vcto']; tbcontacorrente::where('docto',$docto) ->update(['vcto'=>$vcto]); $this->montaPendencias(); } function montaPendencias() { if(request()->input('docto')) { $docto=request()->input('docto'); $codp=session('codp'); tbcontacorrente::where('docto',$docto)->update(['codp'=>$codp]); } $this->pendencias=[]; $contas=tbcontacorrente::where('pgto',0)->orderBy('vcto')->get(); foreach($contas as $conta) { $doc=tbdiario::where('docto',$conta->docto)->first(); $vcto=$conta->vcto; $docto=$conta->docto; $lcto=$doc->lcto; if($doc->contad==130 || $doc->contad==211) { $debito=$doc->valor; $credito=null; } else { $debito=null; $credito=$doc->valor; } $hist=dbr($doc->dia)." ".$doc->hist; if($conta->codp) { $pessoa=tbpessoa::where('codp',$conta->codp)->value('pessoa'); } else { $pessoa="Selecionar"; } $this->pendencias[]=['vcto'=>$vcto,'docto'=>$docto,'lcto'=>$lcto,'debito'=>$debito, 'credito'=>$credito,'hist'=>$hist,'pessoa'=>$pessoa]; } } function mount() { $pendencias=tbcontacorrente::with('diario')->where('pgto',0)->get(); foreach($pendencias as $p) { $eliminar=($p->diario->contad!==130); $eliminar+=($p->diario->contad!==211); $eliminar+=($p->diario->contac!==130); $eliminar+=($p->diario->contac!==211); if($eliminar==4) { tbcontacorrente::where('docto',$p->docto)->delete(); } } $pendencias=tbcontacorrente::pluck('docto'); $doc1=tbdiario::where('dia','>','2023-12-31')->where('contad',130)->pluck('docto'); $doc2=tbdiario::where('dia','>','2023-12-31')->where('contac',130)->pluck('docto'); $doc3=tbdiario::where('dia','>','2023-12-31')->where('contad',211)->pluck('docto'); $doc4=tbdiario::where('dia','>','2023-12-31')->where('contac',211)->pluck('docto'); $documentos=$doc1->merge($doc2)->merge($doc3)->merge($doc4); $diferenca=$documentos->diff($pendencias); foreach($diferenca as $d) { $lcto=tbdiario::where('docto',$d)->value('lcto'); tbcontacorrente::create(['docto'=>$d,'lcto'=>$lcto,'pgto'=>0]); } $this->montaPendencias(); } function ocultar() { if($this->doc1 !== null) { tbcontacorrente::where('docto',$this->doc1) ->update(['pgto'=>1]); } if($this->doc2 !== null) { tbcontacorrente::where('docto',$this->doc2) ->update(['pgto'=>1]); } $this->doc1=$this->doc2=null; $this->montaPendencias(); } function selecionarDocto($docto) { if($this->doc1==null) { $this->doc1 = $docto; } else { if($this->doc2==null) { $this->doc2 = $docto; } } } function selecionarPessoa($docto) { session(['end'=>"lpagar?docto=$docto"]); redirect()->route("lpessoa"); } }
  25. Nessa semana, eu consegui terminar de ver o tutorial gratuito no livewire.laravel.com, são vídeos rápidos falado em inglês. O tutorial gratuito mostra o básico, para recursos mais avançados o portal pede coisa da ordem de R$ 300,00, mesmo assim o tutorial gratuito fala do recurso de validação, confirmação, Alpine.js, e isso ainda não usei aqui. Eu já tinha visto o Livewire antes, mas eu não entendi o propósito dele. Nesse ano, o Laravel lançou a versão 12, o problema é que ele obriga a você escolher uma extensão: o Livewire, o Vue e o React. Eu escolhi o Livewire por achar que era o menos complicado. Eu tive que estudar o Livewire para adaptar o meu código escrito em Laravel. O problema é que eu não consegui adaptar coisa alguma. Assim eu peguei um tutorial e aos poucos fui migrando o meu código em Laravel para o Livewire, e acabei gostando. O Livewire acabou de vez com o mito MVC (modelo, visão e controle) e mostrou que é possível fazer a festa só trabalhando com a variável pública. No tempo do PHP e do Laravel, eu apanhei muito para pegar o valor do <input> para definir o valor da variável lá no Controller, usando uma complicada rotina de <form> e método POST. O Livewire acabou com esse pesadelo, basta você vincular o <input> com a variável através do recurso wire:model. Ele é fantástico! Agora, o Livewire mudou a linguagem, ao invés de Controle e Visão, agora é Componente e Visão; apesar deles serem visualmente diferentes (PHP e HTML), tudo indica que o Livewire conseguiu colocar tudo lá no navegador. O Livewire me deu muita coragem, e agora não tenho medo de mexer com o modal. O modal nada mais é que um código em HTML que você pode esconder e exibir, era necessário você dominar o JavaScript e o CSS para mexer com isso, eu gastei um monte de lenço de papel para fazer o modal funcionar. O Livewire me ensinou a usar um componente como modal, claro que o Copilot me ajudou bastante. O Liveware também me ensinou a fazer depuração. Quando um erro era encontrado no controle do Laravel, o Laravel parava tudo, e mostrava aquela mensagem "você está fazendo a coisa errada". Nem sempre o Liveware faz esse serviço, tudo é diferente. A primeira coisa que o Livewire faz é executar a função mount ( ), e se não tiver nada disso, ele mostra a visão. Se você aperta o botão, e nada acontece, basta usar o web console, e lá vai ter a mensagem 1 erro livewire.js. Eu aprendi que fiz um monte de erro de digitação na view. Mas se essa mensagem não aparece no web console, eu vou lá no componente e crio a variável pública $depuração, vou lá na visão e acrescento o comando {{ $depuração }} e finalmente vou no componente e uso a minha intuição e acrescento o código PHP $this->depuração="O problema pode estar aqui". Nem tudo dá para resolver no Livewire. Nessa semana eu pedi o balancete, mas o Livewire só mostrava o balancete de maio, quando precisava do balancete de abril. Isso é um erro de lógica. Para saber quem estava pedindo o balancete de maio eu usei o VS Code, pedi para ele listar todos os códigos onde havia o comando session(['apuracao'=> pelo comando Find in Files e assim eu cheguei no método tbw, onde ele pega a última data do diário contábil e monta o balancete. Foi fácil consertar, eu só pedi para apagar assim session( )->forget('apuracao') depois que o método conseguiu o que queria.
×
×
  • Criar Novo...