/** * Check if rules module is enabled * * @return bool */ public function hasError() { if (null === $this->blnError) { $this->blnError = in_array('isotope_rules', \Config::getInstance()->getActiveModules()) && Rule::countAll() == 0; } return $this->blnError; }
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; }
/** * Callback for checkout Hook. Transfer active rules to usage table. */ public function writeRuleUsages($objOrder) { $objCart = Cart::findByPk($objOrder->source_collection_id); $objRules = Rule::findActiveWitoutCoupons(); $arrRules = null === $objRules ? array() : $objRules->fetchEach('id'); $arrCoupons = deserialize($objCart->coupons); if (is_array($arrCoupons) && !empty($arrCoupons)) { $blnError = false; foreach ($arrCoupons as $k => $code) { $objRule = Rule::findOneByCouponCode($code, $objCart->getItems()); if (null === $objRule) { Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['couponCodeDropped'], $code)); unset($arrCoupons[$k]); $blnError = true; } else { $arrRules[] = $objRule->id; } } if ($blnError) { $objCart->coupons = $arrCoupons; return false; } } if (!empty($arrRules)) { $time = time(); \Database::getInstance()->query("INSERT INTO tl_iso_rule_usage (pid,tstamp,order_id,config_id,member_id) VALUES (" . implode(", {$time}, {$objOrder->id}, " . (int) Isotope::getConfig()->id . ", {$objOrder->member}), (", $arrRules) . ", {$time}, {$objOrder->id}, " . (int) Isotope::getConfig()->id . ", {$objOrder->member})"); } return true; }
* Isotope eCommerce for Contao Open Source CMS * * Copyright (C) 2009-2014 terminal42 gmbh & Isotope eCommerce Workgroup * * @package Isotope * @link http://isotopeecommerce.org * @license http://opensource.org/licenses/lgpl-3.0.html */ /** * Backend modules */ array_insert($GLOBALS['BE_MOD']['isotope'], 2, array('iso_rules' => array('tables' => array(\Isotope\Model\Rule::getTable()), 'javascript' => \Haste\Util\Debug::uncompressedFile('system/modules/isotope/assets/js/backend.min.js'), 'icon' => 'system/modules/isotope_rules/assets/auction-hammer-gavel.png'))); /** * Models */ $GLOBALS['TL_MODELS'][\Isotope\Model\Rule::getTable()] = 'Isotope\\Model\\Rule'; /** * Checkout Steps * @todo this will no longer work */ array_insert($GLOBALS['ISO_CHECKOUT_STEPS']['review'], 0, array(array('Isotope\\Rules', 'cleanRuleUsages'))); /** * Product collection surcharge */ \Isotope\Model\ProductCollectionSurcharge::registerModelType('rule', 'Isotope\\Model\\ProductCollectionSurcharge\\Rule'); /** * Hooks */ $GLOBALS['ISO_HOOKS']['calculatePrice'][] = array('Isotope\\Rules', 'calculatePrice'); $GLOBALS['ISO_HOOKS']['compileCart'][] = array('Isotope\\Rules', 'getCouponForm'); $GLOBALS['ISO_HOOKS']['findSurchargesForCollection'][] = array('Isotope\\Rules', 'findSurcharges');
<?php /** * Isotope eCommerce for Contao Open Source CMS * * Copyright (C) 2009-2014 terminal42 gmbh & Isotope eCommerce Workgroup * * @package Isotope * @link http://isotopeecommerce.org * @license http://opensource.org/licenses/lgpl-3.0.html */ /** * Table tl_iso_rule_usage */ $GLOBALS['TL_DCA']['tl_iso_rule_usage'] = array('config' => array('sql' => array('keys' => array('id' => 'primary', 'pid' => 'index'))), 'fields' => array('id' => array('sql' => "int(10) unsigned NOT NULL auto_increment"), 'pid' => array('foreignKey' => \Isotope\Model\Rule::getTable() . '.name', 'sql' => "int(10) unsigned NOT NULL default '0'", 'relation' => array('type' => 'belongsTo', 'load' => 'lazy')), 'tstamp' => array('sql' => "int(10) unsigned NOT NULL default '0'"), 'order_id' => array('foreignKey' => \Isotope\Model\ProductCollection::getTable() . '.document_number', 'sql' => "int(10) unsigned NOT NULL default '0'", 'relation' => array('type' => 'hasOne', 'load' => 'lazy')), 'config_id' => array('foreignKey' => \Isotope\Model\Config::getTable() . '.name', 'sql' => "int(10) unsigned NOT NULL default '0'", 'relation' => array('type' => 'hasOne', 'load' => 'lazy')), 'member_id' => array('foreignKey' => \MemberModel::getTable() . '.username', 'sql' => "int(10) unsigned NOT NULL default '0'", 'relation' => array('type' => 'hasOne', 'load' => 'lazy'))));
<?php /** * Isotope eCommerce for Contao Open Source CMS * * Copyright (C) 2009-2014 terminal42 gmbh & Isotope eCommerce Workgroup * * @package Isotope * @link http://isotopeecommerce.org * @license http://opensource.org/licenses/lgpl-3.0.html */ /** * Table tl_iso_rule_restriction */ $GLOBALS['TL_DCA']['tl_iso_rule_restriction'] = array('config' => array('sql' => array('keys' => array('id' => 'primary', 'pid,type' => 'index', 'type,object_id,pid' => 'index'))), 'fields' => array('id' => array('sql' => "int(10) unsigned NOT NULL auto_increment"), 'pid' => array('foreignKey' => \Isotope\Model\Rule::getTable() . '.name', 'sql' => "int(10) unsigned NOT NULL default '0'", 'relation' => array('type' => 'belongsTo', 'load' => 'lazy')), 'tstamp' => array('sql' => "int(10) unsigned NOT NULL default '0'"), 'type' => array('sql' => "varchar(32) NOT NULL default ''"), 'object_id' => array('sql' => "int(10) unsigned NOT NULL default '0'")));