<?php
namespace App\Utils;
use App\Entity\Cabecera;
class Xml
{
/**
* Genera un archivo XML basado en los datos de una cabecera y otros parámetros.
*
* Esta función toma una instancia de Cabecera y otros datos relevantes para
* construir un archivo XML estructurado. El XML generado incluye información
* detallada de la cabecera y puede ser utilizado para diversas finalidades,
* como la exportación de datos o la generación de informes.
*
* @param Cabecera $cab Instancia de la clase Cabecera con los datos del documento.
* @param array $datetime Array asociativo que contiene las claves 'fecha' y 'hora'.
* @param int $numlineas Número total de líneas o elementos a incluir en el XML.
* @param string $filename Nombre del archivo que se generará (sin extensión .xml).
* @return string Una cadena de texto que representa el contenido del archivo XML.
*/
public function generarXml(Cabecera $cab, array $datetime, int $numlineas, string $filename)
{
$cabecera = $this->addCabecera($cab, $datetime, $filename);
$cabeceraLineas = $this->addCabeceraLineas($numlineas, $filename);
$lineas = $this->addLineas($cab->getLineas());
$totales = $this->addTotales($cab);
$propina = $cab->getPropinatotal() ?? 0;
if ($propina > 0) {
$addPropina = $this->addPropina($cab);
} else {
$addPropina = '';
}
return <<<XML
<?xml version="1.0"?>
<minuta>
<cabecera>
$cabecera
</cabecera>
<lineas>
$cabeceraLineas
$lineas$addPropina
</lineas>
$totales
</minuta>
XML;
}
/**
* Genera la cabecera del xml
*/
private function addCabecera($cab, $datetime, $filename)
{
// $nombrecliente = $this->TildesHtml($cab->getNombrecliente());
// $direccioncliente = $this->TildesHtml($cab->getDireccioncliente()) . ' ' . $this->TildesHtml($cab->getDireccion2cliente());
// $observaciones = $this->TildesHtml($cab->getComentario());
// $fecha = $datetime['fecha'];
// $hora = $datetime['hora'];
$cabeceraData = $this->cabeceraData($cab, $datetime, $filename);
$datosdeenvio = $this->addDatosdeenvio($cab);
if (isset($cabeceraData['coddireccionenvio'])) {
$coddireccionEnvio = "<coddireccionenvio>{$cabeceraData['coddireccionenvio']}</coddireccionenvio>";
} else {
$coddireccionEnvio = '';
}
// $tipodeservicio = '';
// if ($cab->getTipodeservicio() == 16) {
// $fechareserva = $cab->getFechareserva()->format('dmY');
// $horareserva = $cab->getFechareserva()->format('His');
// $tipodeservicio .= "<fechareserva>{$fechareserva}</fechareserva>
// <horareserva>{$horareserva}</horareserva>";
// } else {
// $tipodeservicio .= "<fechareserva></fechareserva>
// <horareserva></horareserva>";
// }
// <aliascliente>{$cabeceraData['aliascliente']}</aliascliente>
return <<<CABECERA
<codvendedor>{$cabeceraData['codvendedor']}</codvendedor>
<tiposervicio>{$cabeceraData['tiposervicio']}</tiposervicio>
<fechaminuta>{$cabeceraData['fechaminuta']}</fechaminuta>
<horaminuta>{$cabeceraData['horaminuta']}</horaminuta>
<codcliente>{$cabeceraData['codcliente']}</codcliente>
<tipoidentcliente>{$cabeceraData['tipoidentcliente']}</tipoidentcliente>
<nifcliente>{$cabeceraData['nifcliente']}</nifcliente>
<nombre1cliente>{$cabeceraData['nombre1cliente']}</nombre1cliente>
<apellido1cliente>{$cabeceraData['apellido1cliente']}</apellido1cliente>
<nombrecliente>{$cabeceraData['nombrecliente']}</nombrecliente>
<direccioncliente>{$cabeceraData['direccioncliente']}</direccioncliente>
<direccionfiscalcliente>{$cabeceraData['direccionfiscalcliente']}</direccionfiscalcliente>
$coddireccionEnvio
<paiscliente>{$cabeceraData['paiscliente']}</paiscliente>
<movilcliente>{$cabeceraData['movilcliente']}</movilcliente>
<telefonocliente>{$cabeceraData['movilcliente']}</telefonocliente>
<emailcliente>{$cabeceraData['emailcliente']}</emailcliente>
<codmonedaminuta>1</codmonedaminuta>
<tipopersonacliente>{$cabeceraData['tipopersonacliente']}</tipopersonacliente>
<responsabilidadescliente>{$cabeceraData['responsabilidadescliente']}</responsabilidadescliente>
<detalletributariocliente>{$cabeceraData['detalletributariocliente']}</detalletributariocliente>
<fechareserva>{$cabeceraData['fechareserva']}</fechareserva>
<horareserva>{$cabeceraData['horareserva']}</horareserva>
<ivaincluido>{$cabeceraData['ivaincluido']}</ivaincluido>
<referenciapedido>{$cabeceraData['referenciapedido']}</referenciapedido>
<comensales>1</comensales>
$datosdeenvio
CABECERA;
}
/**
*
*/
private function cabeceraData($cab, $datetime, $filename)
{
$direccionEnvio = $this->TildesHtml($cab->getDireccioncliente()) . ', ' . $this->TildesHtml($cab->getDireccion2cliente());
$fechareserva = $cab->getFechareserva() ? $cab->getFechareserva()->format('dmY') : '';
$horareserva = $cab->getFechareserva() ? $cab->getFechareserva()->format('His') : '';
$data = [
'codcliente' => $cab->getCodcliente(),
'nifcliente' => $cab->getNifcliente(),
'nombre1cliente' => $this->TildesHtml($cab->getNombres()),
'apellido1cliente' => $this->TildesHtml($cab->getApellidos()),
'nombrecliente' => $this->TildesHtml($cab->getNombreCliente()),
'direccioncliente' => $direccionEnvio,
// 'direccionfiscalcliente' => $direccionEnvio,
'direccionfiscalcliente' => $this->TildesHtml($cab->getDireccioncliente()),
'movilcliente' => $cab->getMovilcliente() ?? $cab->getTelefonocliente(),
'telefonocliente' => $cab->getMovilcliente() ?? $cab->getTelefonocliente(),
'emailcliente' => $cab->getEmailcliente(),
'responsabilidadescliente' => $cab->getFeResponsabilidades(),
'detalletributariocliente' => $cab->getFeDetTributario(),
];
if ($cab->getFacturaelectronica()) {
if ($cab->getTipopersona() === '2 Persona Natural') {
$data['tipoidentcliente'] = '13 Cedula de Ciudadania';
$data['tipopersonacliente'] = '2 Persona Natural';
$data['detalletributariocliente'] = 'ZZ Otros tributos';
$data['responsabilidadescliente'] = 'R-99-PN';
} else {
$data['nombre1cliente'] = $this->TildesHtml($cab->getNombreCliente());
$data['apellido1cliente'] = '.';
$data['tipoidentcliente'] = '31 NIT';
$data['tipopersonacliente'] = '1 Persona Juridica';
$data['detalletributariocliente'] = '01 IVA';
$data['responsabilidadescliente'] = 'R-99-PN';
}
$data['aliascliente'] = 1;
$data['coddireccionenvio'] = 2;
} else {
$data = [
'codcliente' => 11984,
'tipoidentcliente' => '13 Cedula de Ciudadania',
'nifcliente' => 222222222222,
'nombre1cliente' => $this->TildesHtml($cab->getNombres()),
'apellido1cliente' => $this->TildesHtml($cab->getApellidos()),
'nombrecliente' => 'CONSUMIDOR FINAL',
'direccioncliente' => 'CARRERA 43A 25A85',
// 'direccionfiscalcliente' => $direccionEnvio,
'direccionfiscalcliente' => $this->TildesHtml($cab->getDireccioncliente()),
'coddireccionenvio' => '2',
'aliascliente' => 0,
'movilcliente' => 6043496810,
'telefonocliente' => 6043496810,
'emailcliente' => 'clientes.fe.medellin@crepesywaffles.com',
'tipopersonacliente' => '2 Persona Natural',
'responsabilidadescliente' => 'R-99-PN',
'detalletributariocliente' => 'ZZ Otros tributos',
];
}
// Otros datos
$otraData = [
'codvendedor' => $cab->getUser()->getCodvendedor(),
// 'aliascliente' => 1,
'tiposervicio' => $cab->getTipodeservicio(),
'fechaminuta' => $datetime['fecha'],
'horaminuta' => $datetime['hora'],
'paiscliente' => 'CO',
'codmonedaminuta' => 1,
'fechareserva' => $fechareserva,
'horareserva' => $horareserva,
'ivaincluido' => 1,
'observacionescliente' => $this->TildesHtml($cab->getComentario()),
'referenciapedido' => 'Callcenter ' . $filename,
'comensales' => 1,
];
return array_merge($data, $otraData);
}
/**
* Genera los datos de envío
*/
private function addDatosdeenvio($cab)
{
$resultado = '<observacionescliente>';
$resultado .= $this->TildesHtml($cab->getDireccion2cliente());
if (!empty($cab->getNombreReceptor())) {
$resultado .= $this->TildesHtml('|Recibe:' . $cab->getNombreReceptor() . '|');
}
if (!empty($cab->getTelefonoReceptor())) {
$resultado .= $this->TildesHtml($cab->getTelefonoReceptor());
}
// if (!empty($cab->getObservacionesReceptor())) {
// $resultado .= $this->TildesHtml($cab->getObservacionesReceptor());
// }
return $resultado . "</observacionescliente>";
}
/**
* Genera la cabecera de las líneas
*
*/
private function addCabeceraLineas($numlineas, $filename)
{
return <<<CABECERA_LINEAS
<numlineas>{$numlineas}</numlineas>
<linea>
<codarticulo>1799</codarticulo>
<descripcion>Callcenter {$filename}</descripcion>
<codformato>0</codformato>
<hora/>
<unidades>1</unidades>
<precio>0</precio>
<precioiva>0</precioiva>
<codimpuesto>5</codimpuesto>
<esmenu>0</esmenu>
<dto>0</dto>
<esmodif>0</esmodif>
<numlineasmodif>0</numlineasmodif>
</linea>
CABECERA_LINEAS;
}
/**
* Genera de la línea parent
*
* @param Linea $cab Instancia de la clase Linea.
*/
private function addLineaParent($linea)
{
$descripcion = $this->TildesHtml($linea->getDescripcion());
$numlineasmodif = $linea->getNumlineasmodif() ?? 0;
$esmodif = $numlineasmodif === 0 ? 0 : 1;
$precio = $linea->getPreciototal() / $linea->getUnidades();
// <precioiva>{$linea->getPreciototal()}</precioiva>
return <<<LINEA_PARENT
<codarticulo>{$linea->getCodarticulo()}</codarticulo>
<descripcion>{$descripcion}</descripcion>
<codFavorito>{$linea->getCodFavoritos()}</codFavorito>
<hora/>
<unidades>{$linea->getUnidades()}</unidades>
<precio>0</precio>
<precioiva>{$precio}</precioiva>
<codimpuesto>{$linea->getCodImpuesto()}</codimpuesto>
<servido>0</servido>
<impreso>0</impreso>
<esmodif>{$esmodif}</esmodif>
<numlineasmodif>{$numlineasmodif}</numlineasmodif>
<dto>0</dto>
LINEA_PARENT;
}
/**
* Genera la línea child
*
*/
private function addLineaChild($linea)
{
$incprecio = $linea->getPrecio() / $linea->getUnidades();
$descripcion = $this->TildesHtml($linea->getDescripcion());
return <<<LINEA_CHILD
<lineamodif>
<esarticulo>1</esarticulo>
<codFavorito></codFavorito>
<codarticulo>{$linea->getCodarticulo()}</codarticulo>
<descripcion>{$descripcion}</descripcion>
<division></division>
<anulado></anulado>
<incprecio>{$incprecio}</incprecio>
</lineamodif>
LINEA_CHILD;
}
/**
* Genera la estructura de las líneas
*
*/
private function addlineas($lineas)
{
$xmlLineas = "";
foreach ($lineas as $linea) {
// Es padre
if ($linea->getParent() == null) {
$n = 0;
$nm = $linea->getNumlineasmodif();
$parent = $this->addLineaParent($linea);
$xmlLineas .= " <linea>\n$parent" . PHP_EOL;
if ($nm > 0) {
$xmlLineas .= " <lineasmodif>" . PHP_EOL;
} else {
$xmlLineas .= " </linea>" . PHP_EOL; // Cerrar línea si no hay hijos
}
}
// Es hijo
if ($linea->getParent() != null) {
$n++;
$child = $this->addLineaChild($linea);
$xmlLineas .= $child . PHP_EOL;
if ($n === $nm) {
$xmlLineas .= " </lineasmodif>\n </linea>" . PHP_EOL; // Cerrar línea y lineasmodif
$n = 0; // Resetear para el próximo padre
}
}
}
return $xmlLineas;
}
/**
* Genera la línea de la propina
*/
private function addPropina($cab)
{
return <<<PROPINA
<linea>
<codarticulo>1964</codarticulo>
<descripcion>APORTE VOLUNTARIO</descripcion>
<codformato>0</codformato>
<hora/>
<unidades>1</unidades>
<precio>0</precio>
<precioiva>{$cab->getPropinatotal()}</precioiva>
<codimpuesto>5</codimpuesto>
<esmenu>0</esmenu>
<dto>0</dto>
<esmodif>0</esmodif>
<numlineasmodif>0</numlineasmodif>
</linea>
PROPINA;
}
/**
*
* Genera los totales
*/
private function addTotales($cab)
{
$propina = $cab->getPropinatotal() ?? 0;
$totalneto = $cab->getTotal() + $propina;
return <<<TOTALES
<totales>
<totalneto>{$totalneto}</totalneto>
</totales>
<formasdepago>
<numformasdepago>1</numformasdepago>
<linea>
<codformapago>{$cab->getMetododepago()}</codformapago>
<codmonedaformapago>1</codmonedaformapago>
<importeformapago>{$totalneto}</importeformapago>
</linea>
</formasdepago>
TOTALES;
}
/**
* Convierte las tildes de un texto a sus entidades HTML.
*
* @param string $cadena Cadena a modificar.
* @return string Cadena de texto con codigos html.
*/
public static function TildesHtml($cadena)
{
// return str_replace(array("á","é","í","ó","ú","ñ","Á","É","Í","Ó","Ú","Ñ","<",">","&"),
// array("á","é","í","ó","ú","ñ",
// "Á","É","Í","Ó","Ú","Ñ",
// "<",">","&"),
// $cadena);
return str_replace(
array("á", "é", "í", "ó", "ú", "ñ", "Á", "É", "Í", "Ó", "Ú", "Ñ", "<", ">", "&"),
array(
"a", "e", "i;", "o", "u", "n",
"A", "E", "I", "O", "U", "N",
"<", ">", "&"
),
$cadena
);
}
}