<commit_before><?php

/**
 * LibreDTE
 * Copyright (C) SASCO SpA (https://sasco.cl)
 *
 * Este programa es software libre: usted puede redistribuirlo y/o
 * modificarlo bajo los términos de la Licencia Pública General Affero de GNU
 * publicada por la Fundación para el Software Libre, ya sea la versión
 * 3 de la Licencia, o (a su elección) cualquier versión posterior de la
 * misma.
 *
 * Este programa se distribuye con la esperanza de que sea útil, pero
 * 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 Affero de GNU para
 * obtener una información más detallada.
 *
 * Debería haber recibido una copia de la Licencia Pública General Affero de GNU
 * junto a este programa.
 * En caso contrario, consulte <http://www.gnu.org/licenses/agpl.html>.
 */

// namespace del controlador
namespace website\Dte;

/**
 * Clase para todas las acciones asociadas a documentos (incluyendo API)
 * @author <NAME>, DeLaF (esteban[at]sasco.cl)
 * @version 2018-05-22
 */
class Controller_Documentos extends \Controller_App
{

    private $IndTraslado = [
        1 => 'Operación constituye venta',
        2 => 'Ventas por efectuar',
        3 => 'Consignaciones',
        4 => 'Entrega gratuita',
        5 => 'Traslados internos',
        6 => 'Otros traslados no venta',
        7 => 'Guía de devolución',
        8 => 'Traslado para exportación. (no venta)',
        9 => 'Venta para exportación',
    ]; ///< tipos de traslado

    private $IndServicio = [
        1 => 'Factura o boleta de servicios períodicos domiciliarios', // boleta es periodico no domiciliario (se ajusta)
        2 => 'Factura o boleta de otros servicios períodicos (no domiciliarios)',  // boleta es periodico domiciliario (se ajusta)
        3 => 'Factura de servicios o boleta de ventas y servicios',
        4 => 'Factura exportación de servicios de hotelería o boleta de espectáculos emitida por cuenta de terceros',
        5 => 'Factura exportación de servicios de transporte internacional',
    ]; ///< Tipos de indicadores de servicios

    private $TpoTranCompra = [
        1 => 'Compra del giro',
        2 => 'Compra en supermercados o similares',
        3 => 'Compra bien raíz',
        4 => 'Compra activo fijo',
        5 => 'Compra con IVA uso común',
        6 => 'Compra sin derecho a crédito',
        7 => 'Compra que no corresponde incluir',
    ]; //< Tipos de transacción para el comprador (es una sugerencia, el comprador lo puede cambiar)

    private $TpoTranVenta = [
        1 => 'Venta del giro',
        2 => 'Venta activo fijo',
        3 => 'Venta bien raíz',
    ]; /// Tipos de transacción para el vendedor

    private $monedas = [
        'DOLAR USA' => 'DOLAR USA',
        'EURO' => 'EURO',
        'PESO CL' => 'PESO CL',
    ]; // Tipo moneda para documentos de exportación

    private $MedioPago = [
        'EF' => 'Efectivo',
        'PE' => 'Depósito o transferencia',
        'TC' => 'Tarjeta de crédito o débito',
        'CH' => 'Cheque',
        'CF' => 'Cheque a fecha',
        'LT' => 'Letra',
        'OT' => 'Otro',
    ]; // Medios de pago

    /**
     * Método que corrije el tipo de documento en caso de ser factura o boleta
     * @author <NAME>, DeLaF (esteban[at]sasco.cl)
     * @version 2016-01-30
     */
    private function getTipoDTE($tipo, $Detalle)
    {
        if (!in_array($tipo, [33, 34, 39,41]))
            return $tipo;
        // determinar tipo de documento
        $netos = 0;
        $exentos = 0;
        if (!isset($Detalle[0]))
            $Detalle = [$Detalle];
        foreach ($Detalle as $d) {
            if (!empty($d['IndExe']))
                $exentos++;
            else
                $netos++;
        }
        // el documento es factura
        if ($tipo == 33 or $tipo == 34) {
            if ($tipo == 33 and !$netos and $exentos)
                return 34;
            if ($tipo == 34 and !$exentos and $netos)
                return 33;
        }
        // es boleta
        else if ($tipo == 39 or $tipo == 41) {
            if ($tipo == 39 and !$netos and $exentos)
                return 41;
            if ($tipo == 41 and !$exentos and $netos)
                return 39;
        }
        // retornar tipo original ya que estaba bien
        return $tipo;
    }

    /**
     * Función de la API que permite emitir un DTE generando su documento
     * temporal. El documento generado no tiene folio, no está firmado y no es
     * enviado al SII. Luego se debe usar la función generar de la API para
     * generar el DTE final y enviarlo al SII.
     * @author <NAME>, DeLaF (esteban[at]sasco.cl)
     * @version 2020-07-17
     */
    public function _api_emitir_POST()
    {
        extract($this->getQuery([
            'formato' => 'json',
            'normalizar' => true,
            'links' => false,
            'email' => false,
        ]));
        // verificar si se pasaron credenciales de un usuario
        $User = $this->Api->getAuthUser();
        if (is_string($User)) {
            $this->Api->send($User, 401);
        }
        // definir formato de los datos que se están usando como entrada
        // y si es diferente a JSON se busca un parser para poder cargar los
        // datos a un arreglo de PHP (formato JSON)
        if ($formato!='json') {
            if (!is_string($this->Api->data)) {
                $this->Api->send('Debe enviar los datos codificados en base64 en un string JSON', 400);
            }
            try {
                $this->Api->data = \sasco\LibreDTE\Sii\Dte\Formatos::toArray(
                    $formato, base64_decode($this->Api->data)
                );
            } catch (\Exception $e) {
                $this->Api->send($e->getMessage(), 400);
            }
        }
        // verificar datos del DTE pasados
        if (!is_array($this->Api->data)) {
            $this->Api->send('Debe enviar el DTE como un objeto JSON', 400);
        }
        // buscar emisor del DTE y verificar que usuario tenga permisos para
        // trabajar con el emisor
        if (!isset($this->Api->data['Encabezado']['Emisor']['RUTEmisor'])) {
            $this->Api->send('Debe especificar RUTEmisor en el objeto JSON', 404);
        }
        $Emisor = new Model_Contribuyente($this->Api->data['Encabezado']['Emisor']['RUTEmisor']);
        if (!$Emisor->usuario) {
            $this->Api->send('Contribuyente no está registrado en la aplicación', 404);
        }
        if (!$Emisor->usuarioAutorizado($User, '/dte/documentos/emitir')) {
            $this->Api->send('No está autorizado a operar con la empresa solicitada', 403);
        }
        // guardar datos del receptor
        try {
            $Receptor = $this->guardarReceptor($this->Api->data['Encabezado']['Receptor']);
        } catch (\Exception $e) {
            $this->Api->send('No fue posible guardar los datos del receptor: '.$e->getMessage(), 507);
        }
        // construir arreglo con datos del DTE por defecto si se normaliza
        if ($normalizar) {<commit_msg>fix mensaje de formato cuando se emite un dte<commit_after><?php

/**
 * LibreDTE
 * Copyright (C) SASCO SpA (https://sasco.cl)
 *
 * Este programa es software libre: usted puede redistribuirlo y/o
 * modificarlo bajo los términos de la Licencia Pública General Affero de GNU
 * publicada por la Fundación para el Software Libre, ya sea la versión
 * 3 de la Licencia, o (a su elección) cualquier versión posterior de la
 * misma.
 *
 * Este programa se distribuye con la esperanza de que sea útil, pero
 * 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 Affero de GNU para
 * obtener una información más detallada.
 *
 * Debería haber recibido una copia de la Licencia Pública General Affero de GNU
 * junto a este programa.
 * En caso contrario, consulte <http://www.gnu.org/licenses/agpl.html>.
 */

// namespace del controlador
namespace website\Dte;

/**
 * Clase para todas las acciones asociadas a documentos (incluyendo API)
 * @author <NAME>, DeLaF (esteban[at]sasco.cl)
 * @version 2018-05-22
 */
class Controller_Documentos extends \Controller_App
{

    private $IndTraslado = [
        1 => 'Operación constituye venta',
        2 => 'Ventas por efectuar',
        3 => 'Consignaciones',
        4 => 'Entrega gratuita',
        5 => 'Traslados internos',
        6 => 'Otros traslados no venta',
        7 => 'Guía de devolución',
        8 => 'Traslado para exportación. (no venta)',
        9 => 'Venta para exportación',
    ]; ///< tipos de traslado

    private $IndServicio = [
        1 => 'Factura o boleta de servicios períodicos domiciliarios', // boleta es periodico no domiciliario (se ajusta)
        2 => 'Factura o boleta de otros servicios períodicos (no domiciliarios)',  // boleta es periodico domiciliario (se ajusta)
        3 => 'Factura de servicios o boleta de ventas y servicios',
        4 => 'Factura exportación de servicios de hotelería o boleta de espectáculos emitida por cuenta de terceros',
        5 => 'Factura exportación de servicios de transporte internacional',
    ]; ///< Tipos de indicadores de servicios

    private $TpoTranCompra = [
        1 => 'Compra del giro',
        2 => 'Compra en supermercados o similares',
        3 => 'Compra bien raíz',
        4 => 'Compra activo fijo',
        5 => 'Compra con IVA uso común',
        6 => 'Compra sin derecho a crédito',
        7 => 'Compra que no corresponde incluir',
    ]; //< Tipos de transacción para el comprador (es una sugerencia, el comprador lo puede cambiar)

    private $TpoTranVenta = [
        1 => 'Venta del giro',
        2 => 'Venta activo fijo',
        3 => 'Venta bien raíz',
    ]; /// Tipos de transacción para el vendedor

    private $monedas = [
        'DOLAR USA' => 'DOLAR USA',
        'EURO' => 'EURO',
        'PESO CL' => 'PESO CL',
    ]; // Tipo moneda para documentos de exportación

    private $MedioPago = [
        'EF' => 'Efectivo',
        'PE' => 'Depósito o transferencia',
        'TC' => 'Tarjeta de crédito o débito',
        'CH' => 'Cheque',
        'CF' => 'Cheque a fecha',
        'LT' => 'Letra',
        'OT' => 'Otro',
    ]; // Medios de pago

    /**
     * Método que corrije el tipo de documento en caso de ser factura o boleta
     * @author <NAME>, DeLaF (esteban[at]sasco.cl)
     * @version 2016-01-30
     */
    private function getTipoDTE($tipo, $Detalle)
    {
        if (!in_array($tipo, [33, 34, 39,41]))
            return $tipo;
        // determinar tipo de documento
        $netos = 0;
        $exentos = 0;
        if (!isset($Detalle[0]))
            $Detalle = [$Detalle];
        foreach ($Detalle as $d) {
            if (!empty($d['IndExe']))
                $exentos++;
            else
                $netos++;
        }
        // el documento es factura
        if ($tipo == 33 or $tipo == 34) {
            if ($tipo == 33 and !$netos and $exentos)
                return 34;
            if ($tipo == 34 and !$exentos and $netos)
                return 33;
        }
        // es boleta
        else if ($tipo == 39 or $tipo == 41) {
            if ($tipo == 39 and !$netos and $exentos)
                return 41;
            if ($tipo == 41 and !$exentos and $netos)
                return 39;
        }
        // retornar tipo original ya que estaba bien
        return $tipo;
    }

    /**
     * Función de la API que permite emitir un DTE generando su documento
     * temporal. El documento generado no tiene folio, no está firmado y no es
     * enviado al SII. Luego se debe usar la función generar de la API para
     * generar el DTE final y enviarlo al SII.
     * @author <NAME>, DeLaF (esteban[at]sasco.cl)
     * @version 2020-07-17
     */
    public function _api_emitir_POST()
    {
        extract($this->getQuery([
            'formato' => 'json',
            'normalizar' => true,
            'links' => false,
            'email' => false,
        ]));
        // verificar si se pasaron credenciales de un usuario
        $User = $this->Api->getAuthUser();
        if (is_string($User)) {
            $this->Api->send($User, 401);
        }
        // definir formato de los datos que se están usando como entrada
        // y si es diferente a JSON se busca un parser para poder cargar los
        // datos a un arreglo de PHP (formato JSON)
        if ($formato!='json') {
            if (!is_string($this->Api->data)) {
                $this->Api->send('Debe enviar los datos codificados en base64 en un string JSON', 400);
            }
            try {
                $this->Api->data = \sasco\LibreDTE\Sii\Dte\Formatos::toArray(
                    $formato, base64_decode($this->Api->data)
                );
            } catch (\Exception $e) {
                $this->Api->send($e->getMessage(), 400);
            }
        }
        // verificar datos del DTE pasados
        if (!is_array($this->Api->data)) {
            $this->Api->send('Debe enviar el DTE en formato: '.$formato, 400);
        }
        // buscar emisor del DTE y verificar que usuario tenga permisos para
        // trabajar con el emisor
        if (!isset($this->Api->data['Encabezado']['Emisor']['RUTEmisor'])) {
            $this->Api->send('Debe especificar RUTEmisor en el objeto JSON', 404);
        }
        $Emisor = new Model_Contribuyente($this->Api->data['Encabezado']['Emisor']['RUTEmisor']);
        if (!$Emisor->usuario) {
            $this->Api->send('Contribuyente no está registrado en la aplicación', 404);
        }
        if (!$Emisor->usuarioAutorizado($User, '/dte/documentos/emitir')) {
            $this->Api->send('No está autorizado a operar con la empresa solicitada', 403);
        }
        // guardar datos del receptor
        try {
            $Receptor = $this->guardarReceptor($this->Api->data['Encabezado']['Receptor']);
        } catch (\Exception $e) {
            $this->Api->send('No fue posible guardar los datos del receptor: '.$e->getMessage(), 507);
        }
        // construir arreglo con datos del DTE por defecto si se normaliza
        if ($normalizar) {
{'fraction_non_alphanumeric': 0.12083976969526752, 'fraction_numerical': 0.015728128071900015, 'mean_word_length': 2.107789657429631, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 163, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4299899', 'n_tokens_mistral': 4784, 'n_tokens_neox': 4607, 'n_words': 1465}