public function handleActions()
 {
     // trigger orders update
     if ($this->requestAction() == 'update_orders') {
         do_action('wpla_update_orders');
     }
     // load order items
     if ($this->requestAction() == 'load_order_items') {
         $lm = new WPLA_OrdersModel();
         $order = $lm->getItem($_REQUEST['amazon_order']);
         if (!$order) {
             return;
         }
         $account = WPLA_AmazonAccount::getAccount($order['account_id']);
         if (!$account) {
             return;
         }
         $api = new WPLA_AmazonAPI($account->id);
         // get report requests
         $items = $api->getOrderLineItems($order['order_id']);
         // echo "<pre>";print_r($items);echo"</pre>";die();
         if (is_array($items)) {
             // run the import
             $this->importOrderItems($items, $order['order_id']);
             $this->showMessage(sprintf(__('%s item(s) were processed for account %s.', 'wpla'), sizeof($items), $account->title));
         } elseif ($items->Error->Message) {
             $this->showMessage(sprintf(__('There was a problem downloading items for account %s.', 'wpla'), $account->title) . '<br>Error: ' . $items->Error->Message, 1);
         } else {
             $this->showMessage(sprintf(__('There was a problem downloading items for account %s.', 'wpla'), $account->title), 1);
         }
     }
     // handle update from Amazon action
     if ($this->requestAction() == 'update') {
         $this->updateOrdersfromAmazon($_REQUEST['amazon_order']);
         // $this->showMessage( __('Not implemented yet.','wpla') );
     }
     // handle delete action
     if ($this->requestAction() == 'delete') {
         $this->deleteOrders($_REQUEST['amazon_order']);
         $this->showMessage(__('Selected items were removed.', 'wpla'));
     }
 }
        ?>
</td> -->
									<td>
										<?php 
        echo $report->CompletedDate;
        ?>
<br>
										<span style="color:silver">
											<?php 
        echo human_time_diff(strtotime($report->CompletedDate), time());
        ?>
 ago
										</span>
									</td>
									<td><?php 
        echo WPLA_AmazonAccount::getAccountTitle($report->account_id);
        ?>
</td>
									<td>
										<a href="admin.php?page=wpla-reports&action=view_amazon_report_details&amazon_report=<?php 
        echo $report->id;
        ?>
" target="_blank">
											<?php 
        echo intval($report->line_count) - 1;
        ?>
 rows
										</a>
									</td>
									<td>
										<a href="admin.php?page=wpla-import&mode=inventory&report_id=<?php 
 public function process_product_meta_variable($post_id)
 {
     WPLA()->logger->info('process_product_meta_variable() - ' . $post_id);
     if (!isset($_POST['variable_sku'])) {
         return;
     }
     $variable_post_id = $_POST['variable_post_id'];
     $variable_amazon_product_id = $_POST['variable_amazon_product_id'];
     $variable_amazon_id_type = $_POST['variable_amazon_id_type'];
     $variable_amazon_asin = $_POST['variable_amazon_asin'];
     $variable_sku = $_POST['variable_sku'];
     $variable_amazon_price = isset($_POST['variable_amazon_price']) ? $_POST['variable_amazon_price'] : '';
     $variable_amazon_minimum_price = isset($_POST['variable_amazon_minimum_price']) ? $_POST['variable_amazon_minimum_price'] : '';
     $variable_amazon_maximum_price = isset($_POST['variable_amazon_maximum_price']) ? $_POST['variable_amazon_maximum_price'] : '';
     $variable_amazon_condition_type = isset($_POST['variable_amazon_condition_type']) ? $_POST['variable_amazon_condition_type'] : '';
     $variable_amazon_condition_note = isset($_POST['variable_amazon_condition_note']) ? $_POST['variable_amazon_condition_note'] : '';
     $variable_amazon_is_disabled = isset($_POST['variable_amazon_is_disabled']) ? $_POST['variable_amazon_is_disabled'] : '';
     // convert decimal comma for all price fields
     $variable_amazon_price = str_replace(',', '.', $variable_amazon_price);
     $variable_amazon_minimum_price = str_replace(',', '.', $variable_amazon_minimum_price);
     $variable_amazon_maximum_price = str_replace(',', '.', $variable_amazon_maximum_price);
     $lm = new WPLA_ListingsModel();
     $all_variations_with_SKU = array();
     $all_variations_with_ASIN = array();
     $max_loop = max(array_keys($_POST['variable_post_id']));
     for ($i = 0; $i <= $max_loop; $i++) {
         if (!isset($variable_post_id[$i])) {
             continue;
         }
         $variation_id = (int) $variable_post_id[$i];
         // Update post meta
         update_post_meta($variation_id, '_amazon_product_id', trim($variable_amazon_product_id[$i]));
         update_post_meta($variation_id, '_amazon_id_type', $variable_amazon_id_type[$i]);
         update_post_meta($variation_id, '_wpla_asin', trim($variable_amazon_asin[$i]));
         update_post_meta($variation_id, '_amazon_price', isset($variable_amazon_price[$i]) ? trim($variable_amazon_price[$i]) : '');
         update_post_meta($variation_id, '_amazon_minimum_price', isset($variable_amazon_minimum_price[$i]) ? trim($variable_amazon_minimum_price[$i]) : '');
         update_post_meta($variation_id, '_amazon_maximum_price', isset($variable_amazon_maximum_price[$i]) ? trim($variable_amazon_maximum_price[$i]) : '');
         update_post_meta($variation_id, '_amazon_condition_type', isset($variable_amazon_condition_type[$i]) ? trim($variable_amazon_condition_type[$i]) : '');
         update_post_meta($variation_id, '_amazon_condition_note', isset($variable_amazon_condition_note[$i]) ? trim($variable_amazon_condition_note[$i]) : '');
         update_post_meta($variation_id, '_amazon_is_disabled', isset($variable_amazon_is_disabled[$i]) ? $variable_amazon_is_disabled[$i] : '');
         // if ( $variable_amazon_product_id[$i] !== 'parent' )
         //     update_post_meta( $variation_id, '_amazon_product_id', $variable_amazon_product_id[$i] );
         // else
         //     delete_post_meta( $variation_id, '_amazon_product_id' );
         // update min/max prices in listings table
         if (isset($_POST['variable_amazon_minimum_price'])) {
             $min_price = isset($variable_amazon_minimum_price[$i]) ? $variable_amazon_minimum_price[$i] : '';
             $max_price = isset($variable_amazon_maximum_price[$i]) ? $variable_amazon_maximum_price[$i] : '';
             $data = array();
             if ($min_price || $max_price) {
                 if ($listing = $lm->getItemByPostID($variation_id)) {
                     if ($min_price != $listing->min_price) {
                         $data['min_price'] = $min_price;
                         $data['pnq_status'] = 1;
                         // mark as changed
                     }
                     if ($max_price != $listing->max_price) {
                         $data['max_price'] = $max_price;
                         $data['pnq_status'] = 1;
                         // mark as changed
                     }
                     // update listing
                     if (!empty($data)) {
                         $lm->updateWhere(array('id' => $listing->id), $data);
                     }
                 }
             }
         }
         // collect (matched) variations with ASIN
         if ($variable_amazon_asin[$i]) {
             $all_variations_with_ASIN[$variation_id] = $variable_amazon_asin[$i];
         }
         // collect all variations with SKU
         if ($variable_sku[$i]) {
             $all_variations_with_SKU[$variation_id] = $variable_sku[$i];
         }
     }
     // each variation
     WPLA()->logger->info('Variations with ASIN: ' . print_r($all_variations_with_ASIN, 1));
     WPLA()->logger->info('Variations with SKU : ' . print_r($all_variations_with_SKU, 1));
     // process matched variations
     // check all variations with ASIN and add missing ones to listings table
     if (!empty($all_variations_with_ASIN)) {
         $lm = new WPLA_ListingsModel();
         $default_account_id = get_option('wpla_default_account_id', 1);
         if (!$default_account_id) {
             return;
         }
         // ***
         foreach ($all_variations_with_ASIN as $variation_id => $asin) {
             // check if this ASIN / ID already exist - skip if it does
             WPLA()->logger->info("searching for existing listing for #{$variation_id} / {$asin}");
             if ($lm->getItemByASIN($asin, false)) {
                 continue;
             }
             if ($lm->getItemByPostID($variation_id)) {
                 continue;
             }
             WPLA()->logger->info("no listing found for variation #{$variation_id} / {$asin}");
             // skip hidden variations
             if (get_post_meta($variation_id, '_amazon_is_disabled', true) == 'on') {
                 continue;
             }
             // insert matched listing
             $success = $lm->insertMatchedProduct($variation_id, $asin, $default_account_id);
             $error_msg = isset($lm->lastError) ? $lm->lastError : '';
             if ($success) {
                 // TODO: use persistent admin message
                 WPLA()->logger->info("Matched variation #{$variation_id} / {$asin} - {$error_msg}");
             } else {
                 echo "Failed to match variation #{$variation_id} - please report this to support: {$error_msg}";
                 WPLA()->logger->error("Failed to match variation #{$variation_id} / {$asin} - {$error_msg}");
             }
         }
         // each matched variation
     }
     // if $all_variations_with_ASIN
     // add missing variations
     // if the parent product has a listing item, then check for and add missing variation listings
     $lm = new WPLA_ListingsModel();
     $parent_listing = $lm->getItemByPostID($post_id);
     if ($parent_listing) {
         // get account from parent listing
         $account = WPLA_AmazonAccount::getAccount($parent_listing->account_id);
         if (!$account) {
             return;
         }
         foreach ($all_variations_with_SKU as $variation_id => $sku) {
             // check if this SKU / ID already exist - skip if it does
             if ($lm->getItemBySKU($sku, false)) {
                 continue;
             }
             if ($lm->getItemByPostID($variation_id)) {
                 continue;
             }
             WPLA()->logger->info("no listing found for missing variation #{$variation_id} / {$sku}");
             // check if this variation has a UPC/EAN set - skip if empty (unless brand registry is enabled)
             $_amazon_product_id = get_post_meta($variation_id, '_amazon_product_id', true);
             if (!$_amazon_product_id && !$account->is_reg_brand) {
                 continue;
             }
             // skip hidden variations
             if (get_post_meta($variation_id, '_amazon_is_disabled', true) == 'on') {
                 continue;
             }
             // insert variation listing
             $success = $lm->insertMissingVariation($variation_id, $sku, $parent_listing);
             $error_msg = isset($lm->lastError) ? $lm->lastError : '';
             if ($success) {
                 // TODO: use persistent admin message
                 WPLA()->logger->info("Matched missing variation #{$variation_id} / {$sku} - {$error_msg}");
             } else {
                 echo "Failed to match missing variation #{$variation_id} - please report this to support: {$error_msg}";
                 WPLA()->logger->error("Failed to match missing variation #{$variation_id} / {$sku} - {$error_msg}");
             }
         }
         // each variation
     }
     // if parent listing exists
 }
 public function handleActions()
 {
     // trigger reports update
     if ($this->requestAction() == 'update_reports') {
         do_action('wpla_update_reports');
     }
     // trigger report request
     if ($this->requestAction() == 'request_report') {
         $accounts = WPLA_AmazonAccount::getAll();
         foreach ($accounts as $account) {
             $api = new WPLA_AmazonAPI($account->id);
             // request report - returns request list as array on success
             $reports = $api->requestReport($_REQUEST['wpla_report_type']);
             if (is_array($reports)) {
                 // process the result
                 // $this->processReportsRequestList( $reports, $account );
                 WPLA_AmazonReport::processReportsRequestList($reports, $account);
                 $this->showMessage(sprintf(__('Report requested for account %s.', 'wpla'), $account->title));
             } elseif ($reports->Error->Message) {
                 $this->showMessage(sprintf(__('There was a problem requesting the report for account %s.', 'wpla'), $account->title) . '<br>Error: ' . $reports->Error->Message, 1);
             } else {
                 $this->showMessage(sprintf(__('There was a problem requesting the report for account %s.', 'wpla'), $account->title), 1);
             }
         }
     }
     // handle load report action
     if ($this->requestAction() == 'load_report_from_amazon') {
         $report = new WPLA_AmazonReport($_REQUEST['amazon_report']);
         $report->loadFromAmazon();
         // $api = new WPLA_AmazonAPI( $report->account_id );
         // $api->getReport( $report->GeneratedReportId );
         $this->showMessage(__('Report was downloaded from Amazon.', 'wpla'));
     }
     // handle process report action
     if ($this->requestAction() == 'process_amazon_report') {
         $this->processReportData($_REQUEST['amazon_report']);
         $this->showMessage(__('Report was processed.', 'wpla'));
     }
     // handle process report action
     if ($this->requestAction() == 'process_fba_shipment_report') {
         $this->processFbaShipmentReportData($_REQUEST['amazon_report']);
     }
     // handle delete_amazon_report action
     if ($this->requestAction() == 'delete_amazon_report') {
         $this->deleteReports($_REQUEST['amazon_report']);
         $this->showMessage(__('Selected items were removed.', 'wpla'));
     }
     // handle update_amazon_report action
     if ($this->requestAction() == 'update_amazon_report') {
         $this->updateReports($_REQUEST['amazon_report']);
         $this->showMessage(__('Selected items were updated.', 'wpla'));
     }
 }
 public function request_daily_inventory_report()
 {
     $report_type = '_GET_MERCHANT_LISTINGS_DATA_';
     $accounts = WPLA_AmazonAccount::getAll();
     foreach ($accounts as $account) {
         $api = new WPLA_AmazonAPI($account->id);
         // request report - returns request list as array on success
         $reports = $api->requestReport($report_type);
         if (is_array($reports)) {
             // process the result
             WPLA_AmazonReport::processReportsRequestList($reports, $account, true);
         } elseif ($reports->Error->Message) {
         } else {
         }
     }
     // foreach account
 }
 /** ************************************************************************
  * REQUIRED! This is where you prepare your data for display. This method will
  * usually be used to query the database, sort and filter the data, and generally
  * get it ready to be displayed. At a minimum, we should set $this->items and
  * $this->set_pagination_args(), although the following properties and methods
  * are frequently interacted with here...
  * 
  * @uses $this->_column_headers
  * @uses $this->items
  * @uses $this->get_columns()
  * @uses $this->get_sortable_columns()
  * @uses $this->get_pagenum()
  * @uses $this->set_pagination_args()
  **************************************************************************/
 function prepare_items()
 {
     // process bulk actions
     $this->process_bulk_action();
     // get pagination state
     $current_page = $this->get_pagenum();
     $per_page = $this->get_items_per_page('accounts_per_page', 20);
     // define columns
     $this->_column_headers = $this->get_column_info();
     // fetch profiles from model
     $accountsModel = new WPLA_AmazonAccount();
     $this->items = $accountsModel->getPageItems($current_page, $per_page);
     $total_items = $accountsModel->total_items;
     // register our pagination options & calculations.
     $this->set_pagination_args(array('total_items' => $total_items, 'per_page' => $per_page, 'total_pages' => ceil($total_items / $per_page)));
 }
 public function requestNewInventoryReport($report_type = '_GET_MERCHANT_LISTINGS_DATA_')
 {
     $accounts = WPLA_AmazonAccount::getAll();
     foreach ($accounts as $account) {
         $api = new WPLA_AmazonAPI($account->id);
         // request report - returns request list as array on success
         $reports = $api->requestReport($report_type);
         if (is_array($reports)) {
             // process the result
             // $this->processReportsRequestList( $reports, $account );
             WPLA_AmazonReport::processReportsRequestList($reports, $account);
             $this->showMessage(sprintf(__('Report requested for account %s.', 'wpla'), $account->title));
         } elseif ($reports->Error->Message) {
             $this->showMessage(sprintf(__('There was a problem requesting the report for account %s.', 'wpla'), $account->title) . '<br>Error: ' . $reports->Error->Message, 1);
         } else {
             $this->showMessage(sprintf(__('There was a problem requesting the report for account %s.', 'wpla'), $account->title), 1);
         }
     }
 }
?>
" name="submit" class="button">
								<p>
									<?php 
echo __('This will find products with ASINs which do not exist on the Listings page. It will then create new listings with the status "matched".', 'wpla');
?>
								</p>
								<p>
									<?php 
echo __('If you have added ASINs to your WooCommerce products using a CSV import tool, use this to add them to WP-Lister automatically.', 'wpla');
?>
								</p>
								<p>
									<?php 
$default_account_id = get_option('wpla_default_account_id', 1);
$account = WPLA_AmazonAccount::getAccount($default_account_id);
?>
									<i>Default Account: <?php 
echo $account->title;
?>
 (<?php 
echo $account->market_code;
?>
)</i> <br>
									<i>Maximum batch size: 1000 items</i> <br>
								</p>
						</form>
						<!br style="clear:both;"/>

					</div>
				</div> <!-- postbox -->
 public function updateFeedStatus($feed_ids)
 {
     WPLA()->logger->info("updateFeedStatus() - " . join(', ', $feed_ids));
     // echo "<pre>";print_r($feed_ids);echo"</pre>";die();
     if (empty($feed_ids)) {
         return;
     }
     $accounts = WPLA_AmazonAccount::getAll();
     foreach ($feed_ids as $feed_id) {
         $feed = new WPLA_AmazonFeed($feed_id);
         $account = new WPLA_AmazonAccount($feed->account_id);
         $api = new WPLA_AmazonAPI($feed->account_id);
         // get feed submissions
         $feeds = $api->getFeedSubmissionList($feed->FeedSubmissionId);
         if (is_array($feeds)) {
             // run the import
             WPLA_AmazonFeed::processFeedsSubmissionList($feeds, $account);
             $msg = sprintf(__('%s feed submission(s) were found for account %s.', 'wpla'), sizeof($feeds), $account->title);
             WPLA()->logger->info($msg);
             $this->showMessage(nl2br($msg), 0, 1);
         } elseif ($feeds->Error->Message) {
             $msg = sprintf(__('There was a problem fetching feed submissions for account %s.', 'wpla'), $account->title) . ' - Error: ' . $feeds->Error->Message;
             WPLA()->logger->error($msg);
             $this->showMessage(nl2br($msg), 1, 1);
         } else {
             $msg = sprintf(__('There was a problem fetching feed submissions for account %s.', 'wpla'), $account->title);
             WPLA()->logger->error($msg);
             $this->showMessage(nl2br($msg), 1, 1);
         }
     }
 }
 public function jobs_run_task()
 {
     // quit if no job name provided
     if (!isset($_REQUEST['job'])) {
         return false;
     }
     if (!isset($_REQUEST['task'])) {
         return false;
     }
     $job = $_REQUEST['job'];
     $task = $_REQUEST['task'];
     // register shutdown handler
     global $wpla_shutdown_handler_enabled;
     $wpla_shutdown_handler_enabled = true;
     register_shutdown_function(array($this, 'shutdown_handler'));
     WPLA()->logger->info('running task: ' . print_r($task, 1));
     // handle job name
     switch ($task['task']) {
         // update listing from Amazon (current used for new listings without ASIN)
         case 'updateProduct':
             // init
             $lm = new WPLA_ListingsModel();
             $listing = $lm->getItem($task['id']);
             $account = WPLA_AmazonAccount::getAccount($listing['account_id']);
             $api = new WPLA_AmazonAPI($account->id);
             // get product attributes
             // $product = $api->getProduct( $listing['asin'] );
             $result = $api->getMatchingProductForId($listing['sku'], 'SellerSKU');
             // echo "<pre>";print_r($product);echo"</pre>";#die();
             // echo "<pre>";print_r($product);echo"</pre>";die();
             if ($result->success) {
                 if (!empty($result->product->ASIN)) {
                     // update listing attributes
                     $listing_id = $listing['id'];
                     // $lm->updateItemAttributes( $product, $listing_id );
                     // $listing = $lm->getItem( $listing_id ); // update values
                     $lm->updateWhere(array('id' => $listing_id), array('asin' => $result->product->ASIN));
                     WPLA()->logger->info('new ASIN for listing #' . $listing['id'] . ': ' . $result->product->ASIN);
                     // update product
                     // $woo = new WPLA_ProductBuilder();
                     // $woo->updateProducts( array( $listing ) );
                     $success = true;
                     $errors = '';
                 } else {
                     $errors = sprintf(__('There was a problem fetching product details for %s.', 'wpla'), $listing['asin']);
                     $errors .= ' The product data received from Amazon was empty.';
                     $success = false;
                 }
             } elseif ($result->Error->Message) {
                 $errors = sprintf(__('There was a problem fetching product details for %s.', 'wpla'), $listing['asin']) . '<br>Error: ' . $result->Error->Message;
                 $success = false;
             } else {
                 $errors = sprintf(__('There was a problem fetching product details for %s.', 'wpla'), $listing['asin']);
                 $success = false;
             }
             // build response
             $response = new stdClass();
             $response->job = $job;
             $response->task = $task;
             $response->errors = empty($errors) ? array() : array(array('HtmlMessage' => $errors));
             $response->success = $success;
             $this->returnJSON($response);
             exit;
             // create new WooCommerce product from imported listing
         // create new WooCommerce product from imported listing
         case 'createProduct':
             // init
             $lm = new WPLA_ListingsModel();
             // $listing = $lm->getItem( $task['id'] );
             $listing_id = $task['id'];
             // create product
             $ProductsImporter = new WPLA_ProductsImporter();
             $success = $ProductsImporter->createProductFromAmazonListing($listing_id);
             $error = $ProductsImporter->lastError;
             $delay = $ProductsImporter->request_count * 1000;
             // ms
             // build response
             $response = new stdClass();
             $response->job = $job;
             $response->task = $task;
             $response->errors = empty($error) ? array() : array(array('HtmlMessage' => $error));
             $response->success = $success;
             $response->delay = $delay;
             $this->returnJSON($response);
             exit;
             // fetch full product description from Amazon and update WooCommerce product
         // fetch full product description from Amazon and update WooCommerce product
         case 'fetchFullProductDescription':
             $webHelper = new WPLA_AmazonWebHelper();
             $webHelper->loadListingDetails($task['id']);
             // echo "<pre>";print_r($webHelper->images);echo"</pre>";#die();
             $lm = new WPLA_ListingsModel();
             $item = $lm->getItem($task['id']);
             if (!empty($webHelper->description)) {
                 // update product
                 $post_id = $item['post_id'];
                 $post_data = array('ID' => $post_id, 'post_content' => trim($webHelper->description));
                 wp_update_post($post_data);
                 $success = true;
                 $errors = '';
             } else {
                 $errors = sprintf(__('There was a problem fetching product details for %s.', 'wpla'), $item['asin']);
                 $errors .= ' The product description received from Amazon was empty.';
                 $success = false;
             }
             // build response
             $response = new stdClass();
             $response->job = $job;
             $response->task = $task;
             $response->errors = empty($errors) ? array() : array(array('HtmlMessage' => $errors));
             $response->success = $success;
             $this->returnJSON($response);
             exit;
             // process Merchant or FBA Report and create / update listings
         // process Merchant or FBA Report and create / update listings
         case 'processReportPage':
             // process report page - both Merchant and FBA reports
             $response = WPLA_ImportHelper::ajax_processReportPage($job, $task);
             $this->returnJSON($response);
             exit;
             // process single row (SKU) Merchant or FBA Report - and create / update listings
         // process single row (SKU) Merchant or FBA Report - and create / update listings
         case 'processSingleSkuFromReport':
             // process report page - both Merchant and FBA reports
             $response = WPLA_ImportHelper::ajax_processReportPage($job, $task, true);
             $this->returnJSON($response);
             exit;
         default:
             // echo "unknown task";
             // exit();
     }
 }
 public function createProductFromAmazonListing($listing)
 {
     $lm = new WPLA_ListingsModel();
     if (is_numeric($listing)) {
         $listing = $lm->getItem($listing);
     }
     if (!$listing) {
         return false;
     }
     $listing_id = $listing['id'];
     WPLA()->logger->info('--- createProductFromAmazonListing() - ID: ' . $listing['id'] . ' / ASIN ' . $listing['asin']);
     $account = WPLA_AmazonAccount::getAccount($listing['account_id']);
     if (!$account) {
         return false;
     }
     // init api
     $api = new WPLA_AmazonAPI($account->id);
     // get product details from amazon
     $result = $api->getMatchingProductForId($listing['asin'], 'ASIN');
     $this->request_count++;
     // echo "<pre>getMatchingProductForId() returned: ";print_r($result);echo"</pre>";#die();
     // handle Import Variations As Simple option
     if ($result->success && get_option('wpla_import_variations_as_simple', 0)) {
         $result->product->variation_type = '_single_';
     }
     // handle empty result error
     if ($result->success && empty($result->product->AttributeSets->ItemAttributes->Title)) {
         if (!empty($result->product->GetMatchingProductForIdResult->Error->Message)) {
             $this->lastError = sprintf(__('There was a problem fetching product details for %s.', 'wpla'), $listing['asin']) . '<br><code>' . $result->product->GetMatchingProductForIdResult->Error->Message . '</code>';
         } else {
             $this->lastError = sprintf(__('There was a problem fetching product details for %s.', 'wpla'), $listing['asin']) . ' The product data received from Amazon was empty.';
         }
         return false;
     }
     // first check if product already exists in WooCommerce...
     $post_id = WPLA_ProductBuilder::getProductIdBySKU($listing['sku']);
     if ($post_id) {
         WPLA()->logger->info('found existing product by SKU ' . $listing['sku'] . ' - post_id: ' . $post_id);
         $this->message = "Found existing product for SKU " . $listing['sku'];
         // if this SKU exists, check whether it is a variation or not
         $_product = get_product($post_id);
         // echo "<pre>";print_r($_product);echo"</pre>";#die();
         // handle child variations
         if ('variation' == $_product->product_type) {
             // set parent_id
             $data = array('post_id' => $_product->variation_id, 'parent_id' => $_product->parent->id, 'product_type' => $_product->product_type);
             $lm->updateListing($listing_id, $data);
             $this->message = "Found existing variation for SKU " . $listing['sku'];
         }
     } else {
         // SKU does not exist in WC...
         $variation_type = $result->success ? $result->product->variation_type : '_unknown_';
         $variation_type = is_string($variation_type) ? $variation_type : '_none_';
         // convert empty object to string
         WPLA()->logger->info('no WC product found for SKU ' . $listing['sku'] . ' - type: ' . $variation_type);
         // process child variation - fetch parent item instead
         if ($result->success && $result->product->variation_type == 'child') {
             // foreign imports should have their title updated first
             // $data = array();
             // $data['listing_title'] = $result->product->AttributeSets->ItemAttributes->Title;
             // $lm->updateListing( $listing_id, $data );
             // update listing attributes and title from result
             $lm->updateItemAttributes($result->product->AttributeSets->ItemAttributes, $listing_id);
             // get parent item - new request
             $parent_asin = $result->product->VariationParentASIN;
             $api = new WPLA_AmazonAPI($account->id);
             // new log record
             $parent_result = $api->getMatchingProductForId($parent_asin, 'ASIN');
             $parent_node = $parent_result->success ? $parent_result->product : false;
             $this->request_count++;
             // check for "variations without attributes"
             // if there are no variation attributes on the parent, fall back to creating a simple product instead
             if (0 == self::countVariationChildNodes($parent_node)) {
                 $msg = $listing['asin'] . " seems to be a child of parent ASIN {$parent_asin} - but that parent has no variation attributes set, so it will be imported as a simple product.";
                 WPLA()->logger->warn($msg);
                 wpla_show_message($msg, 'warn');
                 $result->product->variation_type = '_invalid_parent_';
             } else {
                 WPLA()->logger->info($listing['asin'] . " is a child of parent ASIN {$parent_asin}");
                 $result = $parent_result;
             }
         }
         // process parent variation
         if ($result->success && $result->product->variation_type == 'parent') {
             // get parent listing - or create if it doesn't exist yet
             $parent_listing = $this->getOrCreateParentVariation($result, $listing, $account);
             // all further processing should be using the parent variation - including children
             $result->product = $this->parseVariationChildNodes($result->product, $parent_listing, $account);
             // $listing      = $parent_listing; // $listing is supposed to be an array, $parent listing is an object
             $listing_id = $parent_listing->id;
             $listing = $lm->getItem($listing_id);
         }
     }
     // SKU does not exist in WC
     // import product...
     if ($result->success) {
         // update price for foreign imports (imported by ASIN)
         if ('foreign_import' == $listing['source'] && !$listing['price']) {
             $this->updateListingWithLowestPrice($listing, $account);
         }
         // update listing attributes and title from result
         $lm->updateItemAttributes($result->product->AttributeSets->ItemAttributes, $listing_id);
         $listing = $lm->getItem($listing_id);
         // create product
         $woo = new WPLA_ProductBuilder();
         $woo->importSingleProduct($listing, $result->product);
         // post-process variations - add post_id
         if ($result->product->variation_type == 'parent' && isset($result->product->variations)) {
             $this->fixNewVariationListings($result->product->variations, $parent_listing);
         }
         $success = true;
         $errors = '';
         $this->lastPostID = $woo->last_insert_id;
     } elseif (@$result->Error->Message) {
         $errors = sprintf(__('There was a problem fetching product details for %s.', 'wpla'), $listing['asin']) . '<br>Error: ' . $result->Error->Message;
         $success = false;
     } else {
         $errors = sprintf(__('There was a problem fetching product details for %s.', 'wpla'), $listing['asin']);
         $success = false;
     }
     $this->lastError = $errors;
     return $success;
 }
 public function loadAccounts()
 {
     $accounts = get_option('wpla_db_version') > 3 ? WPLA_AmazonAccount::getAll(true) : array();
     foreach ($accounts as $account) {
         $this->accounts[$account->id] = $account;
     }
     $this->multi_account = count($this->accounts) > 1 ? true : false;
 }
    function extra_tablenav($which)
    {
        if ('top' != $which) {
            return;
        }
        $wpl_profiles = WPLA_AmazonProfile::getAll();
        $wpl_accounts = WPLA_AmazonAccount::getAll(true);
        $profile_id = isset($_REQUEST['profile_id']) ? $_REQUEST['profile_id'] : false;
        $account_id = isset($_REQUEST['account_id']) ? $_REQUEST['account_id'] : false;
        // echo "<pre>";print_r($wpl_profiles);echo"</pre>";die();
        ?>
        <div class="alignleft actions" style="">

            <select name="profile_id">
                <option value=""><?php 
        _e('All profiles', 'wpla');
        ?>
</option>
                <option value="_NONE_" <?php 
        if ($profile_id == '_NONE_') {
            echo 'selected';
        }
        ?>
 ><?php 
        _e('No profile', 'wpla');
        ?>
</option>
                <?php 
        foreach ($wpl_profiles as $profile) {
            ?>
                    <option value="<?php 
            echo $profile->profile_id;
            ?>
"
                        <?php 
            if ($profile_id == $profile->profile_id) {
                echo 'selected';
            }
            ?>
                        ><?php 
            echo $profile->profile_name;
            ?>
</option>
                <?php 
        }
        ?>
            </select>            

            <select name="account_id">
                <option value=""><?php 
        _e('All accounts', 'wpla');
        ?>
</option>
                <?php 
        foreach ($wpl_accounts as $account) {
            ?>
                    <option value="<?php 
            echo $account->id;
            ?>
"
                        <?php 
            if ($account_id == $account->id) {
                echo 'selected';
            }
            ?>
                        ><?php 
            echo $account->title;
            ?>
 (<?php 
            echo $account->market_code;
            ?>
)</option>
                <?php 
        }
        ?>
            </select>            

            <input type="submit" name="" id="post-query-submit" class="button" value="Filter">

        </div>
        <?php 
    }
    function add_wc_order_table_filter_options()
    {
        global $typenow;
        if ($typenow != 'shop_order') {
            return;
        }
        if (!isset($_REQUEST['is_from_amazon'])) {
            return;
        }
        $wpl_accounts = WPLA_AmazonAccount::getAll(true);
        $account_id = isset($_REQUEST['wpla_account_id']) ? $_REQUEST['wpla_account_id'] : false;
        ?>

            <select name="wpla_account_id">
                <option value=""><?php 
        _e('All Amazon accounts', 'wpla');
        ?>
</option>
                <?php 
        foreach ($wpl_accounts as $account) {
            ?>
                    <option value="<?php 
            echo $account->id;
            ?>
"
                        <?php 
            if ($account_id == $account->id) {
                echo 'selected';
            }
            ?>
                        ><?php 
            echo $account->title;
            ?>
 (<?php 
            echo $account->market_code;
            ?>
)</option>
                <?php 
        }
        ?>
            </select>            

            <input type="hidden" name="is_from_amazon" value="<?php 
        echo isset($_REQUEST['is_from_amazon']) ? $_REQUEST['is_from_amazon'] : '';
        ?>
">

        <?php 
    }
 public function displayEditPage()
 {
     // init model
     // get item
     if ($this->requestAction() == 'add_new_profile') {
         $profile = new WPLA_AmazonProfile();
     } else {
         $profile = new WPLA_AmazonProfile($_REQUEST['profile']);
     }
     // $listingsModel = new ListingsModel();
     // $prepared_listings  = $listingsModel->getAllPreparedWithProfile( $item['profile_id'] );
     // $verified_listings  = $listingsModel->getAllVerifiedWithProfile( $item['profile_id'] );
     // $published_listings = $listingsModel->getAllPublishedWithProfile( $item['profile_id'] );
     // $ended_listings     = $listingsModel->getAllEndedWithProfile( $item['profile_id'] );
     $lm = new WPLA_ListingsModel();
     $listings = $profile->profile_id ? $lm->findAllListingsByColumn($profile->profile_id, 'profile_id') : array();
     $accounts = WPLA_AmazonAccount::getAll();
     $templates = WPLA_AmazonFeedTemplate::getAll();
     // separate ListingLoader templates
     $category_templates = array();
     $liloader_templates = array();
     foreach ($templates as $tpl) {
         if ($tpl->title == 'Offer') {
             $tpl->title = "Listing Loader";
             $liloader_templates[] = $tpl;
         } else {
             $category_templates[] = $tpl;
         }
     }
     $aData = array('plugin_url' => self::$PLUGIN_URL, 'message' => $this->message, 'profile' => $profile, 'accounts' => $accounts, 'category_templates' => $category_templates, 'liloader_templates' => $liloader_templates, 'profile_listings' => $listings, 'profile_details' => maybe_unserialize($profile->details), 'form_action' => 'admin.php?page=' . self::ParentMenuId . '-profiles');
     // $this->display( 'profiles_edit_page', array_merge( $aData, $profile ) );
     $this->display('profiles_edit_page', $aData);
 }
 static function getUrlForItemObj($item)
 {
     $item = (array) $item;
     $listing_url = 'http://www.amazon.com/dp/' . $item['asin'] . '/';
     // default to US
     if ($item['account_id']) {
         $account = WPLA_AmazonAccount::getAccount($item['account_id']);
         $market = $account ? WPLA_AmazonMarket::getMarket($account->market_id) : false;
         $listing_url = $market ? 'http://www.' . $market->url . '/dp/' . $item['asin'] . '/' : $listing_url;
     }
     return $listing_url;
 }
    function extra_tablenav($which)
    {
        if ('top' != $which) {
            return;
        }
        $wpl_accounts = WPLA_AmazonAccount::getAll(true);
        $account_id = isset($_REQUEST['account_id']) ? $_REQUEST['account_id'] : false;
        ?>
        <div class="alignleft actions" style="">

            <select name="account_id">
                <option value=""><?php 
        _e('All accounts', 'wpla');
        ?>
</option>
                <?php 
        foreach ($wpl_accounts as $account) {
            ?>
                    <option value="<?php 
            echo $account->id;
            ?>
"
                        <?php 
            if ($account_id == $account->id) {
                echo 'selected';
            }
            ?>
                        ><?php 
            echo $account->title;
            ?>
</option>
                <?php 
        }
        ?>
            </select>            

            <input type="submit" name="" id="post-query-submit" class="button" value="Filter">

        </div>
        <?php 
    }
 static function updatePendingFeeds()
 {
     WPLA()->logger->info('updatePendingFeeds()');
     $accounts = WPLA_AmazonAccount::getAll();
     // WPLA()->logger->info('found accounts: '.print_r($accounts,1));
     foreach ($accounts as $account) {
         self::updatePendingFeedForAccount($account);
     }
 }
 protected function newAccount()
 {
     // make sure all required fields are populated
     if (empty($_POST['wpla_secret_key'])) {
         $this->showMessage(__('No secret key was provided.', 'wpla'), 1);
         return;
     }
     if (empty($_POST['wpla_access_key_id'])) {
         $this->showMessage(__('No AWS Access Key ID was provided.', 'wpla'), 1);
         return;
     }
     if (empty($_POST['wpla_merchant_id'])) {
         $this->showMessage(__('No Merchant ID was provided.', 'wpla'), 1);
         return;
     }
     if (empty($_POST['wpla_marketplace_id'])) {
         $this->showMessage(__('No Marketplace ID was provided.', 'wpla'), 1);
         return;
     }
     // TODO: check nonce
     if (isset($_POST['wpla_merchant_id'])) {
         // create new account
         $account = new WPLA_AmazonAccount();
         $account->title = stripslashes($_POST['wpla_account_title']);
         $account->market_id = trim($_POST['wpla_amazon_market_id']);
         $account->market_code = trim($_POST['wpla_amazon_market_code']);
         $account->merchant_id = trim($_POST['wpla_merchant_id']);
         $account->marketplace_id = trim($_POST['wpla_marketplace_id']);
         $account->access_key_id = trim($_POST['wpla_access_key_id']);
         $account->secret_key = trim($_POST['wpla_secret_key']);
         $account->active = 1;
         $account->add();
         // update allowed markets
         $account->updateMarketplaceParticipations();
         $this->showMessage(__('New account was added.', 'wpla'));
     }
 }
 public function renderDupeTable($listings, $column = 'post_id')
 {
     if (empty($listings)) {
         return '';
     }
     // get current page with paging as url param
     $page = $_REQUEST['page'];
     if (isset($_REQUEST['paged'])) {
         $page .= '&paged=' . $_REQUEST['paged'];
     }
     $listingsModel = new WPLA_ListingsModel();
     $msg = '';
     foreach ($listings as $dupe) {
         $account_title = WPLA_AmazonAccount::getAccountTitle($dupe->account_id);
         $msg .= '<b>' . __('Listings for', 'wpla') . ' ' . strtoupper($column) . ' ' . $dupe->{$column} . ' (' . $account_title . '):</b>';
         $msg .= '<br>';
         $duplicateListings = $listingsModel->findAllListingsByColumn($dupe->{$column}, $column, $dupe->account_id);
         $msg .= '<table style="width:100%">';
         foreach ($duplicateListings as $listing) {
             $color = $listing->status == 'archived' ? 'silver' : '';
             // check if WooCommerce SKU matches Amazon SKU
             $woo_sku = get_post_meta($listing->post_id, '_sku', true);
             $sku_label = $listing->sku == $woo_sku ? $woo_sku : '<span style="color:darkred">' . $woo_sku . ' / ' . $listing->sku . '</span>';
             $msg .= '<tr><td style="width:40%;">';
             $msg .= '<span style="color:' . $color . '">';
             $msg .= $listing->listing_title;
             $msg .= '</span>';
             $msg .= '</td><td style="width:10%;">';
             $msg .= '<i style="color:silver">' . $listing->product_type . '</i>';
             $msg .= '</td><td style="width:10%;">';
             $msg .= '<a href="admin.php?page=wpla&s=' . $listing->sku . '" title="SKU" target="_blank">';
             $msg .= $sku_label . '</a>';
             $msg .= '</td><td style="width:10%;">';
             $msg .= '<a href="admin.php?page=wpla&s=' . $listing->asin . '" title="ASIN" target="_blank">';
             $msg .= $listing->asin . '</a>';
             $msg .= '</td><td style="width:10%;">';
             $msg .= '<a href="admin.php?page=wpla&s=' . $listing->post_id . '" title="Product ID" target="_blank">';
             $msg .= 'ID ' . $listing->post_id . '</a>';
             $msg .= '</td><td style="width:10%;">';
             $msg .= '<i>' . $listing->status . '</i>';
             // if ( in_array( $listing->status, array( 'prepared', 'verified', 'ended', 'sold' ) ) ) {
             // 	$archive_link = sprintf('<a class="archive button button-small" href="?page=%s&action=%s&listing=%s">%s</a>',$page,'archive',$listing->id,__('Click to move to archive','wpla'));
             // 	$msg .= '&nbsp;&nbsp;&nbsp;&nbsp;'.$archive_link;
             // 	$msg .= '<br>';
             // }
             $msg .= '</td><td align="right" style="width:10%;">';
             $delete_btn = sprintf('<a class="delete button button-small button-secondary" href="?page=%s&action=%s&listing=%s">%s</a>', $page, 'delete', $listing->id, __('Remove from database', 'wpla'));
             $msg .= $delete_btn;
             $msg .= '</td></tr>';
         }
         $msg .= '</table>';
         $msg .= '<br>';
     }
     return $msg;
 }