Пример #1
0
 /**
  * Acción que permite subir un caf para un tipo de folio
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-09-22
  */
 public function subir_caf()
 {
     $Emisor = $this->getContribuyente();
     $this->set(['Emisor' => $Emisor]);
     // procesar solo si se envió el formulario
     if (isset($_POST['submit'])) {
         // verificar que se haya podido subir CAF
         if (!isset($_FILES['caf']) or $_FILES['caf']['error']) {
             \sowerphp\core\Model_Datasource_Session::message('Ocurrió un error al subir el CAF', 'error');
             return;
         }
         if (\sowerphp\general\Utility_File::mimetype($_FILES['caf']['tmp_name']) != 'application/xml') {
             \sowerphp\core\Model_Datasource_Session::message('Formato del archivo ' . $_FILES['caf']['name'] . ' es incorrecto', 'error');
             return;
         }
         // cargar caf
         $caf = file_get_contents($_FILES['caf']['tmp_name']);
         $Folios = new \sasco\LibreDTE\Sii\Folios($caf);
         // si no se pudo validar el caf error
         if (!$Folios->getTipo()) {
             \sowerphp\core\Model_Datasource_Session::message('No fue posible cargar el CAF ' . $_FILES['caf']['name'] . ':<br/>' . implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'error');
             return;
         }
         // verificar que el caf tenga previamente cargado un mantenedor de folio
         $DteFolio = new Model_DteFolio($Emisor->rut, $Folios->getTipo(), (int) $Folios->getCertificacion());
         if (!$DteFolio->exists()) {
             \sowerphp\core\Model_Datasource_Session::message('Primero debe crear el mantenedor de los folios de tipo ' . $Folios->getTipo(), 'error');
             return;
         }
         // verificar que el caf sea del emisor
         if ($Folios->getEmisor() != $Emisor->rut . '-' . $Emisor->dv) {
             \sowerphp\core\Model_Datasource_Session::message('RUT del CAF ' . $Folios->getEmisor() . ' no corresponde con el RUT de la empresa ' . $Emisor->razon_social . ' ' . $Emisor->rut . '-' . $Emisor->dv, 'error');
             return;
         }
         // verificar que el folio que se está subiendo sea para el ambiente actual de la empresa
         $ambiente_empresa = $Emisor->certificacion ? 'certificación' : 'producción';
         $ambiente_caf = $Folios->getCertificacion() ? 'certificación' : 'producción';
         if ($ambiente_empresa != $ambiente_caf) {
             \sowerphp\core\Model_Datasource_Session::message('Empresa está en ambiente de ' . $ambiente_empresa . ' pero folios son de ' . $ambiente_caf, 'error');
             return;
         }
         // crear caf para el folio
         $DteCaf = new Model_DteCaf($DteFolio->emisor, $DteFolio->dte, (int) $Folios->getCertificacion(), $Folios->getDesde());
         if ($DteCaf->exists()) {
             \sowerphp\core\Model_Datasource_Session::message('El CAF para el documento de tipo ' . $DteCaf->dte . ' que inicia en ' . $Folios->getDesde() . ' en ambiente de ' . $ambiente_caf . ' ya estaba cargado', 'warning');
             return;
         }
         $DteCaf->hasta = $Folios->getHasta();
         $DteCaf->xml = \website\Dte\Utility_Data::encrypt($caf);
         try {
             $DteCaf->save();
         } catch (\sowerphp\core\Exception_Model_Datasource_Database $e) {
             \sowerphp\core\Model_Datasource_Session::message('No fue posible guardar el CAF: ' . $e->getMessage(), 'error');
             return;
         }
         // actualizar mantenedor de folios
         if (!$DteFolio->disponibles) {
             $DteFolio->siguiente = $Folios->getDesde();
             $DteFolio->disponibles = $Folios->getHasta() - $Folios->getDesde() + 1;
         } else {
             $DteFolio->disponibles += $Folios->getHasta() - $Folios->getDesde() + 1;
         }
         $DteFolio->alertado = 'f';
         try {
             $DteFolio->save();
             \sowerphp\core\Model_Datasource_Session::message('El CAF para el documento de tipo ' . $DteCaf->dte . ' que inicia en ' . $Folios->getDesde() . ' en ambiente de ' . $ambiente_caf . ' fue cargado, el siguiente folio disponible es ' . $DteFolio->siguiente, 'ok');
             $this->redirect('/dte/admin/dte_folios');
         } catch (\sowerphp\core\Exception_Model_Datasource_Database $e) {
             \sowerphp\core\Model_Datasource_Session::message('El CAF se guardó, pero no fue posible actualizar el mantenedor de folios, deberá actualizar manualmente. ' . $e->getMessage(), 'error');
             return;
         }
     }
 }
Пример #2
0
 * SIN GARANTÍA ALGUNA; ni siquiera la garantía implícita
 * MERCANTIL o de APTITUD PARA UN PROPÓSITO DETERMINADO.
 * Consulte los detalles de la Licencia Pública General GNU para obtener
 * una información más detallada.
 *
 * Debería haber recibido una copia de la Licencia Pública General GNU
 * junto a este programa.
 * En caso contrario, consulte <http://www.gnu.org/licenses/gpl.html>.
 */
/**
 * @file 007-folios.php
 *
 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
 * @version 2015-09-16
 */
// respuesta en texto plano
header('Content-type: text/plain');
// incluir archivos php de la biblioteca y configuraciones
include 'inc.php';
// cargar folios
$Folios = new \sasco\LibreDTE\Sii\Folios(file_get_contents('xml/folios.xml'));
// ejemplos métodos
echo 'Folios son validos?: ', $Folios->check() ? 'si' : 'no', "\n\n";
echo 'Rango de folios: ', $Folios->getDesde(), ' al ', $Folios->getHasta(), "\n\n";
echo 'CAF: ', $Folios->getCaf()->C14N(), "\n\n";
echo $Folios->getPrivateKey(), "\n";
echo $Folios->getPublicKey();
// si hubo errores mostrar
foreach (\sasco\LibreDTE\Log::readAll() as $error) {
    echo $error, "\n";
}
 /**
  * Recurso de la API que genera el XML de los DTEs solicitados
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-11-21
  */
 public function _api_generar_xml_POST()
 {
     // verificar si se pasaron credenciales de un usuario
     $User = $this->Api->getAuthUser();
     if (is_string($User)) {
         $this->Api->send($User, 401);
     }
     // verificar que se hayan pasado los índices básicos
     foreach (['Emisor', 'Receptor', 'documentos', 'folios', 'firma'] as $key) {
         if (!isset($this->Api->data[$key])) {
             $this->Api->send('Falta índice/variable ' . $key . ' por POST', 500);
         }
     }
     // recuperar folios y definir ambiente
     $folios = [];
     $certificacion = false;
     foreach ($this->Api->data['folios'] as $folio) {
         $Folios = new \sasco\LibreDTE\Sii\Folios(base64_decode($folio));
         $folios[$Folios->getTipo()] = $Folios;
         if ($Folios->getCertificacion()) {
             $certificacion = true;
         }
     }
     // normalizar datos emisor
     $this->Api->data['Emisor']['RUTEmisor'] = str_replace('.', '', $this->Api->data['Emisor']['RUTEmisor']);
     // normalizar datos receptor
     $this->Api->data['Receptor']['RUTRecep'] = str_replace('.', '', $this->Api->data['Receptor']['RUTRecep']);
     // objeto de la firma
     try {
         $Firma = new \sasco\LibreDTE\FirmaElectronica(['data' => base64_decode($this->Api->data['firma']['data']), 'pass' => $this->Api->data['firma']['pass']]);
     } catch (\Exception $e) {
         $this->Api->send('No fue posible abrir la firma digital, quizás contraseña incorrecta', 500);
     }
     // normalizar dte?
     $normalizar_dte = isset($this->Api->data['normalizar_dte']) ? $this->Api->data['normalizar_dte'] : true;
     // armar documentos y guardar en un arreglo
     $Documentos = [];
     foreach ($this->Api->data['documentos'] as $d) {
         // crear documento
         $d['Encabezado']['Emisor'] = $this->Api->data['Emisor'];
         $d['Encabezado']['Receptor'] = $this->Api->data['Receptor'];
         $DTE = new \sasco\LibreDTE\Sii\Dte($d, $normalizar_dte);
         // timbrar, firmar y validar el documento
         if (!isset($folios[$DTE->getTipo()])) {
             return $this->Api->send('Falta el CAF para el tipo de DTE ' . $DTE->getTipo(), 500);
         }
         if (!$DTE->timbrar($folios[$DTE->getTipo()]) or !$DTE->firmar($Firma) or !$DTE->schemaValidate()) {
             return $this->Api->send(implode("\n", \sasco\LibreDTE\Log::readAll()), 500);
         }
         // agregar el DTE al listado
         $Documentos[] = $DTE;
     }
     // armar EnvioDTE si se pasó fecha de resolución y número de resolución
     if (isset($this->Api->data['resolucion']) and !empty($this->Api->data['resolucion']['FchResol']) and isset($this->Api->data['resolucion']['NroResol'])) {
         $EnvioDte = new \sasco\LibreDTE\Sii\EnvioDte();
         foreach ($Documentos as $DTE) {
             $EnvioDte->agregar($DTE);
         }
         $EnvioDte->setCaratula(['RutEnvia' => $Firma->getID(), 'RutReceptor' => $certificacion ? '60803000-K' : $this->Api->data['Receptor']['RUTRecep'], 'FchResol' => $this->Api->data['resolucion']['FchResol'], 'NroResol' => (int) $this->Api->data['resolucion']['NroResol']]);
         $EnvioDte->setFirma($Firma);
         // generar
         $xml = $EnvioDte->generar();
         // validar schema del DTE
         if (!$EnvioDte->schemaValidate()) {
             return $this->Api->send(implode("\n", \sasco\LibreDTE\Log::readAll()), 500);
         }
         $dir = sys_get_temp_dir() . '/EnvioDTE_' . $this->Api->data['Emisor']['RUTEmisor'] . '_' . $this->Api->data['Receptor']['RUTRecep'] . '_' . date('U') . '.xml';
         file_put_contents($dir, $xml);
     } else {
         // directorio temporal para guardar los XML
         $dir = sys_get_temp_dir() . '/DTE_' . $this->Api->data['Emisor']['RUTEmisor'] . '_' . $this->Api->data['Receptor']['RUTRecep'] . '_' . date('U');
         if (is_dir($dir)) {
             \sasco\LibreDTE\File::rmdir($dir);
         }
         if (!mkdir($dir)) {
             $this->Api->send('No fue posible crear directorio temporal para DTEs', 500);
         }
         // procesar cada DTEs e ir agregándolo al directorio que se comprimirá
         foreach ($Documentos as $DTE) {
             // guardar XML
             file_put_contents($dir . '/dte_' . $this->Api->data['Emisor']['RUTEmisor'] . '_' . $DTE->getID() . '.xml', $DTE->saveXML());
         }
     }
     // guardar datos de emisor, receptor y estadísticas
     if (isset($this->Api->data['resolucion'])) {
         $resolucion = [];
         if (!empty($this->Api->data['resolucion']['FchResol'])) {
             $resolucion['FchResol'] = $this->Api->data['resolucion']['FchResol'];
         }
         if (isset($this->Api->data['resolucion']['NroResol'])) {
             $resolucion['NroResol'] = $this->Api->data['resolucion']['NroResol'];
         }
         $this->guardarEmisor($this->Api->data['Emisor'], $resolucion);
     } else {
         $this->guardarEmisor($this->Api->data['Emisor']);
     }
     $this->guardarReceptor($this->Api->data['Receptor']);
     list($emisor, $dv) = explode('-', $this->Api->data['Emisor']['RUTEmisor']);
     list($receptor, $dv) = explode('-', $this->Api->data['Receptor']['RUTRecep']);
     // entregar archivo comprimido que incluirá cada uno de los DTEs
     \sasco\LibreDTE\File::compress($dir, ['format' => 'zip', 'delete' => true]);
 }
 /**
  * Método que entrega el CAF de un folio de cierto DTE
  * @param dte Tipo de documento para el cual se quiere su CAF
  * @param folio Folio del CAF del DTE que se busca
  * @return \sasco\LibreDTE\Sii\Folios
  * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
  * @version 2015-09-22
  */
 private function getCaf($dte, $folio)
 {
     $caf = $this->db->getValue('
         SELECT xml
         FROM dte_caf
         WHERE
             emisor = :rut
             AND dte = :dte
             AND certificacion = :certificacion
             AND :folio BETWEEN desde AND hasta
     ', [':rut' => $this->rut, ':dte' => $dte, ':certificacion' => (int) $this->certificacion, ':folio' => $folio]);
     if (!$caf) {
         return false;
     }
     $caf = Utility_Data::decrypt($caf);
     if (!$caf) {
         return false;
     }
     $Caf = new \sasco\LibreDTE\Sii\Folios($caf);
     return $Caf->getTipo() ? $Caf : false;
 }