D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
var
/
www
/
html
/
crsys
/
adm
/
vendor
/
api
/
Filename :
imprimeOrcamento_3.php
back
Copy
<?php include_once "ConectaPdo.php"; require_once __DIR__ . "/../../vendor/autoload.php"; use App\adms\Models\helper\AdmsPhpMailer; /* ========================================================== 1) CARREGAR FPDF ANTES DE DECLARAR A CLASSE ========================================================== */ require($_SERVER['DOCUMENT_ROOT'].'/crsys/adm/app/gre/Views/include/fpdf/fpdf.php'); define('FPDF_FONTPATH','font/'); /* ========================================================== 2) EXTENDER FPDF COM NbLines() E Footer() ========================================================== */ class PDF extends FPDF { function NbLines($w, $txt) { $cw = &$this->CurrentFont['cw']; if ($w == 0) $w = $this->w - $this->rMargin - $this->x; $wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize; $s = str_replace("\r", '', $txt); $nb = strlen($s); if ($nb > 0 && $s[$nb - 1] == "\n") $nb--; $sep = -1; $i = 0; $j = 0; $l = 0; $nl = 1; while ($i < $nb) { $c = $s[$i]; if ($c == "\n") { $i++; $sep = -1; $j = $i; $l = 0; $nl++; continue; } if ($c == ' ') $sep = $i; $l += $cw[$c]; if ($l > $wmax) { if ($sep == -1) { if ($i == $j) $i++; } else { $i = $sep + 1; } $sep = -1; $j = $i; $l = 0; $nl++; } else { $i++; } } return $nl; } // ========================================================== // Rodapé dinâmico com repetição de cabeçalho se necessário // ========================================================== function Footer() { global $dados; // dados do orçamento global $mensa; global $parcelas; // var_dump($parcelas[0]); if (!empty(trim($dados[0]['obs_obra']))) { // Largura total da página $larguraPagina = $this->GetPageWidth() - $this->lMargin - $this->rMargin; // Label "Obs:" em preto $this->SetX(5); $this->SetTextColor(0, 0, 0); $this->Cell(8, 6, 'Obs:', 0, 0, 'L'); // largura fixa só para o label // Texto em vermelho $this->SetTextColor(255, 0, 0); $texto = utf8_decode(trim($dados[0]['obs_obra'])); // MultiCell para o texto, ocupando o restante da largura $this->MultiCell($larguraPagina - 8, 6, $texto, 0, 'L'); // Pula uma linha depois de todo o bloco // $this->Ln(6); // Volta cor padrão $this->SetTextColor(0, 0, 0); } $this->SetFont('Arial','',9); // -------------------------- // Configurações do rodapé // -------------------------- $margem = 5; $largTotal = 210 - 2*$margem; // largura total da página - margens // Proporção: quadro esquerdo maior, direito menor $largDir = 60; // largura fixa quadro direito $largEsq = $largTotal - $largDir; // restante para esquerdo // -------------------------- // Texto fixo esquerda // -------------------------- $textoEsq = $mensa; // mantém o espaçamento original para o lado direito $linAlt = 5; // define um espaçamento reduzido apenas para o texto da esquerda $linAltEsq = 3; // pode usar 3 ou 4 se quiser ajustar $linhasEsq = substr_count($textoEsq, "\n") + 1; // altura do quadro esquerdo usando o espaçamento reduzido $alturaEsq = $linAltEsq * $linhasEsq; // adiciona 4 linhas extras usando também o espaçamento reduzido $alturaEsq += $linAltEsq * 4; //var_dump($dados); // -------------------------- // Texto variável direita // -------------------------- $valorTotal = $dados[0]['vlr_total'] ?? 0; $valorEntrada = $dados[0]['valor_entrada'] ?? 0; $frete = $dados[0]['vlr_frete'] ?? 0; $vlr_ns = $dados[0]['vlr_ns'] ?? 0; $desconto = $dados[0]['vlr_desc'] ?? 0; $desconto = $desconto + $vlr_ns; $totalPagar = $dados[0]['vlr_total'] ?? 0; $totalPagar = $totalPagar - $vlr_ns; //var_dump($parcelas); //die; if (!empty($parcelas) and $parcelas[0]['tipo_pagto_id'] == 5) { $formaPag = "Entrada de R$ " . number_format($valorEntrada, 2, ',', '.'); $formaPag .= " Saldo de R$ " . number_format($parcelas[1]['valor_parcela'], 2, ',', '.') . " na entrega."; } elseif (!empty($parcelas) and $parcelas[0]['tipo_pagto_id'] == 6) { $resultado = []; //var_dump('aqui'); //($parcelas); //die; foreach ($parcelas as $item) { // if (!empty($item['perc_cronograma'])) { $resultado[] = $item['nome'] . ' ' . $item['perc_cronograma'] . '%'; // } } $formaPag = implode('; ', $resultado); } else { if ($dados[0]['perc_entrada'] == '' && $dados[0]['num_parcelas'] == '') { $formaPag = utf8_decode($dados[0]['forma_pgto']); } elseif ($dados[0]['perc_entrada'] == 100.00) { $formaPag = "À Vista"; } elseif ($dados[0]['num_parcelas'] == 0) { $formaPag = $dados[0]['forma_pgto']; } else { $formaPag = "Entrada de " . number_format($dados[0]['perc_entrada'], 2, ',', '.') . "% mais " . $dados[0]['num_parcelas'] . " parcelas vencendo a partir de " . date('d/m/Y', strtotime($dados[0]['data_parcela'])); } } $linhasDir = 7; // ajustado para o novo layout // Altura final igual para os dois quadros + padding extra $paddingExtra = 4; // altura extra para caber a linha 8 $alturaFinal = max($alturaEsq, $linAlt * $linhasDir) + $paddingExtra; // -------------------------- // Verifica se cabe na página, senão abre nova página // -------------------------- $espacoRestante = $this->GetPageHeight() - $this->GetY() - $this->bMargin; if ($alturaFinal + 5 > $espacoRestante) { $this->AddPage(); // Repetir cabeçalho do orçamento if (!empty($dados)) { $cab = $dados[0]; $id_user = $cab['id_user'] ?? 0; $this->SetFont('Arial','',10); $this->Image( $_SERVER['DOCUMENT_ROOT'].'/crsys/adm/assets/imagens/logo_login/'.$id_user.'/logo.png', 5, 5, 100, 35, 'PNG' ); $this->SetY(45); $this->SetX(5); $this->Cell(200,6,'Nº do Orçamento: '.$cab['orca_id'].'/'.date('Y', strtotime($cab['created'] ?? date('Y-m-d'))),0,1,'R'); $this->Cell(200,6,'Data: '.date('d/m/Y', strtotime($cab['created'] ?? date('Y-m-d'))),0,1,'R'); $this->Cell(200,6,'Revisão nº: '.$cab['num_revisao'],0,1,'R'); $this->Cell(200,6,'Última Revisão: '.date('d/m/Y', strtotime($cab['data_ult_rev'])),0,1,'R'); $this->SetY($this->GetY()+5); } } $yRodape = $this->GetY(); // -------------------------- // Coluna esquerda com borda // -------------------------- $this->Rect($margem, $yRodape, $largEsq, $alturaFinal); // contorno $this->SetXY($margem + 1, $yRodape + 1); // $this->MultiCell($largEsq - 2, $linAlt, utf8_decode($textoEsq), 0, 'L'); $this->MultiCell($largEsq - 2, $linAltEsq, utf8_decode($textoEsq), 0, 'L'); // -------------------------- // Coluna direita reformulada com células duplas // -------------------------- $xDir = $margem + $largEsq; $this->Rect($xDir, $yRodape, $largDir, $alturaFinal); // contorno $yLinha = $yRodape; // Linha 1: Cabeçalho "Resumo dos Valores" $this->SetFont('Arial','B',9); $this->SetXY($xDir, $yLinha); $this->Cell($largDir, $linAlt, 'Resumo dos Valores', 1, 0, 'C'); $yLinha += $linAlt; // Definir proporção de largura para coluna de texto e coluna de valor $largTexto = 35; $largValor = $largDir - $largTexto; // Linha 2: Valor total $subtotal = $valorTotal - $frete + $desconto - $vlr_ns; $this->SetFont('Arial','',9); $this->SetXY($xDir, $yLinha); $this->Cell($largTexto, $linAlt, 'Sub-Total', 1, 0, 'L'); $this->Cell($largValor, $linAlt, 'R$ '.number_format($subtotal,2,',','.'), 1, 0, 'R'); $yLinha += $linAlt; // Linha 3: Frete $this->SetXY($xDir, $yLinha); $this->Cell($largTexto, $linAlt, 'Frete', 1, 0, 'L'); $this->Cell($largValor, $linAlt, 'R$ '.number_format($frete,2,',','.'), 1, 0, 'R'); $yLinha += $linAlt; // Linha 4: Desconto if($desconto > 0.00 ){ $this->SetXY($xDir, $yLinha); $this->Cell($largTexto, $linAlt, 'Desconto (-)', 1, 0, 'L'); $this->Cell($largValor, $linAlt, 'R$ '.number_format($desconto,2,',','.'), 1, 0, 'R'); $yLinha += $linAlt; } // Linha 5: Valor Final (negrito) $this->SetFont('Arial','B',9); $this->SetXY($xDir, $yLinha); $this->Cell($largTexto, $linAlt, 'Valor Final', 1, 0, 'L'); $this->Cell($largValor, $linAlt, 'R$ '.number_format($totalPagar,2,',','.'), 1, 0, 'R'); $yLinha += $linAlt; // Linha 6: Pequeno cabeçalho "Forma de Pagamento" $this->SetFont('Arial','B',8); $this->SetXY($xDir, $yLinha); $this->Cell($largDir, $linAlt, 'Forma de Pagamento', 1, 0, 'C'); $yLinha += $linAlt; // Linha 7: Texto da forma de pagamento (pode quebrar linha) $this->SetFont('Arial','',9); $this->SetXY($xDir, $yLinha); $this->MultiCell($largDir, $linAlt, utf8_decode($formaPag), 'TLR', 'C'); } } /* ========================================================== 3) FUNÇÃO PARA CALCULAR ALTURA SEM IMPRIMIR ========================================================== */ function calculaAltura($pdf, $texto, $largura, $alturaLinha) { $texto = utf8_decode($texto); $nLinhas = $pdf->NbLines($largura, $texto); return $nLinhas * $alturaLinha; } /* ========================================================== 4) DADOS DO ORÇAMENTO ========================================================== */ $orca_id = $_GET['orca_id'] ?? ''; $num_rev = $_GET['num_revisao'] ?? ''; $id_user = $_GET['id_user'] ?? ''; $tipo = $_GET['tipo'] ?? 'N'; $endereco = $_GET['endereco'] ?? ''; $opcao = $_GET['opcao'] ?? ''; $cont_item = 0; if (!$orca_id) { echo json_encode(["erro" => "Parâmetro 'orca_id' não fornecido."]); exit; } $queryBase = "SELECT c.*, case when c.obra_id is null then concat(c.obra,' - *** NÃO CADASTRADA ***') else c.obra end obra, o.tipo_id, CASE WHEN o.tipo_id = 1 THEN mask(LPAD(o.cnpj, 14, 0), '##.###.###/####-##') ELSE mask(LPAD(o.cpf, 11, 0), '###.###.###-##') END AS docto, u.nome AS vendedor, CASE WHEN CHAR_LENGTH(a.celular) < 11 THEN mask(LPAD(a.celular, 10, 0), '(##) ####-####') ELSE mask(LPAD(a.celular, 11, 0), '(##) #####-####') END AS telefone_obra, CASE WHEN CHAR_LENGTH(c.tel_vend) < 11 THEN mask(LPAD(c.tel_vend, 10, 0), '(##) ####-####') ELSE mask(LPAD(c.tel_vend, 11, 0), '(##) #####-####') END AS cel, mask(LPAD(c.cep_obra, 8, 0), '#####-###') AS cep, DATE_FORMAT(c.data, '%d/%m/%Y') AS data, DATE_FORMAT(c.data_ult_rev, '%d/%m/%Y') AS data_ult_rev, CONCAT('R$ ', FORMAT(vlr_total, 2, 'de_DE')) AS valor_total, c.endereco_obra AS rua, c.numero_obra, c.municipio_obra AS municipio, c.uf_obra AS uf, o.contato AS contato_obra, CASE WHEN CHAR_LENGTH(o.celular) < 11 THEN mask(LPAD(o.celular, 10, 0), '(##) ####-####') ELSE mask(LPAD(o.celular, 11, 0), '(##) #####-####') END AS cel_obra, ( SELECT SUM(i.vlr_total_mo + i.vlr_total_mat) FROM gre_item_orcamento i WHERE i.orca_id = :orca_id_sub AND i.num_revisao = :num_rev_sub ) AS vlr_semdesc, status_id FROM gre_cab_orcamento c LEFT JOIN gre_obras o ON o.id = c.obra_id LEFT JOIN adms_usuarios u ON u.id = c.vend LEFT JOIN gre_arquitetos a ON a.id = c.arquiteto_id WHERE c.orca_id = :orca_id AND c.num_revisao = :num_rev "; $params = [ ':orca_id' => $orca_id, ':num_rev' => $num_rev, ':orca_id_sub' => $orca_id, ':num_rev_sub' => $num_rev ]; $stmt = $pdo->prepare($queryBase); $stmt->execute($params); $dados = $stmt->fetchAll(PDO::FETCH_ASSOC); //echo '<prev>'; //var_dump($dados); //echo '</prev>'; $stmt4 = $pdo->prepare(" SELECT p.orca_id, p.num_revisao, case when c.nome is null then 'Entrada' else nome end nome, p.qtde_parcela, p.tipo_pagto_id, p.vencimento, p.valor_parcela, p.perc_cronograma, p.id_cronograma FROM gre_parcelas p left join gre_pagto_programado c on c.id = p.id_cronograma WHERE p.orca_id = :orca_id and p.num_revisao = :num_revisao order by p.id "); $stmt4->execute([ ':orca_id' => $dados[0]['orca_id'], ':num_revisao' => $dados[0]['num_revisao'] ]); $parcelas = $stmt4->fetchAll(PDO::FETCH_ASSOC); // Consulta itens $stmt2 = $pdo->prepare("SELECT x.*, a.nome AS nome_ambiente, CASE WHEN NULLIF(TRIM(x.CONJ), '') IS NOT NULL THEN ROUND(x.vlr_total, 2) WHEN LOWER(x.unid_prod) = 'unid' THEN ROUND(x.vlr_total, 2) WHEN LOWER(x.unid_prod) = 'ml' THEN ROUND(x.vlr_total / NULLIF(x.ml, 0), 2) WHEN LOWER(x.unid_prod) = 'm2' THEN ROUND(x.vlr_total / NULLIF(x.m2, 0), 2) ELSE ROUND(x.vlr_unit_prod, 2) END AS vlr_unit_prod_calc FROM ( SELECT i.orca_id, i.num_revisao, i.ambiente_id, i.CONJ, CASE WHEN NULLIF(TRIM(i.CONJ), '') IS NOT NULL THEN 'Conj' ELSE MAX(i.unid_prod) END AS unid_prod, MAX(i.utiliza_insumo) AS utiliza_insumo, MAX(i.material) AS material, MAX(i.qtde_pecas) AS qtde_pecas, SUM(i.m2) AS m2, SUM(i.ml) AS ml, SUM(i.vlr_total) AS vlr_total, SUM(i.vlr_insumo) AS vlr_insumo, MAX(i.vlr_unit_prod) AS vlr_unit_prod, CASE WHEN NULLIF(TRIM(i.CONJ), '') IS NOT NULL THEN CONCAT( 'Conjunto contendo: ', GROUP_CONCAT(i.DESCRICAO ORDER BY i.ID SEPARATOR ', mais ') ) ELSE MAX(i.DESCRICAO) END AS descricao, i.status_id FROM gre_item_orcamento i WHERE i.orca_id = :orca_id AND i.num_revisao = :num_rev GROUP BY i.orca_id, i.num_revisao, i.ambiente_id, CASE WHEN NULLIF(TRIM(i.CONJ), '') IS NOT NULL THEN i.CONJ ELSE i.id END ) x LEFT JOIN gre_ambientes a ON a.id = x.ambiente_id ORDER BY x.ambiente_id; "); $stmt2->execute([ ':orca_id' => $orca_id, ':num_rev' => $num_rev ]); $revisoes = $stmt2->fetchAll(PDO::FETCH_ASSOC); //echo '<prev>'; //var_dump($revisoes); //echo '</prev>'; //die; if (empty($dados) || empty($revisoes)) { echo json_encode(["erro" => "ERRO"]); exit; } $stmt3 = $pdo->prepare(" SELECT * FROM gre_mensagem WHERE empr_id = :empr_id "); $stmt3->execute([ ':empr_id' => $dados[0]['empr_id'] ]); $msg = $stmt3->fetchAll(PDO::FETCH_ASSOC); $mensa = $msg[0]['mensagem']; /* ========================================================== 5) CRIAR PDF ========================================================== */ $pdf = new PDF(); $pdf->SetAutoPageBreak(0); $pdf->SetFont('Arial','',10); $num_linhas = 33; $cont_linha = 9999; $ambant = 0; $total_m2 = 0; $vlr_insumos = 0; /* ========================================================== 6) CABEÇALHO COMPLETO ========================================================== */ foreach ($dados as $lcto) { extract($lcto); $vlr_insumos += $vlr_insumo; if ($cont_linha > $num_linhas) { $pdf->AddPage('P','A4'); // LOGO $pdf->Image( $_SERVER['DOCUMENT_ROOT'].'/crsys/adm/assets/imagens/logo_login/'.$id_user.'/logo.png', 5, 5, 80, 25, 'PNG' ); $pdf->Cell(200,10,'',0,1); // Campos do orçamento totalmente à direita $pdf->SetFont('Arial','B',12); $pdf->SetXY(5, 10); $larguraPagina = 210; // A4 $margemDireita = 5; // var_dump($opcao); // var_dump($status_id); // die; if($status_id == '0') { $nome_relatorio = "Nº do Orçamento:"; }else{ $nome_relatorio = "Nº do Pedido:"; } $pdf->SetX(5); $pdf->Cell( $larguraPagina - 2*$margemDireita, 6, utf8_decode($nome_relatorio.' '.$orca_id.'/'.date('Y', strtotime($created ?? date('Y-m-d')))), 0, 1, 'R' ); $pdf->SetX(5); $pdf->Cell($larguraPagina - 2*$margemDireita, 6, utf8_decode('Revisão nº: '.$num_rev), 0, 1, 'R'); $pdf->SetX(5); $pdf->Cell( $larguraPagina - 2*$margemDireita, 6, utf8_decode( 'Última Revisão: ' . date( 'd/m/Y', strtotime($revisoes[0]['data_ult_rev'] ?? date('Y-m-d')) ) ), 0, 1, 'R' ); $pdf->SetDrawColor(0,0,0); $pdf->SetLineWidth(0.1); $y = $pdf->GetY() + 3; $pdf->Line(5, $y, 205, $y); $pdf->Cell(20, 6, '', 0, 1); // Cabeçalho detalhado do cliente/obra $pdf->SetX(5); $pdf->SetFont('Arial','',10); $pdf->Cell(20,6,'Cliente:',0,0); $pdf->Cell(100,6,utf8_decode($nome_cliente),0,0); $pdf->Cell(30,6,'Vendedor:',0,0); $pdf->Cell(40,6,utf8_decode($vendedor),0,1); $pdf->SetX(5); $pdf->Cell(20,6,'Obra:',0,0); $pdf->Cell(100,6,utf8_decode($obra),0,0); $pdf->Cell(30,6,'Telefone:',0,0); $pdf->Cell(40,6,utf8_decode($cel),0,1); $pdf->SetX(5); $pdf->Cell(20,6,'Contato:',0,0); $pdf->Cell(40,6,utf8_decode($contato_obra),0,0); $pdf->Cell(20,6,'Arquiteto:',0,0); $pdf->Cell(40,6,utf8_decode($arquiteto),0,0); $pdf->Cell(30,6,'Email:',0,0); $pdf->Cell(40,6,utf8_decode($email_vend),0,1); $pdf->SetX(5); $pdf->Cell(20,6,'Telefone:',0,0); $pdf->Cell(100,6,utf8_decode($telefone_obra),0,0); $pdf->Cell(30,6,utf8_decode('Orçamentista:'),0,0); $pdf->Cell(40,6,utf8_decode($orcamentista),0,1); $pdf->SetX(5); $pdf->Cell(20,6,'Email:',0,0); $pdf->Cell(40,6,utf8_decode($email_obra),0,1); $pdf->SetX(5); $pdf->Cell(20,6,'End.Obra:',0,0); $pdf->Cell(140,6,utf8_decode($endereco_obra.', '.$numero_obra.' - '.$bairro.' - '.$municipio_obra.'/'.$uf_obra),0,1); // Linha horizontal $pdf->SetDrawColor(0,0,0); $pdf->SetLineWidth(0.1); $y = $pdf->GetY() + 3; $pdf->Line(5, $y, 205, $y); $pdf->Cell(20,6,'',0,1); // Cabeçalho da tabela de itens $pdf->SetX(5); $pdf->SetFont('Arial','B',8); $pdf->Cell(10,7,utf8_decode('Item'),'1',0,'C'); $pdf->Cell(55,7,utf8_decode('Material'),'1',0,'C'); $pdf->Cell(75,7,utf8_decode('Descrição'),'1',0,'C'); $pdf->Cell(10,7,utf8_decode('Qtde'),'1',0,'C'); $pdf->Cell(10,7,utf8_decode('Unid'),'1',0,'C'); $pdf->Cell(20,7,utf8_decode('Vlr Unit'),'1',0,'C'); $pdf->Cell(20,7,utf8_decode('Vlr.Total'),'1',1,'C'); $cont_linha = 0; } } /* ========================================================== 7) TABELA DE ITENS (VERSÃO FINAL CORRIGIDA) ========================================================== */ //var_dump($revisoes); //'vlr_insumo' => string '317.63' (length=6) // 'vlr_total' => string '2643.82' (length=7) foreach ($revisoes as $itens) { extract($itens); // if($status_id == 1){ // $material = $material; // } if ($utiliza_insumo == 1) { $total_m2 += $m2; } // Título do ambiente if ($ambant <> $ambiente_id) { $ambant = $ambiente_id; $pdf->SetX(5); $pdf->SetFont('Arial','B',9); $pdf->Cell(200,7,utf8_decode($nome_ambiente),1,1,'C'); } $pdf->SetFont('Arial','',9); // Larguras $largItem = 10; $largMaterial = 55; $largDesc = 75; $alturaLinha = 4; $xInicial = 5; $yInicial = $pdf->GetY(); $isCinza = ($status_id == 1); /* =============================== MATERIAL – UTF8 + LIMITE 60 =============================== */ $materialLimpo = trim($material); $materialLimpo = mb_substr($materialLimpo, 0, 60, 'UTF-8'); $materialPdf = utf8_decode($materialLimpo); if (mb_strlen($materialLimpo, 'UTF-8') > 30) { $materialPdf = wordwrap($materialPdf, 30, "\n", true); } /* =============================== ALTURA DINÂMICA =============================== */ $alturaMaterial = $pdf->NbLines($largMaterial, $materialPdf) * $alturaLinha; $alturaDescricao = $pdf->NbLines($largDesc, utf8_decode($descricao)) * $alturaLinha; $alturaFinal = max($alturaMaterial, $alturaDescricao); /* =============================== FUNDO GLOBAL (cor uniforme) =============================== */ if ($isCinza) { $pdf->SetFillColor(220, 220, 220); } else { $pdf->SetFillColor(255, 255, 255); } /* =============================== ITEM =============================== */ $cont_item++; $pdf->SetXY($xInicial, $yInicial); $pdf->Cell($largItem, $alturaFinal, $cont_item, 1, 0, 'C', $isCinza); /* =============================== MATERIAL (FUNDO CORRIGIDO) =============================== */ $xMat = $xInicial + $largItem; if ($isCinza) { $pdf->SetXY($xMat, $yInicial); $pdf->Cell($largMaterial, $alturaFinal, '', 1, 0, 'L', true); } $pdf->SetXY($xMat, $yInicial); $pdf->MultiCell($largMaterial, $alturaLinha, $materialPdf, 'TLR', 'L'); /* =============================== DESCRIÇÃO (FUNDO CORRIGIDO) =============================== */ $xDesc = $xInicial + $largItem + $largMaterial; if ($isCinza) { $pdf->SetXY($xDesc, $yInicial); $pdf->Cell($largDesc, $alturaFinal, '', 1, 0, 'L', true); } $pdf->SetXY($xDesc, $yInicial); $pdf->MultiCell($largDesc, $alturaLinha, utf8_decode($descricao), 'TLR', 'L'); /* =============================== COLUNAS NUMÉRICAS =============================== */ $xPos = $xInicial + $largItem + $largMaterial + $largDesc; $pdf->SetXY($xPos, $yInicial); $valor_Unit = $vlr_unit_prod_calc; // Quantidade if ($unid_prod == 'ml') { $pdf->Cell(10,$alturaFinal,number_format($ml,2,',','.'),1,0,'R',$isCinza); } elseif ($unid_prod == 'm2') { $pdf->Cell(10,$alturaFinal,number_format($m2,2,',','.'),1,0,'R',$isCinza); } else { $pdf->Cell(10,$alturaFinal,number_format($qtde_pecas,2,',','.'),1,0,'R',$isCinza); } // Unidade $pdf->Cell(10,$alturaFinal,utf8_decode($unid_prod),1,0,'C',$isCinza); // Valor Unitário $pdf->Cell(20,$alturaFinal,number_format($valor_Unit,2,',','.'),1,0,'R',$isCinza); // Valor Total $pdf->Cell(20,$alturaFinal,number_format($vlr_total,2,',','.'),1,1,'R',$isCinza); } if ($total_m2 > 0) { $pdf->SetFont('Arial','',9); // Larguras $largItem = 10; $largMaterial = 55; $largDesc = 75; $alturaLinha = 5.5; // 🔹 altura fixa da linha $xInicial = 5; $yInicial = $pdf->GetY(); /* =============================== MATERIAL =============================== */ $materialLimpo = 'Insumos'; $materialPdf = utf8_decode(mb_substr($materialLimpo, 0, 60, 'UTF-8')); /* =============================== ALTURA FIXA =============================== */ $alturaFinal = $alturaLinha; /* =============================== ITEM =============================== */ $cont_item++; $pdf->SetXY($xInicial, $yInicial); $pdf->Cell($largItem, $alturaFinal, $cont_item, 1, 0, 'C'); /* =============================== MATERIAL (centralizado vertical) =============================== */ $nbMat = $pdf->NbLines($largMaterial, $materialPdf); $yOffset = $yInicial + ($alturaFinal - ($nbMat * $alturaLinha)) / 2; $pdf->SetXY($xInicial + $largItem, $yOffset); $pdf->MultiCell($largMaterial, $alturaLinha, $materialPdf, 0, 'L'); $pdf->Rect($xInicial + $largItem, $yInicial, $largMaterial, $alturaFinal); /* =============================== DESCRIÇÃO (centralizada vertical) =============================== */ $descPdf = utf8_decode('Insumos utilizados'); $nbDesc = $pdf->NbLines($largDesc, $descPdf); $yOffset = $yInicial + ($alturaFinal - ($nbDesc * $alturaLinha)) / 2; $pdf->SetXY($xInicial + $largItem + $largMaterial, $yOffset); $pdf->MultiCell($largDesc, $alturaLinha, $descPdf, 0, 'L'); $pdf->Rect($xInicial + $largItem + $largMaterial, $yInicial, $largDesc, $alturaFinal); /* =============================== COLUNAS NUMÉRICAS =============================== */ $xPos = $xInicial + $largItem + $largMaterial + $largDesc; $pdf->SetXY($xPos, $yInicial); $valor_Unit = $vlr_insumos / max(1, $total_m2); $pdf->Cell(10, $alturaFinal, number_format($total_m2, 2, ',', '.'), 1, 0, 'R'); $pdf->Cell(10, $alturaFinal, utf8_decode('m²'), 1, 0, 'C'); $pdf->Cell(20, $alturaFinal, number_format($valor_Unit, 2, ',', '.'), 1, 0, 'R'); $pdf->Cell(20, $alturaFinal, number_format($vlr_insumos, 2, ',', '.'), 1, 1, 'R'); }else{ $pdf->Line(5, $pdf->GetY(), 205, $pdf->GetY()); $pdf->Ln(1); } if($tipo == 'N') { $pdf->Output(); }else { // ================================ // BUSCA CONFIGURAÇÃO DE E-MAIL // ================================ $sql = "SELECT * FROM adms_confs_emails WHERE id = :id LIMIT 1"; $param = ['id' => 1]; $stmt = $pdo->prepare($sql); $stmt->execute($param); $dadosEmail = $stmt->fetch(PDO::FETCH_ASSOC); if (!$dadosEmail) { echo " <script> window.opener.postMessage( { status: 'erro', mensagem: 'Configuração de e-mail não encontrada' }, '*' ); window.close(); </script>"; exit; } $sql = "SELECT p.orca_id, p.num_revisao, p.num_parcela, p.qtde_parcela, p.valor_parcela, p.tipo_pagto_id, CASE WHEN p.vencimento IS NULL THEN 'Entrada' ELSE ' ' END AS entrada, DATE_FORMAT(p.vencimento, '%d/%m/%Y') vencimento, case when p.tipo_pagto_id = 6 then c.nome else t.nome end AS nome, p.perc_cronograma, p.id_cronograma FROM gre_parcelas p left join gre_pagto_programado c on c.id = p.id_cronograma left JOIN gre_forma_pagamento t ON p.tipo_pagto_id = t.id WHERE p.orca_id = :orca_id AND p.num_revisao = :num_revisao ORDER BY p.num_parcela; "; $params = [ ':orca_id' => $orca_id, ':num_revisao' => $num_revisao ]; $stmt = $pdo->prepare($sql); $stmt->execute($params); $parcelas = $stmt->fetchAll(PDO::FETCH_ASSOC); $qtde_parcela = $parcelas[0]['qtde_parcela']; // ================================ // GERA O PDF // ================================ $diretorio = $_SERVER['DOCUMENT_ROOT'].'/crsys/adm/orcamento/'.$empr_id; if (!is_dir($diretorio)) { // Cria o diretório com permissões 0777 e de forma recursiva mkdir($diretorio, 0777, true); // Garante que as permissões sejam aplicadas corretamente chmod($diretorio, 0777); } $nome_arquivo = "orcamento_{$empr_id}_{$orca_id}_{$num_rev}.pdf"; $caminho_completo = $diretorio . '/' . $nome_arquivo; // Se o arquivo já existir, exclui if (file_exists($caminho_completo)) { unlink($caminho_completo); } // Grava o novo PDF $pdf->Output('F', $caminho_completo); // ================================ // LOCALIZA O COMPROVANTE JPG // ================================ $nome_comprovante = "comprovante_{$empr_id}_{$orca_id}_{$num_rev}.jpg"; $caminho_comprovante = $diretorio . '/' . $nome_comprovante; $existeComprovante = file_exists($caminho_comprovante); // ================================ // PREPARA CONTEÚDO DO E-MAIL // ================================ $primeiro_nome = explode(" ", $dados[0]['nome_cliente'])[0] ?? 'Cliente'; $tratamento = "Prezado(a) $primeiro_nome"; $conteudo = utf8_decode("$tratamento,<br><br>"); if($opcao == 'C'){ $conteudo .= utf8_decode("Segue em anexo para sua apreciaçao o orçamento solicitado.<br><br>"); $conteudo .= utf8_decode("Aguardamos seu retorno.<br><br><br><br>"); $conteudo .= utf8_decode("Atenciosamente,<br><br>"); $conteudo .= utf8_decode("<b>Mont Blanc Mármores</b><br>"); $conteudo .= utf8_decode('Vendedor: '.$dados[0]['vendedor']."<br>"); $conteudo .= utf8_decode('Fone: '.$dados[0]['cel']."<br><br>"); }else{ $conteudo .= utf8_decode("<i>Nº do Orçamento: </i><b>$orca_id</b><br>"); $conteudo .= utf8_decode("<i>Revisão: </i><b>$num_rev</b><br>"); $conteudo .= utf8_decode("<i>Data: </i><b>" . date('d/m/Y', strtotime($dados[0]['created'] ?? date('Y-m-d'))) . "</b><br><br>"); $conteudo .= utf8_decode("<b><i>Valor Final </i>$valor_total</b><br><br>"); $conteudo .= "<br><strong>FORMA DE PAGAMENTO</strong><br>"; $conteudo .= "<table border='1' cellspacing='0' cellpadding='5' style='border-collapse:collapse; font-size: 13px;'>"; if($parcelas[0]['tipo_pagto_id'] == 6 ){ $conteudo .= " <tr style='background-color:#f0f0f0; font-weight:bold;'> <td colspan='3'><?php echo utf8_decode($parcelas[0]['nome']); ?></td> <tr style='background-color:#f0f0f0; font-weight:bold;'> <td>Tipo</td> <td>Percentual</td> <td>Valor</td> </tr> "; }else{ $conteudo .= " <tr style='background-color:#f0f0f0; font-weight:bold;'> <td>Parcela</td> <td>Vencimento</td> <td>Valor</td> <td>Tipo Pagamento</td> </tr> "; } // Linhas // var_dump($parcelas); // die; if (!empty($parcelas)) { foreach ($parcelas as $p) { $valorFormatado = number_format((float)$p['valor_parcela'], 2, ',', '.'); if($p['tipo_pagto_id'] <> 6){ $vencimento = ($p['num_parcela'] == 0) ? "Entrada" : $p['vencimento']; if($p['tipo_pagto_id'] == 5 and $p['num_parcela'] == 0){ $p['nome'] = ''; } $conteudo .= " <tr> <td>{$p['num_parcela']}</td> <td>{$vencimento}</td> <td>R$ {$valorFormatado}</td> <td>{$p['nome']}</td> </tr> "; }else{ if($p['nome']== ''){ $p['nome'] = 'Entrada';} $conteudo .= ' <tr> <td>' . utf8_decode($p['nome']) . '</td> <td>' . $p['perc_cronograma'] . '%</td> <td>R$ ' . $valorFormatado . '</td> </tr>'; } } } else { $conteudo .= " <tr> <td colspan='4'>Nenhuma parcela cadastrada.</td> </tr> "; } if($qtde_parcela == 0) { $conteudo .= " <tr> <td colspan='4'>{$dados[0]['forma_pgto']}</td> </tr> "; } $conteudo .= "</table><br><br>"; //$conteudo .= utf8_decode("<i>Nota Fiscal</i>: SIM<br><br>"); $conteudo .= utf8_decode("<i>Comissão Vendedor: </i>").number_format($dados[0]['perc_comis'],2,',','.').'%'; $conteudo .= utf8_decode("<i> Valor: </i>").' R$ '.number_format($dados[0]['vlr_comis'],2,',','.').'<br><br>'; $conteudo .= utf8_decode("<b>Arquitetura</b><br><br>"); $conteudo .= utf8_decode("<i>RT: </i>").number_format($dados[0]['rt'],2,',','.').'% <br><br>'; $conteudo .= utf8_decode("<b>Medição e Cobrança</b><br><br>"); $conteudo .= utf8_decode("<i>Nome: </i>".utf8_decode($dados[0]['contato_obra']) ."<br>"); $conteudo .= utf8_decode("<i>Tel: </i>".utf8_decode($dados[0]['cel_obra']) ."<br>"); $conteudo .= utf8_decode("<i>e-Mail: </i>".utf8_decode($dados[0]['email_obra']) ."<br><br>"); $conteudo .= utf8_decode("<b>Faturamento /Cobrança e Obra: </b><br><br>"); if ($dados[0]['tipo_id'] == 1) { $conteudo .= utf8_decode("<i>Razão Social: </i>".utf8_decode($dados[0]['obra']) ."<br><br>"); $conteudo .= utf8_decode("<i>CNPJ: </i>".utf8_decode($dados[0]['docto']) ."<br><br>"); } else { $conteudo .= utf8_decode("<i>Nome: </i>".utf8_decode($dados[0]['obra']) ."<br><br>"); $conteudo .= utf8_decode("<i>CPF: </i>".utf8_decode($dados[0]['docto']) ."<br><br>"); } $conteudo .= utf8_decode("Por favor emitir Contrato com os dados abaixo :.<br><br>"); if ($dados[0]['complemento'] == '') { $endereco = $dados[0]['endereco_obra'] . ', ' . $dados[0]['numero_obra'] . ', ' . $dados[0]['bairro'] . ', ' . $dados[0]['municipio_obra'] . '/' . $dados[0]['uf_obra'].' cep '.$dados[0]['cep']; } else { $endereco = $dados[0]['endereco_obra'] . ', ' . $dados[0]['numero_obra'] . ', ' . $dados[0]['complemento'] . ', ' . $dados[0]['bairro'] . ', ' . $dados[0]['municipio_obra'] . '/' . $dados[0]['uf_obra'].' cep '.$dados[0]['cep']; } $conteudo .= utf8_decode("<i>Endereço da Obra: </i>" . $endereco . "<br><br>"); // Endereço de cobrança $conteudo .= utf8_decode("<i>Endereço de Cobrança: </i>" . $endereco . "<br><br><br>"); $conteudo .= utf8_decode("Atenciosamente,<br><br>"); $conteudo .= utf8_decode($dados[0]['vendedor'] . "<br>"); $conteudo .= utf8_decode($dados[0]['cel'] . "<br>"); $conteudo .= utf8_decode("Departamento Comercial<br>"); } // Endereço da obra // ================================ // ENVIO DO E-MAIL COM PHPMailer // ================================ require_once $_SERVER['DOCUMENT_ROOT'].'/crsys/adm/vendor/phpmailer/phpmailer/src/Exception.php'; require_once $_SERVER['DOCUMENT_ROOT'].'/crsys/adm/vendor/phpmailer/phpmailer/src/PHPMailer.php'; require_once $_SERVER['DOCUMENT_ROOT'].'/crsys/adm/vendor/phpmailer/phpmailer/src/SMTP.php'; try { $mail = new \PHPMailer\PHPMailer\PHPMailer(true); $mail->isSMTP(); $mail->Host = $dadosEmail['host']; $mail->SMTPAuth = true; $mail->Username = $dadosEmail['usuario']; $mail->Password = $dadosEmail['senha']; $mail->SMTPSecure = $dadosEmail['smtpsecure']; $mail->Port = $dadosEmail['porta']; $mail->setFrom('noreply@crsys.com.br', 'Departamento Comercial'); //$mail->addAddress($dados[0]['email_obra'] ?? '', $primeiro_nome); if($opcao == 'C'){ $mail->addAddress('crmarques1402@gmail.com' ?? '', 'Carlos Gmail'); }else{ $mail->addAddress('crmarques@uol.com.br' ?? '', 'Carlos Marques'); } if (!empty($dados[0]['email_vend'])) { $mail->addBCC($dados[0]['email_vend'], $dados[0]['vendedor']); } // Anexa o PDF $mail->addAttachment($caminho_completo); // Anexa o COMPROVANTE JPG se existir if ($existeComprovante) { $mail->addAttachment($caminho_comprovante); } $mail->isHTML(true); if($opcao == 'C'){ $mail->Subject = utf8_decode("ORÇAMENTO Nº {$orca_id}/{$num_revisao} - Obra: {$dados[0]['obra']}"); }else{ $mail->Subject = utf8_decode("PEDIDO EMITIDO - ORÇAMENTO Nº {$orca_id}/{$num_revisao} - Obra {$dados[0]['obra']}"); } $mail->Body = $conteudo; $mail->AltBody = strip_tags($conteudo); $mail->send(); // ================================ // ATUALIZA STATUS DO ORÇAMENTO // ================================ $sqlUpdate = "UPDATE gre_cab_orcamento SET status_id = :status_id WHERE orca_id = :id and num_revisao = :num_revisao "; $stmtUpdate = $pdo->prepare($sqlUpdate); $stmtUpdate->execute([ ':status_id' => 2, // <-- aqui você coloca o status desejado ':id' => $orca_id, ':num_revisao' => $num_revisao ]); echo " <script> window.opener.postMessage( { status: 'ok', mensagem: 'Email do Orçamento enviado com sucesso!' }, '*' ); window.close(); </script>"; exit; } catch (\PHPMailer\PHPMailer\Exception $e) { echo " <script> window.opener.postMessage( { status: 'erro', mensagem: 'Erro ao enviar e-mail: ". addslashes($mail->ErrorInfo) ."' }, '*' ); window.close(); </script>"; exit; } }