/** * Admin JavaScript for Studiou WC Product Category Manager */ (function($) { 'use strict'; // Safe init wrapper - prevents one form's error from breaking others function safeInit(name, selector, initFn) { try { if ($(selector).length) { console.log('STUDIOU WC: ' + name + ' found, initializing'); initFn(); } } catch (e) { console.error('STUDIOU WC: Error initializing ' + name + ':', e); } } // Initialize admin scripts $(document).ready(function() { // Debug: Log that script is loaded console.log('STUDIOU WC: Admin script loaded v1.6.0'); if (typeof studiouWcpcm === 'undefined') { console.error('STUDIOU WC: studiouWcpcm object is NOT defined - AJAX will not work'); return; } console.log('STUDIOU WC: studiouWcpcm object:', studiouWcpcm); safeInit('Import form', '#studiou-wcpcm-import-form', initImportForm); safeInit('Export form', '#studiou-wcpcm-export-form', initExportForm); safeInit('Sample download', '#studiou-wcpcm-download-sample', initSampleDownload); safeInit('Product import form', '#studiou-wcpcm-product-import-form', initProductImportForm); safeInit('Product export form', '#studiou-wcpcm-product-export-form', initProductExportForm); // Category Manipulations page: the manipulation forms live inside // lazily-loaded tab partials, so they are initialised by the tab // controller after their partial is injected (see initManipulationTabs). safeInit('Manipulation tabs', '.studiou-wcpcm-tabs', initManipulationTabs); }); /** * Initialize the tabbed Category Manipulations page. * * Each tab's markup is fetched on demand via the studiou_wcpcm_load_tab * AJAX handler. The first time a tab is opened its partial is rendered into * its own panel and its form handlers are wired; the panel is then kept in * the DOM (hidden) so switching tabs preserves both state and event * handlers - no re-fetch and no re-init. */ function initManipulationTabs() { // Maps a tab slug to the init function that wires its partial's handlers. var TAB_INIT = { 'move': initMoveForm, 'batch-description': initBatchDescriptionForm, 'delete-products': initDeleteProductsForm, 'clear-media': initClearMediaForm, 'remove-unassigned': initRemoveUnassignedMediaForm, 'upvp': initUpdateVariantPricesForm, 'notes': null // static, nothing to wire }; var i18n = (studiouWcpcm && studiouWcpcm.i18n) ? studiouWcpcm.i18n : {}; var $tabs = $('.studiou-wcpcm-tabs .nav-tab'); var $content = $('#studiou-wcpcm-tab-content'); var loaded = {}; // slug -> true once its panel exists in the DOM var allowed = $tabs.map(function() { return $(this).data('tab'); }).get(); function panelFor(slug) { return $content.children('.studiou-wcpcm-tab-panel[data-tab="' + slug + '"]'); } function activate(slug) { if (allowed.indexOf(slug) === -1) { slug = allowed[0]; } $tabs.removeClass('nav-tab-active') .filter('[data-tab="' + slug + '"]').addClass('nav-tab-active'); if (window.history && history.replaceState) { history.replaceState(null, '', '#' + slug); } else { window.location.hash = slug; } // Drop any stale loading / error placeholders, hide every panel. $content.find('.studiou-wcpcm-tab-loading, .studiou-wcpcm-tab-error').remove(); $content.children('.studiou-wcpcm-tab-panel').hide(); // Already loaded - just reveal its panel (handlers + state intact). if (loaded[slug]) { panelFor(slug).show(); return; } $content.append('
' + response.data.message + '
'); $('.studiou-wcpcm-move-results').show(); // Refresh the page to update category counts setTimeout(function() { location.reload(); }, 3000); } else { showNotice('error', response.data.message); } }, error: function(xhr, status, error) { console.error('STUDIOU WC: AJAX error:', status, error); console.error('STUDIOU WC: Response text:', xhr.responseText); showNotice('error', studiouWcpcm.i18n.moveError + ': ' + error); }, complete: function() { // Hide spinner $submitBtn.prop('disabled', false); $spinner.css('visibility', 'hidden'); } }); }); } /** * Initialize batch description form */ function initBatchDescriptionForm() { console.log('STUDIOU WC: Initializing batch description form handlers'); // Check all button handler $('#studiou-wcpcm-check-all').on('click', function(e) { e.preventDefault(); console.log('STUDIOU WC: Check all button clicked'); $('#categories_list input[type="checkbox"]').prop('checked', true); }); // Uncheck all button handler $('#studiou-wcpcm-uncheck-all').on('click', function(e) { e.preventDefault(); console.log('STUDIOU WC: Uncheck all button clicked'); $('#categories_list input[type="checkbox"]').prop('checked', false); }); // Form submit handler $('#studiou-wcpcm-batch-description-form').on('submit', function(e) { e.preventDefault(); console.log('STUDIOU WC: Batch description form submitted'); // Get selected categories var selectedCategories = []; $('#categories_list input[type="checkbox"]:checked').each(function() { selectedCategories.push($(this).val()); }); var description = $('#category_description').val(); console.log('STUDIOU WC: Selected categories:', selectedCategories); console.log('STUDIOU WC: Description:', description); // Validate input if (selectedCategories.length === 0) { console.log('STUDIOU WC: No categories selected'); showNotice('error', 'Please select at least one category'); return; } // Show spinner var $submitBtn = $(this).find('#studiou-wcpcm-batch-description-button'); var $spinner = $(this).find('.spinner'); $submitBtn.prop('disabled', true); $spinner.css('visibility', 'visible'); // Clear previous notices $('.studiou-wcpcm-notice-area').empty(); // Debug: Log AJAX request details console.log('STUDIOU WC: Sending batch description AJAX request to:', studiouWcpcm.ajaxUrl); console.log('STUDIOU WC: Nonce:', studiouWcpcm.nonce); // Send AJAX request $.ajax({ url: studiouWcpcm.ajaxUrl, type: 'POST', data: { action: 'studiou_wcpcm_batch_description', selected_categories: selectedCategories, description: description, nonce: studiouWcpcm.nonce }, success: function(response) { console.log('STUDIOU WC: Batch description AJAX response:', response); if (response.success) { showNotice('success', studiouWcpcm.i18n.batchDescriptionSuccess || 'Batch description operation successful'); // Show results $('#studiou-wcpcm-batch-description-message').html('' + response.data.message + '
'); $('.studiou-wcpcm-batch-description-results').show(); } else { showNotice('error', response.data.message); } }, error: function(xhr, status, error) { console.error('STUDIOU WC: Batch description AJAX error:', status, error); console.error('STUDIOU WC: Response text:', xhr.responseText); showNotice('error', (studiouWcpcm.i18n.batchDescriptionError || 'Batch description operation error') + ': ' + error); }, complete: function() { // Hide spinner $submitBtn.prop('disabled', false); $spinner.css('visibility', 'hidden'); } }); }); } /** * Initialize sample CSV download */ function initSampleDownload() { $('#studiou-wcpcm-download-sample').on('click', function(e) { e.preventDefault(); // Sample CSV content var csvContent = 'name,url-name,parent-name,description,display-type,visibility,protected-passwords,operation\n' + '"Clothing","clothing","","Top quality clothing","default","public","","A"\n' + '"Men","men","Clothing","Men\'s clothing","products","public","","A"\n' + '"Women","women","Clothing","Women\'s clothing","products","protected","password123","A"\n' + '"Kids","kids","Clothing","Kids clothing","products","public","","U"\n' + '"Accessories","accessories","","All accessories","default","public","","D"'; // Create download link var blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); var url = URL.createObjectURL(blob); var link = document.createElement('a'); link.setAttribute('href', url); link.setAttribute('download', 'sample-product-categories.csv'); link.style.visibility = 'hidden'; document.body.appendChild(link); link.click(); document.body.removeChild(link); }); } /** * Initialize delete products form */ function initDeleteProductsForm() { console.log('STUDIOU WC: Initializing delete products form handlers'); console.log('STUDIOU WC: Form element:', $('#studiou-wcpcm-delete-products-form')); console.log('STUDIOU WC: Check all button:', $('#studiou-wcpcm-delete-check-all')); console.log('STUDIOU WC: Delete button:', $('#studiou-wcpcm-delete-products-button')); // Check all button handler $('#studiou-wcpcm-delete-check-all').on('click', function(e) { e.preventDefault(); console.log('STUDIOU WC: Delete check all button clicked'); $('#delete_categories_list input[type="checkbox"]').prop('checked', true); }); // Uncheck all button handler $('#studiou-wcpcm-delete-uncheck-all').on('click', function(e) { e.preventDefault(); console.log('STUDIOU WC: Delete uncheck all button clicked'); $('#delete_categories_list input[type="checkbox"]').prop('checked', false); }); // Form submit handler $('#studiou-wcpcm-delete-products-form').on('submit', function(e) { e.preventDefault(); console.log('STUDIOU WC: Delete products form submitted'); // Get selected categories var selectedCategories = []; $('#delete_categories_list input[type="checkbox"]:checked').each(function() { selectedCategories.push($(this).val()); }); console.log('STUDIOU WC: Selected categories:', selectedCategories); // Validate input if (selectedCategories.length === 0) { console.log('STUDIOU WC: No categories selected'); showNotice('error', studiouWcpcm.i18n.selectAtLeastOneCategory || 'Please select at least one category'); return; } // Confirm deletion if (!confirm(studiouWcpcm.i18n.confirmDelete || 'Are you sure you want to permanently delete ALL products in the selected categories? This action cannot be undone!')) { console.log('STUDIOU WC: User cancelled deletion'); return; } // Show spinner var $submitBtn = $(this).find('#studiou-wcpcm-delete-products-button'); var $spinner = $(this).find('.spinner'); $submitBtn.prop('disabled', true); $spinner.css('visibility', 'visible'); // Clear previous notices $('.studiou-wcpcm-notice-area').empty(); // Hide results, show progress $('.studiou-wcpcm-delete-results').hide(); $('.studiou-wcpcm-delete-progress').show(); $('#studiou-wcpcm-delete-progress-text').text('Initializing...'); updateProgressBar(0); // Debug: Log AJAX request details console.log('STUDIOU WC: Sending delete products AJAX request to:', studiouWcpcm.ajaxUrl); console.log('STUDIOU WC: Nonce:', studiouWcpcm.nonce); // Send AJAX request to get product IDs $.ajax({ url: studiouWcpcm.ajaxUrl, type: 'POST', data: { action: 'studiou_wcpcm_delete_products', delete_categories: selectedCategories, nonce: studiouWcpcm.nonce }, success: function(response) { console.log('STUDIOU WC: Delete products AJAX response:', response); if (response.success) { var productIds = response.data.product_ids; var totalCount = response.data.total_count; console.log('STUDIOU WC: Total products to delete:', totalCount); if (totalCount === 0) { showNotice('success', studiouWcpcm.i18n.noProductsFound || 'No products found in selected categories'); $('.studiou-wcpcm-delete-progress').hide(); $submitBtn.prop('disabled', false); $spinner.css('visibility', 'hidden'); return; } // Process products in batches processDeletionBatches(productIds, totalCount, $submitBtn, $spinner); } else { showNotice('error', response.data.message); $('.studiou-wcpcm-delete-progress').hide(); $submitBtn.prop('disabled', false); $spinner.css('visibility', 'hidden'); } }, error: function(xhr, status, error) { console.error('STUDIOU WC: Delete products AJAX error:', status, error); console.error('STUDIOU WC: Response text:', xhr.responseText); showNotice('error', (studiouWcpcm.i18n.deleteError || 'Delete products operation error') + ': ' + error); $('.studiou-wcpcm-delete-progress').hide(); $submitBtn.prop('disabled', false); $spinner.css('visibility', 'hidden'); } }); }); } /** * Process deletion in batches */ function processDeletionBatches(productIds, totalCount, $submitBtn, $spinner) { var batchSize = 10; // Process 10 products at a time var batches = []; var totalDeleted = 0; var totalFailed = 0; var failedProducts = []; // Split products into batches for (var i = 0; i < productIds.length; i += batchSize) { batches.push(productIds.slice(i, i + batchSize)); } console.log('STUDIOU WC: Processing ' + batches.length + ' batches of products'); var currentBatch = 0; function processBatch() { if (currentBatch >= batches.length) { // All batches completed console.log('STUDIOU WC: All batches completed'); onDeletionComplete(totalDeleted, totalFailed, failedProducts, $submitBtn, $spinner); return; } var batch = batches[currentBatch]; var progress = Math.round((currentBatch / batches.length) * 100); $('#studiou-wcpcm-delete-progress-text').text( 'Deleting products... ' + (currentBatch * batchSize) + ' of ' + totalCount + ' processed' ); updateProgressBar(progress); // Send batch delete request $.ajax({ url: studiouWcpcm.ajaxUrl, type: 'POST', data: { action: 'studiou_wcpcm_delete_products_batch', product_ids: batch, nonce: studiouWcpcm.nonce }, success: function(response) { if (response.success) { totalDeleted += response.data.deleted_count; totalFailed += response.data.failed_count; failedProducts = failedProducts.concat(response.data.failed_products); console.log('STUDIOU WC: Batch ' + currentBatch + ' completed - Deleted: ' + response.data.deleted_count + ', Failed: ' + response.data.failed_count); // Process next batch currentBatch++; processBatch(); } else { showNotice('error', response.data.message); $('.studiou-wcpcm-delete-progress').hide(); $submitBtn.prop('disabled', false); $spinner.css('visibility', 'hidden'); } }, error: function(xhr, status, error) { console.error('STUDIOU WC: Batch delete AJAX error:', status, error); showNotice('error', 'Error deleting batch: ' + error); $('.studiou-wcpcm-delete-progress').hide(); $submitBtn.prop('disabled', false); $spinner.css('visibility', 'hidden'); } }); } // Start processing batches processBatch(); } /** * Handle deletion completion */ function onDeletionComplete(totalDeleted, totalFailed, failedProducts, $submitBtn, $spinner) { // Update progress bar to 100% updateProgressBar(100); $('#studiou-wcpcm-delete-progress-text').text('Deletion complete!'); // Show results var message = 'Deletion Summary:
'; message += 'Deletion Summary:
'; message += 'Deletion Summary:
'; message += 'Import Summary:
'; message += '' + importMessages.join('\n') + '';
$('#studiou-wcpcm-product-import-details-content').html(details);
}
$('.studiou-wcpcm-product-import-results').show();
// Show save failed button if there are failed items
if (importFailed > 0 && importFailedCsv) {
window.studiouWcpcmFailedCsv = importFailedCsv;
$('.studiou-wcpcm-product-import-failed').show();
}
// Hide progress after delay
setTimeout(function() {
$('.studiou-wcpcm-product-import-progress').fadeOut();
}, 2000);
$submitBtn.prop('disabled', false);
$spinner.css('visibility', 'hidden');
} else {
// Process next batch
processBatch(importProcessed, $submitBtn, $spinner);
}
} else {
showNotice('error', response.data.message || 'Batch processing failed');
$('.studiou-wcpcm-product-import-progress').hide();
$submitBtn.prop('disabled', false);
$spinner.css('visibility', 'hidden');
}
},
error: function(xhr, status, error) {
console.error('STUDIOU WC: Batch processing error:', status, error);
showNotice('error', 'Batch processing error: ' + error);
$('.studiou-wcpcm-product-import-progress').hide();
$submitBtn.prop('disabled', false);
$spinner.css('visibility', 'hidden');
}
});
}
// Save failed products button handler
$('#studiou-wcpcm-save-failed-products').on('click', function(e) {
e.preventDefault();
if (window.studiouWcpcmFailedCsv) {
var blob = new Blob([window.studiouWcpcmFailedCsv], { type: 'text/csv;charset=utf-8;' });
var url = URL.createObjectURL(blob);
var link = document.createElement('a');
link.setAttribute('href', url);
link.setAttribute('download', 'failed-products-' + Date.now() + '.csv');
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
});
}
/**
* Initialize product export form
*/
function initProductExportForm() {
console.log('STUDIOU WC: Initializing product export form handlers');
// Select all button handler
$('#studiou-wcpcm-export-select-all').on('click', function(e) {
e.preventDefault();
console.log('STUDIOU WC: Export select all button clicked');
$('#export_categories_list input[type="checkbox"]').prop('checked', true);
});
// Deselect all button handler
$('#studiou-wcpcm-export-deselect-all').on('click', function(e) {
e.preventDefault();
console.log('STUDIOU WC: Export deselect all button clicked');
$('#export_categories_list input[type="checkbox"]').prop('checked', false);
});
// Form submit handler
$('#studiou-wcpcm-product-export-form').on('submit', function(e) {
e.preventDefault();
console.log('STUDIOU WC: Product export form submitted');
// Get selected categories
var selectedCategories = [];
$('#export_categories_list input[type="checkbox"]:checked').each(function() {
selectedCategories.push($(this).val());
});
console.log('STUDIOU WC: Selected categories:', selectedCategories);
// Validate input
if (selectedCategories.length === 0) {
console.log('STUDIOU WC: No categories selected');
showNotice('error', 'Please select at least one category');
return;
}
// Show spinner
var $submitBtn = $(this).find('#studiou-wcpcm-product-export-button');
var $spinner = $(this).find('.spinner');
$submitBtn.prop('disabled', true);
$spinner.css('visibility', 'visible');
// Clear previous notices
$('.studiou-wcpcm-notice-area').empty();
$('.studiou-wcpcm-product-export-results').hide();
// Debug: Log AJAX request details
console.log('STUDIOU WC: Sending product export AJAX request to:', studiouWcpcm.ajaxUrl);
console.log('STUDIOU WC: Nonce:', studiouWcpcm.nonce);
// Send AJAX request
$.ajax({
url: studiouWcpcm.ajaxUrl,
type: 'POST',
data: {
action: 'studiou_wcpcm_product_export',
export_categories: selectedCategories,
nonce: studiouWcpcm.nonce
},
success: function(response) {
console.log('STUDIOU WC: Product export AJAX response:', response);
if (response.success) {
showNotice('success', 'Export successful!');
// Show results
$('#studiou-wcpcm-product-export-message').html('' + response.data.message + '
'); $('#studiou-wcpcm-download-product-export').attr('href', response.data.download_url); $('.studiou-wcpcm-product-export-results').show(); } else { showNotice('error', response.data.message || 'Export failed'); } }, error: function(xhr, status, error) { console.error('STUDIOU WC: Product export AJAX error:', status, error); console.error('STUDIOU WC: Response text:', xhr.responseText); showNotice('error', 'Product export error: ' + error); }, complete: function() { // Hide spinner $submitBtn.prop('disabled', false); $spinner.css('visibility', 'hidden'); } }); }); } /** * Update product import progress bar */ function updateProductImportProgressBar(percentage) { $('#studiou-wcpcm-product-import-progress-bar').css('width', percentage + '%'); $('#studiou-wcpcm-product-import-progress-bar').attr('data-progress', Math.round(percentage) + '%'); } // Additional debug: Check page state after DOM load $(window).on('load', function() { console.log('STUDIOU WC: Window loaded'); console.log('STUDIOU WC: Manipulation tabs exist:', $('.studiou-wcpcm-tabs').length > 0); console.log('STUDIOU WC: Product import form exists:', $('#studiou-wcpcm-product-import-form').length > 0); console.log('STUDIOU WC: Product export form exists:', $('#studiou-wcpcm-product-export-form').length > 0); }); /** * Initialize Update Product Variant Prices form (UPVP) — v1.5.3 */ function initUpdateVariantPricesForm() { var $form = $('#studiou-wcpcm-upvp-form'); var $catList = $('#upvp_categories_list'); var $attrSelect = $('#upvp_attribute'); var $valueSelect = $('#upvp_attribute_value'); var $newPrice = $('#upvp_new_price'); var $countLabel = $('#studiou-wcpcm-upvp-affected-count'); var $dryRunBtn = $('#studiou-wcpcm-upvp-dry-run-button'); var $applyBtn = $('#studiou-wcpcm-upvp-apply-button'); var $spinner = $form.find('.spinner'); var $resultsBox = $('.studiou-wcpcm-upvp-results'); var $resultsMsg = $('#studiou-wcpcm-upvp-message'); var i18n = (studiouWcpcm && studiouWcpcm.i18n) ? studiouWcpcm.i18n : {}; var countDebounceHandle = null; var countInFlight = false; function getSelectedCategoryIds() { var ids = []; $catList.find('input[type="checkbox"]:checked').each(function() { ids.push($(this).val()); }); return ids; } function setApplyEnabled(count) { var enabled = (count > 0) && !countInFlight; $dryRunBtn.prop('disabled', !enabled); $applyBtn.prop('disabled', !enabled); } function loadAttributes() { $attrSelect.prop('disabled', true).html( '' ); $.ajax({ url: studiouWcpcm.ajaxUrl, type: 'POST', data: { action: 'studiou_wcpcm_upvp_get_attributes', nonce: studiouWcpcm.nonce }, success: function(response) { $attrSelect.empty(); $attrSelect.append(''); if (response.success && response.data && response.data.attributes) { $.each(response.data.attributes, function(_, a) { $attrSelect.append( $('') .val(a.key) .attr('data-istax', a.is_taxonomy ? '1' : '0') .text(a.label) ); }); } $attrSelect.prop('disabled', false); }, error: function(xhr, status, error) { console.error('STUDIOU WC UPVP: get_attributes failed', status, error); $attrSelect.prop('disabled', false); } }); } function loadValues() { var key = $attrSelect.val(); $valueSelect.prop('disabled', true).empty(); $valueSelect.append(''); if (!key) { $valueSelect.empty(); $valueSelect.append(''); $valueSelect.prop('disabled', true); refreshCount(); return; } $.ajax({ url: studiouWcpcm.ajaxUrl, type: 'POST', data: { action: 'studiou_wcpcm_upvp_get_attribute_values', nonce: studiouWcpcm.nonce, attribute_key: key, category_ids: getSelectedCategoryIds() }, success: function(response) { $valueSelect.empty(); $valueSelect.append(''); if (response.success && response.data && response.data.values) { $.each(response.data.values, function(_, v) { $valueSelect.append($('').val(v.value).text(v.label)); }); } $valueSelect.prop('disabled', false); refreshCount(); }, error: function(xhr, status, error) { console.error('STUDIOU WC UPVP: get_attribute_values failed', status, error); $valueSelect.empty(); $valueSelect.append(''); $valueSelect.prop('disabled', false); } }); } function refreshCount() { if (countDebounceHandle) { clearTimeout(countDebounceHandle); } countDebounceHandle = setTimeout(doRefreshCount, 300); } function doRefreshCount() { var cats = getSelectedCategoryIds(); var key = $attrSelect.val(); var val = $valueSelect.val(); if (!cats.length || !key || !val) { $countLabel.text('0'); setApplyEnabled(0); return; } countInFlight = true; setApplyEnabled(0); $.ajax({ url: studiouWcpcm.ajaxUrl, type: 'POST', data: { action: 'studiou_wcpcm_upvp_count', nonce: studiouWcpcm.nonce, category_ids: cats, attribute_key: key, attribute_value: val }, success: function(response) { countInFlight = false; if (response.success && response.data) { var c = parseInt(response.data.count, 10) || 0; $countLabel.text(c); setApplyEnabled(c); } else { $countLabel.text('0'); setApplyEnabled(0); } }, error: function() { countInFlight = false; $countLabel.text('0'); setApplyEnabled(0); } }); } function renderSampleTable(sample, newPriceLabel) { if (!sample || !sample.length) return ''; var html = '| ID | SKU | Name | Parent | Current | '; if (newPriceLabel !== undefined) html += 'New | '; html += '
|---|---|---|---|---|---|
| ' + r.id + ' | '; html += '' + (r.sku || '') + ' | '; html += '' + (r.name || '') + ' | '; html += '' + (r.parent_name || '') + ' | '; html += '' + (r.current_price || '') + ' | '; if (newPriceLabel !== undefined) html += '' + newPriceLabel + ' | '; html += '
' + (i18n.upvpNoMatches || 'No variations match the current filter.') + '
'; } else { var tpl = i18n.upvpDryRunComplete || 'Dry run complete: %d variations would be updated to %s.'; msg = '' + tpl.replace('%d', c).replace('%s', price !== '' ? price : '—') + '
'; msg += renderSampleTable(sample, price !== '' ? price : undefined); } $resultsMsg.html(msg); $resultsBox.show(); $countLabel.text(c); setApplyEnabled(c); } else { showNotice('error', (response.data && response.data.message) || 'Dry run failed'); } }, error: function(xhr, status, error) { showNotice('error', 'Dry run error: ' + error); }, complete: function() { $spinner.css('visibility', 'hidden'); } }); }); // Apply $applyBtn.on('click', function(e) { e.preventDefault(); var cats = getSelectedCategoryIds(); var key = $attrSelect.val(); var val = $valueSelect.val(); var price = $newPrice.val(); var count = parseInt($countLabel.text(), 10) || 0; if (!cats.length) { showNotice('error', i18n.selectAtLeastOneCategory || 'Please select at least one category'); return; } if (!key) { showNotice('error', i18n.upvpSelectAttribute || 'Please select an attribute'); return; } if (!val) { showNotice('error', i18n.upvpSelectValue || 'Please select an attribute value'); return; } if (price === '' || isNaN(parseFloat(price)) || parseFloat(price) < 0) { showNotice('error', i18n.upvpInvalidPrice || 'Please enter a valid new price'); return; } var confirmTpl = i18n.upvpConfirmApply || 'Are you sure you want to update %d variations?'; if (!confirm(confirmTpl.replace('%d', count))) { return; } $('.studiou-wcpcm-notice-area').empty(); $resultsBox.hide(); $spinner.css('visibility', 'visible'); $dryRunBtn.prop('disabled', true); $applyBtn.prop('disabled', true); $.ajax({ url: studiouWcpcm.ajaxUrl, type: 'POST', data: { action: 'studiou_wcpcm_upvp_apply', nonce: studiouWcpcm.nonce, category_ids: cats, attribute_key: key, attribute_value: val, new_price: price }, success: function(response) { if (response.success && response.data) { showNotice('success', i18n.upvpApplySuccess || 'Variant prices updated successfully'); var html = '' + (response.data.message || '') + '
'; if (response.data.failed_ids && response.data.failed_ids.length) { html += 'Failed IDs: ' + response.data.failed_ids.join(', ') + '
'; } $resultsMsg.html(html); $resultsBox.show(); refreshCount(); } else { showNotice('error', (response.data && response.data.message) || (i18n.upvpApplyError || 'Variant prices update error')); } }, error: function(xhr, status, error) { showNotice('error', (i18n.upvpApplyError || 'Variant prices update error') + ': ' + error); }, complete: function() { $spinner.css('visibility', 'hidden'); $dryRunBtn.prop('disabled', false); $applyBtn.prop('disabled', false); } }); }); // Initial load loadAttributes(); setApplyEnabled(0); } })(jQuery);