· 5 years ago · Oct 22, 2020, 11:52 PM
1<?php
2use PrestaShop\PrestaShop\Adapter\Entity\Customer;
3
4if ( ! defined( '_PS_VERSION_' ) ) {
5 exit;
6}
7
8require_once dirname( __FILE__ ) . '/classes/Customer.php';
9require_once dirname( __FILE__ ) . '/classes/Invoice.php';
10require_once dirname( __FILE__ ) . '/classes/NubeFact.php';
11
12class Vex_Nubefact extends Module {
13 protected $checkoutProcess;
14 private $VEX_GET_ID_ORDER;
15 private $VEX_SET_DATE_INVOICE;
16
17 // config
18 const CONFIG_LIVEMODE = 'VEX_NUBEFACT_LIVEMODE';
19 const CONFIG_LICENSE = 'VEX_NUBEFACT_LICENSE';
20 const CONFIG_TEST_URL = 'VEX_NUBEFACT_TEST_URL';
21 const CONFIG_TEST_TOKEN = 'VEX_NUBEFACT_TEST_TOKEN';
22 const CONFIG_LIVE_URL = 'VEX_NUBEFACT_LIVE_URL';
23 const CONFIG_LIVE_TOKEN = 'VEX_NUBEFACT_LIVE_TOKEN';
24 const CONFIG_BUSINESS_RUC = 'VEX_NUBEFACT_BUSINESS_RUC';
25 const CONFIG_BUSINESS_NAME = 'VEX_NUBEFACT_BUSINESS_NAME';
26 const CONFIG_BUSINESS_ADDRESS = 'VEX_NUBEFACT_BUSINESS_ADDRESS';
27 const CONFIG_RECEIPT_SERIE = 'VEX_NUBEFACT_RECEIPT_SERIE';
28 const CONFIG_RECEIPT_NUM = 'VEX_NUBEFACT_RECEIPT_NUM';
29 const CONFIG_INVOICE_SERIE = 'VEX_NUBEFACT_INVOICE_SERIE';
30 const CONFIG_INVOICE_NUM = 'VEX_NUBEFACT_INVOICE_NUM';
31 const CONFIG_INVOICE_STATE = 'VEX_NUBEFACT_INVOICE_STATE';
32 const CONFIG_INVOICE_SUNAT_CODE = 'VEX_NUBEFACT_INVOICE_SUNAT_CODE';
33 const CONFIG_API_APPNAME = 'VEX_API_APPNAME';
34 const CONFIG_API_FE_BILLING_NAME = 'VEX_API_FE_BILLING_NAME';
35 const CONFIG_FE_TOKEN_AUTO_INCREMENT_INVOICE = 'VEX_FE_TOKEN_AUTO_INCREMENT_INVOICE';
36 const CONFIG_FE_URL_AUTO_INCREMENT_INVOICE = 'VEX_FE_URL_AUTO_INCREMENT_INVOICE';
37 const CONFIG_FE_F_SUFFIX = 'VEX_FE_F_SUFFIX';
38 const CONFIG_FE_B_SUFFIX = 'VEX_FE_B_SUFFIX';
39
40 const TIPOCOMPROBANTE_FACTURA = 1;
41 const TIPODOCUMENTO_RUC = 6;
42
43 const NUBEFACT_PATH_LOG = _PS_ROOT_DIR_ . "/../logs/modules/vex_nubefact/log";
44
45 public function __construct(){
46 $this->name = 'vex_nubefact';
47 // $this->tab = 'administration';
48 $this->tab = 'billing_invoicing';
49 $this->version = '1.2.0';
50 $this->ps_versions_compliancy = array('min' => '1.7', 'max' => _PS_VERSION_);
51 $this->author = 'Vex Soluciones - Modified by Alekuoshu & German';
52 // $this->controllers = array('validation', 'payment', 'transaction', 'error');
53 $this->bootstrap = true;
54
55
56
57 $this->displayName = 'NubeFact';
58 $this->description = $this->l('Electronic invoicing management module for Peru');
59 $this->confirmUninstall = $this->l('Are you sure about removing NubeFact?');
60 $this->VEX_GET_ID_ORDER = Tools::getValue('VEX_GET_ID_ORDER');
61 $this->VEX_SET_DATE_INVOICE = Tools::getValue('VEX_SET_DATE_INVOICE');
62 parent::__construct();
63
64 // init this function
65 $this->sendMasiveInvoices();
66 }
67
68 public function install()
69 {
70 return (parent::install()
71 && $this->createTabs()
72 && $this->registerHook('header')
73 && $this->registerHook('displayPaymentTop')
74 && $this->registerHook('termsAndConditions')
75 && $this->registerHook('backOfficeHeader')
76 && $this->registerHook('actionOrderStatusPostUpdate')
77 && $this->registerHook('displayOrderDetail')
78 && $this->registerHook('actionObjectCustomerAddAfter')
79 && $this->registerHook('displayAdminCustomersForm')
80 && $this->installDb());
81 }
82
83 public function uninstall(){
84 return (
85 parent::uninstall()
86 );
87 }
88
89 public function installDb()
90 {
91 return (Db::getInstance()->Execute('CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'vex_nubefact_customer` (
92 `id` int(11) NOT NULL AUTO_INCREMENT,
93 `customer_id` int(11) NOT NULL,
94 `cart_id` int(11) NOT NULL,
95 `tipo_de_comprobante` char(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
96 `cliente_tipo_de_documento` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
97 `cliente_numero_de_documento` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
98 `cliente_denominacion` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
99 `cliente_direccion` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
100 `date_add` DATETIME NOT NULL,
101 PRIMARY KEY (`id`)
102 ) ENGINE=' . _MYSQL_ENGINE_ . ' AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;') &&
103 Db::getInstance()->Execute('CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'vex_nubefact_invoice` (
104 `comprobante_id` int(11) NOT NULL AUTO_INCREMENT,
105 `id_customer` int(11) NOT NULL,
106 `id_order` int(11) NOT NULL,
107 `url_pdf` text COLLATE utf8mb4_unicode_ci,
108 `tipo_de_comprobante` char(2) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
109 `serie` char(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
110 `numero` int(11) DEFAULT NULL,
111 `cliente_tipo_de_documento` varchar(6) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
112 `cliente_numero_de_documento` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
113 `cliente_denominacion` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
114 `cliente_direccion` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
115 `cliente_email` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
116 `fecha_de_emision` date DEFAULT NULL,
117 `porcentaje_de_igv` double DEFAULT NULL,
118 `descuento_global` double DEFAULT NULL,
119 `total_descuento` double DEFAULT NULL,
120 `total_gravada` double DEFAULT NULL,
121 `total_igv` double DEFAULT NULL,
122 `total_gratuita` double DEFAULT NULL,
123 `total` double DEFAULT NULL,
124 `wp_data` text COLLATE utf8mb4_unicode_ci,
125 `sunat_estado` char(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT "",
126 `sunat_respuesta_envio` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
127 `sunat_fecha_envio` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
128 `sys_estado` smallint(6) DEFAULT "1",
129 `date_add` DATETIME NOT NULL,
130 PRIMARY KEY (`comprobante_id`,`sunat_estado`)
131 ) ENGINE=' . _MYSQL_ENGINE_ . ' AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;'));
132 }
133
134 private function createTabs()
135 {
136 $tab = new Tab();
137 $tab->active = 1;
138 $tab->class_name = "AdminNubeFact";
139 $tab->id_parent = Tab::getIdFromClassName('AdminParentOrders');
140 $tab->module = $this->name;
141 $tab->name = array();
142
143 foreach (Language::getLanguages() as $lang) {
144 $tab->name[$lang['id_lang']] = "NubeFact";
145 }
146
147 return $tab->add();
148 }
149
150 private function canBeUsed($params)
151 {
152 if (! $this->active) {
153 return false;
154 }
155
156 return true;
157 }
158
159 /**
160 * Add the CSS & JavaScript files in the module's backoffice.
161 *
162 * @return void
163 */
164 public function hookBackOfficeHeader($params)
165 {
166 $controller = Tools::getValue('controller');
167 $submitAddcustomer = Tools::getValue('submitAddcustomer');
168 $tipoDeDocumentoCliente = Tools::getValue('tipo_de_documento_cliente');
169 $id_customer = (int) Tools::getValue('id_customer');
170
171 if (! empty($id_customer) && $controller == 'AdminCustomers' && (bool) $submitAddcustomer && ! empty($tipoDeDocumentoCliente)) {
172
173 $customer = new Customer($id_customer);
174 if (Validate::isLoadedObject($customer))
175 self::updateDataInvoice($customer);
176 }
177
178
179 if (! $this->canBeUsed($params)) {
180 return false;
181 }
182
183 if (Tools::getValue('configure') == $this->name) {
184 $this->context->controller->addCSS($this->_path . 'views/css/backend.css');
185 // if (version_compare(_PS_VERSION_, '1.6', '<') == true) {
186 // $this->context->controller->addCSS($this->_path.'views/css/bootstrap.min.css');
187 // $this->context->controller->addCSS($this->_path.'views/css/configure-ps-15.css');
188 // } else {
189 // $this->context->controller->addCSS($this->_path.'views/css/configure-ps-16.css');
190 // }
191 }
192 }
193
194
195 /**
196 * Add the CSS & JavaScript files on the frontoffice.
197 *
198 * @return void
199 */
200 public function hookHeader($params)
201 {
202 if (! $this->canBeUsed($params)) {
203 return false;
204 }
205
206 // print_r( [$params, $this->context]);
207 $this->context->controller->addJS($this->_path . '/views/js/front.js');
208 // $this->context->controller->addCSS($this->_path.'/views/css/front.css');
209 }
210
211 public function hookDisplayPaymentTop($params)
212 {
213 if (! $this->canBeUsed($params)) {
214 return false;
215 }
216
217 $this->getDataInvoiceForm();
218
219 return $this->display(__FILE__, 'vex_facturacion.tpl');
220 }
221
222 /*
223 * Hook que se acciona al pasar estado depende del valor de la variable CONFIG_INVOICE_STATE
224 */
225 public function hookActionOrderStatusPostUpdate($params)
226 {
227 if (! $this->canBeUsed($params)) {
228 return false;
229 }
230
231 $stateID = trim(Configuration::get(self::CONFIG_INVOICE_STATE));
232
233 // value if state changed is equal to (CONFIG_INVOICE_STATE)
234 if ($params['newOrderStatus']->id == $stateID) {
235
236 $order = new Order($params['id_order']);
237 $customer_id = $order->id_customer;
238 $id_cart = $order->id_cart;
239
240 // evalua si es gratuita o no
241 if ($order->total_paid_tax_incl == 0) {
242 $incluido_impuestos = 0; // total incluido impuesto
243 $sin_impuestos = 0; // total sin impuesto
244 } else {
245 // $incluido_impuestos = $order->total_products_wt; // total incluido impuesto
246 // $sin_impuestos = $order->total_products; // total sin impuesto
247 $incluido_impuestos = $order->total_paid_tax_incl; // total incluido impuesto
248 $sin_impuestos = $order->total_paid_tax_excl; // total sin impuesto
249 }
250
251 $totalGratis = 0;
252 $sumaDescuentoItems = 0;
253 // load saved values
254 // $nubeFactValues = array();
255 if ($nubeFactCustomer = Vex_Nubefact_Customer::getByCustomerId($customer_id)) {
256 // $nubeFactValues = $nubeFactCustomer;
257 // unset( $nubeFactValues['date_add'], $nubeFactValues['cart_id'] );
258 // unset( $nubeFactValues['customer_id'], $nubeFactValues['id'] );
259 $customer = new Customer($customer_id);
260
261 $url = $this->get_url();
262 $token = $this->get_token();
263
264 $nubeFact = new Vex_PrestaShop_NubeFact($url, $token);
265
266 if ($nubeFactCustomer['tipo_de_comprobante'] == self::TIPOCOMPROBANTE_FACTURA) {
267 require_once dirname(__FILE__) . '/classes/NubeFact/FacturaElectronica.php';
268 $document = new Vex_FacturaElectronica();
269
270 $serie = 'F' . Configuration::get( self::CONFIG_INVOICE_SERIE );
271 // $numero = Configuration::get( self::CONFIG_INVOICE_NUM );
272
273 // consulta consecutivo en api
274 $AutoIncrementInvoice = new stdClass();
275 $AutoIncrementInvoice->aplicationName = Configuration::get(self::CONFIG_API_APPNAME);
276 $AutoIncrementInvoice->billingName = Configuration::get(self::CONFIG_API_FE_BILLING_NAME);
277 $AutoIncrementInvoice->idCart = $id_cart;
278 $AutoIncrementInvoice->idOrder = $params['id_order'];
279 $AutoIncrementInvoice->token = Configuration::get(self::CONFIG_FE_TOKEN_AUTO_INCREMENT_INVOICE);
280 $AutoIncrementInvoice->suffix = Configuration::get(self::CONFIG_FE_F_SUFFIX);
281 $AutoIncrementInvoice->production = true;
282
283 $data_string = json_encode($AutoIncrementInvoice);
284
285 $ch = curl_init(Configuration::get(self::CONFIG_FE_URL_AUTO_INCREMENT_INVOICE));
286 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
287 curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
288 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
289 curl_setopt($ch, CURLOPT_HTTPHEADER, array(
290 'Content-Type: application/json',
291 'Content-Length: ' . strlen($data_string)
292 ));
293
294 $response = curl_exec($ch);
295
296 $responseArray = json_decode($response, true);
297 $numero = $responseArray['invoiceNumber'];
298
299 } else {
300 require_once dirname( __FILE__ ) . '/classes/NubeFact/BoletaElectronica.php';
301 $document = new Vex_BoletaElectronica();
302
303 $serie = 'B' . Configuration::get( self::CONFIG_RECEIPT_SERIE );
304 // $numero = Configuration::get( self::CONFIG_RECEIPT_NUM );
305
306 // consulta consecutivo en api
307 $AutoIncrementInvoice = new stdClass();
308 $AutoIncrementInvoice->aplicationName = Configuration::get(self::CONFIG_API_APPNAME);
309 $AutoIncrementInvoice->billingName = Configuration::get(self::CONFIG_API_FE_BILLING_NAME);
310 $AutoIncrementInvoice->idCart = $id_cart;
311 $AutoIncrementInvoice->idOrder = $params['id_order'];
312 $AutoIncrementInvoice->token = Configuration::get(self::CONFIG_FE_TOKEN_AUTO_INCREMENT_INVOICE);
313 $AutoIncrementInvoice->suffix = Configuration::get(self::CONFIG_FE_B_SUFFIX);
314 $AutoIncrementInvoice->production = true;
315
316 $data_string = json_encode($AutoIncrementInvoice);
317
318 $ch = curl_init(Configuration::get(self::CONFIG_FE_URL_AUTO_INCREMENT_INVOICE));
319 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
320 curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
321 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
322 curl_setopt($ch, CURLOPT_HTTPHEADER, array(
323 'Content-Type: application/json',
324 'Content-Length: ' . strlen($data_string)
325 ));
326
327 $response = curl_exec($ch);
328
329 $responseArray = json_decode($response, true);
330 $numero = $responseArray['invoiceNumber'];
331 }
332
333 $document->setSunatEnvioAutomatico( true );
334 $document->setSerie( $serie );
335 $document->setNumero( $numero );
336
337 $document->setCliente( array(
338 'cliente_tipo_de_documento' => $nubeFactCustomer['cliente_tipo_de_documento'],
339 'cliente_numero_de_documento' => trim($nubeFactCustomer['cliente_numero_de_documento']),
340 'cliente_denominacion' => $nubeFactCustomer['cliente_denominacion'],
341 'cliente_direccion' => $nubeFactCustomer['cliente_direccion']
342 ) );
343
344 $document->addClienteEmail( $customer->email );
345
346 // $currency = new Currency($order->id_currency);
347 // $currencies = array(
348 // 'PEN' => Vex_DocumentContract::$SOL,
349 // 'USD' => Vex_DocumentContract::$DOLAR,
350 // 'EUR' => Vex_DocumentContract::$EURO,
351 // );
352
353 // var_export( [$currency, $nubeFactCustomer] );
354
355
356 // $document->setMoneda( $currencies[ $currency->iso_code ] );
357
358 // $document->setTipoCambio();
359 $document->setPorcentajeIGV( $this->get_percent_igv() );
360 $document->setTotal( $incluido_impuestos );
361 $document->setTotalIGV( round( $incluido_impuestos - $sin_impuestos, 2 ) );
362 $document->setTotalGravada( $sin_impuestos );
363 // $document->setTotalInafecta();
364 // $document->setDetraccion();
365 // $document->setObservaciones();
366
367 $features = $this->getFeaturesProductOrder($order->id);
368
369 $giftFlag = false;
370
371 foreach ( $order->getProducts() as $productDetail ) {
372 $TotalConImpuesto = $productDetail['total_price_tax_incl'];
373 $TotalSinImpuesto = $productDetail['total_price_tax_excl'];
374 $discounts = $productDetail['reduction_percent'];
375 $discountAmount = $productDetail['reduction_amount_tax_excl'];
376 $valorUnitario = $productDetail['original_product_price'];
377 $impuestoUnitario = ($valorUnitario * (int) $this->get_percent_igv()) / 100;
378 $precioUnitario = round($valorUnitario + $impuestoUnitario, 2);
379 $tipoIGV = '1';
380 $IGV = $TotalConImpuesto - $TotalSinImpuesto;
381 $total = $TotalConImpuesto;
382 $descuento = 0;
383 $subtotal = ($valorUnitario * $productDetail['product_quantity']) - $descuento;
384
385 // descuento por producto
386 if($discounts > 0) {
387 self::logtxt("Descuento por producto! - Percent");
388 $descuento = ($valorUnitario * $discounts / 100);
389 $sumaDescuentoItems += $descuento;
390 $subtotal = ($valorUnitario - $descuento) * ($productDetail['product_quantity']);
391 $IGV = ($subtotal * (int) $this->get_percent_igv()) / 100;
392
393 if($discounts == 100) {
394 // Si el producto es gratuito
395 self::logtxt("Producto gratuito");
396 $giftFlag = true;
397 $precioUnitario = $valorUnitario;
398 $subtotal = ($valorUnitario * $productDetail['product_quantity']);
399 $tipoIGV = '6';
400 $IGV = 0;
401 $total = $subtotal;
402 $totalGratis += $subtotal;
403 $descuento = 0;
404 }
405
406 }elseif($discountAmount > 0){
407 self::logtxt("Descuento por producto! - Amount");
408 $descuento = $discountAmount;
409 $sumaDescuentoItems += $discountAmount;
410 $subtotal = ($valorUnitario - $descuento) * ($productDetail['product_quantity']);
411 $IGV = ($subtotal * (int) $this->get_percent_igv()) / 100;
412
413 }
414
415 if(!empty($features[$productDetail['product_id']]['value']))
416 $codigo_producto_sunat = $features[$productDetail['product_id']]['value'];
417 else
418 $codigo_producto_sunat = Configuration::get( self::CONFIG_INVOICE_SUNAT_CODE );
419
420 // evalua si es gratuito o no
421 if($order->total_paid_tax_incl == 0){
422 $totalGratis += $subtotal;
423 $precioUnitario = $valorUnitario;
424 $subtotal = ($valorUnitario * $productDetail['product_quantity']);
425 $tipoIGV = '6';
426 $IGV = 0;
427 $total = $valorUnitario;
428 }
429
430 $document->addItem( array(
431 'unidad_de_medida' => 'NIU',
432 'codigo' => $productDetail['product_id'],
433 'descripcion' => $productDetail['product_name'],
434 'cantidad' => $productDetail['product_quantity'],
435 'valor_unitario' => $valorUnitario, // unitario sin impuesto
436 'precio_unitario' => $precioUnitario, // unitario con impuesto
437 'descuento' => $descuento,
438 'subtotal' => $subtotal,
439 'tipo_de_igv' => $tipoIGV,
440 'igv' => $IGV,
441 'total' => $total,
442 'anticipo_regularizacion' => 'false',
443 'anticipo_documento_serie' => '',
444 'anticipo_documento_numero' => '',
445 'codigo_producto_sunat' => $codigo_producto_sunat //Fórmulas y productos para apoyo nutritivo
446 ) );
447 }
448
449 // transporte
450 $shipping_sin_impuestos = $order->total_shipping_tax_excl; // total transporte sin impuesto
451 $shipping_con_impuestos = $order->total_shipping_tax_incl; // total transporte sin impuesto
452 $precioUnitario = round($shipping_con_impuestos, 2);
453 $tipoIGV = '1';
454 $IGV = $shipping_con_impuestos - $shipping_sin_impuestos;
455 $total = $shipping_con_impuestos;
456 if ($shipping_sin_impuestos > 0) {
457 // evalua si es gratuito o no
458 if($order->total_paid_tax_incl == 0){
459 $precioUnitario = $shipping_sin_impuestos;
460 $tipoIGV = '6';
461 $IGV = 0;
462 $total = $shipping_sin_impuestos;
463 }
464
465 $document->addItem( array(
466 'unidad_de_medida' => 'ZZ',
467 'codigo' => '001',
468 'descripcion' => 'Costo de envío',
469 'cantidad' => '1',
470 'valor_unitario' => $shipping_sin_impuestos, // unitario sin impuesto
471 'precio_unitario' => $precioUnitario, // unitario con impuesto
472 'descuento' => '',
473 'subtotal' => $shipping_sin_impuestos,
474 'tipo_de_igv' => $tipoIGV,
475 'igv' => $IGV,
476 'total' => $total,
477 'anticipo_regularizacion' => 'false',
478 'anticipo_documento_serie' => '',
479 'anticipo_documento_numero' => '',
480 'codigo_producto_sunat' => '78140000' //Servicios de transporte
481 ) );
482 }
483
484 // $document->setCodigoUnico();
485
486 // var_export( $document->getArray() );
487
488 // descuento general
489 $total_descuentos = 0;
490 $descuento_general = 0;
491 if($order->total_discounts > 0){
492 $descuento_general = $order->total_discounts_tax_excl; // total descuento orden
493 }
494 $total_descuentos = $descuento_general + $sumaDescuentoItems;
495
496 // si hay descuento general y por item
497 if($order->total_discounts > 0 && $dproductFlag == true){
498 $descuento_general = $order->total_discounts_tax_excl; // total descuento orden
499 $total_descuentos = $sumaDescuentoItems;
500 }
501 $document->setDescuentoGlobal( $descuento_general );
502 $document->setTotalDescuento( $total_descuentos );
503
504 // si es gratuita o no
505 if($order->total_paid_tax_incl == 0){
506 $document->setTotalGratis( $totalGratis );
507 }
508
509 // si existe un producto gratuito
510 if($giftFlag == true){
511 $document->setTotalGratis( $totalGratis );
512 }
513
514 // Evalua el tipo de documento para saber el tipo de transacción (segun sunat) - By Alekuoshu
515 if((int) $nubeFactCustomer['cliente_tipo_de_documento'] == 4 || (int) $nubeFactCustomer['cliente_tipo_de_documento'] == 7){
516 $document->setSunatTransaction( 29 ); // Venta no domiciliados que no califican como exportación
517 }elseif((int) $nubeFactCustomer['cliente_tipo_de_documento'] == 0){
518 $document->setSunatTransaction( 2 ); // Exportanción
519 }else{
520 $document->setSunatTransaction( 1 ); // Venta Interna
521 }
522
523 //create invoice
524 $invoice = new Vex_Nubefact_Invoice();
525
526 $invoice->id_customer = $customer->id;
527 $invoice->id_order = $order->id;
528 $invoice->tipo_de_comprobante = $nubeFactCustomer['tipo_de_comprobante'];
529 $invoice->serie = $serie;
530 $invoice->numero = (int) $numero;
531 $invoice->cliente_tipo_de_documento = $nubeFactCustomer['cliente_tipo_de_documento'];
532 $invoice->cliente_numero_de_documento = trim($nubeFactCustomer['cliente_numero_de_documento']);
533 $invoice->cliente_denominacion = $nubeFactCustomer['cliente_denominacion'];
534 $invoice->cliente_direccion = $nubeFactCustomer['cliente_direccion'];
535 $invoice->cliente_email = $customer->email;
536 $invoice->fecha_de_emision = date( 'Y-m-d' );
537 $invoice->moneda = 1;
538 $invoice->porcentaje_de_igv = $this->get_percent_igv();
539 $invoice->descuento_global = $descuento_general;
540 $invoice->total_descuento = $total_descuentos;
541 $invoice->total_gravada = $sin_impuestos;
542 $invoice->total_igv = round( $incluido_impuestos - $sin_impuestos, 2 );
543 $invoice->total_gratuita = $totalGratis;
544 $invoice->total = $incluido_impuestos;
545
546
547 // validar que no existe ya la factura en nubefact y no este aceptada a la sunat
548 $query = new DbQuery();
549 $query->select('*');
550 $query->from('vex_nubefact_invoice');
551 $query->where('id_order = "'.$order->id.'" AND sunat_estado = 1');
552 $valueR = Db::getInstance()->executeS($query);
553
554 // si no existe en el registro la factura se envia a nubefact
555 if(empty($valueR)){
556 if( $response = $nubeFact->sendDocument( $document ) ){
557 // incrementar numero
558 // if( $nubeFactCustomer['tipo_de_comprobante'] == self::TIPOCOMPROBANTE_FACTURA ){
559 // Configuration::updateValue( self::CONFIG_INVOICE_NUM, $numero+1 );
560 // } else {
561 // Configuration::updateValue( self::CONFIG_RECEIPT_NUM, $numero+1 );
562 // }
563
564 $data = @json_decode( $response );
565
566 // guardar pdf url
567 $invoice->url_pdf = $data->enlace_del_pdf;
568 // respuesta sunat
569 $sunat = $data->aceptada_por_sunat;
570 if($sunat === true){
571 $invoice->sunat_estado = '1';
572 $invoice->sunat_respuesta_envio = $data->sunat_description;
573
574 // Insertamos data en ps_vex_invoices_sent tabla
575 $result = Db::getInstance()->insert('vex_invoices_sent', array(
576 'id_order' => $params['id_order'],
577 'date_add' => date("Y-m-d H:i:s"),
578 ));
579 $error = Db::getInstance()->getMsgError();
580
581 if ($result == true) {
582 self::logtxt("Registro guardado al ps_vex_invoices_sent con exito");
583 } else {
584 if ($error != '') {
585 self::logtxt($error);
586 }
587 self::logtxt("Hubo un error al intentar guardar en vex_invoices_sent");
588 }
589
590 }else{
591 $invoice->sunat_estado = '0';
592 $invoice->sunat_respuesta_envio = $data->sunat_description;
593
594 // Insertamos data en ps_vex_invoices_sent tabla
595 $result = Db::getInstance()->insert('vex_invoices_sent', array(
596 'id_order' => $params['id_order'],
597 'date_add' => date("Y-m-d H:i:s"),
598 ));
599 $error = Db::getInstance()->getMsgError();
600
601 if ($result == true) {
602 self::logtxt("Registro guardado al ps_vex_invoices_sent con exito");
603 } else {
604 if ($error != '') {
605 self::logtxt($error);
606 }
607 self::logtxt("Hubo un error al intentar guardar en vex_invoices_sent");
608 }
609
610 }
611 } else {
612 // var_export( [ $nubeFact->getClient(), $document->getArray() ] );
613 // exit();
614 }
615
616 $invoice->wp_data = $nubeFact->getClient()->response;
617 $invoice->add();
618 }
619
620 }
621 // $customer = new Customer($customer_id);
622
623 // $clientParams = array(
624 // 'cliente_email' => $customer->email,
625 // 'cliente_tipo_de_documento' => '',
626 // 'cliente_numero_de_documento' => '',
627 // 'cliente_denominacion' => '',
628 // 'cliente_direccion' => ''
629 // );
630
631 // $clientParams = array_merge( $clientParams, $nubeFactValues );
632
633 // var_export( [$params['id_order'], $order->id] );
634 // exit();
635
636 }//fin cambio de estado
637
638 }
639
640 // public function hookDisplayCustomerAccount(){
641 // $data = array();
642 // $this->context->smarty->assign( $data );
643
644 // return $this->display(__FILE__, 'customer-account.tpl');
645 // }
646
647 public function hookDisplayOrderDetail( $params ){
648 if( $invoice = Vex_Nubefact_Invoice::getByOrderId( $params['order']->id ) ){
649 $url_pdf = '';
650
651 if( empty( $invoice['url_pdf'] ) ){
652 $data = @json_decode( $invoice['wp_data'] );
653
654 if( isset( $data->enlace_del_pdf ) ){
655 $url_pdf = $data->enlace_del_pdf;
656 }
657 } else {
658 $url_pdf = $invoice['url_pdf'];
659 }
660
661 $this->context->smarty->assign( array(
662 'serie' => $invoice['serie'],
663 'numero' => str_pad( $invoice['numero'], 4, '0', STR_PAD_LEFT ),
664 'url_pdf' => $url_pdf
665 ) );
666
667 return $this->display(__FILE__, 'order-detail.tpl');
668 }
669 }
670
671 public function getContent(){
672 if( Tools::isSubmit( 'submit' . $this->name ) ){
673 $this->postProcess();
674
675 $id_orderM = $this->VEX_GET_ID_ORDER;
676 if($id_orderM){
677 // self::logtxt("Entered in manually mode... ID_Order: $id_orderM");
678 $this->sendDataManually($id_orderM);
679
680 }
681 }
682
683 return $this->displayForm();
684 }
685
686 protected function postProcess(){
687 $test_url = Configuration::get( self::CONFIG_TEST_URL, null, null, null, '' );
688 $test_token = Configuration::get( self::CONFIG_TEST_TOKEN, null, null, null, '' );
689
690 $live_url = Configuration::get( self::CONFIG_LIVE_URL, null, null, null, '' );
691 $live_token = Configuration::get( self::CONFIG_LIVE_TOKEN, null, null, null, '' );
692
693 // save credentials
694 if( Tools::getValue( self::CONFIG_LIVEMODE ) == 0 ){
695 if( ! Tools::getValue( self::CONFIG_TEST_URL ) ){
696 $this->context->controller->errors[] = $this->l('TEST URL required!');
697 } else {
698 $test_url = Tools::getValue( self::CONFIG_TEST_URL, '' );
699 }
700
701 if( ! Tools::getValue( self::CONFIG_TEST_TOKEN ) ){
702 $this->context->controller->errors[] = $this->l('TEST Token required!');
703 } else {
704 $test_token = Tools::getValue( self::CONFIG_TEST_TOKEN, '' );
705 }
706 } else {
707 if( ! Tools::getValue( self::CONFIG_LIVE_URL ) ){
708 $this->context->controller->errors[] = $this->l('LIVE URL required!');
709 } else {
710 $live_url = Tools::getValue( self::CONFIG_LIVE_URL, '' );
711 }
712
713 if( ! Tools::getValue( self::CONFIG_LIVE_TOKEN ) ){
714 $this->context->controller->errors[] = $this->l('LIVE Token required!');
715 } else {
716 $live_token = Tools::getValue( self::CONFIG_LIVE_TOKEN, '' );
717 }
718 }
719
720 // validate business ruc
721 if( ! Tools::getValue( self::CONFIG_BUSINESS_RUC ) ){
722 $this->context->controller->errors[] = $this->l('Business ruc required!');
723 }
724
725 // validate business name
726 if( ! Tools::getValue( self::CONFIG_BUSINESS_NAME ) ){
727 $this->context->controller->errors[] = $this->l('Business name required!');
728 }
729
730 // validate business address
731 if( ! Tools::getValue( self::CONFIG_BUSINESS_ADDRESS ) ){
732 $this->context->controller->errors[] = $this->l('Business address required!');
733 }
734
735 // validate receipt serie
736 if( ! Tools::getValue( self::CONFIG_RECEIPT_SERIE ) ){
737 $this->context->controller->errors[] = $this->l('Receipt serie required!');
738 }
739
740 // validate receipt num
741 if( ! Tools::getValue( self::CONFIG_RECEIPT_NUM ) ){
742 $this->context->controller->errors[] = $this->l('Receipt number required!');
743 }
744
745 // validate invoice serie
746 if( ! Tools::getValue( self::CONFIG_INVOICE_SERIE ) ){
747 $this->context->controller->errors[] = $this->l('Invoice serie required!');
748 }
749
750 // validate invoice num
751 if( ! Tools::getValue( self::CONFIG_INVOICE_NUM ) ){
752 $this->context->controller->errors[] = $this->l('Invoice number required!');
753 }
754
755 // validate invoice state
756 if( ! Tools::getValue( self::CONFIG_INVOICE_STATE ) ){
757 $this->context->controller->errors[] = $this->l('State number required!');
758 }
759
760 // validate api name
761 if( ! Tools::getValue( self::CONFIG_API_APPNAME ) ){
762 $this->context->controller->errors[] = $this->l('Api name required!');
763 }
764
765 // validate billing name
766 if( ! Tools::getValue( self::CONFIG_API_FE_BILLING_NAME ) ){
767 $this->context->controller->errors[] = $this->l('Billing name required!');
768 }
769
770 // validate token
771 if( ! Tools::getValue( self::CONFIG_FE_TOKEN_AUTO_INCREMENT_INVOICE ) ){
772 $this->context->controller->errors[] = $this->l('Token required!');
773 }
774
775 // validate api url
776 if( ! Tools::getValue( self::CONFIG_FE_URL_AUTO_INCREMENT_INVOICE ) ){
777 $this->context->controller->errors[] = $this->l('URL required!');
778 }
779
780 // validate factura suffix
781 if( ! Tools::getValue( self::CONFIG_FE_F_SUFFIX ) ){
782 $this->context->controller->errors[] = $this->l('Factura suffix required!');
783 }
784
785 // validate boleta suffix
786 if( ! Tools::getValue( self::CONFIG_FE_B_SUFFIX ) ){
787 $this->context->controller->errors[] = $this->l('Boleta suffix required!');
788 }
789
790
791
792 // save other fields
793 Configuration::updateValue( self::CONFIG_LIVEMODE, ( int ) Tools::getValue( self::CONFIG_LIVEMODE ) );
794 Configuration::updateValue( self::CONFIG_TEST_URL, $test_url );
795 Configuration::updateValue( self::CONFIG_TEST_TOKEN, $test_token );
796
797 Configuration::updateValue( self::CONFIG_LIVE_URL, $live_url );
798 Configuration::updateValue( self::CONFIG_LIVE_TOKEN, $live_token );
799 Configuration::updateValue( self::CONFIG_BUSINESS_RUC, Tools::getValue( self::CONFIG_BUSINESS_RUC ) );
800 Configuration::updateValue( self::CONFIG_BUSINESS_NAME, Tools::getValue( self::CONFIG_BUSINESS_NAME ) );
801 Configuration::updateValue( self::CONFIG_BUSINESS_ADDRESS, Tools::getValue( self::CONFIG_BUSINESS_ADDRESS ) );
802 Configuration::updateValue( self::CONFIG_RECEIPT_SERIE, Tools::getValue( self::CONFIG_RECEIPT_SERIE ) );
803 Configuration::updateValue( self::CONFIG_RECEIPT_NUM, Tools::getValue( self::CONFIG_RECEIPT_NUM ) );
804 Configuration::updateValue( self::CONFIG_INVOICE_SERIE, Tools::getValue( self::CONFIG_INVOICE_SERIE ) );
805 Configuration::updateValue( self::CONFIG_INVOICE_NUM, Tools::getValue( self::CONFIG_INVOICE_NUM ) );
806 Configuration::updateValue( self::CONFIG_INVOICE_STATE, Tools::getValue( self::CONFIG_INVOICE_STATE ) );
807 Configuration::updateValue( self::CONFIG_INVOICE_SUNAT_CODE, Tools::getValue( self::CONFIG_INVOICE_SUNAT_CODE ) );
808 Configuration::updateValue( self::CONFIG_API_APPNAME, Tools::getValue( self::CONFIG_API_APPNAME ) );
809 Configuration::updateValue( self::CONFIG_API_FE_BILLING_NAME, Tools::getValue( self::CONFIG_API_FE_BILLING_NAME ) );
810 Configuration::updateValue( self::CONFIG_FE_TOKEN_AUTO_INCREMENT_INVOICE, Tools::getValue( self::CONFIG_FE_TOKEN_AUTO_INCREMENT_INVOICE ) );
811 Configuration::updateValue( self::CONFIG_FE_URL_AUTO_INCREMENT_INVOICE, Tools::getValue( self::CONFIG_FE_URL_AUTO_INCREMENT_INVOICE ) );
812 Configuration::updateValue( self::CONFIG_FE_F_SUFFIX, Tools::getValue( self::CONFIG_FE_F_SUFFIX ) );
813 Configuration::updateValue( self::CONFIG_FE_B_SUFFIX, Tools::getValue( self::CONFIG_FE_B_SUFFIX ) );
814
815 if ( ! count( $this->context->controller->errors ) ) {
816 $this->context->controller->confirmations[] = $this->l('Settings saved successfully');
817 }
818 }
819
820 protected function displayForm(){
821 $default_lang = new Language( ( int ) Configuration::get( 'PS_LANG_DEFAULT' ) );
822
823 $helper = new HelperForm();
824 $helper->show_toolbar = true;
825 $helper->table = $this->table;
826 $helper->name_controller = $this->name;
827 $helper->default_form_language = $default_lang->id;
828 $helper->submit_action = 'submit' . $this->name;
829 $helper->currentIndex = $this->context->link->getAdminLink( 'AdminModules', false ) . '&configure=' . $this->name . '&tab_module=' . $this->tab . '&module_name=' . $this->name;
830 $helper->token = Tools::getAdminTokenLite( 'AdminModules' );
831
832 $helper->tpl_vars = array(
833 'fields_value' => $this->getConfigFieldsValues(),
834 'languages' => $this->context->controller->getLanguages(),
835 'id_language' => $this->context->language->id
836 );
837
838 $this->context->controller->addJS( $this->_path . 'views/js/backoffice.js' );
839
840 return $helper->generateForm( $this->getConfigForm() );
841 }
842
843 public function getConfigFieldsValues(){
844 return array(
845 self::CONFIG_LIVEMODE => Configuration::get( self::CONFIG_LIVEMODE ),
846 self::CONFIG_TEST_URL => Configuration::get( self::CONFIG_TEST_URL ),
847 self::CONFIG_TEST_TOKEN => Configuration::get( self::CONFIG_TEST_TOKEN ),
848 self::CONFIG_LIVE_URL => Configuration::get( self::CONFIG_LIVE_URL ),
849 self::CONFIG_LIVE_TOKEN => Configuration::get( self::CONFIG_LIVE_TOKEN ),
850 self::CONFIG_BUSINESS_RUC => Configuration::get( self::CONFIG_BUSINESS_RUC ),
851 self::CONFIG_BUSINESS_NAME => Configuration::get( self::CONFIG_BUSINESS_NAME ),
852 self::CONFIG_BUSINESS_ADDRESS => Configuration::get( self::CONFIG_BUSINESS_ADDRESS ),
853 self::CONFIG_INVOICE_STATE => Configuration::get( self::CONFIG_INVOICE_STATE ),
854 self::CONFIG_INVOICE_SUNAT_CODE => Configuration::get( self::CONFIG_INVOICE_SUNAT_CODE ),
855 self::CONFIG_API_APPNAME => Configuration::get( self::CONFIG_API_APPNAME ),
856 self::CONFIG_API_FE_BILLING_NAME => Configuration::get( self::CONFIG_API_FE_BILLING_NAME ),
857 self::CONFIG_FE_TOKEN_AUTO_INCREMENT_INVOICE => Configuration::get( self::CONFIG_FE_TOKEN_AUTO_INCREMENT_INVOICE ),
858 self::CONFIG_FE_URL_AUTO_INCREMENT_INVOICE => Configuration::get( self::CONFIG_FE_URL_AUTO_INCREMENT_INVOICE ),
859 self::CONFIG_FE_F_SUFFIX => Configuration::get( self::CONFIG_FE_F_SUFFIX ),
860 self::CONFIG_FE_B_SUFFIX => Configuration::get( self::CONFIG_FE_B_SUFFIX ),
861 'VEX_GET_ID_ORDER' => Tools::getValue('VEX_GET_ID_ORDER'),
862 'VEX_SET_DATE_INVOICE' => Tools::getValue('VEX_SET_DATE_INVOICE'),
863 );
864 }
865
866 protected function getConfigForm(){
867 $testmode_form = array(
868 'form' => array(
869 'legend' => array(
870 'title' => $this->l('Environment'),
871 'icon' => 'icon-wrench'
872 ),
873 'input' => array(
874 array(
875 'type' => 'switch',
876 'label' => $this->l('Live mode'),
877 'name' => self::CONFIG_LIVEMODE,
878 'is_bool' => true,
879 'desc' => $this->l('Choose between live or test mode'),
880 'values' => array(
881 array(
882 'id' => 'active_on',
883 'value' => 1,
884 'label' => $this->l('Live')
885 ),
886 array(
887 'id' => 'active_off',
888 'value' => 0,
889 'label' => $this->l('Test')
890 )
891 )
892 )
893 ),
894 'submit' => array(
895 'title' => $this->l('Save')
896 )
897 )
898 );
899
900 $credentials_form = array(
901 'form' => array(
902 'legend' => array(
903 'title' => $this->l('API credentials'),
904 'icon' => 'icon-user'
905 ),
906 'input' => array(
907 array(
908 'type' => 'text',
909 'label' => $this->l('TEST URL'),
910 'name' => self::CONFIG_TEST_URL,
911 'placeholder' => 'https://api.nubefact.com/api/v1/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx',
912 'class' => 'test-field',
913 'required' => true
914 ),
915 array(
916 'type' => 'text',
917 'label' => $this->l('TEST Token'),
918 'name' => self::CONFIG_TEST_TOKEN,
919 'placeholder' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
920 'class' => 'test-field',
921 'required' => true
922 ),
923 array(
924 'type' => 'text',
925 'label' => $this->l('LIVE URL'),
926 'name' => self::CONFIG_LIVE_URL,
927 'placeholder' => 'https://api.nubefact.com/api/v1/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx',
928 'class' => 'live-field',
929 'required' => true
930 ),
931 array(
932 'type' => 'text',
933 'label' => $this->l('LIVE Token'),
934 'name' => self::CONFIG_LIVE_TOKEN,
935 'placeholder' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
936 'class' => 'live-field',
937 'required' => true
938 )
939 ),
940 'submit' => array(
941 'title' => $this->l('Save')
942 )
943 )
944 );
945
946 $business_data_form = array(
947 'form' => array(
948 'legend' => array(
949 'title' => $this->l('Business data'),
950 'icon' => 'icon-wrench'
951 ),
952 'input' => array(
953 array(
954 'type' => 'text',
955 'label' => $this->l('RUC'),
956 'name' => self::CONFIG_BUSINESS_RUC,
957 'placeholder' => '20xxxxxxxxx',
958 'class' => 'fixed-width-xxl',
959 'required' => true
960 ),
961 array(
962 'type' => 'text',
963 'label' => $this->l('Business name'),
964 'name' => self::CONFIG_BUSINESS_NAME,
965 'placeholder' => 'My little shop',
966 'required' => true
967 ),
968 array(
969 'type' => 'text',
970 'label' => $this->l('Business address'),
971 'name' => self::CONFIG_BUSINESS_ADDRESS,
972 'placeholder' => 'Av. xxxxxx #9999',
973 'required' => true
974 ),
975 ),
976 'submit' => array(
977 'title' => $this->l('Save')
978 )
979 )
980 );
981
982 $general_parameters_form = array(
983 'form' => array(
984 'legend' => array(
985 'title' => $this->l('General parameters'),
986 'icon' => 'icon-wrench'
987 ),
988 'input' => array(
989 array(
990 'type' => 'html',
991 'html_content' => $this->billFields( array(
992 'prefix' => 'B',
993 'serie' => array(
994 'name' => self::CONFIG_RECEIPT_SERIE,
995 'value' => Configuration::get( self::CONFIG_RECEIPT_SERIE ),
996 'placeholder' => '001'
997 ),
998 'num' => array(
999 'name' => self::CONFIG_RECEIPT_NUM,
1000 'value' => Configuration::get( self::CONFIG_RECEIPT_NUM ),
1001 'placeholder' => '0001'
1002 )
1003 ) ),
1004 'label' => $this->l('Receipt series'),
1005 'name' => self::CONFIG_RECEIPT_SERIE,
1006 'required' => true
1007 ),
1008 array(
1009 'type' => 'html',
1010 'html_content' => $this->billFields( array(
1011 'prefix' => 'F',
1012 'serie' => array(
1013 'name' => self::CONFIG_INVOICE_SERIE,
1014 'value' => Configuration::get( self::CONFIG_INVOICE_SERIE ),
1015 'placeholder' => '001'
1016 ),
1017 'num' => array(
1018 'name' => self::CONFIG_INVOICE_NUM,
1019 'value' => Configuration::get( self::CONFIG_INVOICE_NUM ),
1020 'placeholder' => '0001'
1021 )
1022 ) ),
1023 'label' => $this->l('Invoice series'),
1024 'name' => self::CONFIG_INVOICE_SERIE,
1025 'required' => true
1026 ),
1027 array(
1028 'type' => 'text',
1029 'label' => $this->l('State Number'),
1030 'name' => self::CONFIG_INVOICE_STATE,
1031 'placeholder' => 'Set the state number id here',
1032 'class' => 'fixed-width-xxl',
1033 'required' => true
1034 ),
1035 array(
1036 'type' => 'text',
1037 'label' => $this->l('Sunat Product Code'),
1038 'name' => self::CONFIG_INVOICE_SUNAT_CODE,
1039 'placeholder' => 'Set the sunat product code here',
1040 'class' => 'fixed-width-xxl',
1041 'required' => true
1042 ),
1043 array(
1044 'type' => 'text',
1045 'label' => $this->l('API Name'),
1046 'name' => self::CONFIG_API_APPNAME,
1047 'placeholder' => 'Api name for invoice number consecutive',
1048 'class' => 'fixed-width-xxl',
1049 'required' => true
1050 ),
1051 array(
1052 'type' => 'text',
1053 'label' => $this->l('Billing Name'),
1054 'name' => self::CONFIG_API_FE_BILLING_NAME,
1055 'placeholder' => 'Ej: FARMALATAM',
1056 'class' => 'fixed-width-xxl',
1057 'required' => true
1058 ),
1059 array(
1060 'type' => 'text',
1061 'label' => $this->l('API Token'),
1062 'name' => self::CONFIG_FE_TOKEN_AUTO_INCREMENT_INVOICE,
1063 'placeholder' => '',
1064 'class' => 'fixed-width-xxl',
1065 'required' => true
1066 ),
1067 array(
1068 'type' => 'text',
1069 'label' => $this->l('URL API'),
1070 'name' => self::CONFIG_FE_URL_AUTO_INCREMENT_INVOICE,
1071 'placeholder' => '',
1072 'class' => 'fixed-width-xxl',
1073 'required' => true
1074 ),
1075 array(
1076 'type' => 'text',
1077 'label' => $this->l('Factura Suffix'),
1078 'name' => self::CONFIG_FE_F_SUFFIX,
1079 'placeholder' => '',
1080 'class' => 'fixed-width-xxl',
1081 'required' => true
1082 ),
1083 array(
1084 'type' => 'text',
1085 'label' => $this->l('Boleta Suffix'),
1086 'name' => self::CONFIG_FE_B_SUFFIX,
1087 'placeholder' => '',
1088 'class' => 'fixed-width-xxl',
1089 'required' => true
1090 ),
1091
1092
1093 ),
1094 'submit' => array(
1095 'title' => $this->l('Save')
1096 )
1097 )
1098 );
1099
1100 $sendManualInvoice = array(
1101 // Send manually data
1102 'form' => array(
1103 'legend' => array(
1104 'title' => $this->l('Send Manual Invoice'),
1105 'icon' => 'icon-terminal',
1106 ),
1107 'input' => array(
1108 array(
1109 'col' => 3,
1110 'type' => 'text',
1111 'prefix' => '<i class="icon icon-gears"></i>',
1112 'desc' => $this->l('Enter order id'),
1113 'name' => 'VEX_GET_ID_ORDER',
1114 'label' => $this->l('Order ID'),
1115 ),
1116 array(
1117 'col' => 9,
1118 'type' => 'date',
1119 'prefix' => '<i class="icon icon-calendar"></i>',
1120 'desc' => $this->l('Enter invoice date'),
1121 'name' => 'VEX_SET_DATE_INVOICE',
1122 'label' => $this->l('Invoice Date'),
1123 ),
1124 ),
1125 'submit' => array(
1126 'title' => $this->l('Send'),
1127 ),
1128 ),
1129 );
1130
1131 return array( $testmode_form, $credentials_form, $business_data_form, $general_parameters_form, $sendManualInvoice );
1132 }
1133
1134 private function billFields( $params ){
1135 $serie_value = isset($params['serie']['value']) ? $params['serie']['value'] : '';
1136 $num_value = isset($params['num']['value']) ? $params['num']['value'] : '';
1137
1138 return <<<EOF
1139<div class="form-inline">
1140 <div class="form-group">
1141 <div class="input-group">
1142 <div class="input-group-addon">{$params['prefix']}</div>
1143 <input type="text" class="form-control" name="{$params['serie']['name']}" id="{$params['serie']['name']}" value="{$serie_value}" placeholder="{$params['serie']['placeholder']}">
1144 </div>
1145 </div>
1146 <div class="form-group hidden-xs"> - </div>
1147 <div class="form-group">
1148 <input type="text" class="form-control" name="{$params['num']['name']}" id="{$params['num']['name']}" value="{$num_value}" placeholder="{$params['num']['placeholder']}">
1149 </div>
1150</div>
1151EOF;
1152 }
1153
1154 // methods
1155 public function is_test_mode(){
1156 return '0' == Configuration::get( self::CONFIG_LIVEMODE, null, null, null, '0' );
1157 }
1158
1159 public function get_url(){
1160 if( $this->is_test_mode() ){
1161 return Configuration::get( self::CONFIG_TEST_URL, null, null, null, '' );
1162 } else {
1163 return Configuration::get( self::CONFIG_LIVE_URL, null, null, null, '' );
1164 }
1165 }
1166
1167 public function get_token(){
1168 if( $this->is_test_mode() ){
1169 return Configuration::get( self::CONFIG_TEST_TOKEN, null, null, null, '' );
1170 } else {
1171 return Configuration::get( self::CONFIG_LIVE_TOKEN, null, null, null, '' );
1172 }
1173 }
1174
1175 public function get_percent_igv(){
1176 return '18.00';
1177 // return Configuration::get( self::CONFIG_TEST_TOKEN, null, null, null, '' );
1178 }
1179
1180 private function getFeaturesProductOrder($id_otrder = 0)
1181 {
1182 $return = array();
1183 $query = new DbQuery();
1184 $query->select('psfp.id_product, psfl.name, psfv.value');
1185 $query->from('feature_product', 'psfp');
1186 $query->join('INNER JOIN`' . _DB_PREFIX_ . 'feature_lang` psfl ON psfl.`id_feature` = psfp.`id_feature` AND psfl.`name` = "codigo_producto_sunat"');
1187 $query->join('INNER JOIN`' . _DB_PREFIX_ . 'feature_value_lang` psfv ON psfv.`id_feature_value` = psfp.`id_feature_value`');
1188 $query->join('INNER JOIN`' . _DB_PREFIX_ . 'order_detail` psod ON psfp.`id_product` = psod.`product_id`');
1189 $query->where('psod.`id_order` = "' . (int) $id_otrder . '"');
1190 $query->groupBy('psfl.name');
1191
1192 if ($result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query)) {
1193
1194 foreach ($result as $value) {
1195 $return[$value['id_product']] = $value;
1196 unset($return[$value['id_product']]['id_product']);
1197 }
1198 }
1199 return $return;
1200 }
1201
1202 public function hookActionObjectCustomerAddAfter($params)
1203 {
1204 $customer = $params['object'];
1205 self::updateDataInvoice($customer);
1206 }
1207
1208 public function hookActionCustomerAccountUpdate($params)
1209 {
1210
1211 }
1212
1213 public function hookActionDispatcherBefore()
1214 {
1215 // error_log('<< hookActionDispatcherBefore >>');
1216 }
1217
1218 public function hookDisplayAdminCustomersForm($params)
1219 {
1220 $this->context->controller->addJS($this->_path . '/views/js/backoffice.js');
1221
1222 // https://api.sunat.cloud/ruc/10403322097
1223 // https://cors-anywhere.herokuapp.com/wmtechnology.org/Consultar-RUC/?modo=1&btnBuscar=Buscar&nruc=10403322097
1224 $this->getDataInvoiceForm();
1225 return $this->display(__FILE__, 'views/templates/hook/customer_invoice.tpl');
1226 }
1227
1228 private function getDataInvoiceForm()
1229 {
1230
1231 // load saved values
1232 $values = array();
1233 $id_customer = (int) (! empty($this->context->customer->id) ? $this->context->customer->id : Tools::getValue('id_customer'));
1234
1235 if (! empty($id_customer) && $nubeFactCustomer = Vex_Nubefact_Customer::getByCustomerId($id_customer)) {
1236 $values = $nubeFactCustomer;
1237 unset($values['date_add'], $values['cart_id'], $values['customer_id'], $values['id']);
1238 }
1239
1240 $staticData = array(
1241 'tiposDeComprobantes' => array(
1242 '1' => 'Factura',
1243 '2' => 'Boleta'
1244 ),
1245 'tiposDeDocumentosCliente' => array(
1246 '1' => 'DNI',
1247 '4' => 'Carnet de extranjeria',
1248 '6' => 'RUC',
1249 '7' => 'Pasaporte'
1250 ),
1251 'tipo_de_comprobante' => '',
1252 'cliente_tipo_de_documento' => '',
1253 'cliente_numero_de_documento' => '',
1254 'cliente_denominacion' => '',
1255 'cliente_direccion' => ''
1256 );
1257
1258 $data = array_merge($staticData, $values);
1259
1260 $this->context->smarty->assign($data);
1261 }
1262
1263 public static function updateDataInvoice($customer = null)
1264 {
1265 $tipo_de_comprobante = pSQL(Tools::getValue('tipo_comprobante'));
1266
1267 if ($tipo_de_comprobante == Vex_Nubefact::TIPOCOMPROBANTE_FACTURA) {
1268 $tipo_documento_cliente = Vex_Nubefact::TIPODOCUMENTO_RUC;
1269 } else {
1270 $tipo_documento_cliente = pSQL(Tools::getValue('tipo_de_documento_cliente'));
1271 }
1272
1273 $context = Context::getContext();
1274
1275 if (empty($customer))
1276 $customer = $context->customer;
1277
1278 $tipo_de_comprobante = $tipo_documento_cliente == 6 ? 1 : 2;
1279
1280 $data = array(
1281 'customer_id' => (int) $customer->id,
1282 'cart_id' => (int) $context->cart->id,
1283 'tipo_de_comprobante' => $tipo_de_comprobante,
1284 'cliente_tipo_de_documento' => $tipo_documento_cliente,
1285 'cliente_numero_de_documento' => pSQL(Tools::getValue('numero_documento')),
1286 'cliente_denominacion' => pSQL(Tools::getValue('cliente_denominacion')),
1287 'cliente_direccion' => pSQL(Tools::getValue('domicilio_facturacion'))
1288 );
1289
1290 $nubeFactCustomerId = 0;
1291 if ($nubeFactCustomer = Vex_Nubefact_Customer::getByCustomerId($data['customer_id'])) {
1292 $nubeFactCustomerId = $nubeFactCustomer['id'];
1293 }
1294
1295 $nubeFactCustomer = new Vex_Nubefact_Customer($nubeFactCustomerId);
1296
1297 $nubeFactCustomer->customer_id = (int) $customer->id;
1298 $nubeFactCustomer->cart_id = (int) $context->cart->id;
1299 $nubeFactCustomer->tipo_de_comprobante = (string) $tipo_de_comprobante;
1300 $nubeFactCustomer->cliente_tipo_de_documento = (string) $tipo_documento_cliente;
1301 $nubeFactCustomer->cliente_numero_de_documento = pSQL(Tools::getValue('numero_documento'));
1302 $nubeFactCustomer->cliente_denominacion = pSQL(Tools::getValue('cliente_denominacion'));
1303 $nubeFactCustomer->cliente_direccion = pSQL(Tools::getValue('domicilio_facturacion'));
1304
1305 try {
1306 return $nubeFactCustomer->save();
1307 } catch (Exception $e) {
1308 error_log('"vex_nubefact" mssage: ' . $e->getMessage());
1309 return false;
1310 }
1311 }
1312
1313 /**
1314 * Function for send data manually
1315 * getting id_order.
1316 */
1317 public function sendDataManually($id_order)
1318 {
1319 self::logtxt("Entro a: sendDataManually");
1320 $stateID = trim(Configuration::get( self::CONFIG_INVOICE_STATE ));
1321
1322 // value if state changed is equal to (CONFIG_INVOICE_STATE)
1323 $order = new Order($id_order);
1324 if($order->current_state == $stateID) {
1325
1326 $customer_id = $order->id_customer;
1327 $id_cart = $order->id_cart;
1328
1329 // evalua si es gratuita o no
1330 if($order->total_paid_tax_incl == 0){
1331 $incluido_impuestos = 0; // total incluido impuesto
1332 $sin_impuestos = 0; // total sin impuesto
1333 }else{
1334 // $incluido_impuestos = $order->total_products_wt; // total incluido impuesto
1335 // $sin_impuestos = $order->total_products; // total sin impuesto
1336 $incluido_impuestos = $order->total_paid_tax_incl; // total incluido impuesto
1337 $sin_impuestos = $order->total_paid_tax_excl; // total sin impuesto
1338 }
1339
1340 $totalGratis = 0;
1341 $sumaDescuentoItems = 0;
1342 // load saved values
1343 // $nubeFactValues = array();
1344 if( $nubeFactCustomer = Vex_Nubefact_Customer::getByCustomerId( $customer_id ) ) {
1345 // $nubeFactValues = $nubeFactCustomer;
1346 // unset( $nubeFactValues['date_add'], $nubeFactValues['cart_id'] );
1347 // unset( $nubeFactValues['customer_id'], $nubeFactValues['id'] );
1348 $customer = new Customer($customer_id);
1349
1350 $url = $this->get_url();
1351 $token = $this->get_token();
1352
1353 $nubeFact = new Vex_PrestaShop_NubeFact( $url, $token );
1354
1355 if( $nubeFactCustomer['tipo_de_comprobante'] == self::TIPOCOMPROBANTE_FACTURA ){
1356 require_once dirname( __FILE__ ) . '/classes/NubeFact/FacturaElectronica.php';
1357 $document = new Vex_FacturaElectronica();
1358
1359 $serie = 'F' . Configuration::get( self::CONFIG_INVOICE_SERIE );
1360 // $numero = Configuration::get( self::CONFIG_INVOICE_NUM );
1361
1362 // consulta consecutivo en api
1363 $AutoIncrementInvoice = new stdClass();
1364 $AutoIncrementInvoice->aplicationName = Configuration::get(self::CONFIG_API_APPNAME);
1365 $AutoIncrementInvoice->billingName = Configuration::get(self::CONFIG_API_FE_BILLING_NAME);
1366 $AutoIncrementInvoice->idCart = $id_cart;
1367 $AutoIncrementInvoice->idOrder = $id_order;
1368 $AutoIncrementInvoice->token = Configuration::get(self::CONFIG_FE_TOKEN_AUTO_INCREMENT_INVOICE);
1369 $AutoIncrementInvoice->suffix = Configuration::get(self::CONFIG_FE_F_SUFFIX);
1370 $AutoIncrementInvoice->production = true;
1371
1372 $data_string = json_encode($AutoIncrementInvoice);
1373
1374 $ch = curl_init(Configuration::get(self::CONFIG_FE_URL_AUTO_INCREMENT_INVOICE));
1375 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
1376 curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
1377 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
1378 curl_setopt($ch, CURLOPT_HTTPHEADER, array(
1379 'Content-Type: application/json',
1380 'Content-Length: ' . strlen($data_string)
1381 ));
1382
1383 $response = curl_exec($ch);
1384
1385 $responseArray = json_decode($response, true);
1386 $numero = $responseArray['invoiceNumber'];
1387
1388 } else {
1389 require_once dirname( __FILE__ ) . '/classes/NubeFact/BoletaElectronica.php';
1390 $document = new Vex_BoletaElectronica();
1391
1392 $serie = 'B' . Configuration::get( self::CONFIG_RECEIPT_SERIE );
1393 // $numero = Configuration::get( self::CONFIG_RECEIPT_NUM );
1394
1395 // consulta consecutivo en api
1396 $AutoIncrementInvoice = new stdClass();
1397 $AutoIncrementInvoice->aplicationName = Configuration::get(self::CONFIG_API_APPNAME);
1398 $AutoIncrementInvoice->billingName = Configuration::get(self::CONFIG_API_FE_BILLING_NAME);
1399 $AutoIncrementInvoice->idCart = $id_cart;
1400 $AutoIncrementInvoice->idOrder = $id_order;
1401 $AutoIncrementInvoice->token = Configuration::get(self::CONFIG_FE_TOKEN_AUTO_INCREMENT_INVOICE);
1402 $AutoIncrementInvoice->suffix = Configuration::get(self::CONFIG_FE_B_SUFFIX);
1403 $AutoIncrementInvoice->production = true;
1404
1405 $data_string = json_encode($AutoIncrementInvoice);
1406
1407 $ch = curl_init(Configuration::get(self::CONFIG_FE_URL_AUTO_INCREMENT_INVOICE));
1408 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
1409 curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
1410 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
1411 curl_setopt($ch, CURLOPT_HTTPHEADER, array(
1412 'Content-Type: application/json',
1413 'Content-Length: ' . strlen($data_string)
1414 ));
1415
1416 $response = curl_exec($ch);
1417
1418 $responseArray = json_decode($response, true);
1419 $numero = $responseArray['invoiceNumber'];
1420 }
1421
1422 $document->setSunatEnvioAutomatico( true );
1423 $document->setSerie( $serie );
1424 $document->setNumero( $numero );
1425
1426 $document->setCliente( array(
1427 'cliente_tipo_de_documento' => $nubeFactCustomer['cliente_tipo_de_documento'],
1428 'cliente_numero_de_documento' => trim($nubeFactCustomer['cliente_numero_de_documento']),
1429 'cliente_denominacion' => $nubeFactCustomer['cliente_denominacion'],
1430 'cliente_direccion' => $nubeFactCustomer['cliente_direccion']
1431 ) );
1432
1433 $document->addClienteEmail( $customer->email );
1434
1435 // $currency = new Currency($order->id_currency);
1436 // $currencies = array(
1437 // 'PEN' => Vex_DocumentContract::$SOL,
1438 // 'USD' => Vex_DocumentContract::$DOLAR,
1439 // 'EUR' => Vex_DocumentContract::$EURO,
1440 // );
1441
1442 // var_export( [$currency, $nubeFactCustomer] );
1443
1444
1445 // $document->setMoneda( $currencies[ $currency->iso_code ] );
1446
1447 // $document->setTipoCambio();
1448 $document->setPorcentajeIGV( $this->get_percent_igv() );
1449 $document->setTotal( $incluido_impuestos );
1450 $document->setTotalIGV( round( $incluido_impuestos - $sin_impuestos, 2 ) );
1451 $document->setTotalGravada( $sin_impuestos );
1452 // $document->setTotalInafecta();
1453 // $document->setDetraccion();
1454 // $document->setObservaciones();
1455
1456 $features = $this->getFeaturesProductOrder($order->id);
1457
1458 $giftFlag = false;
1459 $dproductFlag = false;
1460
1461 foreach ( $order->getProducts() as $productDetail ) {
1462 $TotalConImpuesto = $productDetail['total_price_tax_incl'];
1463 $TotalSinImpuesto = $productDetail['total_price_tax_excl'];
1464 $discounts = $productDetail['reduction_percent'];
1465 $discountAmount = $productDetail['reduction_amount_tax_excl'];
1466 $valorUnitario = $productDetail['original_product_price'];
1467 $impuestoUnitario = ($valorUnitario * (int) $this->get_percent_igv()) / 100;
1468 $precioUnitario = round($valorUnitario + $impuestoUnitario, 2);
1469 $tipoIGV = '1';
1470 $IGV = $TotalConImpuesto - $TotalSinImpuesto;
1471 $total = $TotalConImpuesto;
1472 $descuento = 0;
1473 $subtotal = ($valorUnitario * $productDetail['product_quantity']) - $descuento;
1474
1475 // descuento por producto
1476 if($discounts > 0) {
1477 self::logtxt("Descuento por producto! - Percent");
1478 $descuento = ($valorUnitario * $discounts / 100);
1479 $sumaDescuentoItems += $descuento;
1480 $subtotal = ($valorUnitario - $descuento) * ($productDetail['product_quantity']);
1481 $IGV = ($subtotal * (int) $this->get_percent_igv()) / 100;
1482 $dproductFlag = true;
1483
1484 if($discounts == 100) {
1485 // Si el producto es gratuito
1486 self::logtxt("Producto gratuito");
1487 $giftFlag = true;
1488 $precioUnitario = $valorUnitario;
1489 $subtotal = ($valorUnitario * $productDetail['product_quantity']);
1490 $tipoIGV = '6';
1491 $IGV = 0;
1492 $total = $subtotal;
1493 $totalGratis += $subtotal;
1494 $descuento = 0;
1495 }
1496
1497 }elseif($discountAmount > 0){
1498 self::logtxt("Descuento por producto! - Amount");
1499 $descuento = $discountAmount;
1500 $sumaDescuentoItems += $discountAmount;
1501 $subtotal = ($valorUnitario - $descuento) * ($productDetail['product_quantity']);
1502 $IGV = ($subtotal * (int) $this->get_percent_igv()) / 100;
1503 $dproductFlag = true;
1504
1505 }
1506
1507 if(!empty($features[$productDetail['product_id']]['value']))
1508 $codigo_producto_sunat = $features[$productDetail['product_id']]['value'];
1509 else
1510 $codigo_producto_sunat = Configuration::get( self::CONFIG_INVOICE_SUNAT_CODE );
1511
1512 // evalua si es gratuito o no
1513 if($order->total_paid_tax_incl == 0){
1514 $totalGratis += $subtotal;
1515 $precioUnitario = $valorUnitario;
1516 $subtotal = ($valorUnitario * $productDetail['product_quantity']);
1517 $tipoIGV = '6';
1518 $IGV = 0;
1519 $total = $valorUnitario;
1520 }
1521
1522 $document->addItem( array(
1523 'unidad_de_medida' => 'NIU',
1524 'codigo' => $productDetail['product_id'],
1525 'descripcion' => $productDetail['product_name'],
1526 'cantidad' => $productDetail['product_quantity'],
1527 'valor_unitario' => $valorUnitario, // unitario sin impuesto
1528 'precio_unitario' => $precioUnitario, // unitario con impuesto
1529 'descuento' => $descuento,
1530 'subtotal' => $subtotal,
1531 'tipo_de_igv' => $tipoIGV,
1532 'igv' => $IGV,
1533 'total' => $total,
1534 'anticipo_regularizacion' => 'false',
1535 'anticipo_documento_serie' => '',
1536 'anticipo_documento_numero' => '',
1537 'codigo_producto_sunat' => $codigo_producto_sunat //Fórmulas y productos para apoyo nutritivo
1538 ) );
1539 }
1540
1541 // transporte
1542 $shipping_sin_impuestos = $order->total_shipping_tax_excl; // total transporte sin impuesto
1543 $shipping_con_impuestos = $order->total_shipping_tax_incl; // total transporte sin impuesto
1544 $precioUnitario = round($shipping_con_impuestos, 2);
1545 $tipoIGV = '1';
1546 $IGV = $shipping_con_impuestos - $shipping_sin_impuestos;
1547 $total = $shipping_con_impuestos;
1548 if ($shipping_sin_impuestos > 0) {
1549 // evalua si es gratuito o no
1550 if($order->total_paid_tax_incl == 0){
1551 $precioUnitario = $shipping_sin_impuestos;
1552 $tipoIGV = '6';
1553 $IGV = 0;
1554 $total = $shipping_sin_impuestos;
1555 }
1556
1557 $document->addItem( array(
1558 'unidad_de_medida' => 'ZZ',
1559 'codigo' => '001',
1560 'descripcion' => 'Costo de envío',
1561 'cantidad' => '1',
1562 'valor_unitario' => $shipping_sin_impuestos, // unitario sin impuesto
1563 'precio_unitario' => $precioUnitario, // unitario con impuesto
1564 'descuento' => '',
1565 'subtotal' => $shipping_sin_impuestos,
1566 'tipo_de_igv' => $tipoIGV,
1567 'igv' => $IGV,
1568 'total' => $total,
1569 'anticipo_regularizacion' => 'false',
1570 'anticipo_documento_serie' => '',
1571 'anticipo_documento_numero' => '',
1572 'codigo_producto_sunat' => '78140000' //Servicios de transporte
1573 ) );
1574 }
1575
1576 // $document->setCodigoUnico();
1577
1578 // var_export( $document->getArray() );
1579
1580 // descuento general
1581 $total_descuentos = 0;
1582 $descuento_general = 0;
1583 if($order->total_discounts > 0){
1584 $descuento_general = $order->total_discounts_tax_excl; // total descuento orden
1585 }
1586 $total_descuentos = $descuento_general + $sumaDescuentoItems;
1587
1588 // si hay descuento general y por item
1589 if($order->total_discounts > 0 && $dproductFlag == true){
1590 $descuento_general = $order->total_discounts_tax_excl; // total descuento orden
1591 $total_descuentos = $sumaDescuentoItems;
1592 }
1593 $document->setDescuentoGlobal( $descuento_general );
1594 $document->setTotalDescuento( $total_descuentos );
1595
1596 // si es gratuita o no
1597 if($order->total_paid_tax_incl == 0){
1598 $document->setTotalGratis( $totalGratis );
1599 }
1600
1601 // si existe un producto gratuito
1602 if($giftFlag == true){
1603 $document->setTotalGratis( $totalGratis );
1604 }
1605
1606 // si por configuración no se obtiene la fecha de emisión se toma la actual
1607 if($this->VEX_SET_DATE_INVOICE){
1608 $fechaEmision = $this->VEX_SET_DATE_INVOICE;
1609 $date = date_create($fechaEmision);
1610 $document->setFechaEmision( date_format($date,"d-m-Y") );
1611 }else{
1612 $fechaEmision = date( 'd-m-Y' );
1613 $document->setFechaEmision( $fechaEmision );
1614 }
1615
1616 // Evalua el tipo de documento para saber el tipo de transacción (segun sunat) - By Alekuoshu
1617 if((int) $nubeFactCustomer['cliente_tipo_de_documento'] == 4 || (int) $nubeFactCustomer['cliente_tipo_de_documento'] == 7){
1618 $document->setSunatTransaction( 29 ); // Venta no domiciliados que no califican como exportación
1619 }elseif((int) $nubeFactCustomer['cliente_tipo_de_documento'] == 0){
1620 $document->setSunatTransaction( 2 ); // Exportanción
1621 }else{
1622 $document->setSunatTransaction( 1 ); // Venta Interna
1623 }
1624
1625 //create invoice
1626 $invoice = new Vex_Nubefact_Invoice();
1627
1628 $invoice->id_customer = $customer->id;
1629 $invoice->id_order = $order->id;
1630 $invoice->tipo_de_comprobante = $nubeFactCustomer['tipo_de_comprobante'];
1631 $invoice->serie = $serie;
1632 $invoice->numero = (int) $numero;
1633 $invoice->cliente_tipo_de_documento = $nubeFactCustomer['cliente_tipo_de_documento'];
1634 $invoice->cliente_numero_de_documento = trim($nubeFactCustomer['cliente_numero_de_documento']);
1635 $invoice->cliente_denominacion = $nubeFactCustomer['cliente_denominacion'];
1636 $invoice->cliente_direccion = $nubeFactCustomer['cliente_direccion'];
1637 $invoice->cliente_email = $customer->email;
1638 $invoice->fecha_de_emision = $fechaEmision;
1639 $invoice->moneda = 1;
1640 $invoice->porcentaje_de_igv = $this->get_percent_igv();
1641 $invoice->descuento_global = $descuento_general;
1642 $invoice->total_descuento = $total_descuentos;
1643 $invoice->total_gravada = $sin_impuestos;
1644 $invoice->total_igv = round( $incluido_impuestos - $sin_impuestos, 2 );
1645 $invoice->total_gratuita = $totalGratis;
1646 $invoice->total = $incluido_impuestos;
1647
1648 // Get json for sent to log
1649 $jsonEnviado = json_encode($document->getArray());
1650 self::logtxt("Json_enviado: ".$jsonEnviado);
1651
1652
1653 // validar que no existe ya la factura en nubefact y no este aceptada a la sunat
1654 $query = new DbQuery();
1655 $query->select('*');
1656 $query->from('vex_nubefact_invoice');
1657 $query->where('id_order = "'.$order->id.'" AND sunat_estado = 1');
1658 $valueR = Db::getInstance()->executeS($query);
1659
1660 // si no existe en el registro la factura se envia a nubefact
1661 if(empty($valueR)){
1662 if( $response = $nubeFact->sendDocument( $document ) ){
1663 // incrementar numero
1664 // if( $nubeFactCustomer['tipo_de_comprobante'] == self::TIPOCOMPROBANTE_FACTURA ){
1665 // Configuration::updateValue( self::CONFIG_INVOICE_NUM, $numero+1 );
1666 // } else {
1667 // Configuration::updateValue( self::CONFIG_RECEIPT_NUM, $numero+1 );
1668 // }
1669
1670 $data = @json_decode( $response );
1671
1672 // guardar pdf url
1673 $invoice->url_pdf = $data->enlace_del_pdf;
1674 // respuesta sunat
1675 $sunat = $data->aceptada_por_sunat;
1676 if($sunat === true){
1677 $invoice->sunat_estado = '1';
1678 $invoice->sunat_respuesta_envio = $data->sunat_description;
1679
1680 // Insertamos data en ps_vex_invoices_sent tabla
1681 $result = Db::getInstance()->insert('vex_invoices_sent', array(
1682 'id_order' => $id_order,
1683 'date_add' => date("Y-m-d H:i:s"),
1684 ));
1685 $error = Db::getInstance()->getMsgError();
1686
1687 if ($result == true) {
1688 self::logtxt("Registro guardado al ps_vex_invoices_sent con exito");
1689 } else {
1690 if ($error != '') {
1691 self::logtxt($error);
1692 }
1693 self::logtxt("Hubo un error al intentar guardar en vex_invoices_sent");
1694 }
1695
1696 }else{
1697 $invoice->sunat_estado = '0';
1698 $invoice->sunat_respuesta_envio = $data->sunat_description;
1699
1700 // Insertamos data en ps_vex_invoices_sent tabla
1701 $result = Db::getInstance()->insert('vex_invoices_sent', array(
1702 'id_order' => $id_order,
1703 'date_add' => date("Y-m-d H:i:s"),
1704 ));
1705 $error = Db::getInstance()->getMsgError();
1706
1707 if ($result == true) {
1708 self::logtxt("Registro guardado al ps_vex_invoices_sent con exito");
1709 } else {
1710 if ($error != '') {
1711 self::logtxt($error);
1712 }
1713 self::logtxt("Hubo un error al intentar guardar en vex_invoices_sent");
1714 }
1715
1716 }
1717 } else {
1718 // var_export( [ $nubeFact->getClient(), $document->getArray() ] );
1719 // exit();
1720 }
1721
1722 $invoice->wp_data = $nubeFact->getClient()->response;
1723 $invoice->add();
1724 }
1725
1726 }
1727 // $customer = new Customer($customer_id);
1728
1729 // $clientParams = array(
1730 // 'cliente_email' => $customer->email,
1731 // 'cliente_tipo_de_documento' => '',
1732 // 'cliente_numero_de_documento' => '',
1733 // 'cliente_denominacion' => '',
1734 // 'cliente_direccion' => ''
1735 // );
1736
1737 // $clientParams = array_merge( $clientParams, $nubeFactValues );
1738
1739 // var_export( [$params['id_order'], $order->id] );
1740 // exit();
1741
1742 }//fin cambio de estado
1743 }
1744
1745
1746 /**
1747 * Function for send masive invoices
1748 * getting id_order.
1749 */
1750 public function sendMasiveInvoices()
1751 {
1752 $key = 'sendInvoice@2020';
1753 // set by post: date like 2020-07
1754 // Example: curl -s 'https://tienda.ensure.abbott/pe?k=sendInvoice@2020&date=2020-07' > /dev/null
1755 // curl --silent --output /dev/null http://example.com
1756
1757 $date = Tools::getValue('date');
1758
1759 if (Tools::getValue('k') == $key) {
1760
1761 self::logtxt("---- Envio masivo de Facturas ----");
1762 self::logtxt("---- Fecha insertada: $date ----");
1763
1764 // get orders ids
1765 $sql = new DbQuery();
1766 $sql->select('*');
1767 $sql->from('orders', 'A');
1768 $sql->where('A.current_state = 5 AND A.date_add >= "'.$date.'-01 00:00:00" AND A.date_add <= "'.$date.'-31 23:59:59" AND NOT EXISTS (SELECT id_order FROM ps_vex_invoices_sent WHERE id_order = A.id_order)');
1769
1770 $resOrders = Db::getInstance()->executeS($sql);
1771
1772 // if results
1773 if (!empty($resOrders)) {
1774 $numData = count($resOrders);
1775 self::logtxt("sendMasiveInvoices: Hay ".$numData." registros para enviar!");
1776
1777 // iterate all id orders that we need
1778 foreach ($resOrders as $key => $Order) {
1779
1780 // get values request
1781 $id_order = $Order['id_order'];
1782 self::logtxt("id_order: $id_order");
1783
1784 $stateID = trim(Configuration::get( self::CONFIG_INVOICE_STATE ));
1785
1786 // value if state changed is equal to (CONFIG_INVOICE_STATE)
1787 $order = new Order($id_order);
1788 if($order->current_state == $stateID) {
1789
1790 $customer_id = $order->id_customer;
1791 $id_cart = $order->id_cart;
1792
1793 // evalua si es gratuita o no
1794 if($order->total_paid_tax_incl == 0){
1795 $incluido_impuestos = 0; // total incluido impuesto
1796 $sin_impuestos = 0; // total sin impuesto
1797 }else{
1798 // $incluido_impuestos = $order->total_products_wt; // total incluido impuesto
1799 // $sin_impuestos = $order->total_products; // total sin impuesto
1800 $incluido_impuestos = $order->total_paid_tax_incl; // total incluido impuesto
1801 $sin_impuestos = $order->total_paid_tax_excl; // total sin impuesto
1802 }
1803
1804 $totalGratis = 0;
1805 $sumaDescuentoItems = 0;
1806 // load saved values
1807 // $nubeFactValues = array();
1808 if( $nubeFactCustomer = Vex_Nubefact_Customer::getByCustomerId( $customer_id ) ) {
1809 // $nubeFactValues = $nubeFactCustomer;
1810 // unset( $nubeFactValues['date_add'], $nubeFactValues['cart_id'] );
1811 // unset( $nubeFactValues['customer_id'], $nubeFactValues['id'] );
1812 $customer = new Customer($customer_id);
1813
1814 $url = $this->get_url();
1815 $token = $this->get_token();
1816
1817 $nubeFact = new Vex_PrestaShop_NubeFact( $url, $token );
1818
1819 if( $nubeFactCustomer['tipo_de_comprobante'] == self::TIPOCOMPROBANTE_FACTURA ){
1820 require_once dirname( __FILE__ ) . '/classes/NubeFact/FacturaElectronica.php';
1821 $document = new Vex_FacturaElectronica();
1822
1823 $serie = 'F' . Configuration::get( self::CONFIG_INVOICE_SERIE );
1824 // $numero = Configuration::get( self::CONFIG_INVOICE_NUM );
1825
1826 // consulta consecutivo en api
1827 $AutoIncrementInvoice = new stdClass();
1828 $AutoIncrementInvoice->aplicationName = Configuration::get(self::CONFIG_API_APPNAME);
1829 $AutoIncrementInvoice->billingName = Configuration::get(self::CONFIG_API_FE_BILLING_NAME);
1830 $AutoIncrementInvoice->idCart = $id_cart;
1831 $AutoIncrementInvoice->idOrder = $id_order;
1832 $AutoIncrementInvoice->token = Configuration::get(self::CONFIG_FE_TOKEN_AUTO_INCREMENT_INVOICE);
1833 $AutoIncrementInvoice->suffix = Configuration::get(self::CONFIG_FE_F_SUFFIX);
1834 $AutoIncrementInvoice->production = true;
1835
1836 $data_string = json_encode($AutoIncrementInvoice);
1837
1838 $ch = curl_init(Configuration::get(self::CONFIG_FE_URL_AUTO_INCREMENT_INVOICE));
1839 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
1840 curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
1841 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
1842 curl_setopt($ch, CURLOPT_HTTPHEADER, array(
1843 'Content-Type: application/json',
1844 'Content-Length: ' . strlen($data_string)
1845 ));
1846
1847 $response = curl_exec($ch);
1848
1849 $responseArray = json_decode($response, true);
1850 $numero = $responseArray['invoiceNumber'];
1851
1852 } else {
1853 require_once dirname( __FILE__ ) . '/classes/NubeFact/BoletaElectronica.php';
1854 $document = new Vex_BoletaElectronica();
1855
1856 $serie = 'B' . Configuration::get( self::CONFIG_RECEIPT_SERIE );
1857 // $numero = Configuration::get( self::CONFIG_RECEIPT_NUM );
1858
1859 // consulta consecutivo en api
1860 $AutoIncrementInvoice = new stdClass();
1861 $AutoIncrementInvoice->aplicationName = Configuration::get(self::CONFIG_API_APPNAME);
1862 $AutoIncrementInvoice->billingName = Configuration::get(self::CONFIG_API_FE_BILLING_NAME);
1863 $AutoIncrementInvoice->idCart = $id_cart;
1864 $AutoIncrementInvoice->idOrder = $id_order;
1865 $AutoIncrementInvoice->token = Configuration::get(self::CONFIG_FE_TOKEN_AUTO_INCREMENT_INVOICE);
1866 $AutoIncrementInvoice->suffix = Configuration::get(self::CONFIG_FE_B_SUFFIX);
1867 $AutoIncrementInvoice->production = true;
1868
1869 $data_string = json_encode($AutoIncrementInvoice);
1870
1871 $ch = curl_init(Configuration::get(self::CONFIG_FE_URL_AUTO_INCREMENT_INVOICE));
1872 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
1873 curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
1874 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
1875 curl_setopt($ch, CURLOPT_HTTPHEADER, array(
1876 'Content-Type: application/json',
1877 'Content-Length: ' . strlen($data_string)
1878 ));
1879
1880 $response = curl_exec($ch);
1881
1882 $responseArray = json_decode($response, true);
1883 $numero = $responseArray['invoiceNumber'];
1884 }
1885
1886 $document->setSunatEnvioAutomatico( true );
1887 $document->setSerie( $serie );
1888 $document->setNumero( $numero );
1889
1890 $document->setCliente( array(
1891 'cliente_tipo_de_documento' => $nubeFactCustomer['cliente_tipo_de_documento'],
1892 'cliente_numero_de_documento' => trim($nubeFactCustomer['cliente_numero_de_documento']),
1893 'cliente_denominacion' => $nubeFactCustomer['cliente_denominacion'],
1894 'cliente_direccion' => $nubeFactCustomer['cliente_direccion']
1895 ) );
1896
1897 $document->addClienteEmail( $customer->email );
1898
1899 // $currency = new Currency($order->id_currency);
1900 // $currencies = array(
1901 // 'PEN' => Vex_DocumentContract::$SOL,
1902 // 'USD' => Vex_DocumentContract::$DOLAR,
1903 // 'EUR' => Vex_DocumentContract::$EURO,
1904 // );
1905
1906 // var_export( [$currency, $nubeFactCustomer] );
1907
1908
1909 // $document->setMoneda( $currencies[ $currency->iso_code ] );
1910
1911 // $document->setTipoCambio();
1912 $document->setPorcentajeIGV( $this->get_percent_igv() );
1913 $document->setTotal( $incluido_impuestos );
1914 $document->setTotalIGV( round( $incluido_impuestos - $sin_impuestos, 2 ) );
1915 $document->setTotalGravada( $sin_impuestos );
1916 // $document->setTotalInafecta();
1917 // $document->setDetraccion();
1918 // $document->setObservaciones();
1919
1920 $features = $this->getFeaturesProductOrder($order->id);
1921
1922 $giftFlag = false;
1923
1924 foreach ( $order->getProducts() as $productDetail ) {
1925 $TotalConImpuesto = $productDetail['total_price_tax_incl'];
1926 $TotalSinImpuesto = $productDetail['total_price_tax_excl'];
1927 $discounts = $productDetail['reduction_percent'];
1928 $discountAmount = $productDetail['reduction_amount_tax_excl'];
1929 $valorUnitario = $productDetail['original_product_price'];
1930 $impuestoUnitario = ($valorUnitario * (int) $this->get_percent_igv()) / 100;
1931 $precioUnitario = round($valorUnitario + $impuestoUnitario, 2);
1932 $tipoIGV = '1';
1933 $IGV = $TotalConImpuesto - $TotalSinImpuesto;
1934 $total = $TotalConImpuesto;
1935 $descuento = 0;
1936 $subtotal = ($valorUnitario * $productDetail['product_quantity']) - $descuento;
1937
1938 // descuento por producto
1939 if($discounts > 0) {
1940 self::logtxt("Descuento por producto! - Percent");
1941 $descuento = ($valorUnitario * $discounts / 100);
1942 $sumaDescuentoItems += $descuento;
1943 $subtotal = ($valorUnitario - $descuento) * ($productDetail['product_quantity']);
1944 $IGV = ($subtotal * (int) $this->get_percent_igv()) / 100;
1945
1946 if($discounts == 100) {
1947 // Si el producto es gratuito
1948 self::logtxt("Producto gratuito");
1949 $giftFlag = true;
1950 $precioUnitario = $valorUnitario;
1951 $subtotal = ($valorUnitario * $productDetail['product_quantity']);
1952 $tipoIGV = '6';
1953 $IGV = 0;
1954 $total = $subtotal;
1955 $totalGratis += $subtotal;
1956 $descuento = 0;
1957 }
1958
1959 }elseif($discountAmount > 0){
1960 self::logtxt("Descuento por producto! - Amount");
1961 $descuento = $discountAmount;
1962 $sumaDescuentoItems += $discountAmount;
1963 $subtotal = ($valorUnitario - $descuento) * ($productDetail['product_quantity']);
1964 $IGV = ($subtotal * (int) $this->get_percent_igv()) / 100;
1965
1966 }
1967
1968 if(!empty($features[$productDetail['product_id']]['value']))
1969 $codigo_producto_sunat = $features[$productDetail['product_id']]['value'];
1970 else
1971 $codigo_producto_sunat = Configuration::get( self::CONFIG_INVOICE_SUNAT_CODE );
1972
1973 // evalua si es gratuito o no
1974 if($order->total_paid_tax_incl == 0){
1975 $totalGratis += $subtotal;
1976 $precioUnitario = $valorUnitario;
1977 $subtotal = ($valorUnitario * $productDetail['product_quantity']);
1978 $tipoIGV = '6';
1979 $IGV = 0;
1980 $total = $valorUnitario;
1981 }
1982
1983 $document->addItem( array(
1984 'unidad_de_medida' => 'NIU',
1985 'codigo' => $productDetail['product_id'],
1986 'descripcion' => $productDetail['product_name'],
1987 'cantidad' => $productDetail['product_quantity'],
1988 'valor_unitario' => $valorUnitario, // unitario sin impuesto
1989 'precio_unitario' => $precioUnitario, // unitario con impuesto
1990 'descuento' => $descuento,
1991 'subtotal' => $subtotal,
1992 'tipo_de_igv' => $tipoIGV,
1993 'igv' => $IGV,
1994 'total' => $total,
1995 'anticipo_regularizacion' => 'false',
1996 'anticipo_documento_serie' => '',
1997 'anticipo_documento_numero' => '',
1998 'codigo_producto_sunat' => $codigo_producto_sunat //Fórmulas y productos para apoyo nutritivo
1999 ) );
2000 }
2001
2002 // transporte
2003 $shipping_sin_impuestos = $order->total_shipping_tax_excl; // total transporte sin impuesto
2004 $shipping_con_impuestos = $order->total_shipping_tax_incl; // total transporte sin impuesto
2005 $precioUnitario = round($shipping_con_impuestos, 2);
2006 $tipoIGV = '1';
2007 $IGV = $shipping_con_impuestos - $shipping_sin_impuestos;
2008 $total = $shipping_con_impuestos;
2009 if ($shipping_sin_impuestos > 0) {
2010 // evalua si es gratuito o no
2011 if($order->total_paid_tax_incl == 0){
2012 $precioUnitario = $shipping_sin_impuestos;
2013 $tipoIGV = '6';
2014 $IGV = 0;
2015 $total = $shipping_sin_impuestos;
2016 }
2017
2018 $document->addItem( array(
2019 'unidad_de_medida' => 'ZZ',
2020 'codigo' => '001',
2021 'descripcion' => 'Costo de envío',
2022 'cantidad' => '1',
2023 'valor_unitario' => $shipping_sin_impuestos, // unitario sin impuesto
2024 'precio_unitario' => $precioUnitario, // unitario con impuesto
2025 'descuento' => '',
2026 'subtotal' => $shipping_sin_impuestos,
2027 'tipo_de_igv' => $tipoIGV,
2028 'igv' => $IGV,
2029 'total' => $total,
2030 'anticipo_regularizacion' => 'false',
2031 'anticipo_documento_serie' => '',
2032 'anticipo_documento_numero' => '',
2033 'codigo_producto_sunat' => '78140000' //Servicios de transporte
2034 ) );
2035 }
2036
2037 // $document->setCodigoUnico();
2038
2039 // var_export( $document->getArray() );
2040
2041 // descuento general
2042 $total_descuentos = 0;
2043 $descuento_general = 0;
2044 if($order->total_discounts > 0){
2045 $descuento_general = $order->total_discounts_tax_excl; // total descuento orden
2046 }
2047 $total_descuentos = $descuento_general + $sumaDescuentoItems;
2048
2049 // si hay descuento general y por item
2050 if($order->total_discounts > 0 && $dproductFlag == true){
2051 $descuento_general = $order->total_discounts_tax_excl; // total descuento orden
2052 $total_descuentos = $sumaDescuentoItems;
2053 }
2054 $document->setDescuentoGlobal( $descuento_general );
2055 $document->setTotalDescuento( $total_descuentos );
2056
2057 // si es gratuita o no
2058 if($order->total_paid_tax_incl == 0){
2059 $document->setTotalGratis( $totalGratis );
2060 }
2061
2062 // si existe un producto gratuito
2063 if($giftFlag == true){
2064 $document->setTotalGratis( $totalGratis );
2065 }
2066
2067 // Evalua el tipo de documento para saber el tipo de transacción (segun sunat) - By Alekuoshu
2068 if((int) $nubeFactCustomer['cliente_tipo_de_documento'] == 4 || (int) $nubeFactCustomer['cliente_tipo_de_documento'] == 7){
2069 $document->setSunatTransaction( 29 ); // Venta no domiciliados que no califican como exportación
2070 }elseif((int) $nubeFactCustomer['cliente_tipo_de_documento'] == 0){
2071 $document->setSunatTransaction( 2 ); // Exportanción
2072 }else{
2073 $document->setSunatTransaction( 1 ); // Venta Interna
2074 }
2075
2076 //create invoice
2077 $invoice = new Vex_Nubefact_Invoice();
2078
2079 $invoice->id_customer = $customer->id;
2080 $invoice->id_order = $order->id;
2081 $invoice->tipo_de_comprobante = $nubeFactCustomer['tipo_de_comprobante'];
2082 $invoice->serie = $serie;
2083 $invoice->numero = (int) $numero;
2084 $invoice->cliente_tipo_de_documento = $nubeFactCustomer['cliente_tipo_de_documento'];
2085 $invoice->cliente_numero_de_documento = trim($nubeFactCustomer['cliente_numero_de_documento']);
2086 $invoice->cliente_denominacion = $nubeFactCustomer['cliente_denominacion'];
2087 $invoice->cliente_direccion = $nubeFactCustomer['cliente_direccion'];
2088 $invoice->cliente_email = $customer->email;
2089 $invoice->fecha_de_emision = date( 'Y-m-d' );
2090 $invoice->moneda = 1;
2091 $invoice->porcentaje_de_igv = $this->get_percent_igv();
2092 $invoice->descuento_global = $descuento_general;
2093 $invoice->total_descuento = $total_descuentos;
2094 $invoice->total_gravada = $sin_impuestos;
2095 $invoice->total_igv = round( $incluido_impuestos - $sin_impuestos, 2 );
2096 $invoice->total_gratuita = $totalGratis;
2097 $invoice->total = $incluido_impuestos;
2098
2099
2100 // validar que no existe ya la factura en nubefact y no este aceptada a la sunat
2101 $query = new DbQuery();
2102 $query->select('*');
2103 $query->from('vex_nubefact_invoice');
2104 $query->where('id_order = "'.$order->id.'" AND sunat_estado = 1');
2105 $valueR = Db::getInstance()->executeS($query);
2106
2107 // si no existe en el registro la factura se envia a nubefact
2108 if(empty($valueR)){
2109 if( $response = $nubeFact->sendDocument( $document ) ){
2110 // incrementar numero
2111 // if( $nubeFactCustomer['tipo_de_comprobante'] == self::TIPOCOMPROBANTE_FACTURA ){
2112 // Configuration::updateValue( self::CONFIG_INVOICE_NUM, $numero+1 );
2113 // } else {
2114 // Configuration::updateValue( self::CONFIG_RECEIPT_NUM, $numero+1 );
2115 // }
2116
2117 $data = @json_decode( $response );
2118
2119 // guardar pdf url
2120 $invoice->url_pdf = $data->enlace_del_pdf;
2121 // respuesta sunat
2122 $sunat = $data->aceptada_por_sunat;
2123 if($sunat === true){
2124 $invoice->sunat_estado = '1';
2125 $invoice->sunat_respuesta_envio = $data->sunat_description;
2126
2127 // Insertamos data en ps_vex_invoices_sent tabla
2128 $result = Db::getInstance()->insert('vex_invoices_sent', array(
2129 'id_order' => $id_order,
2130 'date_add' => date("Y-m-d H:i:s"),
2131 ));
2132 $error = Db::getInstance()->getMsgError();
2133
2134 if ($result == true) {
2135 self::logtxt("Registro guardado al ps_vex_invoices_sent con exito");
2136 self::logtxt("sendMasiveInvoices: #Orden: $id_order Enviada!");
2137 } else {
2138 if ($error != '') {
2139 self::logtxt($error);
2140 }
2141 self::logtxt("Hubo un error al intentar guardar en vex_invoices_sent");
2142 }
2143
2144 }else{
2145 $invoice->sunat_estado = '0';
2146 $invoice->sunat_respuesta_envio = $data->sunat_description;
2147
2148 // Insertamos data en ps_vex_invoices_sent tabla
2149 $result = Db::getInstance()->insert('vex_invoices_sent', array(
2150 'id_order' => $id_order,
2151 'date_add' => date("Y-m-d H:i:s"),
2152 ));
2153 $error = Db::getInstance()->getMsgError();
2154
2155 if ($result == true) {
2156 self::logtxt("Registro guardado al ps_vex_invoices_sent con exito");
2157 self::logtxt("sendMasiveInvoices: #Orden: $id_order Enviada!");
2158 } else {
2159 if ($error != '') {
2160 self::logtxt($error);
2161 }
2162 self::logtxt("Hubo un error al intentar guardar en vex_invoices_sent");
2163 }
2164
2165 }
2166 } else {
2167 // var_export( [ $nubeFact->getClient(), $document->getArray() ] );
2168 // exit();
2169 }
2170
2171 $invoice->wp_data = $nubeFact->getClient()->response;
2172 $invoice->add();
2173 }
2174
2175 }
2176 // $customer = new Customer($customer_id);
2177
2178 // $clientParams = array(
2179 // 'cliente_email' => $customer->email,
2180 // 'cliente_tipo_de_documento' => '',
2181 // 'cliente_numero_de_documento' => '',
2182 // 'cliente_denominacion' => '',
2183 // 'cliente_direccion' => ''
2184 // );
2185
2186 // $clientParams = array_merge( $clientParams, $nubeFactValues );
2187
2188 // var_export( [$params['id_order'], $order->id] );
2189 // exit();
2190
2191 }//fin cambio de estado
2192
2193 } //end foreach iterate items
2194
2195 }else{
2196 self::logtxt("sendMasiveInvoices: No hay registros para enviar!");
2197
2198 }// end if results sql statement
2199
2200
2201 }//end value key for consume
2202
2203
2204 }//end sendMasiveInvoices
2205
2206 /**
2207 * Error log
2208 *
2209 * @param string $text text that will be saved in the file
2210 * @return void Error record in file "errors.log"
2211 */
2212 public static function logtxt($text = "") {
2213
2214 if (file_exists(self::NUBEFACT_PATH_LOG)) {
2215
2216 $fp = fopen(self::NUBEFACT_PATH_LOG . "/errors.log", "a+");
2217 fwrite($fp, date('l jS \of F Y h:i:s A') . ", " . $text . "\r\n");
2218 fclose($fp);
2219 return true;
2220 } else {
2221 self::createPath(self::NUBEFACT_PATH_LOG);
2222 }
2223 }
2224
2225 /**
2226 * Recursively create a string of directories
2227 */
2228 public static function createPath($path) {
2229
2230 if (is_dir($path))
2231 return true;
2232
2233 $prev_path = substr($path, 0, strrpos($path, '/', -2) + 1);
2234 $return = self::createPath($prev_path);
2235 return ($return && is_writable($prev_path)) ? mkdir($path) : false;
2236 }
2237}
2238