admin.js 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  1. /**
  2. * Admin JavaScript for Studiou WC Product Category Manager
  3. */
  4. (function($) {
  5. 'use strict';
  6. // Initialize admin scripts
  7. $(document).ready(function() {
  8. // Debug: Log that script is loaded
  9. console.log('STUDIOU WC: Admin script loaded');
  10. console.log('STUDIOU WC: studiouWcpcm object:', studiouWcpcm);
  11. // Import form handling
  12. if ($('#studiou-wcpcm-import-form').length) {
  13. console.log('STUDIOU WC: Import form found');
  14. initImportForm();
  15. }
  16. // Export form handling
  17. if ($('#studiou-wcpcm-export-form').length) {
  18. console.log('STUDIOU WC: Export form found');
  19. initExportForm();
  20. }
  21. // Move products form handling
  22. if ($('#studiou-wcpcm-move-form').length) {
  23. console.log('STUDIOU WC: Move form found');
  24. initMoveForm();
  25. } else {
  26. console.log('STUDIOU WC: Move form NOT found');
  27. }
  28. // Batch description form handling
  29. if ($('#studiou-wcpcm-batch-description-form').length) {
  30. console.log('STUDIOU WC: Batch description form found');
  31. initBatchDescriptionForm();
  32. }
  33. // Delete products form handling
  34. if ($('#studiou-wcpcm-delete-products-form').length) {
  35. console.log('STUDIOU WC: Delete products form found');
  36. initDeleteProductsForm();
  37. }
  38. // Sample CSV download handler
  39. if ($('#studiou-wcpcm-download-sample').length) {
  40. initSampleDownload();
  41. }
  42. // Product import form handling
  43. if ($('#studiou-wcpcm-product-import-form').length) {
  44. console.log('STUDIOU WC: Product import form found');
  45. initProductImportForm();
  46. }
  47. // Product export form handling
  48. if ($('#studiou-wcpcm-product-export-form').length) {
  49. console.log('STUDIOU WC: Product export form found');
  50. initProductExportForm();
  51. }
  52. });
  53. /**
  54. * Initialize import form
  55. */
  56. function initImportForm() {
  57. $('#studiou-wcpcm-import-form').on('submit', function(e) {
  58. e.preventDefault();
  59. // Show spinner
  60. var $submitBtn = $(this).find('#studiou-wcpcm-import-button');
  61. var $spinner = $(this).find('.spinner');
  62. $submitBtn.prop('disabled', true);
  63. $spinner.css('visibility', 'visible');
  64. // Clear previous notices
  65. $('.studiou-wcpcm-notice-area').empty();
  66. // Create form data
  67. var formData = new FormData(this);
  68. formData.append('action', 'studiou_wcpcm_import');
  69. formData.append('nonce', studiouWcpcm.nonce);
  70. // Send AJAX request
  71. $.ajax({
  72. url: studiouWcpcm.ajaxUrl,
  73. type: 'POST',
  74. data: formData,
  75. processData: false,
  76. contentType: false,
  77. success: function(response) {
  78. if (response.success) {
  79. showNotice('success', studiouWcpcm.i18n.importSuccess);
  80. // Show results
  81. $('#studiou-wcpcm-import-results').text(response.data.message);
  82. $('.studiou-wcpcm-import-results').show();
  83. } else {
  84. showNotice('error', response.data.message);
  85. }
  86. },
  87. error: function() {
  88. showNotice('error', studiouWcpcm.i18n.importError);
  89. },
  90. complete: function() {
  91. // Hide spinner
  92. $submitBtn.prop('disabled', false);
  93. $spinner.css('visibility', 'hidden');
  94. }
  95. });
  96. });
  97. }
  98. /**
  99. * Initialize export form
  100. */
  101. function initExportForm() {
  102. $('#studiou-wcpcm-export-form').on('submit', function(e) {
  103. e.preventDefault();
  104. // Show spinner
  105. var $submitBtn = $(this).find('#studiou-wcpcm-export-button');
  106. var $spinner = $(this).find('.spinner');
  107. $submitBtn.prop('disabled', true);
  108. $spinner.css('visibility', 'visible');
  109. // Clear previous notices
  110. $('.studiou-wcpcm-notice-area').empty();
  111. // Send AJAX request
  112. $.ajax({
  113. url: studiouWcpcm.ajaxUrl,
  114. type: 'POST',
  115. data: {
  116. action: 'studiou_wcpcm_export',
  117. nonce: studiouWcpcm.nonce
  118. },
  119. success: function(response) {
  120. if (response.success) {
  121. showNotice('success', studiouWcpcm.i18n.exportSuccess);
  122. // Show download link
  123. $('#studiou-wcpcm-export-message').text(response.data.message);
  124. $('#studiou-wcpcm-download-export').attr('href', response.data.download_url);
  125. $('.studiou-wcpcm-export-results').show();
  126. } else {
  127. showNotice('error', response.data.message);
  128. }
  129. },
  130. error: function() {
  131. showNotice('error', studiouWcpcm.i18n.exportError);
  132. },
  133. complete: function() {
  134. // Hide spinner
  135. $submitBtn.prop('disabled', false);
  136. $spinner.css('visibility', 'hidden');
  137. }
  138. });
  139. });
  140. }
  141. /**
  142. * Initialize move products form
  143. */
  144. function initMoveForm() {
  145. console.log('STUDIOU WC: Initializing move form handlers');
  146. // Add debug button click handler first
  147. $('#studiou-wcpcm-move-button').on('click', function(e) {
  148. console.log('STUDIOU WC: Move button clicked directly');
  149. });
  150. $('#studiou-wcpcm-move-form').on('submit', function(e) {
  151. e.preventDefault();
  152. // Debug: Log form submission
  153. console.log('STUDIOU WC: Move form submitted');
  154. // Validate that different categories are selected
  155. var sourceCategory = $('#source_category').val();
  156. var targetCategory = $('#target_category').val();
  157. console.log('STUDIOU WC: Source category:', sourceCategory, 'Target category:', targetCategory);
  158. if (!sourceCategory || !targetCategory) {
  159. console.log('STUDIOU WC: Missing category selection');
  160. showNotice('error', 'Please select both source and target categories');
  161. return;
  162. }
  163. if (sourceCategory === targetCategory) {
  164. console.log('STUDIOU WC: Same category selected');
  165. showNotice('error', studiouWcpcm.i18n.selectDifferentCategories);
  166. return;
  167. }
  168. // Show spinner
  169. var $submitBtn = $(this).find('#studiou-wcpcm-move-button');
  170. var $spinner = $(this).find('.spinner');
  171. $submitBtn.prop('disabled', true);
  172. $spinner.css('visibility', 'visible');
  173. // Clear previous notices
  174. $('.studiou-wcpcm-notice-area').empty();
  175. // Debug: Log AJAX request details
  176. console.log('STUDIOU WC: Sending AJAX request to:', studiouWcpcm.ajaxUrl);
  177. console.log('STUDIOU WC: Nonce:', studiouWcpcm.nonce);
  178. // Send AJAX request
  179. $.ajax({
  180. url: studiouWcpcm.ajaxUrl,
  181. type: 'POST',
  182. data: {
  183. action: 'studiou_wcpcm_move_products',
  184. source_category: sourceCategory,
  185. target_category: targetCategory,
  186. nonce: studiouWcpcm.nonce
  187. },
  188. success: function(response) {
  189. console.log('STUDIOU WC: AJAX response:', response);
  190. if (response.success) {
  191. showNotice('success', studiouWcpcm.i18n.moveSuccess);
  192. // Show results
  193. $('#studiou-wcpcm-move-message').html('<p>' + response.data.message + '</p>');
  194. $('.studiou-wcpcm-move-results').show();
  195. // Refresh the page to update category counts
  196. setTimeout(function() {
  197. location.reload();
  198. }, 3000);
  199. } else {
  200. showNotice('error', response.data.message);
  201. }
  202. },
  203. error: function(xhr, status, error) {
  204. console.error('STUDIOU WC: AJAX error:', status, error);
  205. console.error('STUDIOU WC: Response text:', xhr.responseText);
  206. showNotice('error', studiouWcpcm.i18n.moveError + ': ' + error);
  207. },
  208. complete: function() {
  209. // Hide spinner
  210. $submitBtn.prop('disabled', false);
  211. $spinner.css('visibility', 'hidden');
  212. }
  213. });
  214. });
  215. }
  216. /**
  217. * Initialize batch description form
  218. */
  219. function initBatchDescriptionForm() {
  220. console.log('STUDIOU WC: Initializing batch description form handlers');
  221. // Check all button handler
  222. $('#studiou-wcpcm-check-all').on('click', function(e) {
  223. e.preventDefault();
  224. console.log('STUDIOU WC: Check all button clicked');
  225. $('#categories_list input[type="checkbox"]').prop('checked', true);
  226. });
  227. // Uncheck all button handler
  228. $('#studiou-wcpcm-uncheck-all').on('click', function(e) {
  229. e.preventDefault();
  230. console.log('STUDIOU WC: Uncheck all button clicked');
  231. $('#categories_list input[type="checkbox"]').prop('checked', false);
  232. });
  233. // Form submit handler
  234. $('#studiou-wcpcm-batch-description-form').on('submit', function(e) {
  235. e.preventDefault();
  236. console.log('STUDIOU WC: Batch description form submitted');
  237. // Get selected categories
  238. var selectedCategories = [];
  239. $('#categories_list input[type="checkbox"]:checked').each(function() {
  240. selectedCategories.push($(this).val());
  241. });
  242. var description = $('#category_description').val();
  243. console.log('STUDIOU WC: Selected categories:', selectedCategories);
  244. console.log('STUDIOU WC: Description:', description);
  245. // Validate input
  246. if (selectedCategories.length === 0) {
  247. console.log('STUDIOU WC: No categories selected');
  248. showNotice('error', 'Please select at least one category');
  249. return;
  250. }
  251. // Show spinner
  252. var $submitBtn = $(this).find('#studiou-wcpcm-batch-description-button');
  253. var $spinner = $(this).find('.spinner');
  254. $submitBtn.prop('disabled', true);
  255. $spinner.css('visibility', 'visible');
  256. // Clear previous notices
  257. $('.studiou-wcpcm-notice-area').empty();
  258. // Debug: Log AJAX request details
  259. console.log('STUDIOU WC: Sending batch description AJAX request to:', studiouWcpcm.ajaxUrl);
  260. console.log('STUDIOU WC: Nonce:', studiouWcpcm.nonce);
  261. // Send AJAX request
  262. $.ajax({
  263. url: studiouWcpcm.ajaxUrl,
  264. type: 'POST',
  265. data: {
  266. action: 'studiou_wcpcm_batch_description',
  267. selected_categories: selectedCategories,
  268. description: description,
  269. nonce: studiouWcpcm.nonce
  270. },
  271. success: function(response) {
  272. console.log('STUDIOU WC: Batch description AJAX response:', response);
  273. if (response.success) {
  274. showNotice('success', studiouWcpcm.i18n.batchDescriptionSuccess || 'Batch description operation successful');
  275. // Show results
  276. $('#studiou-wcpcm-batch-description-message').html('<p>' + response.data.message + '</p>');
  277. $('.studiou-wcpcm-batch-description-results').show();
  278. } else {
  279. showNotice('error', response.data.message);
  280. }
  281. },
  282. error: function(xhr, status, error) {
  283. console.error('STUDIOU WC: Batch description AJAX error:', status, error);
  284. console.error('STUDIOU WC: Response text:', xhr.responseText);
  285. showNotice('error', (studiouWcpcm.i18n.batchDescriptionError || 'Batch description operation error') + ': ' + error);
  286. },
  287. complete: function() {
  288. // Hide spinner
  289. $submitBtn.prop('disabled', false);
  290. $spinner.css('visibility', 'hidden');
  291. }
  292. });
  293. });
  294. }
  295. /**
  296. * Initialize sample CSV download
  297. */
  298. function initSampleDownload() {
  299. $('#studiou-wcpcm-download-sample').on('click', function(e) {
  300. e.preventDefault();
  301. // Sample CSV content
  302. var csvContent = 'name,url-name,parent-name,description,display-type,visibility,protected-passwords,operation\n' +
  303. '"Clothing","clothing","","Top quality clothing","default","public","","A"\n' +
  304. '"Men","men","Clothing","Men\'s clothing","products","public","","A"\n' +
  305. '"Women","women","Clothing","Women\'s clothing","products","protected","password123","A"\n' +
  306. '"Kids","kids","Clothing","Kids clothing","products","public","","U"\n' +
  307. '"Accessories","accessories","","All accessories","default","public","","D"';
  308. // Create download link
  309. var blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
  310. var url = URL.createObjectURL(blob);
  311. var link = document.createElement('a');
  312. link.setAttribute('href', url);
  313. link.setAttribute('download', 'sample-product-categories.csv');
  314. link.style.visibility = 'hidden';
  315. document.body.appendChild(link);
  316. link.click();
  317. document.body.removeChild(link);
  318. });
  319. }
  320. /**
  321. * Initialize delete products form
  322. */
  323. function initDeleteProductsForm() {
  324. console.log('STUDIOU WC: Initializing delete products form handlers');
  325. console.log('STUDIOU WC: Form element:', $('#studiou-wcpcm-delete-products-form'));
  326. console.log('STUDIOU WC: Check all button:', $('#studiou-wcpcm-delete-check-all'));
  327. console.log('STUDIOU WC: Delete button:', $('#studiou-wcpcm-delete-products-button'));
  328. // Check all button handler
  329. $('#studiou-wcpcm-delete-check-all').on('click', function(e) {
  330. e.preventDefault();
  331. console.log('STUDIOU WC: Delete check all button clicked');
  332. $('#delete_categories_list input[type="checkbox"]').prop('checked', true);
  333. });
  334. // Uncheck all button handler
  335. $('#studiou-wcpcm-delete-uncheck-all').on('click', function(e) {
  336. e.preventDefault();
  337. console.log('STUDIOU WC: Delete uncheck all button clicked');
  338. $('#delete_categories_list input[type="checkbox"]').prop('checked', false);
  339. });
  340. // Form submit handler
  341. $('#studiou-wcpcm-delete-products-form').on('submit', function(e) {
  342. e.preventDefault();
  343. console.log('STUDIOU WC: Delete products form submitted');
  344. // Get selected categories
  345. var selectedCategories = [];
  346. $('#delete_categories_list input[type="checkbox"]:checked').each(function() {
  347. selectedCategories.push($(this).val());
  348. });
  349. console.log('STUDIOU WC: Selected categories:', selectedCategories);
  350. // Validate input
  351. if (selectedCategories.length === 0) {
  352. console.log('STUDIOU WC: No categories selected');
  353. showNotice('error', studiouWcpcm.i18n.selectAtLeastOneCategory || 'Please select at least one category');
  354. return;
  355. }
  356. // Confirm deletion
  357. if (!confirm(studiouWcpcm.i18n.confirmDelete || 'Are you sure you want to permanently delete ALL products in the selected categories? This action cannot be undone!')) {
  358. console.log('STUDIOU WC: User cancelled deletion');
  359. return;
  360. }
  361. // Show spinner
  362. var $submitBtn = $(this).find('#studiou-wcpcm-delete-products-button');
  363. var $spinner = $(this).find('.spinner');
  364. $submitBtn.prop('disabled', true);
  365. $spinner.css('visibility', 'visible');
  366. // Clear previous notices
  367. $('.studiou-wcpcm-notice-area').empty();
  368. // Hide results, show progress
  369. $('.studiou-wcpcm-delete-results').hide();
  370. $('.studiou-wcpcm-delete-progress').show();
  371. $('#studiou-wcpcm-delete-progress-text').text('Initializing...');
  372. updateProgressBar(0);
  373. // Debug: Log AJAX request details
  374. console.log('STUDIOU WC: Sending delete products AJAX request to:', studiouWcpcm.ajaxUrl);
  375. console.log('STUDIOU WC: Nonce:', studiouWcpcm.nonce);
  376. // Send AJAX request to get product IDs
  377. $.ajax({
  378. url: studiouWcpcm.ajaxUrl,
  379. type: 'POST',
  380. data: {
  381. action: 'studiou_wcpcm_delete_products',
  382. delete_categories: selectedCategories,
  383. nonce: studiouWcpcm.nonce
  384. },
  385. success: function(response) {
  386. console.log('STUDIOU WC: Delete products AJAX response:', response);
  387. if (response.success) {
  388. var productIds = response.data.product_ids;
  389. var totalCount = response.data.total_count;
  390. console.log('STUDIOU WC: Total products to delete:', totalCount);
  391. if (totalCount === 0) {
  392. showNotice('success', studiouWcpcm.i18n.noProductsFound || 'No products found in selected categories');
  393. $('.studiou-wcpcm-delete-progress').hide();
  394. $submitBtn.prop('disabled', false);
  395. $spinner.css('visibility', 'hidden');
  396. return;
  397. }
  398. // Process products in batches
  399. processDeletionBatches(productIds, totalCount, $submitBtn, $spinner);
  400. } else {
  401. showNotice('error', response.data.message);
  402. $('.studiou-wcpcm-delete-progress').hide();
  403. $submitBtn.prop('disabled', false);
  404. $spinner.css('visibility', 'hidden');
  405. }
  406. },
  407. error: function(xhr, status, error) {
  408. console.error('STUDIOU WC: Delete products AJAX error:', status, error);
  409. console.error('STUDIOU WC: Response text:', xhr.responseText);
  410. showNotice('error', (studiouWcpcm.i18n.deleteError || 'Delete products operation error') + ': ' + error);
  411. $('.studiou-wcpcm-delete-progress').hide();
  412. $submitBtn.prop('disabled', false);
  413. $spinner.css('visibility', 'hidden');
  414. }
  415. });
  416. });
  417. }
  418. /**
  419. * Process deletion in batches
  420. */
  421. function processDeletionBatches(productIds, totalCount, $submitBtn, $spinner) {
  422. var batchSize = 10; // Process 10 products at a time
  423. var batches = [];
  424. var totalDeleted = 0;
  425. var totalFailed = 0;
  426. var failedProducts = [];
  427. // Split products into batches
  428. for (var i = 0; i < productIds.length; i += batchSize) {
  429. batches.push(productIds.slice(i, i + batchSize));
  430. }
  431. console.log('STUDIOU WC: Processing ' + batches.length + ' batches of products');
  432. var currentBatch = 0;
  433. function processBatch() {
  434. if (currentBatch >= batches.length) {
  435. // All batches completed
  436. console.log('STUDIOU WC: All batches completed');
  437. onDeletionComplete(totalDeleted, totalFailed, failedProducts, $submitBtn, $spinner);
  438. return;
  439. }
  440. var batch = batches[currentBatch];
  441. var progress = Math.round((currentBatch / batches.length) * 100);
  442. $('#studiou-wcpcm-delete-progress-text').text(
  443. 'Deleting products... ' + (currentBatch * batchSize) + ' of ' + totalCount + ' processed'
  444. );
  445. updateProgressBar(progress);
  446. // Send batch delete request
  447. $.ajax({
  448. url: studiouWcpcm.ajaxUrl,
  449. type: 'POST',
  450. data: {
  451. action: 'studiou_wcpcm_delete_products_batch',
  452. product_ids: batch,
  453. nonce: studiouWcpcm.nonce
  454. },
  455. success: function(response) {
  456. if (response.success) {
  457. totalDeleted += response.data.deleted_count;
  458. totalFailed += response.data.failed_count;
  459. failedProducts = failedProducts.concat(response.data.failed_products);
  460. console.log('STUDIOU WC: Batch ' + currentBatch + ' completed - Deleted: ' +
  461. response.data.deleted_count + ', Failed: ' + response.data.failed_count);
  462. // Process next batch
  463. currentBatch++;
  464. processBatch();
  465. } else {
  466. showNotice('error', response.data.message);
  467. $('.studiou-wcpcm-delete-progress').hide();
  468. $submitBtn.prop('disabled', false);
  469. $spinner.css('visibility', 'hidden');
  470. }
  471. },
  472. error: function(xhr, status, error) {
  473. console.error('STUDIOU WC: Batch delete AJAX error:', status, error);
  474. showNotice('error', 'Error deleting batch: ' + error);
  475. $('.studiou-wcpcm-delete-progress').hide();
  476. $submitBtn.prop('disabled', false);
  477. $spinner.css('visibility', 'hidden');
  478. }
  479. });
  480. }
  481. // Start processing batches
  482. processBatch();
  483. }
  484. /**
  485. * Handle deletion completion
  486. */
  487. function onDeletionComplete(totalDeleted, totalFailed, failedProducts, $submitBtn, $spinner) {
  488. // Update progress bar to 100%
  489. updateProgressBar(100);
  490. $('#studiou-wcpcm-delete-progress-text').text('Deletion complete!');
  491. // Show results
  492. var message = '<p><strong>Deletion Summary:</strong></p>';
  493. message += '<ul>';
  494. message += '<li>Total products deleted: ' + totalDeleted + '</li>';
  495. if (totalFailed > 0) {
  496. message += '<li>Failed to delete: ' + totalFailed + '</li>';
  497. if (failedProducts.length > 0) {
  498. message += '<li>Failed product IDs: ' + failedProducts.join(', ') + '</li>';
  499. }
  500. }
  501. message += '</ul>';
  502. $('#studiou-wcpcm-delete-message').html(message);
  503. $('.studiou-wcpcm-delete-results').show();
  504. // Hide progress after a delay
  505. setTimeout(function() {
  506. $('.studiou-wcpcm-delete-progress').fadeOut();
  507. }, 2000);
  508. if (totalDeleted > 0) {
  509. showNotice('success', (studiouWcpcm.i18n.deleteSuccess || 'Successfully deleted') + ' ' + totalDeleted + ' products');
  510. // Reload page after 3 seconds
  511. setTimeout(function() {
  512. location.reload();
  513. }, 3000);
  514. } else {
  515. showNotice('error', studiouWcpcm.i18n.deleteError || 'Failed to delete any products');
  516. }
  517. $submitBtn.prop('disabled', false);
  518. $spinner.css('visibility', 'hidden');
  519. }
  520. /**
  521. * Update progress bar
  522. */
  523. function updateProgressBar(percentage) {
  524. $('#studiou-wcpcm-delete-progress-bar').css('width', percentage + '%');
  525. $('#studiou-wcpcm-delete-progress-bar').attr('data-progress', percentage + '%');
  526. }
  527. /**
  528. * Show notice message
  529. *
  530. * @param {string} type Notice type (success, error)
  531. * @param {string} message Notice message
  532. */
  533. function showNotice(type, message) {
  534. var $notice = $('<div class="studiou-wcpcm-notice studiou-wcpcm-notice-' + type + '"></div>').text(message);
  535. $('.studiou-wcpcm-notice-area').append($notice);
  536. // Scroll to notice
  537. $('html, body').animate({
  538. scrollTop: $('.studiou-wcpcm-notice-area').offset().top - 50
  539. }, 500);
  540. }
  541. /**
  542. * Initialize product import form
  543. */
  544. function initProductImportForm() {
  545. console.log('STUDIOU WC: Initializing product import form handlers');
  546. // Global variables for batch processing
  547. var importTransientKey = null;
  548. var importTotal = 0;
  549. var importProcessed = 0;
  550. var importSuccess = 0;
  551. var importFailed = 0;
  552. var importSkipped = 0;
  553. var importMessages = [];
  554. var importFailedCsv = '';
  555. $('#studiou-wcpcm-product-import-form').on('submit', function(e) {
  556. e.preventDefault();
  557. console.log('STUDIOU WC: Product import form submitted');
  558. // Validate file is selected
  559. var fileInput = $('#import_file')[0];
  560. if (!fileInput.files || !fileInput.files[0]) {
  561. showNotice('error', 'Please select a CSV file to import');
  562. return;
  563. }
  564. // Show spinner and progress
  565. var $submitBtn = $(this).find('#studiou-wcpcm-product-import-button');
  566. var $spinner = $(this).find('.spinner');
  567. $submitBtn.prop('disabled', true);
  568. $spinner.css('visibility', 'visible');
  569. // Clear previous results
  570. $('.studiou-wcpcm-notice-area').empty();
  571. $('.studiou-wcpcm-product-import-results').hide();
  572. $('.studiou-wcpcm-product-import-failed').hide();
  573. // Reset counters
  574. importTransientKey = null;
  575. importTotal = 0;
  576. importProcessed = 0;
  577. importSuccess = 0;
  578. importFailed = 0;
  579. importSkipped = 0;
  580. importMessages = [];
  581. importFailedCsv = '';
  582. // Show progress bar
  583. $('.studiou-wcpcm-product-import-progress').show();
  584. $('#studiou-wcpcm-product-import-progress-text').text('Parsing CSV file...');
  585. updateProductImportProgressBar(0);
  586. // Step 1: Parse CSV file
  587. var formData = new FormData(this);
  588. formData.append('action', 'studiou_wcpcm_product_import_parse');
  589. formData.append('nonce', studiouWcpcm.nonce);
  590. $.ajax({
  591. url: studiouWcpcm.ajaxUrl,
  592. type: 'POST',
  593. data: formData,
  594. processData: false,
  595. contentType: false,
  596. success: function(response) {
  597. console.log('STUDIOU WC: Product import parse response:', response);
  598. if (response.success) {
  599. importTransientKey = response.data.transient_key;
  600. importTotal = response.data.total;
  601. // Start batch processing
  602. processBatch(0, $submitBtn, $spinner);
  603. } else {
  604. showNotice('error', response.data.message || 'Parse failed');
  605. $('.studiou-wcpcm-product-import-progress').hide();
  606. $submitBtn.prop('disabled', false);
  607. $spinner.css('visibility', 'hidden');
  608. }
  609. },
  610. error: function(xhr, status, error) {
  611. console.error('STUDIOU WC: Product import parse error:', status, error);
  612. console.error('STUDIOU WC: Response text:', xhr.responseText);
  613. showNotice('error', 'Product import error: ' + error);
  614. $('.studiou-wcpcm-product-import-progress').hide();
  615. $submitBtn.prop('disabled', false);
  616. $spinner.css('visibility', 'hidden');
  617. }
  618. });
  619. });
  620. // Process batch of products
  621. function processBatch(offset, $submitBtn, $spinner) {
  622. console.log('STUDIOU WC: Processing batch at offset', offset);
  623. $.ajax({
  624. url: studiouWcpcm.ajaxUrl,
  625. type: 'POST',
  626. data: {
  627. action: 'studiou_wcpcm_product_import_batch',
  628. nonce: studiouWcpcm.nonce,
  629. transient_key: importTransientKey,
  630. offset: offset
  631. },
  632. success: function(response) {
  633. console.log('STUDIOU WC: Batch response:', response);
  634. if (response.success) {
  635. // Accumulate results
  636. importSuccess += response.data.success;
  637. importFailed += response.data.failed;
  638. importSkipped += response.data.skipped;
  639. importProcessed = response.data.processed;
  640. importTotal = response.data.total;
  641. importMessages = importMessages.concat(response.data.messages);
  642. if (response.data.failed_csv) {
  643. importFailedCsv = response.data.failed_csv;
  644. }
  645. // Update progress
  646. var percent = (importProcessed / importTotal) * 100;
  647. updateProductImportProgressBar(percent);
  648. $('#studiou-wcpcm-product-import-progress-text').text(
  649. 'Processing: ' + importProcessed + ' / ' + importTotal + ' products'
  650. );
  651. // Check if complete
  652. if (importProcessed >= importTotal) {
  653. // Import complete
  654. $('#studiou-wcpcm-product-import-progress-text').text('Complete!');
  655. showNotice('success', 'Product import completed!');
  656. // Show results
  657. var message = '<p><strong>Import Summary:</strong></p>';
  658. message += '<ul>';
  659. message += '<li>Successful: ' + importSuccess + '</li>';
  660. message += '<li>Failed: ' + importFailed + '</li>';
  661. message += '<li>Skipped: ' + importSkipped + '</li>';
  662. message += '</ul>';
  663. $('#studiou-wcpcm-product-import-message').html(message);
  664. // Show detailed messages
  665. if (importMessages.length > 0) {
  666. var details = '<pre>' + importMessages.join('\n') + '</pre>';
  667. $('#studiou-wcpcm-product-import-details-content').html(details);
  668. }
  669. $('.studiou-wcpcm-product-import-results').show();
  670. // Show save failed button if there are failed items
  671. if (importFailed > 0 && importFailedCsv) {
  672. window.studiouWcpcmFailedCsv = importFailedCsv;
  673. $('.studiou-wcpcm-product-import-failed').show();
  674. }
  675. // Hide progress after delay
  676. setTimeout(function() {
  677. $('.studiou-wcpcm-product-import-progress').fadeOut();
  678. }, 2000);
  679. $submitBtn.prop('disabled', false);
  680. $spinner.css('visibility', 'hidden');
  681. } else {
  682. // Process next batch
  683. processBatch(importProcessed, $submitBtn, $spinner);
  684. }
  685. } else {
  686. showNotice('error', response.data.message || 'Batch processing failed');
  687. $('.studiou-wcpcm-product-import-progress').hide();
  688. $submitBtn.prop('disabled', false);
  689. $spinner.css('visibility', 'hidden');
  690. }
  691. },
  692. error: function(xhr, status, error) {
  693. console.error('STUDIOU WC: Batch processing error:', status, error);
  694. showNotice('error', 'Batch processing error: ' + error);
  695. $('.studiou-wcpcm-product-import-progress').hide();
  696. $submitBtn.prop('disabled', false);
  697. $spinner.css('visibility', 'hidden');
  698. }
  699. });
  700. }
  701. // Save failed products button handler
  702. $('#studiou-wcpcm-save-failed-products').on('click', function(e) {
  703. e.preventDefault();
  704. if (window.studiouWcpcmFailedCsv) {
  705. var blob = new Blob([window.studiouWcpcmFailedCsv], { type: 'text/csv;charset=utf-8;' });
  706. var url = URL.createObjectURL(blob);
  707. var link = document.createElement('a');
  708. link.setAttribute('href', url);
  709. link.setAttribute('download', 'failed-products-' + Date.now() + '.csv');
  710. link.style.visibility = 'hidden';
  711. document.body.appendChild(link);
  712. link.click();
  713. document.body.removeChild(link);
  714. }
  715. });
  716. }
  717. /**
  718. * Initialize product export form
  719. */
  720. function initProductExportForm() {
  721. console.log('STUDIOU WC: Initializing product export form handlers');
  722. // Select all button handler
  723. $('#studiou-wcpcm-export-select-all').on('click', function(e) {
  724. e.preventDefault();
  725. console.log('STUDIOU WC: Export select all button clicked');
  726. $('#export_categories_list input[type="checkbox"]').prop('checked', true);
  727. });
  728. // Deselect all button handler
  729. $('#studiou-wcpcm-export-deselect-all').on('click', function(e) {
  730. e.preventDefault();
  731. console.log('STUDIOU WC: Export deselect all button clicked');
  732. $('#export_categories_list input[type="checkbox"]').prop('checked', false);
  733. });
  734. // Form submit handler
  735. $('#studiou-wcpcm-product-export-form').on('submit', function(e) {
  736. e.preventDefault();
  737. console.log('STUDIOU WC: Product export form submitted');
  738. // Get selected categories
  739. var selectedCategories = [];
  740. $('#export_categories_list input[type="checkbox"]:checked').each(function() {
  741. selectedCategories.push($(this).val());
  742. });
  743. console.log('STUDIOU WC: Selected categories:', selectedCategories);
  744. // Validate input
  745. if (selectedCategories.length === 0) {
  746. console.log('STUDIOU WC: No categories selected');
  747. showNotice('error', 'Please select at least one category');
  748. return;
  749. }
  750. // Show spinner
  751. var $submitBtn = $(this).find('#studiou-wcpcm-product-export-button');
  752. var $spinner = $(this).find('.spinner');
  753. $submitBtn.prop('disabled', true);
  754. $spinner.css('visibility', 'visible');
  755. // Clear previous notices
  756. $('.studiou-wcpcm-notice-area').empty();
  757. $('.studiou-wcpcm-product-export-results').hide();
  758. // Debug: Log AJAX request details
  759. console.log('STUDIOU WC: Sending product export AJAX request to:', studiouWcpcm.ajaxUrl);
  760. console.log('STUDIOU WC: Nonce:', studiouWcpcm.nonce);
  761. // Send AJAX request
  762. $.ajax({
  763. url: studiouWcpcm.ajaxUrl,
  764. type: 'POST',
  765. data: {
  766. action: 'studiou_wcpcm_product_export',
  767. export_categories: selectedCategories,
  768. nonce: studiouWcpcm.nonce
  769. },
  770. success: function(response) {
  771. console.log('STUDIOU WC: Product export AJAX response:', response);
  772. if (response.success) {
  773. showNotice('success', 'Export successful!');
  774. // Show results
  775. $('#studiou-wcpcm-product-export-message').html('<p>' + response.data.message + '</p>');
  776. $('#studiou-wcpcm-download-product-export').attr('href', response.data.download_url);
  777. $('.studiou-wcpcm-product-export-results').show();
  778. } else {
  779. showNotice('error', response.data.message || 'Export failed');
  780. }
  781. },
  782. error: function(xhr, status, error) {
  783. console.error('STUDIOU WC: Product export AJAX error:', status, error);
  784. console.error('STUDIOU WC: Response text:', xhr.responseText);
  785. showNotice('error', 'Product export error: ' + error);
  786. },
  787. complete: function() {
  788. // Hide spinner
  789. $submitBtn.prop('disabled', false);
  790. $spinner.css('visibility', 'hidden');
  791. }
  792. });
  793. });
  794. }
  795. /**
  796. * Update product import progress bar
  797. */
  798. function updateProductImportProgressBar(percentage) {
  799. $('#studiou-wcpcm-product-import-progress-bar').css('width', percentage + '%');
  800. $('#studiou-wcpcm-product-import-progress-bar').attr('data-progress', Math.round(percentage) + '%');
  801. }
  802. // Additional debug: Check if elements exist after DOM load
  803. $(window).on('load', function() {
  804. console.log('STUDIOU WC: Window loaded');
  805. console.log('STUDIOU WC: Move form exists:', $('#studiou-wcpcm-move-form').length > 0);
  806. console.log('STUDIOU WC: Move button exists:', $('#studiou-wcpcm-move-button').length > 0);
  807. console.log('STUDIOU WC: Source select exists:', $('#source_category').length > 0);
  808. console.log('STUDIOU WC: Target select exists:', $('#target_category').length > 0);
  809. console.log('STUDIOU WC: Batch description form exists:', $('#studiou-wcpcm-batch-description-form').length > 0);
  810. console.log('STUDIOU WC: Batch description button exists:', $('#studiou-wcpcm-batch-description-button').length > 0);
  811. console.log('STUDIOU WC: Delete products form exists:', $('#studiou-wcpcm-delete-products-form').length > 0);
  812. console.log('STUDIOU WC: Product import form exists:', $('#studiou-wcpcm-product-import-form').length > 0);
  813. console.log('STUDIOU WC: Product export form exists:', $('#studiou-wcpcm-product-export-form').length > 0);
  814. });
  815. })(jQuery);