Пример #1
0
 public function screen()
 {
     if (!current_user_can('shopp_promotions')) {
         wp_die(__('You do not have sufficient permissions to access this page.'));
     }
     $table = ShoppDatabaseObject::tablename(ShoppPromo::$table);
     $defaults = array('page' => false, 'status' => false, 'type' => false, 'paged' => 1, 'per_page' => 20, 's' => '');
     $args = array_merge($defaults, $_GET);
     extract($args, EXTR_SKIP);
     $url = add_query_arg(array_merge($_GET, array('page' => $this->page)), admin_url('admin.php'));
     $f = array('action', 'selected', 's');
     $url = remove_query_arg($f, $url);
     $pagenum = absint($paged);
     $start = $per_page * ($pagenum - 1);
     $where = array();
     if (!empty($s)) {
         $where[] = "name LIKE '%{$s}%'";
     }
     if ($status) {
         $datesql = ShoppPromo::activedates();
         switch (strtolower($status)) {
             case 'active':
                 $where[] = "status='enabled' AND {$datesql}";
                 break;
             case 'inactive':
                 $where[] = "status='enabled' AND NOT {$datesql}";
                 break;
             case 'enabled':
                 $where[] = "status='enabled'";
                 break;
             case 'disabled':
                 $where[] = "status='disabled'";
                 break;
         }
     }
     if ($type) {
         switch (strtolower($type)) {
             case 'catalog':
                 $where[] = "target='Catalog'";
                 break;
             case 'cart':
                 $where[] = "target='Cart'";
                 break;
             case 'cartitem':
                 $where[] = "target='Cart Item'";
                 break;
         }
     }
     $select = sDB::select(array('table' => $table, 'columns' => 'SQL_CALC_FOUND_ROWS *', 'where' => $where, 'orderby' => 'created DESC', 'limit' => "{$start},{$per_page}"));
     $Promotions = sDB::query($select, 'array');
     $count = sDB::found();
     $num_pages = ceil($count / $per_page);
     $ListTable = ShoppUI::table_set_pagination($this->id, $count, $num_pages, $per_page);
     $states = array('active' => __('Active', 'Shopp'), 'inactive' => __('Not Active', 'Shopp'), 'enabled' => __('Enabled', 'Shopp'), 'disabled' => __('Disabled', 'Shopp'));
     $types = array('catalog' => __('Catalog Discounts', 'Shopp'), 'cart' => __('Cart Discounts', 'Shopp'), 'cartitem' => __('Cart Item Discounts', 'Shopp'));
     $num_pages = ceil($count / $per_page);
     $page_links = paginate_links(array('base' => add_query_arg('pagenum', '%#%'), 'format' => '', 'total' => $num_pages, 'current' => $pagenum));
     include $this->ui('discounts.php');
 }
Пример #2
0
 protected function save()
 {
     if (empty($_POST['save'])) {
         return;
     }
     check_admin_referer('shopp-save-discount');
     if ('new' !== $_POST['id']) {
         $Promotion = new ShoppPromo($_POST['id']);
         $wascatalog = 'Catalog' == $Promotion->target;
     } else {
         $Promotion = new ShoppPromo();
     }
     if (!empty($_POST['starts']['month']) && !empty($_POST['starts']['date']) && !empty($_POST['starts']['year'])) {
         $_POST['starts'] = mktime(0, 0, 0, $_POST['starts']['month'], $_POST['starts']['date'], $_POST['starts']['year']);
     } else {
         $_POST['starts'] = 1;
     }
     if (!empty($_POST['ends']['month']) && !empty($_POST['ends']['date']) && !empty($_POST['ends']['year'])) {
         $_POST['ends'] = mktime(23, 59, 59, $_POST['ends']['month'], $_POST['ends']['date'], $_POST['ends']['year']);
     } else {
         $_POST['ends'] = 1;
     }
     if (isset($_POST['rules'])) {
         $_POST['rules'] = stripslashes_deep($_POST['rules']);
         foreach ($_POST['rules'] as &$rule) {
             if ('promo code' == strtolower($rule['property'])) {
                 $rule['value'] = trim($rule['value']);
             }
             if (false !== stripos($rule['property'], 'country') && 'USA' == $rule['value']) {
                 $rule['value'] = 'US';
             }
             // country-based rules must use 2-character ISO code, see #3129
         }
     }
     $Promotion->updates($_POST);
     $Promotion->save();
     do_action_ref_array('shopp_promo_saved', array(&$Promotion));
     // Apply catalog promotion discounts to catalog product price lines
     if ('Catalog' == $Promotion->target) {
         $Promotion->catalog();
     } elseif ($wascatalog) {
         // Unapply catalog discounts for discounts that no longer target catalog products
         $priceids = ShoppPromo::discounted_prices(array($Promotion->id));
         $Promotion->uncatalog($priceids);
     }
     // Set confirmation notice
     $this->notice(Shopp::__('Promotion has been updated!'));
     // Stay in the editor
     $url = add_query_arg('id', $Promotion->id, $this->url);
     wp_redirect($url);
     exit;
 }
Пример #3
0
 /**
  * Set or load the discounts applied to this order
  *
  * @author Jonathan Davis
  * @since 1.3
  *
  * @param ShoppDiscounts $ShoppDiscounts The ShoppDiscounts object from the order to add to this purchase
  * @return array List of discounts applied
  **/
 public function discounts(ShoppDiscounts $ShoppDiscounts = null)
 {
     if (empty($this->id)) {
         return false;
     }
     if (isset($ShoppDiscounts)) {
         // Save the given discounts
         $discounts = array();
         foreach ($ShoppDiscounts as $Discount) {
             $discounts[$Discount->id()] = new ShoppPurchaseDiscount($Discount);
         }
         shopp_set_meta($this->id, 'purchase', 'discounts', $discounts);
         $this->discounts = $discounts;
         ShoppPromo::used(array_keys($discounts));
     }
     if (empty($this->discounts)) {
         $this->discounts = shopp_meta($this->id, 'purchase', 'discounts');
     }
     return $this->discounts;
 }
Пример #4
0
 /**
  * Match a rule to the item
  *
  * @author Jonathan Davis
  * @since 1.1
  *
  * @param array $rule A structured rule array
  * @return boolean
  **/
 public function match($rule)
 {
     extract($rule);
     switch ($property) {
         case 'Any item name':
             $subject = $this->name;
             break;
         case 'Any item quantity':
             $subject = (int) $this->quantity;
             break;
         case 'Any item amount':
             $subject = $this->total;
             break;
         case 'Name':
             $subject = $this->name;
             break;
         case 'Category':
             $subject = $this->categories;
             break;
         case 'Tag name':
             $subject = $this->tags;
             break;
         case 'Variation':
             $subject = $this->option->label;
             break;
         case 'Input name':
             foreach ($this->data as $inputName => $inputValue) {
                 if (ShoppPromo::match_rule($inputName, $logic, $value, $property)) {
                     return true;
                 }
             }
             return false;
         case 'Input value':
             foreach ($this->data as $inputName => $inputValue) {
                 if (ShoppPromo::match_rule($inputValue, $logic, $value, $property)) {
                     return true;
                 }
             }
             return false;
         case 'Quantity':
             $subject = $this->quantity;
             break;
         case 'Unit price':
             $subject = $this->unitprice;
             break;
         case 'Total price':
             $subject = $this->total;
             break;
         case 'Discount amount':
             $subject = $this->discount;
             break;
     }
     return ShoppPromo::match_rule($subject, $logic, $value, $property);
 }
Пример #5
0
 /**
  * Aggregates product pricing information
  *
  * @author Jonathan Davis
  * @since 1.1
  *
  * @param array $options shopp() tag option list
  * @return void
  **/
 public function pricing(&$records, &$price, $restat = false)
 {
     if (isset($this->products) && !empty($this->products)) {
         if (!isset($this->products[$price->product])) {
             return false;
         }
         if (!isset($this->_last_product)) {
             $this->_last_product = false;
         }
         if ($this->_last_product != false && $this->_last_product != $price->product && isset($this->products[$this->_last_product])) {
             $this->products[$this->_last_product]->sumup();
         }
         if ($this->_last_product != $price->product) {
             $this->products[$price->product]->resum();
         }
         $target =& $this->products[$price->product];
         $this->_last_product = $price->product;
     } else {
         $target =& $this;
     }
     // Skip calulating variant pricing when variants are not enabled for the product
     if (!(isset($target->variants) && Shopp::str_true($target->variants)) && 'variation' == $price->context) {
         return;
     }
     $target->prices[] = $price;
     // Force to floats
     $price->price = (double) $price->price;
     $price->saleprice = (double) $price->saleprice;
     $price->shipfee = (double) $price->shipfee;
     $price->promoprice = (double) Shopp::str_true($price->sale) ? $price->saleprice : $price->price;
     // Build secondary lookup table using the price id as the key
     $target->priceid[$price->id] = $price;
     // Set promoprice before data aggregation
     if (Shopp::str_true($price->sale)) {
         $price->promoprice = $price->saleprice;
     }
     // Do not count disabled price lines or addon price lines in aggregate summary stats
     if ('N/A' == $price->type || 'addon' == $price->context) {
         return;
     }
     // Simple product or variant product is on sale
     if (Shopp::str_true($price->sale)) {
         $target->sale = $price->sale;
     }
     // Build third lookup table using the combined optionkey
     $target->pricekey[$price->optionkey] = $price;
     if (Shopp::str_true($price->inventory)) {
         $target->stock += $price->stock;
         $target->inventory = $price->inventory;
         $target->lowstock($price->stock, $price->stocked);
     }
     $freeshipping = false;
     if (!Shopp::str_true($price->shipping) && 'Shipped' == $price->type) {
         $freeshipping = true;
     }
     // Calculate catalog discounts if not already calculated
     if (!empty($price->discounts)) {
         $discount = ShoppPromo::pricing($price->promoprice, $price->discounts);
         if ($discount->freeship) {
             $freeshipping = true;
         }
         $price->promoprice = $discount->pricetag;
     }
     $price->_sale = $price->sale;
     // Keep a copy of the price record "sale" setting {@see issue #2797}
     if ($price->promoprice < $price->price) {
         $target->sale = $price->sale = 'on';
     }
     // Grab price and saleprice ranges (minimum - maximum)
     if (!$price->price) {
         $price->price = 0;
     }
     // Variation range index/properties
     $varranges = array('price' => 'price', 'saleprice' => 'promoprice');
     if (Shopp::str_true($price->inventory)) {
         $varranges['stock'] = 'stock';
     }
     foreach ($varranges as $name => $prop) {
         if (!isset($price->{$prop})) {
             continue;
         }
         if (!isset($target->min[$name]) || $target->min[$name] == 0) {
             $target->min[$name] = $price->{$prop};
         } else {
             $target->min[$name] = min($target->min[$name], $price->{$prop});
         }
         if ($target->min[$name] == $price->{$prop}) {
             $target->min[$name . '_tax'] = $price->tax == "on";
         }
         if (!isset($target->max[$name])) {
             $target->max[$name] = $price->{$prop};
         } else {
             $target->max[$name] = max($target->max[$name], $price->{$prop});
         }
         if ($target->max[$name] == $price->{$prop}) {
             $target->max[$name . '_tax'] = $price->tax == "on";
         }
     }
     // Determine savings ranges
     if (Shopp::str_true($target->sale)) {
         if (!isset($target->min['saved']) || $target->min['saved'] === false) {
             $target->min['saved'] = $price->price;
             $target->min['savings'] = 100;
             $target->max['saved'] = $target->max['savings'] = 0;
         }
         $target->min['saved'] = min($target->min['saved'], $price->price - $price->promoprice);
         $target->max['saved'] = max($target->max['saved'], $price->price - $price->promoprice);
         // Find lowest savings percentage
         $delta = $price->price - $price->promoprice;
         if ($price->price == 0) {
             // no savings possible
             $target->min['savings'] = 0;
         } else {
             if ($delta <= 0) {
                 // total savings
                 $target->max['savings'] = 100;
             } else {
                 $savings = $delta / $price->price * 100;
                 $target->min['savings'] = min($target->min['savings'], $savings);
                 $target->max['savings'] = max($target->max['savings'], $savings);
             }
         }
     }
     if (shopp_setting_enabled('inventory') && Shopp::str_true($target->inventory)) {
         $target->outofstock = $target->stock <= 0;
     }
     if ($freeshipping) {
         $target->freeship = 'on';
     }
 }
Пример #6
0
 /**
  * Load active promotions
  *
  * @author Jonathan Davis
  * @since 1.3
  *
  * @return array List of loaded ShoppOrderPromo objects
  **/
 public function load()
 {
     if ($this->loaded) {
         return;
     }
     // Don't load twice in one request
     $table = ShoppDatabaseObject::tablename(ShoppPromo::$table);
     $where = array("status='enabled'", ShoppPromo::activedates(), "target IN ('" . join("','", self::$targets) . "')");
     $orderby = 'target DESC';
     $queryargs = compact('table', 'where', 'orderby');
     $query = sDB::select($queryargs);
     $loaded = sDB::query($query, 'array', array('ShoppPromotions', 'loader'));
     if (!$loaded || 0 == count($loaded)) {
         return;
     }
     $this->populate($loaded);
     $this->loaded = true;
 }
Пример #7
0
 /**
  * Calculates promotional discounts applied to the price record
  *
  * @author Jonathan Davis
  * @since 1.1
  *
  * @return boolean True if a discount applies
  **/
 public function discounts()
 {
     if (empty($this->discounts)) {
         return false;
     }
     $pricetag = Shopp::str_true($this->sale) ? $this->saleprice : $this->price;
     $discount = ShoppPromo::pricing($pricetag, $this->discounts);
     $this->promoprice = $discount->pricetag;
     if ($discount->freeship) {
         $this->freeship = true;
     }
     return true;
 }
Пример #8
0
 /**
  * Disables an entire set of promotions
  *
  * @author Jonathan Davis
  * @since 1.2
  *
  * @param array $ids List of promotion IDs to disable
  * @return boolean Success/fail
  **/
 static function disableset($ids)
 {
     if (empty($ids) || !is_array($ids)) {
         return false;
     }
     $table = ShoppDatabaseObject::tablename(self::$table);
     sDB::query("UPDATE {$table} SET status='disabled' WHERE id IN (" . join(',', $ids) . ")");
     $catalogpromos = sDB::query("SELECT id FROM {$table} WHERE target='Catalog'", 'array', 'col', 'id');
     foreach ($catalogpromos as $promoid) {
         $Promo = new ShoppPromo($promoid);
         $Promo->catalog();
     }
     return true;
 }