<?php
/**
* Isotope eCommerce for Contao Open Source CMS
*
* Copyright (C) 2009-2016 terminal42 gmbh & Isotope eCommerce Workgroup
*
* @link https://isotopeecommerce.org
* @license https://opensource.org/licenses/lgpl-3.0.html
*/
namespace eSM_isotope_custom\Model\ProductCollectionSurcharge;
use Haste\Units\Mass\Weight;
use Isotope\Interfaces\IsotopeProductCollection;
use Isotope\Interfaces\IsotopeProductCollectionSurcharge;
use Isotope\Isotope;
use Isotope\Model\ProductCollectionSurcharge;
use Isotope\Model\Rule as RuleModel;
use Isotope\Model\ProductCollectionSurcharge\Rule;
/**
* Class Payment
*
* Implements payment surcharge in product collection
* @copyright Isotope eCommerce Workgroup 2009-2012
* @author Andreas Schempp <andreas.schempp@terminal42.ch>
*/
class AffentalerRule extends ProductCollectionSurcharge implements IsotopeProductCollectionSurcharge
{
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;
}
// Cart weight
$objScale = Isotope::getCart()->addToScale();
if (($minWeight = Weight::createFromTimePeriod($objRule->minWeight)) !== null
&& $objScale->isLessThan($minWeight)
) {
return null;
}
if (($maxWeight = Weight::createFromTimePeriod($objRule->maxWeight)) !== null
&& $objScale->isMoreThan($maxWeight)
) {
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;
}
}
$intSubstitute = (($objRule->minItemQuantity-1) > 0 ? ($objRule->minItemQuantity-1) : 0);
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':
if ($intSubstitute - $objItem->quantity > 0)
{
$intItemSubstitute = $objItem->quantity;
} else if ($intSubstitute > 0) {
$intItemSubstitute = $intSubstitute;
} else {
$intItemSubstitute = 0;
}
$intSubstitute = $intSubstitute - $objItem->quantity;
$fltPrice = ($blnPercentage ? ($objItem->getPrice() / 100 * $fltDiscount) : $objRule->discount) * ($objItem->quantity-$intItemSubstitute);
$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 += (float) $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;
}
}