Changeset 3436167
- Timestamp:
- 01/09/2026 05:30:58 PM (3 weeks ago)
- Location:
- andreani-shipping/trunk
- Files:
-
- 12 edited
-
andreani.php (modified) (1 diff)
-
includes/andreani-plugin.php (modified) (2 diffs)
-
includes/api/andreani-api-manager.php (modified) (1 diff)
-
includes/api/common/andreani-api-utils.php (modified) (1 diff)
-
includes/api/corpo/andreani-corpo.php (modified) (3 diffs)
-
includes/api/pyme/andreani-pyme.php (modified) (3 diffs)
-
includes/assets/css/admin.css (modified) (2 diffs)
-
includes/assets/js/admin.js (modified) (4 diffs)
-
includes/shipping/andreani-form-fields-shipping-config.php (modified) (1 diff)
-
includes/shipping/andreani-shipping.php (modified) (1 diff)
-
includes/utils/andreani-utils.php (modified) (4 diffs)
-
readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
andreani-shipping/trunk/andreani.php
r3434734 r3436167 4 4 * Plugin URI: https://wordpress.org/plugins/andreani-shipping 5 5 * Description: Plugin oficial de Andreani. Simplifica la gestión de tus envíos con Andreani. 6 * Version: 1. 2.06 * Version: 1.3.0 7 7 * Author: Andreani 8 8 * Author URI: https://www.andreani.com -
andreani-shipping/trunk/includes/andreani-plugin.php
r3434734 r3436167 83 83 add_filter( 'woocommerce_shipping_methods', array( $this, 'add_andreani_shipping_method' ) ); 84 84 add_action( 'woocommerce_shipping_init', array( $this, 'init_andreani_shipping_method' ) ); 85 add_action( 'wp_ajax_andreani_refresh_contratos', array( $this, 'ajax_refresh_contratos' ) ); 85 86 86 87 Andreani_Checkout::get_instance(); … … 182 183 183 184 return array_merge( $plugin_links, $links ); 185 } 186 187 /** 188 * AJAX handler para refrescar contratos corporativos 189 */ 190 public function ajax_refresh_contratos() { 191 check_ajax_referer( 'andreani_refresh_contratos', 'nonce' ); 192 193 if ( ! current_user_can( 'manage_woocommerce' ) ) { 194 wp_send_json_error( array( 'message' => __( 'No tienes permisos para realizar esta acción.', 'andreani-shipping' ) ) ); 195 } 196 197 $settings = $this->get_shipping_settings(); 198 $hash_andreani = isset( $settings['hash_andreani'] ) ? $settings['hash_andreani'] : ''; 199 $tipo_cliente = isset( $settings['tipo_cliente'] ) ? $settings['tipo_cliente'] : ''; 200 201 if ( empty( $hash_andreani ) || 'corporativo' !== $tipo_cliente ) { 202 wp_send_json_error( array( 'message' => __( 'Configuración no válida para refrescar contratos.', 'andreani-shipping' ) ) ); 203 } 204 205 $corpo_api = Andreani_Corpo_Api::get_instance(); 206 $result = $corpo_api->validate_hash( $hash_andreani ); 207 208 if ( ! $result ) { 209 wp_send_json_error( array( 'message' => __( 'Error al conectar con Andreani. Verifica tu credencial.', 'andreani-shipping' ) ) ); 210 } 211 212 Andreani_Api_Manager::clear_settings_cache(); 213 214 wp_send_json_success( array( 'message' => __( 'Contratos actualizados correctamente.', 'andreani-shipping' ) ) ); 215 } 216 217 /** 218 * Obtener configuración del método de envío 219 */ 220 private function get_shipping_settings() { 221 global $wpdb; 222 223 $option_pattern = $wpdb->esc_like( 'woocommerce_' . ANDREANI_SHIPPING_METHOD_ID . '_' ) . '%' . $wpdb->esc_like( '_settings' ); 224 225 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 226 $results = $wpdb->get_results( 227 $wpdb->prepare( 228 "SELECT option_value FROM {$wpdb->options} WHERE option_name LIKE %s LIMIT 1", 229 $option_pattern 230 ), 231 ARRAY_A 232 ); 233 234 if ( ! empty( $results ) ) { 235 return maybe_unserialize( $results[0]['option_value'] ); 236 } 237 238 return array(); 184 239 } 185 240 -
andreani-shipping/trunk/includes/api/andreani-api-manager.php
r3434734 r3436167 165 165 'mostrar_sin_decimales' => isset($settings['mostrar_sin_decimales']) ? $settings['mostrar_sin_decimales'] === 'yes' : false, 166 166 'envio_gratis' => isset($settings['envio_gratis']) ? $settings['envio_gratis'] === 'yes' : false, 167 'envio_gratis_monto_minimo' => isset($settings['envio_gratis_monto_minimo']) && $settings['envio_gratis_monto_minimo'] !== '' ? floatval($settings['envio_gratis_monto_minimo']) : 0, 167 168 ); 168 169 -
andreani-shipping/trunk/includes/api/common/andreani-api-utils.php
r3434734 r3436167 75 75 * @param string $prefix Prefijo del método de envío 76 76 * @param bool $envio_gratis Si el envío es gratis para el cliente 77 * @param float $monto_minimo Monto mínimo de compra para aplicar envío gratis (0 = sin mínimo) 78 * @param float $cart_total Total del carrito 77 79 * @return array Tarifas de envío formateadas 78 80 */ 79 public static function create_shipping_rate_from_response($rates, $prefix, $envio_gratis = false ) {81 public static function create_shipping_rate_from_response($rates, $prefix, $envio_gratis = false, $monto_minimo = 0, $cart_total = 0) { 80 82 $shipping_rates = array(); 81 83 $codes_used = array(); 84 85 // Determinar si aplica envío gratis 86 $aplicar_envio_gratis = false; 87 if ( $envio_gratis ) { 88 // Si no hay monto mínimo configurado (0), siempre aplica envío gratis 89 // Si hay monto mínimo, el carrito debe ser >= al monto mínimo 90 $aplicar_envio_gratis = ( $monto_minimo <= 0 ) || ( $cart_total >= $monto_minimo ); 91 } 82 92 83 93 foreach ($rates as $rate) { 84 94 $code = $rate['code']; 85 95 if (!in_array($code, $codes_used)) { 86 $cost = $envio_gratis ? 0 : $rate['total']; 96 $cost = $aplicar_envio_gratis ? 0 : $rate['total']; 97 $label = "Andreani (" . sprintf("%s", $rate['code']) . ")"; 98 99 if ( $aplicar_envio_gratis ) { 100 $label .= ' - ¡Envío gratis!'; 101 } 102 87 103 $shipping_rates[] = array( 88 104 'id' => $prefix . "$code", 89 'label' => "Andreani (" . sprintf("%s", $rate['code']) . ")",105 'label' => $label, 90 106 'cost' => $cost, 91 107 'calc_tax' => 'per_item', -
andreani-shipping/trunk/includes/api/corpo/andreani-corpo.php
r3434734 r3436167 18 18 private $mostrar_sin_decimales; 19 19 private $envio_gratis; 20 private $envio_gratis_monto_minimo; 20 21 private $hash_andreani; 21 22 private $info_cliente; … … 38 39 $this->mostrar_sin_decimales = isset($settings['mostrar_sin_decimales']) ? $settings['mostrar_sin_decimales'] === 'yes' : false; 39 40 $this->envio_gratis = isset($settings['envio_gratis']) ? $settings['envio_gratis'] : false; 41 $this->envio_gratis_monto_minimo = isset($settings['envio_gratis_monto_minimo']) ? floatval($settings['envio_gratis_monto_minimo']) : 0; 40 42 $this->info_cliente = $this->get_client_info(); 41 43 … … 108 110 $errors[] = $result->get_error_message(); 109 111 } else { 110 $rates = Andreani_Api_Utils::create_shipping_rate_from_response( $result, self::SHIPPING_METHOD_PREFIX, $this->envio_gratis ); 112 $cart_total = isset( $package['contents_cost'] ) ? floatval( $package['contents_cost'] ) : 0; 113 $rates = Andreani_Api_Utils::create_shipping_rate_from_response( $result, self::SHIPPING_METHOD_PREFIX, $this->envio_gratis, $this->envio_gratis_monto_minimo, $cart_total ); 111 114 } 112 115 -
andreani-shipping/trunk/includes/api/pyme/andreani-pyme.php
r3434734 r3436167 18 18 private $mostrar_sin_decimales; 19 19 private $envio_gratis; 20 private $envio_gratis_monto_minimo; 20 21 private $hash_andreani; 21 22 private $info_cliente; … … 38 39 $this->mostrar_sin_decimales = isset($settings['mostrar_sin_decimales']) ? $settings['mostrar_sin_decimales'] === 'yes' : false; 39 40 $this->envio_gratis = isset($settings['envio_gratis']) ? $settings['envio_gratis'] : false; 41 $this->envio_gratis_monto_minimo = isset($settings['envio_gratis_monto_minimo']) ? floatval($settings['envio_gratis_monto_minimo']) : 0; 40 42 $this->info_cliente = $this->get_client_info(); 41 43 … … 257 259 $errors[] = $result->get_error_message(); 258 260 } else { 259 $rates = Andreani_Api_Utils::create_shipping_rate_from_response( $result, self::SHIPPING_METHOD_PREFIX, $this->envio_gratis ); 261 $cart_total = isset( $package['contents_cost'] ) ? floatval( $package['contents_cost'] ) : 0; 262 $rates = Andreani_Api_Utils::create_shipping_rate_from_response( $result, self::SHIPPING_METHOD_PREFIX, $this->envio_gratis, $this->envio_gratis_monto_minimo, $cart_total ); 260 263 } 261 264 -
andreani-shipping/trunk/includes/assets/css/admin.css
r3434734 r3436167 277 277 } 278 278 279 /* Contratos Card */ 280 .andreani-settings-card--contratos { 281 margin-top: 20px; 282 transition: opacity 0.3s ease, transform 0.3s ease; 283 } 284 285 .andreani-settings-card--hidden { 286 opacity: 0; 287 transform: translateY(-10px); 288 pointer-events: none; 289 height: 0; 290 overflow: hidden; 291 margin: 0; 292 padding: 0; 293 } 294 295 .andreani-badge--info { 296 background: #f0f0f0; 297 color: #50575e; 298 font-size: 11px; 299 padding: 4px 10px; 300 } 301 302 .andreani-contratos-list { 303 display: grid; 304 gap: 12px; 305 } 306 307 .andreani-contrato-item { 308 background-color: #f8f9fa; 309 border: 1px solid #e0e0e0; 310 border-radius: 6px; 311 padding: 12px 16px; 312 display: grid; 313 grid-template-columns: repeat(3, 1fr); 314 gap: 8px; 315 } 316 317 .andreani-contrato-item__row { 318 display: flex; 319 flex-direction: column; 320 gap: 2px; 321 } 322 323 .andreani-contrato-item__label { 324 font-size: 11px; 325 color: #667085; 326 text-transform: uppercase; 327 letter-spacing: 0.3px; 328 } 329 330 .andreani-contrato-item__value { 331 font-size: 14px; 332 color: #1d2327; 333 font-weight: 500; 334 } 335 336 .andreani-contrato-item__value--code { 337 font-family: monospace; 338 background-color: #fff; 339 padding: 2px 6px; 340 border-radius: 4px; 341 border: 1px solid #e0e0e0; 342 display: inline-block; 343 } 344 345 /* Refresh Contratos Button */ 346 .andreani-refresh-contratos { 347 display: inline-flex; 348 align-items: center; 349 gap: 6px; 350 margin-left: auto; 351 padding: 6px 12px; 352 background-color: #fff; 353 border: 1px solid #d0d5dd; 354 border-radius: 6px; 355 font-size: 13px; 356 font-weight: 500; 357 color: #667085; 358 cursor: pointer; 359 transition: all 0.2s ease; 360 } 361 362 .andreani-refresh-contratos:hover { 363 background-color: #f8f9fa; 364 border-color: #e31e24; 365 color: #e31e24; 366 } 367 368 .andreani-refresh-contratos:disabled { 369 opacity: 0.7; 370 cursor: not-allowed; 371 } 372 373 .andreani-refresh-contratos svg { 374 width: 16px; 375 height: 16px; 376 fill: currentColor; 377 } 378 379 .andreani-refresh-contratos--loading svg { 380 animation: andreani-spin 1s linear infinite; 381 } 382 383 @keyframes andreani-spin { 384 from { 385 transform: rotate(0deg); 386 } 387 to { 388 transform: rotate(360deg); 389 } 390 } 391 279 392 .andreani-admin-notice { 280 393 border-left-color: #e31e24 !important; … … 327 440 width: 100%; 328 441 } 329 } 442 443 .andreani-contrato-item { 444 grid-template-columns: 1fr; 445 } 446 } -
andreani-shipping/trunk/includes/assets/js/admin.js
r3434734 r3436167 13 13 this.addTooltipSpacing(); 14 14 this.initCredentialEdit(); 15 this.initEnvioGratisToggle(); 16 this.initRefreshContratos(); 15 17 }, 16 18 … … 38 40 }, 39 41 42 initRefreshContratos() { 43 const $refreshBtn = $('.andreani-refresh-contratos'); 44 if ($refreshBtn.length === 0) return; 45 46 $refreshBtn.on('click', function(e) { 47 e.preventDefault(); 48 const $btn = $(this); 49 const nonce = $btn.data('nonce'); 50 const originalText = $btn.html(); 51 52 $btn.prop('disabled', true).addClass('andreani-refresh-contratos--loading'); 53 $btn.html('<svg class="andreani-spinner" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/></svg> Actualizando...'); 54 55 $.ajax({ 56 url: ajaxurl, 57 type: 'POST', 58 data: { 59 action: 'andreani_refresh_contratos', 60 nonce: nonce 61 }, 62 success: function(response) { 63 if (response.success) { 64 AndreaniAdmin.showNotice(response.data.message, 'success'); 65 setTimeout(() => location.reload(), 1000); 66 } else { 67 AndreaniAdmin.showNotice(response.data.message || 'Error al actualizar contratos.', 'error'); 68 $btn.prop('disabled', false).removeClass('andreani-refresh-contratos--loading'); 69 $btn.html(originalText); 70 } 71 }, 72 error: function() { 73 AndreaniAdmin.showNotice('Error de conexión. Intenta nuevamente.', 'error'); 74 $btn.prop('disabled', false).removeClass('andreani-refresh-contratos--loading'); 75 $btn.html(originalText); 76 } 77 }); 78 }); 79 }, 80 81 initEnvioGratisToggle() { 82 const $envioGratisCheckbox = $('input[id*="envio_gratis"]').not('[id*="monto_minimo"]'); 83 const $montoMinimoInput = $('input[id*="envio_gratis_monto_minimo"]'); 84 const $montoMinimoRow = $montoMinimoInput.closest('tr'); 85 86 if ($envioGratisCheckbox.length === 0 || $montoMinimoInput.length === 0) return; 87 88 // Ocultar la fila original 89 $montoMinimoRow.hide(); 90 91 // Crear el contenedor inline debajo del checkbox 92 const $checkboxLabel = $envioGratisCheckbox.closest('label'); 93 const $fieldset = $checkboxLabel.closest('fieldset'); 94 const $container = $fieldset.length > 0 ? $fieldset : $checkboxLabel.parent(); 95 96 const $inlineWrapper = $('<div class="andreani-monto-minimo-wrapper"></div>'); 97 $inlineWrapper.css({ 98 'margin-top': '10px', 99 'padding-left': '24px', 100 'display': 'flex', 101 'align-items': 'center', 102 'gap': '8px' 103 }); 104 105 const $label = $('<label></label>').css({ 106 'font-weight': 'normal', 107 'color': '#50575e', 108 'white-space': 'nowrap' 109 }).text('Aplicar solo en compras mayores a $'); 110 111 // Clonar el input y configurarlo 112 const $newInput = $montoMinimoInput.clone(); 113 $newInput.css({ 114 'width': '120px', 115 'margin': '0' 116 }); 117 118 // Sincronizar valores entre inputs 119 $newInput.on('input', function() { 120 $montoMinimoInput.val($(this).val()); 121 }); 122 123 $inlineWrapper.append($label).append($newInput); 124 $container.append($inlineWrapper); 125 126 // Estado inicial 127 if (!$envioGratisCheckbox.is(':checked')) { 128 $inlineWrapper.hide(); 129 } 130 131 // Escuchar cambios 132 $envioGratisCheckbox.on('change', () => { 133 if ($envioGratisCheckbox.is(':checked')) { 134 $inlineWrapper.slideDown(200); 135 } else { 136 $inlineWrapper.slideUp(200); 137 } 138 }); 139 }, 140 40 141 bindEvents() { 41 142 $(document).on("submit", "form", function (e) { … … 49 150 $(".andreani-cancel-edit").toggle(hasChanged); 50 151 $(".andreani-badge").toggleClass("andreani-badge--hidden", hasChanged); 152 $(".andreani-settings-card--contratos").toggleClass("andreani-settings-card--hidden", hasChanged); 51 153 }); 52 154 … … 62 164 $(".andreani-cancel-edit").hide(); 63 165 $(".andreani-badge").removeClass("andreani-badge--hidden"); 166 $(".andreani-settings-card--contratos").removeClass("andreani-settings-card--hidden"); 64 167 $credentialField.blur(); 65 168 }, -
andreani-shipping/trunk/includes/shipping/andreani-form-fields-shipping-config.php
r3434734 r3436167 38 38 ), 39 39 40 'envio_gratis_monto_minimo' => array( 41 'title' => __( 'Monto mínimo para envío gratis', 'andreani-shipping' ), 42 'type' => 'number', 43 'default' => '', 44 'placeholder' => __( 'Sin mínimo', 'andreani-shipping' ), 45 'description' => __( 'Monto mínimo de compra para aplicar envío gratis. Dejar vacío para que siempre sea gratis.', 'andreani-shipping' ), 46 'desc_tip' => true, 47 'custom_attributes' => array( 48 'min' => '0', 49 'step' => '1', 50 ), 51 ), 52 40 53 'mostrar_sin_decimales' => array( 41 54 'title' => __( 'Mostrar sin decimales', 'andreani-shipping' ), -
andreani-shipping/trunk/includes/shipping/andreani-shipping.php
r3434734 r3436167 101 101 </div> 102 102 </div> 103 104 <?php 105 if ( 'corporativo' === $tipo_cliente && ! empty( $hash_andreani ) ) : 106 $info_corporativo = get_option( 'andreani_corporativo_info', array() ); 107 $contratos_raw = isset( $info_corporativo['contratos'] ) ? $info_corporativo['contratos'] : array(); 108 109 $tipos_permitidos = array( 'paquetes', 'encomienda'); 110 $contratos = array_filter( $contratos_raw, function( $contrato ) use ( $tipos_permitidos ) { 111 $tipo = isset( $contrato['tipoDeEnvioNombre'] ) ? strtolower( $contrato['tipoDeEnvioNombre'] ) : ''; 112 return in_array( $tipo, $tipos_permitidos, true ); 113 } ); 114 115 if ( ! empty( $contratos ) ) : 116 ?> 117 <div class="andreani-settings-card andreani-settings-card--contratos"> 118 <div class="andreani-settings-card__header"> 119 <div class="andreani-settings-card__icon"> 120 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z"/></svg> 121 </div> 122 <h3 class="andreani-settings-card__title"><?php esc_html_e( 'Contratos Habilitados', 'andreani-shipping' ); ?></h3> 123 <span class="andreani-badge andreani-badge--info"><?php echo esc_html( count( $contratos ) ); ?></span> 124 <button type="button" class="andreani-refresh-contratos" data-nonce="<?php echo esc_attr( wp_create_nonce( 'andreani_refresh_contratos' ) ); ?>"> 125 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/></svg> 126 <?php esc_html_e( 'Actualizar', 'andreani-shipping' ); ?> 127 </button> 128 </div> 129 <div class="andreani-settings-card__body"> 130 <div class="andreani-contratos-list"> 131 <?php foreach ( $contratos as $contrato ) : ?> 132 <div class="andreani-contrato-item"> 133 <div class="andreani-contrato-item__row"> 134 <span class="andreani-contrato-item__label"><?php esc_html_e( 'Servicio:', 'andreani-shipping' ); ?></span> 135 <span class="andreani-contrato-item__value"><?php echo esc_html( $contrato['tipoDeEnvioNombre'] ); ?></span> 136 </div> 137 <div class="andreani-contrato-item__row"> 138 <span class="andreani-contrato-item__label"><?php esc_html_e( 'Modo de entrega:', 'andreani-shipping' ); ?></span> 139 <span class="andreani-contrato-item__value"><?php echo esc_html( ucfirst( $contrato['modoDeEntregaNombre'] ) ); ?></span> 140 </div> 141 <div class="andreani-contrato-item__row"> 142 <span class="andreani-contrato-item__label"><?php esc_html_e( 'Contrato:', 'andreani-shipping' ); ?></span> 143 <span class="andreani-contrato-item__value andreani-contrato-item__value--code"><?php echo esc_html( $contrato['numeroDeContrato'] ); ?></span> 144 </div> 145 </div> 146 <?php endforeach; ?> 147 </div> 148 </div> 149 </div> 150 <?php 151 endif; 152 endif; 153 ?> 103 154 104 155 <div class="andreani-settings-footer"> -
andreani-shipping/trunk/includes/utils/andreani-utils.php
r3434734 r3436167 38 38 $endpoint_path = $endpoint_path ? basename( $endpoint_path ) : 'unknown'; 39 39 40 $body_log = ''; 41 if ( ! empty( $body ) && 'GET' !== $method ) { 42 $body_json = wp_json_encode( $body ); 43 $body_log = ' | Body: ' . $body_json; 44 } 45 40 46 $attempt = 0; 41 47 $start_time = microtime( true ); … … 48 54 $error_code = $response->get_error_code(); 49 55 $error_msg = $response->get_error_message(); 50 self::andreani_log( "[HTTP] {$method} /{$endpoint_path} - Error de conexión: [{$error_code}] {$error_msg} (intento " . ( $attempt + 1 ) . ", {$elapsed_ms}ms) ", 'error' );56 self::andreani_log( "[HTTP] {$method} /{$endpoint_path} - Error de conexión: [{$error_code}] {$error_msg} (intento " . ( $attempt + 1 ) . ", {$elapsed_ms}ms){$body_log}", 'error' ); 51 57 if ( ++$attempt > $retries ) return $response; 52 58 self::sleep_retry($attempt); … … 59 65 $response_body = wp_remote_retrieve_body( $response ); 60 66 $error_detail = self::extract_api_error_message( $response_body ); 61 self::andreani_log( "[HTTP] {$method} /{$endpoint_path} - Error {$response_code}: {$error_detail} (intento " . ( $attempt + 1 ) . ", {$elapsed_ms}ms) ", 'error' );67 self::andreani_log( "[HTTP] {$method} /{$endpoint_path} - Error {$response_code}: {$error_detail} (intento " . ( $attempt + 1 ) . ", {$elapsed_ms}ms){$body_log}", 'error' ); 62 68 if ( ++$attempt > $retries ) return new WP_Error( 'http_error', "Error HTTP {$response_code}: {$error_detail}" ); 63 69 self::sleep_retry($attempt); … … 67 73 68 74 $response_body = wp_remote_retrieve_body( $response ); 69 self::andreani_log( "[HTTP] {$method} /{$endpoint_path} - OK {$response_code} ({$elapsed_ms}ms) ", 'debug' );75 self::andreani_log( "[HTTP] {$method} /{$endpoint_path} - OK {$response_code} ({$elapsed_ms}ms){$body_log}", 'debug' ); 70 76 71 77 return $response_body; -
andreani-shipping/trunk/readme.txt
r3434734 r3436167 5 5 Requires at least: 5.0 6 6 Tested up to: 6.8 7 Stable tag: 1. 2.07 Stable tag: 1.3.0 8 8 Contributors: integracionandreani 9 9 Donate link: … … 67 67 == Changelog == 68 68 69 = 1.3.0 = 70 * Nueva funcionalidad: Configuración de monto mínimo personalizado para envío gratis por método de envío 71 * Nueva herramienta administrativa: Botón para refrescar contratos corporativos vía AJAX sin recargar la página 72 * Mejoras en la interfaz de administración con mejor feedback visual y estados de carga 73 * Optimización en el manejo de contratos Andreani con validación mejorada 74 69 75 = 1.2.0 = 70 76 * Detección automática del tipo de cliente (Pyme/Corporativo) al validar credenciales
Note: See TracChangeset
for help on using the changeset viewer.