Beispiel #1
0
 public static function createForRuleInCollection(RuleModel $objRule, IsotopeProductCollection $objCollection)
 {
     // Cart subtotal
     if ($objRule->minSubtotal > 0 && $objCollection->getSubtotal() < $objRule->minSubtotal || $objRule->maxSubtotal > 0 && $objCollection->getSubtotal() > $objRule->maxSubtotal) {
         return null;
     }
     $arrCollectionItems = $objCollection->getItems();
     $blnMatch = false;
     $blnPercentage = $objRule->isPercentage();
     $fltDiscount = $blnPercentage ? $objRule->getPercentage() : 0;
     $fltTotal = 0;
     $arrSubtract = array();
     $objSurcharge = new static();
     $objSurcharge->label = $objRule->getLabel();
     $objSurcharge->price = $objRule->getPercentageLabel();
     $objSurcharge->total_price = 0;
     $objSurcharge->tax_class = 0;
     $objSurcharge->before_tax = true;
     $objSurcharge->addToTotal = true;
     // Product or producttype restrictions
     if ($objRule->productRestrictions != '' && $objRule->productRestrictions != 'none') {
         $arrLimit = \Database::getInstance()->execute("SELECT object_id FROM tl_iso_rule_restriction WHERE pid={$objRule->id} AND type='{$objRule->productRestrictions}'")->fetchEach('object_id');
         if ($objRule->productRestrictions == 'pages' && !empty($arrLimit)) {
             $arrLimit = \Database::getInstance()->execute("SELECT pid FROM " . \Isotope\Model\ProductCategory::getTable() . " WHERE page_id IN (" . implode(',', $arrLimit) . ")")->fetchEach('pid');
         }
         if ($objRule->quantityMode == 'cart_products' || $objRule->quantityMode == 'cart_items') {
             $intTotal = 0;
             foreach ($arrCollectionItems as $objItem) {
                 if (!$objItem->hasProduct()) {
                     continue;
                 }
                 $objProduct = $objItem->getProduct();
                 if (($objRule->productRestrictions == 'products' || $objRule->productRestrictions == 'variants' || $objRule->productRestrictions == 'pages') && (in_array($objProduct->id, $arrLimit) || $objProduct->pid > 0 && in_array($objProduct->pid, $arrLimit)) || $objRule->productRestrictions == 'producttypes' && in_array($objProduct->type, $arrLimit)) {
                     $intTotal += $objRule->quantityMode == 'cart_items' ? $objItem->quantity : 1;
                 }
             }
         }
     } else {
         switch ($objRule->quantityMode) {
             case 'cart_products':
                 $intTotal = $objCollection->countItems();
                 break;
             case 'cart_items':
                 $intTotal = $objCollection->sumItemsQuantity();
                 break;
         }
     }
     foreach ($arrCollectionItems as $objItem) {
         if (!$objItem->hasProduct()) {
             continue;
         }
         $objProduct = $objItem->getProduct();
         // Product restrictions
         if (($objRule->productRestrictions == 'products' || $objRule->productRestrictions == 'variants' || $objRule->productRestrictions == 'pages') && (!in_array($objProduct->id, $arrLimit) && ($objProduct->pid == 0 || !in_array($objProduct->pid, $arrLimit))) || $objRule->productRestrictions == 'producttypes' && !in_array($objProduct->type, $arrLimit)) {
             continue;
         } elseif ($objRule->productRestrictions == 'attribute') {
             switch ($objRule->attributeCondition) {
                 case 'eq':
                     if (!($objProduct->{$objRule->attributeName} == $objRule->attributeValue)) {
                         continue 2;
                     }
                     break;
                 case 'neq':
                     if (!($objProduct->{$objRule->attributeName} != $objRule->attributeValue)) {
                         continue 2;
                     }
                     break;
                 case 'lt':
                     if (!($objProduct->{$objRule->attributeName} < $objRule->attributeValue)) {
                         continue 2;
                     }
                     break;
                 case 'gt':
                     if (!($objProduct->{$objRule->attributeName} > $objRule->attributeValue)) {
                         continue 2;
                     }
                     break;
                 case 'elt':
                     if (!($objProduct->{$objRule->attributeName} <= $objRule->attributeValue)) {
                         continue 2;
                     }
                     break;
                 case 'egt':
                     if (!($objProduct->{$objRule->attributeName} >= $objRule->attributeValue)) {
                         continue 2;
                     }
                     break;
                 case 'starts':
                     if (stripos($objProduct->{$objRule->attributeName}, $objRule->attributeValue) !== 0) {
                         continue 2;
                     }
                     break;
                 case 'ends':
                     if (strripos($objProduct->{$objRule->attributeName}, $objRule->attributeValue) !== strlen($objProduct->{$objRule->attributeName}) - strlen($objRule->attributeValue)) {
                         continue 2;
                     }
                     break;
                 case 'contains':
                     if (stripos($objProduct->{$objRule->attributeName}, $objRule->attributeValue) === false) {
                         continue 2;
                     }
                     break;
                 default:
                     throw new \Exception('Unknown rule condition "' . $objRule->attributeCondition . '"');
             }
         }
         // Because we apply to the quantity of only this product, we override $intTotal in every foreach loop
         // This matches tl_iso_rules.quantityMode="product_quantity"
         if ($objRule->quantityMode != 'cart_products' && $objRule->quantityMode != 'cart_items') {
             $intTotal = $objItem->quantity;
         }
         // Quantity does not match, do not apply to this product
         if ($objRule->minItemQuantity > 0 && $objRule->minItemQuantity > $intTotal || $objRule->maxItemQuantity > 0 && $objRule->maxItemQuantity < $intTotal) {
             continue;
         }
         // Apply To
         switch ($objRule->applyTo) {
             case 'products':
                 $fltPrice = $blnPercentage ? $objItem->getTotalPrice() / 100 * $fltDiscount : $objRule->discount;
                 $fltPrice = $fltPrice > 0 ? floor($fltPrice * 100) / 100 : ceil($fltPrice * 100) / 100;
                 $objSurcharge->total_price += $fltPrice;
                 $objSurcharge->setAmountForCollectionItem($fltPrice, $objItem);
                 break;
             case 'items':
                 $fltPrice = ($blnPercentage ? $objItem->getPrice() / 100 * $fltDiscount : $objRule->discount) * $objItem->quantity;
                 $fltPrice = $fltPrice > 0 ? floor($fltPrice * 100) / 100 : ceil($fltPrice * 100) / 100;
                 $objSurcharge->total_price += $fltPrice;
                 $objSurcharge->setAmountForCollectionItem($fltPrice, $objItem);
                 break;
             case 'subtotal':
                 $blnMatch = true;
                 $objSurcharge->total_price += $objItem->getTotalPrice();
                 if ($objRule->tax_class == -1) {
                     if ($blnPercentage) {
                         $fltPrice = $objItem->getTotalPrice() / 100 * $fltDiscount;
                         $objSurcharge->setAmountForCollectionItem($fltPrice, $objItem);
                     } else {
                         $arrSubtract[] = $objItem;
                         $fltTotal += (double) $objItem->getTaxFreeTotalPrice();
                     }
                 }
                 break;
         }
     }
     if ($objRule->applyTo == 'subtotal' && $blnMatch) {
         // discount total! not related to tax subtraction
         $fltPrice = $blnPercentage ? $objSurcharge->total_price / 100 * $fltDiscount : $objRule->discount;
         $objSurcharge->total_price = $fltPrice > 0 ? floor(round($fltPrice * 100, 4)) / 100 : ceil(round($fltPrice * 100, 4)) / 100;
         $objSurcharge->before_tax = $objRule->tax_class != 0 ? true : false;
         $objSurcharge->tax_class = $objRule->tax_class > 0 ? $objRule->tax_class : 0;
         // If fixed price discount with splitted taxes, calculate total amount of discount per taxed product
         if ($objRule->tax_class == -1 && !$blnPercentage) {
             foreach ($arrSubtract as $objItem) {
                 $fltPrice = $objRule->discount / 100 * (100 / $fltTotal * $objItem->getTaxFreeTotalPrice());
                 $objSurcharge->setAmountForCollectionItem($fltPrice, $objItem);
             }
         }
     }
     return $objSurcharge->total_price == 0 ? null : $objSurcharge;
 }
 /**
  * Replace insert tag for a product collection.
  *
  * @param IsotopeProductCollection $collection
  * @param array                    $tokens
  *
  * @return string
  */
 private function getValueForCollectionTag(IsotopeProductCollection $collection, array $tokens)
 {
     switch ($tokens[1]) {
         case 'items':
             return $collection->countItems();
         case 'quantity':
             return $collection->sumItemsQuantity();
         case 'items_label':
             $intCount = $collection->countItems();
             if (!$intCount) {
                 return '';
             }
             if ($intCount == 1) {
                 return '(' . $GLOBALS['TL_LANG']['MSC']['productSingle'] . ')';
             } else {
                 return sprintf('(' . $GLOBALS['TL_LANG']['MSC']['productMultiple'] . ')', $intCount);
             }
             break;
         case 'quantity_label':
             $intCount = $collection->sumItemsQuantity();
             if (!$intCount) {
                 return '';
             }
             if ($intCount == 1) {
                 return '(' . $GLOBALS['TL_LANG']['MSC']['productSingle'] . ')';
             } else {
                 return sprintf('(' . $GLOBALS['TL_LANG']['MSC']['productMultiple'] . ')', $intCount);
             }
             break;
         case 'subtotal':
             return Isotope::formatPriceWithCurrency($collection->getSubtotal());
         case 'taxfree_subtotal':
             return Isotope::formatPriceWithCurrency($collection->getTaxFreeSubtotal());
         case 'total':
             return Isotope::formatPriceWithCurrency($collection->getTotal());
         case 'taxfree_total':
             return Isotope::formatPriceWithCurrency($collection->getTaxFreeTotal());
         case 'billing_address':
             if (!$collection instanceof IsotopeOrderableCollection || ($address = $collection->getBillingAddress()) === null) {
                 return '';
             }
             return $this->getValueForAddressTag($address, $tokens[2]);
         case 'shipping_address':
             if (!$collection instanceof IsotopeOrderableCollection || !$collection->hasShipping() || ($address = $collection->getShippingAddress()) === null) {
                 return '';
             }
             return $this->getValueForAddressTag($address, $tokens[2]);
         default:
             return $collection->{$tokens[1]};
     }
 }