Version 2.7.0 con la opción de generar clabes interbancarias por medio de una etiqueta con nombre 'CREARCLABESTRIPE' y además permite crear las clabes de manera automática cuando el cliente pasa de potencial a cliente regular

This commit is contained in:
server 2025-03-24 22:47:43 -06:00
parent 9db9febc39
commit 96d7fe6b27
18917 changed files with 5592 additions and 50 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 104 KiB

File diff suppressed because one or more lines are too long

View File

@ -5,7 +5,7 @@
"displayName": "SIIP - Procesador de Pagos en línea con Stripe, Oxxo y Transferencia, Sincronizador de CallBell y Envío de Notificaciones y comprobantes vía WhatsApp",
"description": "Este plugin sincroniza los clientes del sistema UISP CRM con los contactos de WhatsApp en CallBell, además procesa pagos de Stripe como las trasferencias bancarias y genera referencias de pago vía OXXO, además envía comprobantes de pago en formato imagen PNG o texto vía Whatsapp a los clientes",
"url": "https://siip.mx/",
"version": "2.6.9.1",
"version": "2.7.0",
"unmsVersionCompliancy": {
"min": "2.1.0",
"max": null

View File

@ -305,6 +305,7 @@ abstract class AbstractOxxoOperationsFacade
$this->logger->info("Referencia OXXO: " . $oxxo_reference . PHP_EOL);
$this->logger->info("URL del recibo: " . $oxxo_receipt_url . PHP_EOL);
$this->captureScreenshot($oxxo_receipt_url);
//devolver un array con los campos de url de oxxo, descripción de la falla, clientID y amount
$arrayOxxoPayment['oxxo_reference'] = $oxxo_reference;
$arrayOxxoPayment['url'] = $oxxo_receipt_url;
@ -479,4 +480,38 @@ abstract class AbstractOxxoOperationsFacade
}
/**
* Función para capturar una pantalla de una URL usando el servicio Puppeteer.
*
* @param string $url La URL de la página web que se desea capturar.
* @return string La ruta del archivo de la captura de pantalla.
*/
function captureScreenshot($url) {
// URL del servicio Puppeteer
$puppeteerUrl = 'http://172.16.5.134:4000';
// Datos a enviar
$data = http_build_query(['url' => $url]);
// Configurar la solicitud POST
$options = [
'http' => [
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => $data,
],
];
// Ejecutar la solicitud
$context = stream_context_create($options);
$response = file_get_contents($puppeteerUrl, false, $context);
if ($response === false) {
throw new Exception("Error al comunicarse con el servicio Puppeteer.");
}
return trim($response);
}
}

View File

@ -188,18 +188,19 @@ abstract class AbstractStripeOperationsFacade
return;
}
$this->createCustomerStripe($notificationData, $stripe, $baseUri, $UCRMAPIToken);
// Acceder a "isLead" de forma segura
$isLead = $dataObject->isLead ?? null;
// $isLead = $dataObject->isLead ?? null;
$this->logger->info("El valor de 'isLead' es: " . ($isLead ? "true" : "false") . PHP_EOL);
// $this->logger->info("El valor de 'isLead' es: " . ($isLead ? "true" : "false") . PHP_EOL);
if ($isLead === true) {
$this->logger->info("El cliente es un lead, no se procesará" . PHP_EOL);
return;
} else {
$this->logger->info("El cliente NO es un lead, se procesará" . PHP_EOL);
$this->createCustomerStripe($notificationData, $stripe, $baseUri, $UCRMAPIToken);
}
// if ($isLead === true) {
// $this->logger->info("El cliente es un lead, no se procesará" . PHP_EOL);
// return;
// } else {
// $this->logger->info("El cliente NO es un lead, se procesará" . PHP_EOL);
// $this->createCustomerStripe($notificationData, $stripe, $baseUri, $UCRMAPIToken);
// }
}
@ -256,31 +257,43 @@ abstract class AbstractStripeOperationsFacade
$this->logger->info('ahora se procede a validar el teléfono!!! ' . PHP_EOL);
$phone = $this->validarNumeroTelefono($phone); //validamos y procesamos el número de celular del cliente para que se vaya a 10 dígitos ya que Stripe por si mismo les agrega el +52
//******************************************** */
//si la variable $phone no esta vacia o null se valida con la funcion validarNumeroTelefono
if ($phone == '') {
$this->logger->info('El número de teléfono está vacío o no es válido.' . PHP_EOL);
//se manda a crear pero sin numero de teléfono
$this->logger->info('AHORA SE MANDA A CREAR EL CLIENTE A STRIPE!!! ' . PHP_EOL);
$result = $stripe->customers->create([
"description" => "Cliente SIIP CRM con client_id: " . $ucrm_client_id,
"name" => $firstName . ' ' . $lastName,
"email" => $email,
'preferred_locales' => ['es-419']
]); //aquí se contruye la petición de creación de un customer en Stripe y se consume la API
$this->logger->info('AHORA SE MANDA A CREAR EL CLIENTE A STRIPE!!! ' . PHP_EOL);
$result = $stripe->customers->create([
"description" => "Cliente SIIP CRM con client_id: " . $ucrm_client_id,
"name" => $firstName . ' ' . $lastName,
"phone" => $phone,
"email" => $email,
'preferred_locales' => ['es-419']
]); //aquí se contruye la petición de creación de un customer en Stripe y se consume la API
} else {
$phone = $this->validarNumeroTelefono($phone); //validamos y procesamos el número de celular del cliente para que se vaya a 10 dígitos ya que Stripe por si mismo les agrega el +52
$this->logger->info('AHORA SE MANDA A CREAR EL CLIENTE A STRIPE!!! ' . PHP_EOL);
$result = $stripe->customers->create([
"description" => "Cliente SIIP CRM con client_id: " . $ucrm_client_id,
"name" => $firstName . ' ' . $lastName,
"phone" => $phone,
"email" => $email,
'preferred_locales' => ['es-419']
]); //aquí se contruye la petición de creación de un customer en Stripe y se consume la API
}
$this->logger->info(json_encode($result) . PHP_EOL); //imprimir respuesta de creación del cliente
//ejemplo de respuesta de stripe cuando se crea el cliente: {"id":"cus_Rkh9CoRTpjlZUu","object":"customer","address":null,"balance":0,"created":1739250682,"currency":null,"default_source":null,"delinquent":false,"description":"Cliente SIIP CRM con client_id: 167","discount":null,"email":null,"invoice_prefix":"5017E9D3","invoice_settings":{"custom_fields":null,"default_payment_method":null,"footer":null,"rendering_options":null},"livemode":false,"metadata":[],"name":"Javier Alatorre","next_invoice_sequence":1,"phone":"4181878106","preferred_locales":["es-419"],"shipping":null,"tax_exempt":"none","test_clock":null}
//validar si se creo el cliente con la API de Stripe $stripe->customers->create
if (isset($result->id)){
if (!isset($result['id'])) { //si no existe el ID del cliente en la respuesta de Stripe entonces se manda un mensaje de error
$this->logger->info('Error al crear el cliente en Stripe: ' . json_encode($result) . PHP_EOL);
}
$stripe_customer_id = $result['id']; //obtenemos el customer id de Stripe recibido por medio del consumo del API y lo asignamos a una variable $stripe_customer_id
$stripe_customer_id = $result['id']; //obtenemos el customer id de Stripe recibido por medio del consumo del API y lo asignamos a una variable $stripe_customer_id
sleep(2);
$result2 = $stripe->customers->update(
$stripe_customer_id,
@ -358,12 +371,11 @@ abstract class AbstractStripeOperationsFacade
} catch (GuzzleException $error) {
$this->logger->info("Error al hacer el patch al CRM: " . $error->getMessage() . PHP_EOL);
//exit();
return false; // Return false if patch fails
}
$this->logger->info(json_encode($responseCRM) . PHP_EOL); //imprimir respuesta del patch de CRM con la clabe y Customer ID Stripe
return true; // Return true if all operations succeed
}
function validarNumeroTelefono($telefono)

View File

@ -1164,6 +1164,7 @@ class ClientCallBellAPI
$data_CRM = array(
"name" => $nombre_cliente,
"custom_fields" => array(
"Estado" => (
isset($notificationData->serviceData['status'])

View File

@ -237,14 +237,6 @@ class Plugin
$configManager = \Ubnt\UcrmPluginSdk\Service\PluginConfigManager::create();
$config = $configManager->loadConfig();
//ejemplo de json para facturas de borrador: {"uuid":"cc5164fa-a7ec-483a-ae62-1eb02e69d82c","changeType":"insert","entity":"invoice","entityId":"1563","eventName":"invoice.add_draft","extraData":{"entity":{"id":1563,"clientId":2,"number":"001521","createdDate":"2025-02-18T12:48:43-0600","dueDate":"2025-03-04T12:48:43-0600","emailSentDate":null,"maturityDays":14,"taxableSupplyDate":"2025-02-18T00:00:00-0600","notes":null,"adminNotes":null,"items":[{"id":1566,"type":"service","label":"PREMIUM 18\/02\/2025 \u2013 28\/02\/2025","price":700,"quantity":0.36666666666666664,"total":256.66666666666663,"unit":null,"tax1Id":null,"tax2Id":null,"tax3Id":null,"serviceId":134,"serviceSurchargeId":null,"productId":null,"feeId":null,"discountPrice":0,"discountQuantity":0,"discountTotal":0}],"subtotal":256.67,"discount":null,"discountLabel":"Descuento","taxes":[],"total":256.67,"amountPaid":0,"totalUntaxed":256.67,"totalDiscount":0,"totalTaxAmount":0,"amountToPay":256.67,"currencyCode":"MXN","status":1,"paymentCovers":[],"invoiceTemplateId":2,"proformaInvoiceTemplateId":2,"organizationName":"SIIP Pruebas","organizationRegistrationNumber":null,"organizationTaxId":null,"organizationStreet1":"Morel 34","organizationStreet2":null,"organizationCity":"Dolores Hidalgo","organizationStateId":null,"organizationCountryId":173,"organizationZipCode":"37800","organizationBankAccountName":null,"organizationBankAccountField1":null,"organizationBankAccountField2":null,"clientFirstName":"Daniel Humberto","clientLastName":"Soto Villegas el boy","clientCompanyName":null,"clientCompanyRegistrationNumber":null,"clientCompanyTaxId":null,"clientStreet1":"31 Chiapas","clientStreet2":null,"clientCity":"Dolores Hidalgo Cuna de la Independencia Nacional","clientCountryId":173,"clientStateId":null,"clientZipCode":"37800","attributes":[],"uncollectible":false,"proforma":false,"generatedInvoiceId":null,"proformaInvoiceId":null,"isAppliedVatReverseCharge":false,"payAutomatically":false},"entityBeforeEdit":null}}
$jsonTest = '{"uuid":"cc5164fa-a7ec-483a-ae62-1eb02e69d82c","changeType":"insert","entity":"invoice","entityId":"1563","eventName":"invoice.add_draft","extraData":{"entity":{"id":1563,"clientId":2,"number":"001521","createdDate":"2025-02-18T12:48:43-0600","dueDate":"2025-03-04T12:48:43-0600","emailSentDate":null,"maturityDays":14,"taxableSupplyDate":"2025-02-18T00:00:00-0600","notes":null,"adminNotes":null,"items":[{"id":1566,"type":"service","label":"PREMIUM 18\/02\/2025 \u2013 28\/02\/2025","price":700,"quantity":0.36666666666666664,"total":256.66666666666663,"unit":null,"tax1Id":null,"tax2Id":null,"tax3Id":null,"serviceId":134,"serviceSurchargeId":null,"productId":null,"feeId":null,"discountPrice":0,"discountQuantity":0,"discountTotal":0}],"subtotal":256.67,"discount":null,"discountLabel":"Descuento","taxes":[],"total":256.67,"amountPaid":0,"totalUntaxed":256.67,"totalDiscount":0,"totalTaxAmount":0,"amountToPay":256.67,"currencyCode":"MXN","status":1,"paymentCovers":[],"invoiceTemplateId":2,"proformaInvoiceTemplateId":2,"organizationName":"SIIP Pruebas","organizationRegistrationNumber":null,"organizationTaxId":null,"organizationStreet1":"Morel 34","organizationStreet2":null,"organizationCity":"Dolores Hidalgo","organizationStateId":null,"organizationCountryId":173,"organizationZipCode":"37800","organizationBankAccountName":null,"organizationBankAccountField1":null,"organizationBankAccountField2":null,"clientFirstName":"Daniel Humberto","clientLastName":"Soto Villegas el boy","clientCompanyName":null,"clientCompanyRegistrationNumber":null,"clientCompanyTaxId":null,"clientStreet1":"31 Chiapas","clientStreet2":null,"clientCity":"Dolores Hidalgo Cuna de la Independencia Nacional","clientCountryId":173,"clientStateId":null,"clientZipCode":"37800","attributes":[],"uncollectible":false,"proforma":false,"generatedInvoiceId":null,"proformaInvoiceId":null,"isAppliedVatReverseCharge":false,"payAutomatically":false},"entityBeforeEdit":null}}
';
$jsonData = json_decode($jsonTest, true);
$accountBalance = $jsonData['extraData']['entity']['tags'];
$this->logger->info('Webhook test successful.');
return;
@ -356,7 +348,7 @@ class Plugin
$this->logger->debug('Se actualiza a un cliente');
$this->logger->debug('Valor de json_data: ' . json_encode($jsonData));
//ejemplo de json_data: {"uuid":"17e043a7-03b5-4312-ab81-a7818124a77e","changeType":"edit","entity":"client","entityId":"158","eventName":"client.edit","extraData":{"entity":{"id":158,"userIdent":null,"previousIsp":null,"isLead":false,"clientType":1,"companyName":null,"companyRegistrationNumber":null,"companyTaxId":null,"companyWebsite":null,"street1":"23 San Luis","street2":null,"city":"Dolores Hidalgo Cuna de la Independencia Nacional","countryId":173,"stateId":null,"zipCode":"37804","fullAddress":"San Luis 23, Guadalupe, Dolores Hidalgo Cuna de la Independencia Nacional, Gto., M\u00e9xico","invoiceStreet1":null,"invoiceStreet2":null,"invoiceCity":null,"invoiceStateId":null,"invoiceCountryId":null,"invoiceZipCode":null,"invoiceAddressSameAsContact":true,"note":null,"sendInvoiceByPost":null,"invoiceMaturityDays":null,"stopServiceDue":null,"stopServiceDueDays":null,"organizationId":1,"tax1Id":null,"tax2Id":null,"tax3Id":null,"registrationDate":"2025-01-06T00:00:00-0600","leadConvertedAt":"2025-02-09T03:15:49-0600","companyContactFirstName":null,"companyContactLastName":null,"isActive":false,"firstName":"Luis","lastName":"Guti\u00e9rrez","username":null,"contacts":[{"id":162,"clientId":158,"email":null,"phone":null,"name":null,"isBilling":true,"isContact":true,"types":[{"id":1,"name":"Billing"},{"id":2,"name":"General"}]}],"attributes":[],"accountBalance":0,"accountCredit":0,"accountOutstanding":0,"currencyCode":"MXN","organizationName":"SIIP Pruebas","bankAccounts":[],"tags":[],"invitationEmailSentDate":null,"avatarColor":"#2196f3","addressGpsLat":21.153272,"addressGpsLon":-100.9134508,"isArchived":false,"generateProformaInvoices":null,"usesProforma":false,"hasOverdueInvoice":false,"hasOutage":false,"hasSuspendedService":false,"hasServiceWithoutDevices":false,"referral":null,"hasPaymentSubscription":false,"hasAutopayCreditCard":false},"entityBeforeEdit":{"id":158,"userIdent":null,"previousIsp":null,"isLead":true,"clientType":1,"companyName":null,"companyRegistrationNumber":null,"companyTaxId":null,"companyWebsite":null,"street1":"23 San Luis","street2":null,"city":"Dolores Hidalgo Cuna de la Independencia Nacional","countryId":173,"stateId":null,"zipCode":"37804","fullAddress":"San Luis 23, Guadalupe, Dolores Hidalgo Cuna de la Independencia Nacional, Gto., M\u00e9xico","invoiceStreet1":null,"invoiceStreet2":null,"invoiceCity":null,"invoiceStateId":null,"invoiceCountryId":null,"invoiceZipCode":null,"invoiceAddressSameAsContact":true,"note":null,"sendInvoiceByPost":null,"invoiceMaturityDays":null,"stopServiceDue":null,"stopServiceDueDays":null,"organizationId":1,"tax1Id":null,"tax2Id":null,"tax3Id":null,"registrationDate":"2025-01-06T00:00:00-0600","leadConvertedAt":null,"companyContactFirstName":null,"companyContactLastName":null,"isActive":false,"firstName":"Luis","lastName":"Guti\u00e9rrez","username":null,"contacts":[{"id":162,"clientId":158,"email":null,"phone":null,"name":null,"isBilling":true,"isContact":true,"types":[{"id":1,"name":"Billing"},{"id":2,"name":"General"}]}],"attributes":[],"accountBalance":0,"accountCredit":0,"accountOutstanding":0,"currencyCode":"MXN","organizationName":"SIIP Pruebas","bankAccounts":[],"tags":[],"invitationEmailSentDate":null,"avatarColor":"#2196f3","addressGpsLat":21.153272,"addressGpsLon":-100.9134508,"isArchived":false,"generateProformaInvoices":null,"usesProforma":false,"hasOverdueInvoice":false,"hasOutage":false,"hasSuspendedService":false,"hasServiceWithoutDevices":false,"referral":null,"hasPaymentSubscription":false,"hasAutopayCreditCard":false}}}
// Validar que 'extraData' existe y contiene las claves necesarias
if (
@ -368,28 +360,24 @@ class Plugin
$this->logger->debug('Validando claves dentro de entityBeforeEdit y entity');
// Validar que 'isLead' existe en ambas entidades
// Validar si 'isLead' esta en true en entityBeforeEdit y en false en entity
if (array_key_exists('isLead', $entityBeforeEdit) && array_key_exists('isLead', $entity)) {
$this->logger->debug('Los datos entityBeforeEdit y entity contienen el campo isLead');
$isLeadBefore = $entityBeforeEdit['isLead'];
$isLeadAfter = $entity['isLead'];
// Validar el tipo de dato de isLead
if (!is_bool($isLeadBefore) || !is_bool($isLeadAfter)) {
$this->logger->warning('El campo isLead no es de tipo booleano');
// Comprobar si 'isLead' cambió de true a false
if ($isLeadBefore === true && $isLeadAfter === false) {
$this->logger->debug('El cliente cambió de potencial a cliente');
$this->pluginNotifierFacade->createStripeClient($notification);
} else {
// Comprobar si 'isLead' cambió de true a false
if ($isLeadBefore === true && $isLeadAfter === false) {
$this->logger->debug('El campo isLead cambió de true a false');
$this->pluginNotifierFacade->createStripeClient($notification);
} else {
$this->logger->debug('No hubo cambio de true a false en el campo isLead');
}
$this->logger->debug('El cliente no cambió de potencial a cliente');
}
} else {
$this->logger->warning('El campo isLead no existe en entityBeforeEdit o entity');
}
// buscar si existe la etiqueta 'STRIPE' en entity pero no en entityBeforeEdit
$tags = $jsonData['extraData']['entity']['tags'];
@ -410,13 +398,13 @@ class Plugin
$stripeTagExists = false;
$stripeTagExistsBefore = false;
foreach ($tags as $tag) {
if ($tag['name'] === 'STRIPE') {
if ($tag['name'] === 'CREARCLABESTRIPE') {
$stripeTagExists = true;
break;
}
}
foreach ($tagsBefore as $tag) {
if ($tag['name'] === 'STRIPE') {
if ($tag['name'] === 'CREARCLABESTRIPE') {
$stripeTagExistsBefore = true;
break;
}

View File

@ -5,7 +5,7 @@
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => '59aac17968cf6f8bb03edcd81c8c25877a11c8cc',
'reference' => '9db9febc39027c302495c041d5a28e198c035b21',
'name' => 'ucrm-plugins/sms-twilio',
'dev' => false,
),
@ -307,7 +307,7 @@
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => '59aac17968cf6f8bb03edcd81c8c25877a11c8cc',
'reference' => '9db9febc39027c302495c041d5a28e198c035b21',
'dev_requirement' => false,
),
),

View File

View File

0
vendor/google/apiclient-services/src/AnalyticsHub/JavaScriptUDF.php vendored Normal file → Executable file
View File

View File

View File

View File

View File

View File

0
vendor/google/apiclient-services/src/Backupdr/BackupDrPlanRule.php vendored Normal file → Executable file
View File

View File

0
vendor/google/apiclient-services/src/Backupdr/BackupLocation.php vendored Normal file → Executable file
View File

View File

0
vendor/google/apiclient-services/src/Backupdr/PitrSettings.php vendored Normal file → Executable file
View File

View File

0
vendor/google/apiclient-services/src/Batch/CancelJobRequest.php vendored Normal file → Executable file
View File

View File

View File

View File

0
vendor/google/apiclient-services/src/CertificateManager/UsedBy.php vendored Normal file → Executable file
View File

View File

View File

View File

View File

View File

View File

View File

View File

0
vendor/google/apiclient-services/src/CloudKMS/ChecksummedData.php vendored Normal file → Executable file
View File

0
vendor/google/apiclient-services/src/CloudRedis/EncryptionInfo.php vendored Normal file → Executable file
View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

0
vendor/google/apiclient-services/src/CloudWorkstations/Status.php vendored Normal file → Executable file
View File

View File

View File

View File

View File

View File

View File

0
vendor/google/apiclient-services/src/Cloudbilling.php vendored Normal file → Executable file
View File

View File

0
vendor/google/apiclient-services/src/Cloudbilling/AuditConfig.php vendored Normal file → Executable file
View File

View File

View File

Some files were not shown because too many files have changed in this diff Show More