/**
  * Acción para generar y mostrar previsualización de emisión de DTE
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
  * @version 2016-01-02
  */
 public function previsualizacion()
 {
     $Emisor = $this->getContribuyente();
     // si no se viene por POST redirigir
     if (!isset($_POST['submit'])) {
         \sowerphp\core\Model_Datasource_Session::message('No puede acceder de forma directa a la previsualización', 'error');
         $this->redirect('/dte/documentos/emitir');
     }
     // si no está autorizado a emitir el tipo de documento redirigir
     if (!$Emisor->documentoAutorizado($_POST['TpoDoc'])) {
         \sowerphp\core\Model_Datasource_Session::message('No está autorizado a emitir el tipo de documento ' . $_POST['TpoDoc'], 'error');
         $this->redirect('/dte/documentos/emitir');
     }
     // revisar datos mínimos
     $datos_minimos = ['TpoDoc', 'FchEmis', 'GiroEmis', 'Acteco', 'DirOrigen', 'CmnaOrigen', 'RUTRecep', 'RznSocRecep', 'GiroRecep', 'DirRecep', 'CmnaRecep', 'NmbItem'];
     foreach ($datos_minimos as $attr) {
         if (empty($_POST[$attr])) {
             \sowerphp\core\Model_Datasource_Session::message('Error al recibir campos mínimos, falta: ' . $attr);
             $this->redirect('/dte/documentos/emitir');
         }
     }
     // copiar datos del emisor
     $Emisor->giro = $_POST['GiroEmis'];
     $Emisor->actividad_economica = $_POST['Acteco'];
     $Emisor->direccion = $_POST['DirOrigen'];
     $Emisor->comuna = $_POST['CmnaOrigen'];
     // crear receptor
     list($rut, $dv) = explode('-', str_replace('.', '', $_POST['RUTRecep']));
     $Receptor = new Model_Contribuyente($rut);
     $Receptor->dv = $dv;
     $Receptor->razon_social = $_POST['RznSocRecep'];
     $Receptor->giro = substr($_POST['GiroRecep'], 0, 40);
     $Receptor->telefono = $_POST['Contacto'];
     $Receptor->email = $_POST['CorreoRecep'];
     $Receptor->direccion = $_POST['DirRecep'];
     $Receptor->comuna = $_POST['CmnaRecep'];
     // guardar receptor si no tiene usuario asociado
     if (!$Receptor->usuario) {
         $Receptor->modificado = date('Y-m-d H:i:s');
         try {
             $Receptor->save();
         } catch (\sowerphp\core\Exception_Model_Datasource_Database $e) {
             \sowerphp\core\Model_Datasource_Session::message('No fue posible guardar el receptor: ' . $e->getMessage());
             $this->redirect('/dte/documentos/emitir');
         }
     }
     // generar datos del encabezado para el dte
     $dte = ['Encabezado' => ['IdDoc' => ['TipoDTE' => $_POST['TpoDoc'], 'Folio' => 0, 'FchEmis' => $_POST['FchEmis']], 'Emisor' => ['RUTEmisor' => $Emisor->rut . '-' . $Emisor->dv, 'RznSoc' => $Emisor->razon_social, 'GiroEmis' => $Emisor->giro, 'Telefono' => $Emisor->telefono ? $Emisor->telefono : false, 'CorreoEmisor' => $Emisor->email ? $Emisor->email : false, 'Acteco' => $Emisor->actividad_economica, 'CdgSIISucur' => $Emisor->sucursal_sii ? $Emisor->sucursal_sii : false, 'DirOrigen' => $Emisor->direccion, 'CmnaOrigen' => $Emisor->getComuna()->comuna], 'Receptor' => ['RUTRecep' => $Receptor->rut . '-' . $Receptor->dv, 'RznSocRecep' => $Receptor->razon_social, 'GiroRecep' => $Receptor->giro, 'Contacto' => $Receptor->telefono ? $Receptor->telefono : false, 'CorreoRecep' => $Receptor->email ? $Receptor->email : false, 'DirRecep' => $Receptor->direccion, 'CmnaRecep' => $Receptor->getComuna()->comuna]]];
     // agregar datos de traslado si es guía de despacho
     if ($dte['Encabezado']['IdDoc']['TipoDTE'] == 52) {
         $dte['Encabezado']['IdDoc']['IndTraslado'] = $_POST['IndTraslado'];
         if (!empty($_POST['Patente']) or !empty($_POST['RUTTrans']) or !empty($_POST['RUTChofer']) and !empty($_POST['NombreChofer']) or !empty($_POST['DirDest']) or !empty($_POST['CmnaDest'])) {
             $dte['Encabezado']['Transporte'] = ['Patente' => !empty($_POST['Patente']) ? $_POST['Patente'] : false, 'RUTTrans' => !empty($_POST['RUTTrans']) ? str_replace('.', '', $_POST['RUTTrans']) : false, 'Chofer' => (!empty($_POST['RUTChofer']) and !empty($_POST['NombreChofer'])) ? ['RUTChofer' => str_replace('.', '', $_POST['RUTChofer']), 'NombreChofer' => $_POST['NombreChofer']] : false, 'DirDest' => !empty($_POST['DirDest']) ? $_POST['DirDest'] : false, 'CmnaDest' => !empty($_POST['CmnaDest']) ? (new \sowerphp\app\Sistema\General\DivisionGeopolitica\Model_Comuna($_POST['CmnaDest']))->comuna : false];
         }
     }
     // agregar detalle a los datos
     $n_detalles = count($_POST['NmbItem']);
     $dte['Detalle'] = [];
     $n_itemAfecto = 0;
     $n_itemExento = 0;
     for ($i = 0; $i < $n_detalles; $i++) {
         $detalle = [];
         // código del item
         if (!empty($_POST['VlrCodigo'][$i])) {
             $detalle['CdgItem'] = ['TpoCodigo' => !empty($_POST['TpoCodigo'][$i]) ? $_POST['TpoCodigo'][$i] : 'INT1', 'VlrCodigo' => $_POST['VlrCodigo'][$i]];
         }
         // otros datos
         $datos = ['IndExe', 'NmbItem', 'DscItem', 'QtyItem', 'UnmdItem', 'PrcItem'];
         foreach ($datos as $d) {
             if (!empty($_POST[$d][$i])) {
                 $detalle[$d] = $_POST[$d][$i];
             }
         }
         // descuento
         if (!empty($_POST['ValorDR'][$i]) and !empty($_POST['TpoValor'][$i])) {
             if ($_POST['TpoValor'][$i] == '%') {
                 $detalle['DescuentoPct'] = $_POST['ValorDR'][$i];
             } else {
                 $detalle['DescuentoMonto'] = $_POST['ValorDR'][$i];
             }
         }
         // agregar detalle al listado
         $dte['Detalle'][] = $detalle;
         // contabilizar item afecto o exento
         if (empty($detalle['IndExe'])) {
             $n_itemAfecto++;
         } else {
             $n_itemExento++;
         }
     }
     // agregar descuento globales
     if (!empty($_POST['ValorDR_global']) and !empty($_POST['TpoValor_global'])) {
         $dte['DscRcgGlobal'] = [];
         if ($n_itemAfecto) {
             $dte['DscRcgGlobal'][] = ['TpoMov' => 'D', 'TpoValor' => $_POST['TpoValor_global'], 'ValorDR' => $_POST['ValorDR_global']];
         }
         if ($n_itemExento) {
             $dte['DscRcgGlobal'][] = ['TpoMov' => 'D', 'TpoValor' => $_POST['TpoValor_global'], 'ValorDR' => $_POST['ValorDR_global'], 'IndExeDR' => 1];
         }
     }
     // agregar referencias
     if (isset($_POST['TpoDocRef'][0])) {
         $n_referencias = count($_POST['TpoDocRef']);
         $dte['Referencia'] = [];
         for ($i = 0; $i < $n_referencias; $i++) {
             $dte['Referencia'][] = ['TpoDocRef' => $_POST['TpoDocRef'][$i], 'FolioRef' => $_POST['FolioRef'][$i], 'FchRef' => $_POST['FchRef'][$i], 'CodRef' => !empty($_POST['CodRef'][$i]) ? $_POST['CodRef'][$i] : false, 'RazonRef' => !empty($_POST['RazonRef'][$i]) ? $_POST['RazonRef'][$i] : false];
         }
     }
     // crear objeto Dte y asignar variables para la vista
     $Dte = new \sasco\LibreDTE\Sii\Dte($dte);
     $resumen = $Dte->getResumen();
     $DteTmp = new Model_DteTmp();
     $DteTmp->datos = json_encode($Dte->getDatos());
     $DteTmp->emisor = $Emisor->rut;
     $DteTmp->receptor = $Receptor->rut;
     $DteTmp->dte = $resumen['TpoDoc'];
     $DteTmp->codigo = md5($DteTmp->datos);
     $DteTmp->fecha = $resumen['FchDoc'];
     $DteTmp->total = $resumen['MntTotal'];
     try {
         $DteTmp->save();
     } catch (\sowerphp\core\Exception_Model_Datasource_Database $e) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible guardar el DTE temporal: ' . $e->getMessage());
         $this->redirect('/dte/documentos/emitir');
     }
     $this->set(['resumen' => $resumen, 'DteTmp' => $DteTmp]);
 }