public function ajax_wpla_show_minmax_price_wizard()
 {
     // load template
     $tpldata = array('plugin_url' => WPLA_URL, 'selected_items' => $_REQUEST['item_ids'] ? explode(',', $_REQUEST['item_ids']) : array(), 'form_action' => 'admin.php?page=wpla-tools&tab=repricing');
     WPLA()->pages['listings']->display('tools/price_wizard', $tpldata);
     exit;
 }
 public function decodeObject($str, $assoc = false, $loadAmazonClasses = false)
 {
     // load Amazon classes if required
     // if ( $loadAmazonClasses ) self::loadAmazonClasses();
     if ($str == '') {
         return false;
     }
     // json_decode
     $obj = json_decode($str, $assoc);
     //WPLA()->logger->info('json_decode: '.print_r($obj,1));
     if (is_object($obj) || is_array($obj)) {
         return $obj;
     }
     // unserialize fallback
     $obj = maybe_unserialize($str);
     //WPLA()->logger->info('unserialize: '.print_r($obj,1));
     if (is_object($obj) || is_array($obj)) {
         return $obj;
     }
     // mb_unserialize fallback
     $obj = $this->mb_unserialize($str);
     // WPLA()->logger->info('mb_unserialize: '.print_r($obj,1));
     if (is_object($obj) || is_array($obj)) {
         return $obj;
     }
     // log error
     $e = new Exception();
     WPLA()->logger->error('backtrace: ' . $e->getTraceAsString());
     WPLA()->logger->error('mb_unserialize returned: ' . print_r($obj, 1));
     WPLA()->logger->error('decodeObject() - not an valid object: ' . $str);
     return $str;
 }
Exemplo n.º 3
0
 function insertJob($jobname, $tasklist)
 {
     global $wpdb;
     // get current user id
     $user = wp_get_current_user();
     // generate job key
     $key = md5($jobname . rand());
     // insert row into db
     $data = array();
     $data['job_key'] = $key;
     $data['job_name'] = $jobname;
     $data['tasklist'] = self::encodeObject($tasklist);
     $data['date_created'] = date('Y-m-d H:i:s');
     $data['user_id'] = $user->ID;
     $wpdb->insert($this->tablename, $data);
     WPLA()->logger->info("insertJob( {$jobname} ) - key {$key}");
     $this->key = $key;
     return $key;
 }
 function wpla_woocommerce_custom_product_columns($column)
 {
     global $post, $woocommerce, $the_product;
     if (empty($the_product) || $the_product->id != $post->ID) {
         $the_product = get_product($post);
     }
     switch ($column) {
         case 'listed_on_amazon':
             // $item_source = get_post_meta( $post->ID, '_amazon_item_source', true );
             // if ( ! $item_source ) return;
             // $asin = get_post_meta( $post->ID, '_wpla_asin', true );
             // $asin = $listingsModel->getASINFromPostID( $post->ID );
             // if ( $asin ) $status = 'online';
             // get all listings for product ID
             $listingsModel = new WPLA_ListingsModel();
             $listings = $listingsModel->getAllItemsByPostID($post->ID);
             if (empty($listings)) {
                 // $listings = $listingsModel->getAllItemsByParentID( $post->ID );
                 // $item = $listings ? reset($listings) : false;
                 // get ALL child items (variations)
                 $listings = $listingsModel->getAllItemsByParentID($post->ID);
                 // echo "<pre>count 2: ";echo sizeof($listings);echo"</pre>";//die();
                 // group found child items by account
                 $grouped_listings = array();
                 foreach ($listings as $listing) {
                     $account_id = $listing->account_id;
                     if (isset($grouped_listings[$account_id])) {
                         $grouped_listings[$account_id]->counter++;
                     } else {
                         $listing->counter = 1;
                         $grouped_listings[$account_id] = $listing;
                     }
                 }
                 $listings = $grouped_listings;
             }
             // show select profile button if no listings found
             if (empty($listings)) {
                 if ($the_product->product_type == 'variable') {
                     $msg = 'Variable products can only be matched on the edit product page where you need to select an ASIN for each variation.';
                     echo '<a href="#" onclick="alert(\'' . $msg . '\');return false;" class="tips" data-tip="' . __('Match on Amazon', 'wpla') . '" style="width:16px;height:16px; padding:0; cursor:pointer;" ><img src="' . WPLA_URL . '/img/search3.png" alt="match" /></a>';
                 } elseif ($the_product->post->post_status == 'draft') {
                     $msg = 'This product is a draft. You need to publish your product before you can list it on Amazon.';
                     echo '<a href="#" onclick="alert(\'' . $msg . '\');return false;" class="tips" data-tip="' . __('Match on Amazon', 'wpla') . '" style="width:16px;height:16px; padding:0; cursor:pointer;" ><img src="' . WPLA_URL . '/img/search3.png" alt="match" /></a>';
                 } else {
                     $tb_url = 'admin-ajax.php?action=wpla_show_product_matches&id=' . $post->ID . '&width=640&height=420';
                     echo '<a href="' . $tb_url . '" class="thickbox tips" data-tip="' . __('Match on Amazon', 'wpla') . '" style="width:16px;height:16px; padding:0; cursor:pointer;" ><img src="' . WPLA_URL . '/img/search3.png" alt="match" /></a>';
                 }
                 return;
             }
             // show all found listings
             foreach ($listings as $item) {
                 $msg_1 = 'Amazon item is ' . $item->status . '.';
                 $msg_2 = '';
                 $msg_3 = 'Click to view all listings for this product in WP-Lister.';
                 $linkurl = 'admin.php?page=wpla&amp;s=' . $post->ID;
                 $imgfile = 'amazon-16x16.png';
                 switch ($item->status) {
                     case 'online':
                     case 'changed':
                         // $msg_1   = 'This product is published on Amazon';
                         $msg_3 = 'Click to open this listing on Amazon in a new tab.';
                         $imgfile = 'icon-success-32x32.png';
                         // get proper amazon_url
                         if ($item->asin && $item->account_id) {
                             $account = new WPLA_AmazonAccount($item->account_id);
                             $market = new WPLA_AmazonMarket($account->market_id);
                             $amazon_url = 'http://www.' . $market->url . '/dp/' . $item->asin . '/';
                         }
                         $linkurl = isset($amazon_url) ? $amazon_url : 'http://www.amazon.com/dp/' . $item->asin;
                         break;
                     case 'matched':
                     case 'prepared':
                         // echo '<img src="'.WPLA_URL.'/img/amazon-orange-16x16.png" class="tips" data-tip="'.__('This product is scheduled to be submitted to Amazon.','wpla').'" />';
                         $imgfile = 'amazon-orange-16x16.png';
                         break;
                     case 'failed':
                         // echo '<img src="'.WPLA_URL.'/img/amazon-red-16x16.png" class="tips" data-tip="'.__('There was a problem submitting this product to Amazon.','wpla').'" />';
                         $imgfile = 'amazon-red-16x16.png';
                         break;
                     default:
                         // echo '<img src="'.WPLA_URL.'/img/search3.png" class="tips" data-tip="unmatched" />';
                         break;
                 }
                 // get account
                 $accounts = WPLA()->accounts;
                 $account = isset($accounts[$item->account_id]) ? $accounts[$item->account_id] : false;
                 if ($account && sizeof($accounts) > 0) {
                     $msg_2 = '<i>' . $account->title . ' (' . $account->market_code . ')</i><br>';
                 }
                 // show counter
                 if (isset($item->counter)) {
                     $msg_2 .= '<small>Variation listings: ' . $item->counter . '</small><br>';
                 }
                 // output icon
                 $msg_html = '<b>' . $msg_1 . '</b><br/>' . $msg_2 . '<br/>' . $msg_3;
                 echo '<a href="' . $linkurl . '" target="_blank">';
                 echo '<img src="' . WPLA_URL . '/img/' . $imgfile . '" class="tips" data-tip="' . esc_attr($msg_html) . '" style="width:16px;height:16px; padding:0; cursor:pointer;" />';
                 echo '</a>';
             }
             // each listing
             break;
     }
     // switch ($column)
 }
 public static function processReportsRequestList($reports, $account, $is_new_request = false)
 {
     // if this is a new report request, add to reports in progress - otherwise reset it
     // TODO: count reports in progress per account
     if ($is_new_request) {
         $reports_in_progress = get_option('wpla_reports_in_progress', 0);
     } else {
         $reports_in_progress = 0;
     }
     foreach ($reports as $report) {
         // check if report exists
         $existing_record = WPLA_AmazonReport::getReportByRequestId($report->ReportRequestId);
         if ($existing_record) {
             // skip existing report if it was requested using another "account" (different marketplace using the same account)
             if ($existing_record->account_id != $account->id) {
                 WPLA()->logger->info('skipped existing report ' . $existing_record->id . ' for account ' . $existing_record->account_id);
                 continue;
             }
             $new_report = new WPLA_AmazonReport($existing_record->id);
             $new_report->ReportRequestId = $report->ReportRequestId;
             $new_report->ReportType = $report->ReportType;
             $new_report->ReportProcessingStatus = $report->ReportProcessingStatus;
             $new_report->SubmittedDate = $report->SubmittedDate;
             $new_report->StartedProcessingDate = isset($report->StartedProcessingDate) ? $report->StartedProcessingDate : '';
             $new_report->CompletedDate = isset($report->CompletedDate) ? $report->CompletedDate : '';
             $new_report->GeneratedReportId = isset($report->GeneratedReportId) ? $report->GeneratedReportId : '';
             // $new_report->account_id             = $account->id;
             $new_report->results = maybe_serialize($report);
             // save new record
             $new_report->update();
         } else {
             // add new record
             $new_report = new WPLA_AmazonReport();
             $new_report->ReportRequestId = $report->ReportRequestId;
             $new_report->ReportType = $report->ReportType;
             $new_report->ReportProcessingStatus = $report->ReportProcessingStatus;
             $new_report->SubmittedDate = $report->SubmittedDate;
             $new_report->StartedProcessingDate = isset($report->StartedProcessingDate) ? $report->StartedProcessingDate : '';
             $new_report->CompletedDate = isset($report->CompletedDate) ? $report->CompletedDate : '';
             $new_report->GeneratedReportId = isset($report->GeneratedReportId) ? $report->GeneratedReportId : '';
             $new_report->account_id = $account->id;
             $new_report->results = maybe_serialize($report);
             // save new record
             $new_report->add();
         }
         // load data for new reports automatically (not older than 24 hours)
         if (!$new_report->data && in_array($report->ReportProcessingStatus, array('_DONE_'))) {
             $report_completed_date = strtotime($new_report->CompletedDate);
             $one_day_ago = time() - 3600 * 24;
             if ($report_completed_date > $one_day_ago) {
                 $new_report->loadFromAmazon();
                 $new_report->autoProcessNewReport();
             }
             // $new_report->loadFromAmazon();
             // $new_report->processReportData();
         }
         // check if report is in progress
         if (in_array($report->ReportProcessingStatus, array('_SUBMITTED_', '_IN_PROGRESS_'))) {
             $reports_in_progress++;
         }
     }
     // update report progress status
     update_option('wpla_reports_in_progress', $reports_in_progress);
 }
function wpla_register_profile_shortcode($shortcode, $title, $callback)
{
    WPLA()->shortcodes[$shortcode] = array('slug' => $shortcode, 'title' => $title, 'callback' => $callback, 'content' => false);
}
<?php

$buildin_shortcodes = array('[product_title]' => 'Product title', '[product_sku]' => 'SKU', '[product_price]' => 'Price', '[product_sale_price]' => 'Sale price', '[product_sale_start]' => 'Sale start date', '[product_sale_end]' => 'Sale end date', '[product_msrp]' => 'MSRP price', '[product_quantity]' => 'Quantity', '[product_content]' => 'Product description', '[product_excerpt]' => 'Product short description', '[product_length]' => 'Product length', '[product_width]' => 'Product width', '[product_height]' => 'Product height', '[product_weight]' => 'Product weight', '[amazon_product_id]' => 'Amazon product ID', '[meta_YOUR-CUSTOM-FIELD]' => '-- custom meta field --', '[---]' => '-- leave empty --');
// handle custom shortcodes registered by wpla_register_profile_shortcode()
foreach (WPLA()->shortcodes as $key => $custom_shortcode) {
    $buildin_shortcodes["[{$key}]"] = $custom_shortcode['title'];
}
// handle custom variation meta fields
$variation_meta_fields = get_option('wpla_variation_meta_fields', array());
foreach ($variation_meta_fields as $key => $varmeta) {
    $key = 'meta_' . $key;
    $buildin_shortcodes["[{$key}]"] = $varmeta['label'];
}
// $product_attributes = WPLA_ProductWrapper::getAttributeTaxonomies();
// echo "<pre>";print_r($product_attributes);echo"</pre>";#die();
?>

	<div id="wpla_shortcode_selection_container">
		
		<p>
			Click on a shortcode and it will be inserted to the selected field.
		</p>

		<table style="width:100%;">
			<tr>
				<th>Product properties</th>
				<th>Product attributes</th>
			</tr>
			<tr>
				<td style="width:50%; vertical-align:top;">
					<?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 ajax_wpla_tail_log()
 {
     require_once WPLA_PATH . '/includes/php-tail/PHPTail.php';
     // Initilize a new instance of PHPTail - 3 sec reload, 512k max
     $tail = new PHPTail(array('log' => WPLA()->logger->file), 3000, 524288);
     // handle ajax call
     if (isset($_GET['ajax'])) {
         echo $tail->getNewLines('log', @$_GET['lastsize'], $_GET['grep'], $_GET['invert']);
         die;
     }
     // else show gui
     $tail->generateGUI();
     die;
 }
 function parseBTG($csv_rows)
 {
     global $wpdb;
     // $table = $wpdb->prefix . self::TABLENAME;
     $table = $wpdb->prefix . 'amazon_btg';
     $path_cache = array();
     $child_cache = array();
     // first remove all nodes with this file's top id (v1)
     $wpdb->delete($table, array('top_id' => $csv_rows[0][0], 'site_id' => $this->site_id));
     $wpdb->delete($table, array('node_id' => $csv_rows[0][0], 'site_id' => $this->site_id));
     // echo "<pre>";print_r( $csv_rows[0][0] );echo"</pre>";die();
     // first remove all nodes for current tpl_id (v2)
     $wpdb->delete($table, array('tpl_id' => $this->tpl_id, 'site_id' => $this->site_id));
     $wpdb->delete($table, array('tpl_id' => 0, 'site_id' => $this->site_id));
     // remove unassigned/stale items from old version
     foreach ($csv_rows as $line => $row) {
         // basic values
         $node_id = $row[0];
         // Node ID
         $node_path = $row[1];
         // Node Path
         $node_name = basename($node_path);
         $level = substr_count($node_path, '/');
         $top_id = 0;
         $parent_id = 0;
         $leaf = 1;
         $keyword = '';
         // extract keyword
         if (preg_match('/item_type_keyword:([[:alnum:]_-]*)/', @$row[2], $matches)) {
             $keyword = $matches[1];
         }
         if (preg_match('/item_type_keyword:([[:alnum:]_-]*)/', @$row[3], $matches)) {
             $keyword = $matches[1];
         }
         // analyze hierarchy
         $parent_path = dirname($node_path);
         if (isset($path_cache[$parent_path])) {
             $parent_id = $path_cache[$parent_path];
             $top_name = substr($node_path, 0, strpos($node_path, '/'));
             $top_id = isset($path_cache[$top_name]) ? $path_cache[$top_name] : 0;
         } elseif ($level) {
             // echo "<pre>Warning: could not find parent node: ";print_r($parent_path);echo"</pre>";#die();
             // use "grand parent" - fix nodes like 'PS/2 Cables' and 'I/O Adapters'
             $parent_path = dirname($parent_path);
             if (isset($path_cache[$parent_path])) {
                 $parent_id = $path_cache[$parent_path];
                 $top_name = substr($node_path, 0, strpos($node_path, '/'));
                 $top_id = isset($path_cache[$top_name]) ? $path_cache[$top_name] : 0;
             }
         }
         // update leaf cache
         if ($parent_id) {
             $child_cache[$parent_id] = true;
         }
         // self check
         if ($level && !$parent_id) {
             echo "<pre>Warning: skipped corrupted node: ";
             print_r($node_path);
             echo "</pre>";
             #die();
             continue;
         }
         // build sql columns
         $data = array();
         $data['node_id'] = $node_id;
         $data['node_path'] = $node_path;
         $data['node_name'] = $node_name;
         $data['keyword'] = $keyword;
         $data['parent_id'] = $parent_id;
         $data['top_id'] = $top_id;
         $data['level'] = $level;
         $data['leaf'] = $leaf;
         $data['tpl_id'] = $this->tpl_id;
         $data['site_id'] = $this->site_id;
         // echo "<pre>";print_r($data);echo"</pre>";#die();
         // insert to db...
         $result = $wpdb->insert($table, $data);
         // WPLA()->logger->info("inserted browse tree node $node_id: $node_path");
         // add to cache
         $path_cache[$node_path] = $node_id;
     }
     // process parent categories - set leaf to 0
     foreach ($child_cache as $node_id => $has_childs) {
         $data = array('leaf' => 0);
         $where = array('node_id' => $node_id);
         $result = $wpdb->update($table, $data, $where);
     }
     WPLA()->logger->info("browse tree nodes processed: " . sizeof($path_cache));
     return sizeof($path_cache);
 }
 public function fetchPageContent($listing_url)
 {
     WPLA()->logger->info('fetching URL: ' . $listing_url);
     // fetch HTML content
     $response = wp_remote_get($listing_url, array('timeout' => 15, 'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36'));
     // WPLA()->logger->info("BODY: ".$response['body']);
     // handle errors
     if (is_wp_error($response)) {
         // echo "<pre>";print_r($response);echo"</pre>";
         // $this->showMessage( "Couldn't fetch URL $listing_url - ".$response->get_error_message(), 1, 1 );
         WPLA()->logger->error("Couldn't fetch URL {$listing_url} - " . $response->get_error_message());
         wpla_show_message("Couldn't fetch URL {$listing_url} - " . $response->get_error_message());
         $this->errors[] = "Couldn't fetch URL {$listing_url} - " . $response->get_error_message();
         // doesn't show
         return false;
     }
     if ($response['response']['code'] != 200) {
         // echo "<pre>Couldn't fetch URL $listing_url - server returned error code ".$response['response']['code']."</pre>";
         // $this->showMessage( "Couldn't fetch URL $listing_url - server returned error code ".$response['response']['code'], 1, 1 );
         WPLA()->logger->error("Couldn't fetch URL {$listing_url} - server returned error code " . $response['response']['code']);
         wpla_show_message("Couldn't fetch URL {$listing_url} - server returned error code " . $response['response']['code']);
         $this->errors[] = "Couldn't fetch URL {$listing_url} - server returned error code " . $response['response']['code'];
         return false;
     }
     // log to db - enable only for debugging (limited to 64k)
     // $this->dblogger = new WPLA_AmazonLogger();
     // $this->dblogger->updateLog( array(
     //     'callname'    => 'wp_remote_get',
     //     'request'     => 'internal action hook',
     //     'parameters'  => maybe_serialize( $listing_url ),
     //     'request_url' => $listing_url,
     //     'account_id'  => '',
     //     'market_id'   => '',
     //     'response'    => $response['body'],
     //     'result'      => json_encode( $response ),
     //     'success'     => 'Success'
     // ));
     // return HTML content
     $html_content = $response['body'];
     $this->success = true;
     // echo "<pre>";htmlspecialchars($html_content);echo"</pre>";#die();
     return $html_content;
 }
 function update_products_on_shutdown()
 {
     // get queue
     $collected_products = get_option('wpla_updated_products_queue', array());
     if (!is_array($collected_products)) {
         $collected_products = array();
     }
     // DEBUG
     WPLA()->logger->info("CSV: update_products_on_shutdown() - collected_products: " . print_r($collected_products, 1));
     // mark each queued product as modified
     $lm = new WPLA_ListingsModel();
     foreach ($collected_products as $post_id) {
         // do_action( 'wpla_product_has_changed', $post_id );
         $lm->markItemAsModified($post_id, true);
         // set $skip_updating_feeds = true
     }
     // clear queue
     delete_option('wpla_updated_products_queue');
     // update pending feeds - after all items have been updated
     if (!empty($collected_products)) {
         WPLA_AmazonFeed::updatePendingFeeds();
     }
 }
 function addHistory($order_id, $action, $msg, $details = array(), $success = true)
 {
     global $wpdb;
     $table = $wpdb->prefix . self::TABLENAME;
     // build history record
     $record = new stdClass();
     $record->action = $action;
     $record->msg = $msg;
     $record->details = $details;
     $record->success = $success;
     $record->time = time();
     // load history
     $history = $wpdb->get_var("\n\t\t\tSELECT history\n\t\t\tFROM {$table}\n\t\t\tWHERE order_id = '{$order_id}'\n\t\t");
     // init with empty array
     $history = maybe_unserialize($history);
     if (!$history) {
         $history = array();
     }
     // prevent fatal error if $history is not an array
     if (!is_array($history)) {
         WPLA()->logger->error("invalid history value in OrdersImporter::addHistory(): " . $history);
         // build history record
         $rec = new stdClass();
         $rec->action = 'reset_history';
         $rec->msg = 'Corrupted history data was cleared';
         $rec->details = array();
         $rec->success = 'ERROR';
         $rec->time = time();
         $history = array();
         $history[] = $record;
     }
     // add record
     $history[] = $record;
     // update history
     $history = serialize($history);
     $wpdb->query("\n\t\t\tUPDATE {$table}\n\t\t\tSET history = '{$history}'\n\t\t\tWHERE order_id = '{$order_id}'\n\t\t");
 }
 public function removeLock()
 {
     if (file_exists($this->lockfile)) {
         unlink($this->lockfile);
         WPLA()->logger->info("lockfile was removed: " . $this->lockfile);
     }
 }
 public function requestReport_v2($ReportType)
 {
     WPLA()->logger->info('requestReport_v2()');
     $this->initAPI();
     $marketplaceIdArray = array("Id" => array($this->MarketplaceId));
     $request = new MarketplaceWebService_Model_RequestReportRequest();
     $request->setMerchant($this->SellerId);
     $request->setMarketplaceIdList($marketplaceIdArray);
     $request->setReportType($ReportType);
     // $request->setReportOptions('ShowSalesChannel=true');
     $result = $this->invokeRequestReport($this->service, $request);
     return $result;
 }
 public function checkSoldStock()
 {
     // get all published listings
     $lm = new WPLA_ListingsModel();
     $listings = $lm->getWhere('status', 'sold');
     $out_of_stock_products = array();
     // process published listings
     foreach ($listings as $item) {
         // get wc product
         $_product = $this->getProduct($item['post_id']);
         // checking parent variations makes no sense in WPLA, so skip them
         if ($_product->product_type == 'variable') {
             continue;
         }
         // check stock level
         // $stock = WPLA_ProductWrapper::getStock( $item['post_id'] );
         $stock = $_product ? $_product->get_total_stock() : 0;
         if ($stock == 0) {
             continue;
         }
         // mark listing as changed
         // if ( isset( $_REQUEST['mark_as_changed'] ) ) {
         // 	$lm->updateListing( $item['id'], array( 'status' => 'changed' ) );
         // 	$item['status'] = 'changed';
         // }
         // add to list of out of stock products
         $item['stock'] = $stock;
         $item['exists'] = $_product ? true : false;
         $item['parent_id'] = $_product->product_type == 'variation' ? $_product->parent->id : false;
         $out_of_stock_products[] = $item;
     }
     // return if empty
     if (empty($out_of_stock_products)) {
         WPLA()->showMessage('No sold products have stock in WooCommerce.', 0, 1);
         return;
     }
     $msg = '<p>';
     $msg .= 'Warning: Some sold listings are still in stock in WooCommerce.';
     $msg .= '</p>';
     // table header
     $msg .= '<table style="width:100%">';
     $msg .= "<tr>";
     $msg .= "<th style='text-align:left'>Stock</th>";
     $msg .= "<th style='text-align:left'>SKU</th>";
     $msg .= "<th style='text-align:left'>Product</th>";
     $msg .= "<th style='text-align:left'>Qty</th>";
     $msg .= "<th style='text-align:left'>ASIN</th>";
     $msg .= "<th style='text-align:left'>Ended at</th>";
     $msg .= "<th style='text-align:left'>Status</th>";
     $msg .= "</tr>";
     // table rows
     foreach ($out_of_stock_products as $item) {
         // get column data
         // $qty     = $item['quantity'] - $item['quantity_sold'];
         $sku = $item['sku'];
         $qty = $item['quantity'];
         $stock = $item['stock'] . ' x ';
         $title = $item['listing_title'];
         $post_id = $item['post_id'];
         $asin = $item['asin'];
         $status = $item['status'];
         $exists = $item['exists'];
         $date_ended = $item['date_finished'] ? $item['date_finished'] : $item['end_date'];
         // build links
         $amazon_url = $item['ViewItemURL'] ? $item['ViewItemURL'] : ($amazon_url = 'http://www.amazon.com/itm/' . $asin);
         $amazon_url = 'admin.php?page=wpla&s=' . $asin;
         $amazon_link = '<a href="' . $amazon_url . '" target="_blank">' . $asin . '</a>';
         $edit_link = '<a href="post.php?action=edit&post=' . ($item['parent_id'] ? $item['parent_id'] : $post_id) . '" target="_blank">' . $title . '</a>';
         // mark non existent products
         if (!$exists) {
             $stock = 'N/A';
             $post_id .= ' missing!';
         }
         // build table row
         $msg .= "<tr>";
         $msg .= "<td>{$stock}</td>";
         $msg .= "<td>{$sku}</td>";
         $msg .= "<td>{$edit_link} (ID {$post_id})</td>";
         $msg .= "<td>{$qty} x </td>";
         $msg .= "<td>{$amazon_link}</td>";
         $msg .= "<td>{$date_ended}</td>";
         $msg .= "<td>{$status}</td>";
         $msg .= "</tr>";
     }
     $msg .= '</table>';
     // show 'check again' button
     $msg .= '<p>';
     $url = 'admin.php?page=wpla-tools&action=check_wc_sold_stock&_wpnonce=' . wp_create_nonce('wpla_tools_page');
     $msg .= '<a href="' . $url . '" class="button">' . __('Check again', 'wpla') . '</a> &nbsp; ';
     $msg .= '</p>';
     // $msg .= '<p>';
     // $url = 'admin.php?page=wpla-tools&action=check_wc_out_of_stock&mark_as_changed=yes&_wpnonce='.wp_create_nonce('wpla_tools_page');
     // $msg .= '<a href="'.$url.'" class="button">'.__('Mark all as changed','wpla').'</a> &nbsp; ';
     // $msg .= 'Click this button to mark all found listings as changed in WP-Lister.';
     // $msg .= '</p>';
     WPLA()->showMessage($msg, 1, 1);
 }
 public function fixNewVariationListings($variations, $parent_listing)
 {
     WPLA()->logger->info("fixNewVariationListings()");
     $lm = new WPLA_ListingsModel();
     // get post_id of parent which has been created by now
     // $parent_listing = $lm->getItemByASIN( $parent_listing->asin );
     $parent_listing = $lm->getItemBySKU($parent_listing->sku);
     // catch Invalid argument error
     if (!is_array($variations)) {
         WPLA()->logger->error("no variations found for parent variable ASIN {$parent_listing->asin} (not checked)");
         WPLA()->logger->error("no variations found for parent variable SKU  {$parent_listing->sku}");
         WPLA()->logger->error('variations:' . print_r($variations, 1));
         // echo 'Error: no variations found for variable ASIN '.$parent_listing->asin.'<br>';
         // echo "<pre>variations: ";print_r($variations);echo"</pre>";#die();
         return;
     }
     foreach ($variations as $var) {
         $post_id = WPLA_ProductBuilder::getProductIdBySKU($var->sku);
         if (!$post_id) {
             WPLA()->logger->warn("fixing SKU {$var->sku} ... no product found for this SKU!!");
             continue;
         }
         $data = array('post_id' => $post_id, 'parent_id' => $parent_listing->post_id);
         $lm->updateListing($var->listing_id, $data);
         WPLA()->logger->info("fixed SKU {$var->sku} - post_id: {$post_id}");
     }
 }
 static function parseOrderColumn($column, $post_id)
 {
     $value = '';
     switch ($column) {
         case 'order-id':
             $value = get_post_meta($post_id, '_wpla_amazon_order_id', true);
             break;
         case 'ship-date':
             // $value = get_post_meta( $post_id, '_wpla_date_shipped', true );
             // $value .= ' 00:01:23'; // without this, amazon would use 07:00:00 UTC by default
             $date = get_post_meta($post_id, '_wpla_date_shipped', true);
             $time = get_post_meta($post_id, '_wpla_time_shipped', true);
             $dt = new DateTime('now', new DateTimeZone('UTC'));
             if (!$date) {
                 $date = $dt->format('Y-m-d');
                 // add current date in UTC
             }
             if (!$time) {
                 $time = $dt->format('H:i:s');
                 // add current time in UTC
                 // $time .= '+00:00' 	      // UTC (works as well as 'Z')
                 // $time .= 'Z'; 			  // Z stands for UTC timezone
             }
             $value = $date . ' ' . $time . 'Z';
             break;
         case 'carrier-code':
             $value = get_post_meta($post_id, '_wpla_tracking_provider', true);
             if (empty($value) && ($tracking = self::getThirdPartyPluginTrackingData($post_id))) {
                 $value = 'Other';
             }
             break;
         case 'carrier-name':
             $carrier = WPLA()->memcache->getColumnValue('shipfeed_oid_' . $post_id, 'carrier-code');
             $value = get_post_meta($post_id, '_wpla_tracking_service_name', true);
             if (empty($value) && ($tracking = self::getThirdPartyPluginTrackingData($post_id))) {
                 $value = $tracking->provider;
             }
             if (empty($value) && $carrier == 'Other') {
                 $value = get_option('wpla_default_shipping_service_name', '');
                 if (empty($value)) {
                     $value = 'N/A';
                 }
                 // we can't leave carrier-name empty if carrier-code is 'Other'
             }
             break;
         case 'tracking-number':
             $value = get_post_meta($post_id, '_wpla_tracking_number', true);
             if (empty($value) && ($tracking = self::getThirdPartyPluginTrackingData($post_id))) {
                 $value = $tracking->number;
             }
             break;
         default:
             # code...
             break;
     }
     return $value;
 }
 public function getProductImagesFilenames($id)
 {
     global $wpdb;
     $results = $wpdb->get_col("\n\t\t\tSELECT guid\n\t\t\tFROM {$wpdb->prefix}posts\n\t\t\tWHERE post_type = 'attachment'\n\t\t\t  AND post_parent = '{$id}'\n\t\t\t");
     WPLA()->logger->debug("getProductImagesFilenames( {$id} ) : " . print_r($results, 1));
     $filenames = array();
     foreach ($results as $row) {
         $filenames[] = basename($row);
     }
     return $filenames;
 }
 public function displayRepricingPage()
 {
     // handle actions and show notes
     // $this->handleActions();
     if ($this->requestAction() == 'wpla_apply_lowest_price_to_all_items') {
         $this->applyLowestPricesToAllItems();
     }
     if ($this->requestAction() == 'wpla_resubmit_pnq_update') {
         $this->resubmitPnqUpdateForSelectedItems();
     }
     if ($this->requestAction() == 'wpla_bulk_apply_lowest_prices') {
         $this->applyLowestPricesToSelectedItems();
     }
     if ($this->requestAction() == 'wpla_bulk_apply_minmax_prices') {
         $this->applyMinMaxPrices();
     }
     // handle bulk action - get_compet_price
     if ($this->requestAction() == 'get_compet_price') {
         WPLA()->pages['listings']->get_compet_price();
         WPLA()->pages['listings']->get_lowest_offers();
     }
     if ($this->requestAction() == 'wpla_resubmit_all_failed_prices') {
         $lm = new WPLA_ListingsModel();
         $items = $lm->getWhere('pnq_status', -1);
         foreach ($items as $item) {
             // set pnq status to changed (1)
             $lm->updateWhere(array('id' => $item->id), array('pnq_status' => 1));
         }
         $this->showMessage(sprintf(__('%s failed prices were scheduled for resubmission.', 'wpla'), count($items)));
     }
     // create table and fetch items to show
     $this->repricingTable = new WPLA_RepricingTable();
     $this->repricingTable->prepare_items();
     $active_tab = 'repricing';
     $aData = array('plugin_url' => self::$PLUGIN_URL, 'message' => $this->message, 'listingsTable' => $this->repricingTable, 'default_account' => get_option('wpla_default_account_id'), 'tools_url' => 'admin.php?page=' . self::ParentMenuId . '-tools', 'form_action' => 'admin.php?page=' . self::ParentMenuId . '-tools' . '&tab=' . $active_tab);
     $this->display('tools_repricing', $aData);
 }
Exemplo n.º 21
0
 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);
         }
     }
 }
Exemplo n.º 22
0
 public function clearLogfile()
 {
     file_put_contents(WPLA()->logger->file, '');
 }
 public function applyProfileToItem($profile, $item)
 {
     global $wpdb;
     // allow to pass a listing_id instead of item object
     if (!is_object($item)) {
         $item = $this->getItem($item, OBJECT);
     }
     // echo "<pre>";print_r($item);echo"</pre>";#die();
     // get item data
     $id = $item->id;
     $post_id = $item->post_id;
     $status = $item->status;
     $asin = $item->asin;
     // gather profile data
     $data = array();
     $data['profile_id'] = $profile->id;
     $data['account_id'] = $profile->account_id;
     // apply profile price
     $data['price'] = WPLA_ProductWrapper::getPrice($post_id);
     $data['price'] = $profile->processProfilePrice($data['price']);
     // update vtheme for child and parent variations
     if (in_array($item->product_type, array('variation', 'variable'))) {
         // $data['vtheme'] == $item->vtheme; ? // check for actual change
         // check profile for variation_theme
         $profile_fields = maybe_unserialize($profile->fields);
         if (is_array($profile_fields) && isset($profile_fields['variation_theme']) && !empty($profile_fields['variation_theme'])) {
             // use variation theme from profile
             $data['vtheme'] = $profile_fields['variation_theme'];
         } else {
             // update variation theme from product (parent variation)
             $parent_id = $item->parent_id ? $item->parent_id : $item->post_id;
             $data['vtheme'] = self::getVariationThemeForPostID($parent_id);
         }
     }
     // if variable product
     // default new status is 'changed'
     $data['status'] = 'changed';
     if ($status == 'failed') {
         $data['status'] = 'changed';
     }
     if ($status == 'online') {
         $data['status'] = 'changed';
     }
     // except for matched or imported products
     if ($status == 'matched') {
         $data['status'] = $status;
     }
     if ($status == 'imported') {
         $data['status'] = $status;
     }
     if ($status == 'prepared') {
         $data['status'] = $status;
     }
     // submitted items stay 'submitted' and archived items stay archived
     if ($status == 'submitted') {
         $data['status'] = $status;
     }
     if ($status == 'archived') {
         $data['status'] = $status;
     }
     if ($status == 'trash') {
         $data['status'] = $status;
     }
     if ($status == 'trashed') {
         $data['status'] = $status;
     }
     // debug
     if ($status != $data['status']) {
         WPLA()->logger->info('applyProfileToItem(' . $id . ') old status: ' . $status);
         WPLA()->logger->info('applyProfileToItem(' . $id . ') new status: ' . $data['status']);
     }
     // update auctions table
     $wpdb->update($this->tablename, $data, array('id' => $id));
     // WPLA()->logger->info('updating listing ID '.$id);
     // WPLA()->logger->info('data: '.print_r($data,1));
     // WPLA()->logger->info('sql: '.$wpdb->last_query);
     // WPLA()->logger->info('error: '.$wpdb->last_error);
 }
 static function findVariationID($parent_id, $VariationSpecifics)
 {
     $variations = self::getVariations($parent_id);
     foreach ($variations as $var) {
         $diffs = array_diff_assoc($var['variation_attributes'], $VariationSpecifics);
         if (count($diffs) == 0) {
             WPLA()->logger->info('findVariationID(' . $parent_id . ') found: ' . $var['post_id']);
             WPLA()->logger->info('VariationSpecifics: ' . print_r($VariationSpecifics, 1));
             return $var['post_id'];
         }
     }
     return false;
 }
Exemplo n.º 25
0
 function processFbaSubmissionOrderItem($order_item, $_order)
 {
     // Flat File FBA Shipment Injection Fulfillment Feed
     $feed_type = '_POST_FLAT_FILE_FULFILLMENT_ORDER_REQUEST_DATA_';
     // use account from first order item (for now)
     $lm = new WPLA_ListingsModel();
     $post_id = $order_item['variation_id'] ? $order_item['variation_id'] : $order_item['product_id'];
     $listing = $lm->getItemByPostID($post_id);
     $account_id = $listing->account_id;
     $account = new WPLA_AmazonAccount($account_id);
     WPLA()->logger->info('updateFbaSubmissionFeed() ' . $feed_type . ' - post id: ' . $post_id . ' - account id: ' . $account->id);
     // create pending feed if it doesn't exist
     if (!($this->id = self::getPendingFeedId($feed_type, null, $account->id))) {
         # build feed data
         WPLA()->logger->info('building FBA submission feed...');
         $csv = WPLA_FeedDataBuilder::buildFbaSubmissionFeedData($post_id, $_order, $order_item, $listing, $account->id, true);
         if (!$csv) {
             WPLA()->logger->warn('no feed data - not creating feed');
             return;
         }
         // add new feed
         $this->FeedType = $feed_type;
         $this->status = 'pending';
         $this->account_id = $account->id;
         $this->date_created = date('Y-m-d H:i:s');
         $this->data = $csv;
         $this->add();
         WPLA()->logger->info('added NEW feed - id ' . $this->id);
     } else {
         WPLA()->logger->info('found existing feed ' . $this->id);
         $existing_feed = new WPLA_AmazonFeed($this->id);
         # append feed data
         WPLA()->logger->info('updating FBA submission feed...');
         $csv = WPLA_FeedDataBuilder::buildFbaSubmissionFeedData($post_id, $_order, $order_item, $listing, $account->id, false);
         $this->data = $existing_feed->data . $csv;
     }
     // update feed
     $this->line_count = sizeof($csv);
     $this->FeedProcessingStatus = 'pending';
     $this->date_created = date('Y-m-d H:i:s');
     $this->update();
     WPLA()->logger->info('feed was built and updated - ' . $this->id);
 }
 protected function handleFbaCronSettings($schedule)
 {
     WPLA()->logger->info("handleFbaCronSettings( {$schedule} )");
     // remove scheduled event
     $timestamp = wp_next_scheduled('wpla_fba_report_schedule');
     wp_unschedule_event($timestamp, 'wpla_fba_report_schedule');
     if (!wp_next_scheduled('wpla_fba_report_schedule')) {
         wp_schedule_event(time(), $schedule, 'wpla_fba_report_schedule');
     }
 }
 public static function adjustLowestPriceForProducts($items = false, $verbose = false)
 {
     $items = $items ? $items : WPLA_ListingQueryHelper::getItemsWithMinMaxAndLowestPrice();
     $changed_product_ids = array();
     $repricing_margin = floatval(get_option('wpla_repricing_margin'));
     $lowest_offer_mode = get_option('wpla_repricing_use_lowest_offer', 0);
     // loop found listings
     foreach ($items as $item) {
         // make sure there is a product - and min/max prices are set (0 != NULL)
         if (!$item->post_id) {
             continue;
         }
         if (!$item->min_price) {
             continue;
         }
         if (!$item->max_price) {
             continue;
         }
         if (!$item->buybox_price && !$item->compet_price) {
             continue;
         }
         // build target price from BuyBox and/or competitor price
         if ($item->buybox_price && !$item->has_buybox) {
             // apply undercut to BuyBox price - if there is a BuyBox price and it's not the seller's
             $target_price = $item->buybox_price - $repricing_margin;
             if ($verbose) {
                 wpla_show_message($item->sku . ': Other seller has BuyBox at ' . $item->buybox_price . ' - your target price: ' . $target_price);
             }
         } elseif ($item->buybox_price && $item->has_buybox && $item->compet_price) {
             // decide based on uppricing mode
             if ($lowest_offer_mode && $item->buybox_price != $item->compet_price) {
                 // seller has BuyBox and there is competition - apply undercut to competitor price (beta)
                 $target_price = $item->compet_price - $repricing_margin;
                 if ($verbose) {
                     wpla_show_message($item->sku . ': You have the BuyBox, but there is a competitor at ' . $item->compet_price . ' - new target price: ' . $target_price);
                 }
             } else {
                 // seller has BuyBox and there is competition - keep price for now
                 $target_price = $item->buybox_price;
                 if ($verbose) {
                     wpla_show_message($item->sku . ': You have the BuyBox - keeping current price: ' . $target_price);
                 }
             }
         } elseif ($item->buybox_price && $item->has_buybox && !$item->compet_price) {
             // seller has BuyBox and NO competition - fall back to max_price
             $target_price = $item->max_price;
             if ($verbose) {
                 wpla_show_message($item->sku . ': You have the BuyBox but there is no competitor - falling back to Max Price: ' . $target_price);
             }
         } elseif ($item->compet_price) {
             $target_price = $item->compet_price;
             if ($verbose) {
                 wpla_show_message($item->sku . ': No BuyBox price - falling back to next competitor: ' . $target_price);
             }
         } else {
             $target_price = $item->max_price;
             if ($verbose) {
                 wpla_show_message($item->sku . ': No BuyBox price, no competitor - falling back to Max Price: ' . $target_price);
             }
         }
         $target_price = round($target_price, 2);
         // update price
         $price_was_changed = self::updateAmazonPrice($item, $target_price, $verbose);
         if ($price_was_changed) {
             $changed_product_ids[] = $item->post_id;
             WPLA()->logger->info('adjustLowestPriceForProducts() - new price for #' . $item->sku . ': ' . $target_price);
         }
     }
     // foreach item
     // echo "<pre>";print_r($changed_product_ids);echo"</pre>";#die();
     // echo "<pre>";print_r($items);echo"</pre>";die();
     return $changed_product_ids;
 }