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 17 registros

  1. 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>
  2. É 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>
  3. 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>
  4. 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>
  5. 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"); } }
  6. 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>
  7. 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.
  8. 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>
  9. 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.
  10. 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.
  11. 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.
  12. 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.
  13. 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>
  14. 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.
  15. 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; } } ?>
  16. 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"); } }
  17. 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...