public function jobs_load_tasks()
 {
     // quit if no job name provided
     if (!isset($_REQUEST['job'])) {
         return false;
     }
     $jobname = $_REQUEST['job'];
     // check if an array of listing IDs was provided
     $lm = new WPLA_ListingsModel();
     $listing_ids = isset($_REQUEST['item_ids']) && is_array($_REQUEST['item_ids']) ? $_REQUEST['item_ids'] : false;
     if ($listing_ids) {
         $items = $lm->getItemsByIdArray($listing_ids);
     }
     // register shutdown handler
     global $wpla_shutdown_handler_enabled;
     $wpla_shutdown_handler_enabled = true;
     register_shutdown_function(array($this, 'shutdown_handler'));
     // handle job name
     switch ($jobname) {
         case 'updateProductsWithoutASIN':
             // get prepared items
             $sm = new WPLA_ListingsModel();
             $items = $sm->getAllOnlineWithoutASIN();
             // create job from items and send response
             $response = $this->_create_bulk_listing_job('updateProduct', $items, $jobname);
             $this->returnJSON($response);
             exit;
         case 'createAllImportedProducts':
             // get prepared items
             $sm = new WPLA_ListingsModel();
             $items = $sm->getAllImported();
             // DEV: limit to 10 tasks at a time ***
             // $items = array_slice($items, 0, 10, true);
             // create job from items and send response
             $response = $this->_create_bulk_listing_job('createProduct', $items, $jobname);
             $this->returnJSON($response);
             exit;
         case 'processAmazonReport':
             // get report
             $id = $_REQUEST['item_id'];
             $report = new WPLA_AmazonReport($id);
             $rows = $report->get_data_rows();
             $rows_count = sizeof($rows);
             $page_size = 500;
             $number_of_pages = intval($rows_count / $page_size) + 1;
             $items = array();
             if ($number_of_pages > 0) {
                 for ($page = 0; $page < $number_of_pages; $page++) {
                     $from_row = $page * $page_size + 1;
                     $to_row = ($page + 1) * $page_size;
                     if ($to_row > $rows_count) {
                         $to_row = $rows_count;
                     }
                     $items[] = array('id' => $id, 'page' => $page, 'from_row' => $from_row, 'to_row' => $to_row, 'title' => 'Processing rows ' . $from_row . ' to ' . $to_row);
                 }
             }
             // create job from items and send response
             $response = $this->_create_bulk_listing_job('processReportPage', $items, $jobname);
             $this->returnJSON($response);
             exit;
         case 'processRowsFromAmazonReport':
             $id = $_REQUEST['report_id'];
             $skus = $_REQUEST['sku_list'];
             foreach ($skus as $sku) {
                 $items[] = array('id' => $id, 'sku' => $sku, 'title' => 'Processing SKU ' . $sku);
             }
             // create job from items and send response
             $response = $this->_create_bulk_listing_job('processSingleSkuFromReport', $items, $jobname);
             $this->returnJSON($response);
             exit;
         case 'fetchProductDescription':
             // create job from items and send response
             $response = $this->_create_bulk_listing_job('fetchFullProductDescription', $items, $jobname);
             $this->returnJSON($response);
             exit;
         default:
             // echo "unknown job";
             // break;
     }
     // exit();
 }
 public function action_update_missing_asins()
 {
     WPLA()->logger->info("do_action: wpla_update_missing_asins");
     $accounts = WPLA_AmazonAccount::getAll();
     $listingsModel = new WPLA_ListingsModel();
     $batch_size = 10;
     // update 10 items at a time
     foreach ($accounts as $account) {
         $account_id = $account->id;
         $listings = $listingsModel->getAllOnlineWithoutASIN($account_id, 10, OBJECT_K);
         if (empty($listings)) {
             continue;
         }
         // process one listing at a time (for now)
         foreach ($listings as $listing) {
             WPLA()->logger->info('fetching ASIN for SKU ' . $listing->sku . ' (' . $listing->id . ') - type: ' . $listing->product_type);
             $api = new WPLA_AmazonAPI($account->id);
             $result = $api->getMatchingProductForId($listing->sku, 'SellerSKU');
             if ($result->success) {
                 if (!empty($result->product->ASIN)) {
                     // update listing ASIN
                     $listingsModel->updateWhere(array('id' => $listing->id), array('asin' => $result->product->ASIN));
                     WPLA()->logger->info('new ASIN for listing #' . $listing->id . ': ' . $result->product->ASIN);
                 } else {
                     // this is what happens when new products are listed but Amazon fails to assign an ASIN
                     // in which case the user might have to contact Amazon seller support...
                     $error_msg = sprintf(__('There was a problem fetching product details for %s.', 'wpla'), $listing->sku);
                     WPLA()->logger->error($error_msg . ' - empty product data!');
                     $error_msg .= ' This SKU does not seem to exist in your inventory on Seller Central. You can try to submit this listing again, but you may have to report this to Amazon Seller Support.';
                     // // build history array (overwrite)
                     // $history = array (
                     //   	'errors' => array (
                     // 	    array (
                     // 			'original-record-number' => '0',
                     // 			'sku'                    => $listing->sku,
                     // 			'error-code'             => '42',
                     // 			'error-type'             => 'Error',
                     // 			'error-message'          => $error_msg,
                     // 	    ),
                     // 	),
                     //   	'warnings' => array(),
                     // );
                     // load existing history data - or init new history array
                     $history = maybe_unserialize($listing->history);
                     if (!is_array($history) || !isset($history['errors'])) {
                         $history = array('errors' => array(), 'warnings' => array());
                     }
                     // add custom error to history array
                     $error_42 = array('original-record-number' => '0', 'sku' => $listing->sku, 'error-code' => '42', 'error-type' => 'Error', 'error-message' => $error_msg);
                     $history['errors'][] = $error_42;
                     // mark as failed - and include error message
                     $listingsModel->updateWhere(array('id' => $listing->id), array('status' => 'failed', 'history' => serialize($history)));
                 }
             } elseif ($result->Error->Message) {
                 $errors = sprintf(__('There was a problem fetching product details for %s.', 'wpla'), $listing->sku) . '<br>Error: ' . $result->Error->Message;
                 WPLA()->logger->error($errors);
             } else {
                 $errors = sprintf(__('There was a problem fetching product details for %s.', 'wpla'), $listing->sku);
                 WPLA()->logger->error($errors);
             }
         }
         // foreach listing
     }
     // each account
 }
 public function showNotifications()
 {
     self::checkForDeletedProducts();
     // get listing status summary
     $listingsModel = new WPLA_ListingsModel();
     $summary = WPLA_ListingsModel::getStatusSummary();
     $no_asin = $listingsModel->getAllOnlineWithoutASIN();
     // check for changed, matched and prepared items - and show message
     $is_feed_page = isset($_GET['page']) && $_GET['page'] == 'wpla-feeds';
     if (isset($summary->changed) || isset($summary->prepared) || isset($summary->matched)) {
         $next_schedule = $this->print_schedule_info('wpla_update_schedule');
         // build nice combined message
         $summary_msg = '';
         $summary_array = array();
         foreach (array('changed', 'prepared', 'matched') as $status) {
             if (!isset($summary->{$status})) {
                 continue;
             }
             $link_url = 'admin.php?page=wpla&listing_status=' . $status;
             $link_title = $summary->{$status} . ' ' . $status;
             $summary_array[] = '<a href="' . $link_url . '">' . $link_title . '</a>';
         }
         $summary_msg = join(' and ', $summary_array);
         $msg = '<p>';
         $msg .= sprintf(__('%s product(s) will be submitted to Amazon %s.', 'wpla'), $summary_msg, $next_schedule);
         $msg .= '&nbsp;&nbsp;';
         if ($is_feed_page) {
             $msg .= '<a href="admin.php?page=wpla-feeds&action=submit_pending_feeds_to_amazon" id="" class="button button-small wpl_job_button">' . __('Submit pending feeds', 'wpla') . '</a>';
         } else {
             $msg .= '<a href="admin.php?page=wpla-feeds" id="" class="button button-small wpl_job_button">' . __('Visit feeds', 'wpla') . '</a>';
         }
         $msg .= '</p>';
         $this->showMessage($msg);
     }
     // check for prepared items and display info
     if (isset($summary->prepared)) {
         // $next_schedule = $this->print_schedule_info( 'wpla_update_schedule' );
         // $msg  = '<p>';
         // $msg .= sprintf( __('%d %s product(s) will be submitted to Amazon %s.','wpla'), $summary->prepared, 'prepared', $next_schedule );
         // $msg .= '&nbsp;&nbsp;';
         // $msg .= '<a href="admin.php?page=wpla&listing_status=prepared" id="" class="button button-small wpl_job_button">' . __('Show products','wpla') . '</a>';
         // $msg .= '&nbsp;&nbsp;';
         // $msg .= '<a href="admin.php?page=wpla-feeds" id="" class="button button-small wpl_job_button">' . __('Visit feeds','wpla') . '</a>';
         // $msg .= '</p>';
         // $this->showMessage( $msg );
         // check prepared products for problems
         $problems = WPLA_FeedValidator::checkPreparedProducts();
         if ($problems) {
             $this->showMessage($problems, 1);
         }
     }
     // check changed products for problems
     if (isset($summary->changed)) {
         $problems = WPLA_FeedValidator::checkChangedProducts();
         if ($problems) {
             $this->showMessage($problems, 1);
         }
     }
     // check for new online items without ASIN
     if (sizeof($no_asin)) {
         $msg = '<p>';
         $msg .= sprintf(__('There are %s newly added product(s) which need to be updated from Amazon.', 'wpla'), sizeof($no_asin));
         $msg .= '&nbsp;&nbsp;';
         $msg .= '<a id="btn_batch_update_no_asin" class="btn_batch_update_no_asin button button-primary button-small wpl_job_button">' . __('Update products', 'wpla') . '</a>';
         $msg .= '&nbsp;&nbsp;';
         $msg .= '<a href="admin.php?page=wpla&listing_status=no_asin" id="" class="button button-small wpl_job_button">' . __('Show products', 'wpla') . '</a>';
         $msg .= '<br><!br>';
         $msg .= '<small>This step is required to fetch the ASIN and other details that were assigned by Amazon when the product was created.</small>';
         $msg .= '</p>';
         $this->showMessage($msg);
     }
     // check for imported items and display reminder
     $dismiss_imported_products_notice = self::getOption('dismiss_imported_products_notice');
     $is_imported_page = isset($_GET['listing_status']) && $_GET['listing_status'] == 'imported';
     if ($is_imported_page) {
         $dismiss_imported_products_notice = false;
     }
     if (isset($summary->imported) && !$dismiss_imported_products_notice) {
         $msg = '<p>';
         $msg .= sprintf(__('There are %s imported item(s) which can be created in WooCommerce.', 'wpla'), $summary->imported);
         $msg .= '&nbsp;&nbsp;';
         $msg .= '<a id="btn_batch_create_products_reminder" class="button button-primary button-small wpl_job_button">' . __('Create products', 'wpla') . '</a>';
         if (!$is_imported_page) {
             $msg .= '&nbsp;&nbsp;';
             $msg .= '<a href="admin.php?page=wpla&action=wpla_dismiss_imported_products_notice" class="button button-small wpl_job_button">' . __('Dismiss', 'wpla') . '</a>';
         }
         $msg .= '<br>';
         $msg .= '<small>';
         $msg .= __('If a product with a matching SKU exists in WooCommerce it will be linked to the product on Amazon.', 'wpla');
         $msg .= '</small>';
         $msg .= '</p>';
         $this->showMessage($msg);
     }
 }