/**
  * Método que elimina un DTE temporal
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
  * @version 2015-09-23
  */
 public function eliminar($receptor, $dte, $codigo)
 {
     $Emisor = $this->getContribuyente();
     // obtener DTE temporal
     $DteTmp = new Model_DteTmp($Emisor->rut, $receptor, $dte, $codigo);
     if (!$DteTmp->exists()) {
         \sowerphp\core\Model_Datasource_Session::message('No existe el DTE temporal solicitado', 'error');
         $this->redirect('/dte/dte_tmps');
     }
     // eliminar
     try {
         $DteTmp->delete();
         \sowerphp\core\Model_Datasource_Session::message('DTE temporal eliminado', 'ok');
         $this->redirect('/dte/dte_tmps');
     } catch (\sowerphp\core\Exception_Model_Datasource_Database $e) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible eliminar el DTE temporal: ' . $e->getMessage());
         $this->redirect('/dte/dte_tmps');
     }
 }
 /**
  * Método que genera la el XML del DTE temporal con Folio y Firma y lo envía
  * al SII
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
  * @version 2016-01-02
  */
 public function generar($receptor, $dte, $codigo)
 {
     $Emisor = $this->getContribuyente();
     // obtener DTE temporal
     $DteTmp = new Model_DteTmp($Emisor->rut, $receptor, $dte, $codigo);
     if (!$DteTmp->exists()) {
         \sowerphp\core\Model_Datasource_Session::message('No existe el DTE temporal solicitado', 'error');
         $this->redirect('/dte/documentos/emitir');
     }
     // obtener firma electrónica
     $Firma = $Emisor->getFirma($this->Auth->User->id);
     if (!$Firma) {
         \sowerphp\core\Model_Datasource_Session::message('No hay firma electrónica asociada a la empresa (o bien no se pudo cargar), debe agregar su firma antes de generar DTE', 'error');
         $this->redirect('/dte/admin/firma_electronicas');
     }
     // solicitar folio
     $FolioInfo = $Emisor->getFolio($DteTmp->dte);
     if (!$FolioInfo) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible obtener un folio para el DTE de tipo ' . $DteTmp->dte, 'error');
         $this->redirect('/dte/dte_tmps');
     }
     // si quedan pocos folios y se debe alertar al usuario admnistrador de la empresa se hace
     if ($FolioInfo->DteFolio->disponibles <= $FolioInfo->DteFolio->alerta and !$FolioInfo->DteFolio->alertado) {
         $msg = 'Se ha alcanzado el límite de folios del tipo de DTE ' . $FolioInfo->DteFolio->dte . ' para el contribuyente ' . $Emisor->razon_social . ', quedan ' . $FolioInfo->DteFolio->disponibles . '. Por favor, solicite un nuevo archivo CAF y súbalo en: ' . "\n\n" . $this->request->url . '/dte/admin/dte_folios';
         if ($this->Notify->send(null, $Emisor->getUsuario()->id, $msg, 'email')) {
             $FolioInfo->DteFolio->alertado = 1;
             $FolioInfo->DteFolio->save();
         }
     }
     // armar xml a partir de json del DTE temporal
     $EnvioDte = $DteTmp->getEnvioDte($FolioInfo->folio, $FolioInfo->Caf, $Firma);
     $xml = $EnvioDte->generar();
     if (!$xml) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible generar el XML del EnvioDTE. Folio ' . $FolioInfo->folio . ' quedará sin usar.<br/>' . implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'error');
         $this->redirect('/dte/documentos/emitir');
     }
     // guardar DTE
     $r = $EnvioDte->getDocumentos()[0]->getResumen();
     $DteEmitido = new Model_DteEmitido($Emisor->rut, $r['TpoDoc'], $r['NroDoc'], (int) $Emisor->certificacion);
     if ($DteEmitido->exists()) {
         \sowerphp\core\Model_Datasource_Session::message('Ya existe un DTE del tipo ' . $r['TpoDoc'] . ' y folio ' . $r['NroDoc'] . ' emitido', 'error');
         $this->redirect('/dte/dte_emitidos/ver/' . $r['TpoDoc'] . '/' . $r['NroDoc'] . '/' . (int) $Emisor->certificacion);
     }
     $cols = ['tasa' => 'TasaImp', 'fecha' => 'FchDoc', 'sucursal_sii' => 'CdgSIISucur', 'receptor' => 'RUTDoc', 'exento' => 'MntExe', 'neto' => 'MntNeto', 'iva' => 'MntIVA', 'total' => 'MntTotal'];
     foreach ($cols as $attr => $col) {
         if ($r[$col] !== false) {
             $DteEmitido->{$attr} = $r[$col];
         }
     }
     $DteEmitido->receptor = substr($DteEmitido->receptor, 0, -2);
     $DteEmitido->xml = base64_encode($xml);
     $DteEmitido->usuario = $this->Auth->User->id;
     // guardar referencias si existen
     $datos = json_decode($DteTmp->datos, true);
     if (isset($datos['Referencia'])) {
         foreach ($datos['Referencia'] as $referencia) {
             $DteReferencia = new Model_DteReferencia();
             $DteReferencia->emisor = $DteEmitido->emisor;
             $DteReferencia->dte = $DteEmitido->dte;
             $DteReferencia->folio = $DteEmitido->folio;
             $DteReferencia->certificacion = $DteEmitido->certificacion;
             $DteReferencia->referencia_dte = $referencia['TpoDocRef'];
             $DteReferencia->referencia_folio = $referencia['FolioRef'];
             $DteReferencia->codigo = !empty($referencia['CodRef']) ? $referencia['CodRef'] : null;
             $DteReferencia->razon = !empty($referencia['RazonRef']) ? $referencia['RazonRef'] : null;
             $DteReferencia->save();
         }
     }
     // eliminar DTE temporal
     $DteTmp->delete();
     // enviar DTE al SII y redireccionar a página del DTE
     $track_id = $EnvioDte->enviar();
     if ($track_id) {
         $DteEmitido->track_id = $track_id;
         \sowerphp\core\Model_Datasource_Session::message('Documento emitido y envíado al SII, ahora debe verificar estado del envío. TrackID: ' . $track_id, 'ok');
     } else {
         \sowerphp\core\Model_Datasource_Session::message('Documento emitido, pero no pudo ser envíado al SII, debe reenviar.<br/>' . implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'warning');
     }
     $DteEmitido->save();
     $this->redirect('/dte/dte_emitidos/ver/' . $r['TpoDoc'] . '/' . $r['NroDoc'] . '/' . (int) $Emisor->certificacion);
 }