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 parseVariationChildNodes($product_node, $parent_listing, $account)
 {
     WPLA()->logger->info("parseVariationChildNodes()");
     if (!isset($product_node->Relationships->VariationChild)) {
         return $product_node;
     }
     // if ( ! is_array( $product_node->Relationships->VariationChild ) ) return $product_node;
     // if only a single variation is returned, convert VariationChild node to array
     if (is_object($product_node->Relationships->VariationChild)) {
         $product_node->Relationships->VariationChild = array($product_node->Relationships->VariationChild);
     }
     // count number of attributes
     $number_of_attributes = self::countVariationChildNodes($product_node);
     // loop variations
     $lm = new WPLA_ListingsModel();
     $variations = array();
     foreach ($product_node->Relationships->VariationChild as $VariationChild) {
         // build simple variation object
         $newvar = new stdClass();
         $newvar->asin = $VariationChild->Identifiers->MarketplaceASIN->ASIN;
         $newvar->sku = $VariationChild->Identifiers->MarketplaceASIN->ASIN;
         unset($VariationChild->Identifiers);
         $newvar->vtheme = array();
         $newvar->attributes = array();
         $newvar->attribute_values = array();
         foreach ($VariationChild as $attribute_name => $attribute_value) {
             $attrib = new stdClass();
             $attrib->name = $attribute_name;
             $attrib->value = $attribute_value;
             $newvar->attributes[] = $attrib;
             $newvar->vtheme[] = $attribute_name;
             $newvar->attribute_values[] = $attribute_value;
         }
         $newvar->vtheme = join('-', $newvar->vtheme);
         // skip variations with missing attributes
         if (sizeof($newvar->attributes) < $number_of_attributes) {
             WPLA()->logger->info("skipped variation {$newvar->asin} because it has less than the required number of attributes: " . $number_of_attributes);
             continue;
         }
         // check if this variation exist in listing table
         // (using getItemByASIN() does no harm here - parseVariationChildNodes() is only called when no SKU was found)
         if ($var_item = $lm->getItemByASIN($newvar->asin)) {
             // use SKU, price and quantity from listing (usually imported from report)
             $newvar->sku = $var_item->sku;
             $newvar->qty = $var_item->quantity;
             $newvar->price = $var_item->price;
             $newvar->variation_image = '';
             WPLA()->logger->info("Found existing variation child for ASIN {$newvar->asin} - id: " . $var_item->id);
             // convert items from report to real variation listing
             $data = array();
             $data['post_id'] = '';
             // filled in after creating the product
             $data['parent_id'] = $parent_listing->post_id;
             $data['vtheme'] = $newvar->vtheme;
             $data['product_type'] = 'variation';
             $data['date_created'] = date('Y-m-d H:i:s', time());
             // this is to fix the sort order only
             $data['status'] = $var_item->source == 'foreign_import' ? 'matched' : 'online';
             $lm->updateListing($var_item->id, $data);
             $newvar->listing_id = $var_item->id;
             // TODO: variation image
             // $var_item->attributes = maybe_unserialize( $var_item->attributes )
             // $newvar->variation_image = $var_item->attributes-> ... ->URL; // ?
         } else {
             // variation (ASIN) does not exist in listings table - which means it does not exist in the inventory report / ASIN list
             // unless "create all variations" is enabled, skip this variation
             if (get_option('wpla_import_creates_all_variations') != 1) {
                 WPLA()->logger->info("SKIPPED foreign variation - ASIN {$newvar->asin}");
                 continue;
             }
             $newvar->qty = '';
             $newvar->price = '';
             $newvar->variation_image = '';
             $id = $this->insertVariationListing($newvar, $product_node, $parent_listing, $account);
             WPLA()->logger->info("Created new variation child for ASIN {$newvar->asin} - id: {$id}");
             $newvar->listing_id = $id;
         }
         // fetch variation details from Amazon - set variation_image
         if (get_option('wpla_enable_variation_image_import', 1)) {
             $variation_image = $this->getVariationImageForASIN($newvar->asin, $account->id);
             $newvar->variation_image = $variation_image;
         }
         $variations[] = $newvar;
     }
     // add vtheme to parent listing
     $lm->updateListing($parent_listing->id, array('vtheme' => $newvar->vtheme));
     // echo "<pre>";print_r($variations);echo"</pre>";die();
     $product_node->variations = $variations;
     return $product_node;
 }