Esempio n. 1
0
 public function getShortProductVariations($post_id)
 {
     // update cache if required
     if (!array_key_exists($post_id, $this->short_variations)) {
         $this->short_variations[$post_id] = ProductWrapper::getVariations($post_id, true);
     }
     return $this->short_variations[$post_id];
 }
Esempio n. 2
0
 function getVariationsHTML($item)
 {
     $profile_data = ListingsModel::decodeObject($item['profile_data'], true);
     $variations = ProductWrapper::getVariations($item['post_id']);
     $variations_html = '<div class="variations_list" style="margin:10px 0;">';
     $variations_html .= '<table style="margin-bottom: 8px;">';
     //table header
     if (true) {
         // first column: quantity
         $variations_html .= '<tr>';
         $first_variation = reset($variations);
         if (is_array($first_variation['variation_attributes'])) {
             foreach ($first_variation['variation_attributes'] as $name => $value) {
                 $variations_html .= '<th>';
                 $variations_html .= $name;
                 $variations_html .= '</th>';
             }
         }
         // last column: price
         $variations_html .= '<th align="right">';
         $variations_html .= __('Price', 'wplister');
         $variations_html .= '</th></tr>';
     }
     //table body
     foreach ($variations as $var) {
         // first column: quantity
         // $variations_html .= '<tr><td align="right">';
         // $variations_html .= intval( $var['stock'] ) . '&nbsp;x';
         // $variations_html .= '</td><td>';
         $variations_html .= '<tr>';
         foreach ($var['variation_attributes'] as $name => $value) {
             // $variations_html .= $name.': '.$value ;
             $variations_html .= '<td>';
             $variations_html .= $value;
             $variations_html .= '</td>';
         }
         // $variations_html .= '('.$var['sku'].') ';
         // $variations_html .= '('.$var['image'].') ';
         // last column: price
         $variations_html .= '<td align="right">';
         $price = ListingsModel::applyProfilePrice($var['price'], $profile_data['details']['start_price']);
         $variations_html .= number_format_i18n(floatval($price), 2);
         $variations_html .= '</td></tr>';
     }
     $variations_html .= '</table>';
     $variations_html .= '</div>';
     // return html
     return $variations_html;
 }
Esempio n. 3
0
 public function applyProfileToItem($profile, $item, $update_title = true)
 {
     global $wpdb;
     // get item data
     $id = $item['id'];
     $post_id = $item['post_id'];
     $status = WPLE_ListingQueryHelper::getStatus($id);
     $ebay_id = self::getEbayIDFromID($id);
     $post_title = get_the_title($item['post_id']);
     WPLE()->logger->info("applyProfileToItem() - listing_id: {$id} / post_id: {$post_id}");
     // WPLE()->logger->callStack( debug_backtrace() );
     // skip ended auctions - or not, if you want to relist them...
     // if ( $status == 'ended' ) return;
     // use parent title for single (split) variation
     if (ProductWrapper::isSingleVariation($post_id)) {
         $parent_id = ProductWrapper::getVariationParent($post_id);
         $post_title = get_the_title($parent_id);
         // check if parent product has a custom eBay title set
         if (get_post_meta($parent_id, '_ebay_title', true)) {
             $post_title = trim(get_post_meta($parent_id, '_ebay_title', true));
         }
         // get variations
         $variations = ProductWrapper::getVariations($parent_id);
         // find this variation in all variations of this parent
         foreach ($variations as $var) {
             if ($var['post_id'] == $post_id) {
                 // append attribute values to title
                 $post_title = self::processSingleVariationTitle($post_title, $var['variation_attributes']);
             }
         }
     }
     // gather profile data
     $data = array();
     $data['profile_id'] = $profile['profile_id'];
     $data['account_id'] = $profile['account_id'];
     $data['site_id'] = $profile['site_id'];
     $data['auction_type'] = $profile['type'];
     $data['listing_duration'] = $profile['listing_duration'];
     $data['template'] = $profile['details']['template'];
     $data['quantity'] = $profile['details']['quantity'];
     $data['date_created'] = date('Y-m-d H:i:s');
     $data['profile_data'] = self::encodeObject($profile);
     // echo "<pre>";print_r($data);echo"</pre>";die();
     // add prefix and suffix to product title
     if ($update_title) {
         // append space to prefix, prepend space to suffix
         // TODO: make this an option
         $title_prefix = trim($profile['details']['title_prefix']) . ' ';
         $title_suffix = ' ' . trim($profile['details']['title_suffix']);
         // custom post meta fields override profile values
         if (get_post_meta($post_id, 'ebay_title_prefix', true)) {
             $title_prefix = trim(get_post_meta($post_id, 'ebay_title_prefix', true)) . ' ';
         }
         if (get_post_meta($post_id, 'ebay_title_suffix', true)) {
             $title_prefix = trim(get_post_meta($post_id, 'ebay_title_suffix', true)) . ' ';
         }
         $data['auction_title'] = trim($title_prefix . $post_title . $title_suffix);
         // custom post meta title override
         if (get_post_meta($post_id, '_ebay_title', true)) {
             $data['auction_title'] = trim(get_post_meta($post_id, '_ebay_title', true));
         } elseif (get_post_meta($post_id, 'ebay_title', true)) {
             $data['auction_title'] = trim(get_post_meta($post_id, 'ebay_title', true));
         }
         // process attribute shortcodes in title - like [[attribute_Brand]]
         if (strpos($data['auction_title'], ']]') > 0) {
             $templatesModel = new TemplatesModel();
             WPLE()->logger->info('auction_title before processing: ' . $data['auction_title'] . '');
             $data['auction_title'] = $templatesModel->processAllTextShortcodes($item['post_id'], $data['auction_title'], 80);
         }
         WPLE()->logger->info('auction_title after processing : ' . $data['auction_title'] . '');
         // trim title to 255 characters - longer titles will break $wpdb->update()
         if (strlen($data['auction_title']) > 255) {
             $data['auction_title'] = self::mb_substr($data['auction_title'], 0, 80);
             // eBay titles can not be longer than 80 characters
         }
     }
     // apply profile price
     $data['price'] = ProductWrapper::getPrice($post_id);
     $data['price'] = self::applyProfilePrice($data['price'], $profile['details']['start_price']);
     // fetch product stock if no quantity set in profile - and apply max_quantity limit
     if (intval($data['quantity']) == 0) {
         $max = isset($profile['details']['max_quantity']) && intval($profile['details']['max_quantity']) > 0 ? $profile['details']['max_quantity'] : PHP_INT_MAX;
         $data['quantity'] = min($max, intval(ProductWrapper::getStock($post_id)));
         // update listing quantity properly - using setListingQuantity() which regards current quantity_sold
         self::setListingQuantity($post_id, $data['quantity']);
         unset($data['quantity']);
     }
     // default new status is 'prepared'
     $data['status'] = 'prepared';
     // except for already published items where it is 'changed'
     if (intval($ebay_id) > 0) {
         $data['status'] = 'changed';
     }
     // ended items stay 'ended' and sold items stay sold
     if ($status == 'ended') {
         $data['status'] = 'ended';
     }
     if ($status == 'sold') {
         $data['status'] = 'sold';
     }
     if ($status == 'archived') {
         $data['status'] = 'archived';
     }
     // locked items simply keep their status
     if (@$item['locked']) {
         $data['status'] = $status;
     }
     // but if apply_changes_to_all_locked checkbox is ticked, even locked published items will be marked as 'changed'
     if (@$item['locked'] && $status == 'published' && isset($_POST['wpl_e2e_apply_changes_to_all_locked'])) {
         $data['status'] = 'changed';
     }
     // except for selected items which shouldn't be locked in the first place
     if ($status == 'selected') {
         $data['status'] = 'prepared';
     }
     // and reselected items which have already been 'ended'
     if ($status == 'reselected') {
         $data['status'] = 'ended';
     }
     // and items which have already been 'changed' and now had a new profile applied
     if ($status == 'changed_profile') {
         $data['status'] = 'changed';
     }
     // debug
     if ($status != $data['status']) {
         WPLE()->logger->info('applyProfileToItem(' . $id . ') old status: ' . $status);
         WPLE()->logger->info('applyProfileToItem(' . $id . ') new status: ' . $data['status']);
     }
     // update auctions table
     $wpdb->update($this->tablename, $data, array('id' => $id));
     // WPLE()->logger->info('updating listing ID '.$id);
     // WPLE()->logger->info('data: '.print_r($data,1));
     // WPLE()->logger->info('sql: '.$wpdb->last_query);
     // WPLE()->logger->info('error: '.$wpdb->last_error);
 }
Esempio n. 4
0
 public function checkProductInventory($mode = 'published', $compare_prices = false, $step = 0)
 {
     $batch_size = get_option('wplister_inventory_check_batch_size', 200);
     $limit = $batch_size;
     $offset = $batch_size * $step;
     // get listings - or return false
     $lm = new ListingsModel();
     $listings = $mode == 'published' ? WPLE_ListingQueryHelper::getAllPublished($limit, $offset) : WPLE_ListingQueryHelper::getAllEnded($limit, $offset);
     if (empty($listings)) {
         return false;
     }
     // restore previous data
     $tmp_result = get_option('wple_inventory_check_queue_data', false);
     if ($tmp_result) {
         $out_of_sync_products = $tmp_result['out_of_sync_products'];
         $published_count = $tmp_result['published_count'];
     } else {
         $out_of_sync_products = array();
         $published_count = 0;
     }
     // process published listings
     foreach ($listings as $item) {
         // check wc product
         $post_id = $item['post_id'];
         $_product = ProductWrapper::getProduct($post_id);
         // echo "<pre>";print_r($_product);echo"</pre>";die();
         // get stock level and price
         $stock = ProductWrapper::getStock($item['post_id']);
         $price = ProductWrapper::getPrice($item['post_id']);
         // $item['price_max'] = $price;
         // echo "<pre>";print_r($price);echo"</pre>";#die();
         // echo "<pre>";print_r($item);echo"</pre>";die();
         // apply profile settings to stock level
         $profile_data = ListingsModel::decodeObject($item['profile_data'], true);
         $profile_details = $profile_data['details'];
         $item['qty'] = $item['quantity'] - $item['quantity_sold'];
         // echo "<pre>";print_r($profile_details);echo"</pre>";#die();
         // apply max_quantity from profile
         $max_quantity = isset($profile_details['max_quantity']) && intval($profile_details['max_quantity']) > 0 ? $profile_details['max_quantity'] : false;
         if ($max_quantity) {
             $stock = min($max_quantity, intval($stock));
         }
         // apply price modified from profile
         $profile_start_price = isset($profile_details['start_price']) && !empty($profile_details['start_price']) ? $profile_details['start_price'] : false;
         if ($profile_start_price) {
             // echo "<pre>price: ";print_r($profile_start_price);echo"</pre>";#die();
         }
         // check if product has variations
         if ($_product) {
             $variations = $_product->product_type == 'variable' ? ProductWrapper::getVariations($item['post_id']) : array();
         } else {
             $variations = array();
         }
         // get total stock for all variations
         if (!empty($variations)) {
             // reset prices and stock
             $stock = 0;
             $price_min = PHP_INT_MAX;
             $price_max = 0;
             $ebay_stock = 0;
             $ebay_price_min = PHP_INT_MAX;
             $ebay_price_max = 0;
             // check WooCommerce variations
             foreach ($variations as $var) {
                 // total stock
                 if ($max_quantity) {
                     $stock += min($max_quantity, intval($var['stock']));
                 } else {
                     $stock += $var['stock'];
                 }
                 // min / max prices
                 $price_min = min($price_min, $var['price']);
                 $price_max = max($price_max, $var['price']);
             }
             // check eBay variations
             $cached_variations = maybe_unserialize($item['variations']);
             if (is_array($cached_variations)) {
                 foreach ($cached_variations as $var) {
                     $ebay_stock += $var['stock'];
                     $ebay_price_min = min($ebay_price_min, $var['price']);
                     $ebay_price_max = max($ebay_price_max, $var['price']);
                 }
             }
             // set default values
             $item['qty'] = $ebay_stock;
             $item['price'] = $ebay_price_min != PHP_INT_MAX ? $ebay_price_min : 0;
             $item['price_max'] = $ebay_price_max;
             // echo "<pre>";print_r($cached_variations);echo"</pre>";die();
         } else {
             $price_min = false;
             $price_max = false;
             $ebay_price_min = false;
             $ebay_price_max = false;
         }
         // check if product and ebay listing are in sync
         $in_sync = true;
         // check stock level
         if ($stock != $item['qty']) {
             $in_sync = false;
         }
         // check price
         if ($compare_prices) {
             $price_to_compare = $price;
             if ($profile_start_price) {
                 $price_to_compare = ListingsModel::applyProfilePrice($price, $profile_start_price);
             }
             if (round($price_to_compare, 2) != round($item['price'], 2)) {
                 $in_sync = false;
             }
             // check max price
             if (isset($price_max) && isset($item['price_max']) && round($price_max, 2) != round($item['price_max'], 2)) {
                 $in_sync = false;
             }
         }
         // if in sync, continue with next item
         if ($in_sync) {
             continue;
         }
         // mark listing as changed
         if (isset($_REQUEST['mark_as_changed']) && $_REQUEST['mark_as_changed'] == 'yes') {
             if ($_product) {
                 // only existing products can have a profile re-applied
                 $lm->markItemAsModified($item['post_id']);
             }
             // in case the product is locked or missing, force the listing to be changed
             ListingsModel::updateListing($item['id'], array('status' => 'changed'));
             $item['status'] = 'changed';
         }
         // remove unneccessary data to consume less memory - doesn't seem to work...
         // unset( $item['profile_data'] );
         // unset( $item['post_content'] );
         // unset( $item['details'] );
         // unset( $item['variations'] );
         // unset( $item['last_errors'] );
         // unset( $item['history'] );
         // unset( $item['eps'] );
         // unset( $item['template'] );
         // add to list of out of sync products
         $item['price_woo'] = $price;
         $item['price_woo_max'] = isset($price_max) ? $price_max : false;
         $item['stock'] = $stock;
         $item['exists'] = $_product ? true : false;
         $item['type'] = $_product ? $_product->product_type : 'missing';
         $item['profile_start_price'] = $profile_start_price;
         $out_of_sync_products[] = $item;
         // count products which have not yet been marked as changed
         if ($item['status'] == 'published') {
             $published_count += 1;
         }
     }
     // store result so far
     $tmp_result = array('mode' => $mode, 'compare_prices' => $compare_prices, 'out_of_sync_products' => $out_of_sync_products, 'published_count' => $published_count);
     update_option('wple_inventory_check_queue_data', $tmp_result, 'no');
     // true means we processed more items
     return true;
 }
Esempio n. 5
0
 public function flattenVariations($id, $item, $post_id, $profile_details)
 {
     WPLE()->logger->info("flattenVariations({$id})");
     // get product variations
     // $p = ListingsModel::getItem( $id );
     $variations = ProductWrapper::getVariations($post_id);
     $this->variationAttributes = array();
     $total_stock = 0;
     // find default variation
     $default_variation = reset($variations);
     foreach ($variations as $var) {
         // find default variation
         if ($var['is_default']) {
             $default_variation = $var;
         }
         // build array of variation attributes, which will be needed in builtItemSpecifics()
         foreach ($var['variation_attributes'] as $name => $value) {
             $this->variationAttributes[] = $name;
         }
         // count total stock
         $total_stock += $var['stock'];
     }
     // list accumulated stock quantity if not set in profile
     if (!$item->Quantity) {
         $item->Quantity = $total_stock;
     }
     // fetch default variations start price
     if (intval($item->StartPrice->value) == 0) {
         $start_price = $default_variation['price'];
         $start_price = ListingsModel::applyProfilePrice($start_price, $profile_details['start_price']);
         $item->StartPrice->setTypeValue(self::dbSafeFloatval($start_price));
         WPLE()->logger->info("using default variations price: " . print_r($item->StartPrice->value, 1));
     }
     // ebay doesn't allow different weight and dimensions for varations
     // so for calculated shipping services we just fetch those from the default variation
     // and overwrite
     // $isCalc = $profile_details['shipping_service_type'] == 'calc' ? true : false;
     $service_type = $profile_details['shipping_service_type'];
     $isCalc = in_array($service_type, array('calc', 'FlatDomesticCalculatedInternational', 'CalculatedDomesticFlatInternational')) ? true : false;
     $hasWeight = in_array($service_type, array('calc', 'FreightFlat', 'FlatDomesticCalculatedInternational', 'CalculatedDomesticFlatInternational')) ? true : false;
     if ($isCalc) {
         // get weight and dimensions from default variation
         $weight_major = $default_variation['weight_major'];
         $weight_minor = $default_variation['weight_minor'];
         $dimensions = $default_variation['dimensions'];
         $item->ShippingDetails->CalculatedShippingRate->setWeightMajor(self::dbSafeFloatval($weight_major));
         $item->ShippingDetails->CalculatedShippingRate->setWeightMinor(self::dbSafeFloatval($weight_minor));
         if (trim(@$dimensions['width']) != '') {
             $item->ShippingDetails->CalculatedShippingRate->setPackageWidth($dimensions['width']);
         }
         if (trim(@$dimensions['length']) != '') {
             $item->ShippingDetails->CalculatedShippingRate->setPackageLength($dimensions['length']);
         }
         if (trim(@$dimensions['height']) != '') {
             $item->ShippingDetails->CalculatedShippingRate->setPackageDepth($dimensions['height']);
         }
         // debug
         WPLE()->logger->info('default variations weight: ' . print_r($weight, 1));
         WPLE()->logger->info('default variations dimensions: ' . print_r($dimensions, 1));
     }
     // set ShippingPackageDetails
     if ($hasWeight) {
         // get weight and dimensions from default variation
         $weight_major = $default_variation['weight_major'];
         $weight_minor = $default_variation['weight_minor'];
         $dimensions = $default_variation['dimensions'];
         $shippingPackageDetails = new ShipPackageDetailsType();
         $shippingPackageDetails->setWeightMajor(self::dbSafeFloatval($weight_major));
         $shippingPackageDetails->setWeightMinor(self::dbSafeFloatval($weight_minor));
         if (trim(@$dimensions['width']) != '') {
             $shippingPackageDetails->setPackageWidth($dimensions['width']);
         }
         if (trim(@$dimensions['length']) != '') {
             $shippingPackageDetails->setPackageLength($dimensions['length']);
         }
         if (trim(@$dimensions['height']) != '') {
             $shippingPackageDetails->setPackageDepth($dimensions['height']);
         }
         $item->setShippingPackageDetails($shippingPackageDetails);
     }
     return $item;
 }