/**
  * Acción que actualiza el estado del envío del DTE
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-09-30
  */
 public function actualizar_estado($dte, $folio)
 {
     $Emisor = $this->getContribuyente();
     // obtener DTE emitido
     $DteEmitido = new Model_DteEmitido($Emisor->rut, $dte, $folio, (int) $Emisor->certificacion);
     if (!$DteEmitido->exists()) {
         \sowerphp\core\Model_Datasource_Session::message('No existe el DTE solicitado', 'error');
         $this->redirect('/dte/dte_emitidos/listar');
     }
     // si no tiene track id error
     if (!$DteEmitido->track_id) {
         \sowerphp\core\Model_Datasource_Session::message('DTE no tiene Track ID, primero debe enviarlo al SII', 'error');
         $this->redirect(str_replace('actualizar_estado', 'ver', $this->request->request));
     }
     // buscar correo con respuesta
     $Imap = $Emisor->getEmailImap('sii');
     if (!$Imap) {
         \sowerphp\core\Model_Datasource_Session::message('No fue posible conectar mediante IMAP a ' . $Emisor->sii_imap . ', verificar mailbox, usuario y/o contraseña de contacto SII:<br/>' . implode('<br/>', imap_errors()), 'error');
         $this->redirect(str_replace('actualizar_estado', 'ver', $this->request->request));
     }
     $asunto = 'Resultado de Revision Envio ' . $DteEmitido->track_id . ' - ' . $Emisor->rut . '-' . $Emisor->dv;
     $uids = $Imap->search('FROM @sii.cl SUBJECT "' . $asunto . '" UNSEEN');
     if (!$uids) {
         \sowerphp\core\Model_Datasource_Session::message('No se encontró respuesta de envío del DTE, espere unos segundos o solicite nueva revisión.');
         $this->redirect(str_replace('actualizar_estado', 'ver', $this->request->request));
     }
     // procesar emails recibidos
     foreach ($uids as $uid) {
         $estado = $detalle = null;
         $m = $Imap->getMessage($uid);
         if (!$m) {
             continue;
         }
         foreach ($m['attachments'] as $file) {
             if ($file['type'] != 'application/xml') {
                 continue;
             }
             $xml = new \SimpleXMLElement($file['data'], LIBXML_COMPACT);
             // obtener estado y detalle
             if (isset($xml->REVISIONENVIO)) {
                 if ($xml->REVISIONENVIO->REVISIONDTE->TIPODTE == $DteEmitido->dte and $xml->REVISIONENVIO->REVISIONDTE->FOLIO == $DteEmitido->folio) {
                     $estado = (string) $xml->REVISIONENVIO->REVISIONDTE->ESTADO;
                     $detalle = (string) $xml->REVISIONENVIO->REVISIONDTE->DETALLE;
                 }
             } else {
                 $estado = (string) $xml->IDENTIFICACION->ESTADO;
                 $detalle = (int) $xml->ESTADISTICA->SUBTOTAL->ACEPTA ? 'DTE aceptado' : 'DTE no aceptado';
             }
         }
         if (isset($estado)) {
             $DteEmitido->revision_estado = $estado;
             $DteEmitido->revision_detalle = $detalle;
             try {
                 $DteEmitido->save();
                 \sowerphp\core\Model_Datasource_Session::message('Se actualizó el estado del DTE', 'ok');
             } catch (\sowerphp\core\Exception_Model_Datasource_Database $e) {
                 \sowerphp\core\Model_Datasource_Session::message('El estado se obtuvo pero no fue posible guardarlo en la base de datos<br/>' . $e->getMessage(), 'error');
             }
             // marcar email como leído
             $Imap->setSeen($uid);
         }
     }
     // redireccionar
     $this->redirect(str_replace('actualizar_estado', 'ver', $this->request->request));
 }
Ejemplo n.º 2
0
 /**
  * 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);
 }