/**
     * @static
     * @param $id_lang
     * @param $id_customer
     * @param bool $active
     * @param bool $includeGeneric
     * @param bool $inStock
     * @param Cart|null $cart
     * @return array
     */
    public static function getCustomerCartRules($id_lang, $id_customer, $active = false, $includeGeneric = true, $inStock = false, Cart $cart = null)
    {
        if (!CartRule::isFeatureActive()) {
            return array();
        }
        $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
		SELECT *
		FROM `' . _DB_PREFIX_ . 'cart_rule` cr
		LEFT JOIN `' . _DB_PREFIX_ . 'cart_rule_lang` crl ON (cr.`id_cart_rule` = crl.`id_cart_rule` AND crl.`id_lang` = ' . (int) $id_lang . ')
		WHERE (
			cr.`id_customer` = ' . (int) $id_customer . ' OR cr.group_restriction = 1
			' . ($includeGeneric ? 'OR cr.`id_customer` = 0' : '') . '
		)
		AND cr.date_from < "' . date('Y-m-d H:i:s') . '"
		AND cr.date_to > "' . date('Y-m-d H:i:s') . '"
		' . ($active ? 'AND cr.`active` = 1' : '') . '
		' . ($inStock ? 'AND cr.`quantity` > 0' : ''));
        // Remove cart rule that does not match the customer groups
        $customerGroups = Customer::getGroupsStatic($id_customer);
        foreach ($result as $key => $cart_rule) {
            if ($cart_rule['group_restriction']) {
                $cartRuleGroups = Db::getInstance()->executeS('SELECT id_group FROM ' . _DB_PREFIX_ . 'cart_rule_group WHERE id_cart_rule = ' . (int) $cart_rule['id_cart_rule']);
                foreach ($cartRuleGroups as $cartRuleGroup) {
                    if (in_array($cartRuleGroup['id_group'], $customerGroups)) {
                        continue 2;
                    }
                }
                unset($result[$key]);
            }
        }
        foreach ($result as &$cart_rule) {
            if ($cart_rule['quantity_per_user']) {
                $quantity_used = Order::getDiscountsCustomer((int) $id_customer, (int) $cart_rule['id_cart_rule']);
                if (isset($cart) && isset($cart->id)) {
                    $quantity_used += $cart->getDiscountsCustomer((int) $cart_rule['id_cart_rule']);
                }
                $cart_rule['quantity_for_user'] = $cart_rule['quantity_per_user'] - $quantity_used;
            } else {
                $cart_rule['quantity_for_user'] = 0;
            }
        }
        unset($cart_rule);
        foreach ($result as $key => $cart_rule) {
            if ($cart_rule['shop_restriction']) {
                $cartRuleShops = Db::getInstance()->executeS('SELECT id_shop FROM ' . _DB_PREFIX_ . 'cart_rule_shop WHERE id_cart_rule = ' . (int) $cart_rule['id_cart_rule']);
                foreach ($cartRuleShops as $cartRuleShop) {
                    if (Shop::isFeatureActive() && $cartRuleShop['id_shop'] == Context::getContext()->shop->id) {
                        continue 2;
                    }
                }
                unset($result[$key]);
            }
        }
        if (isset($cart) && isset($cart->id)) {
            foreach ($result as $key => $cart_rule) {
                if ($cart_rule['product_restriction']) {
                    $cr = new CartRule((int) $cart_rule['id_cart_rule']);
                    $r = $cr->checkProductRestrictions(Context::getContext(), false, false);
                    if ($r !== false) {
                        continue;
                    }
                    unset($result[$key]);
                }
            }
        }
        foreach ($result as $key => $cart_rule) {
            if ($cart_rule['country_restriction']) {
                $countries = Db::getInstance()->ExecuteS('
					SELECT `id_country`
					FROM `' . _DB_PREFIX_ . 'address`
					WHERE `id_customer` = ' . (int) $id_customer . '
					AND `deleted` = 0');
                if (is_array($countries) && count($countries)) {
                    foreach ($countries as $country) {
                        $id_cart_rule = (bool) Db::getInstance()->getValue('
							SELECT crc.id_cart_rule
							FROM ' . _DB_PREFIX_ . 'cart_rule_country crc
							WHERE crc.id_cart_rule = ' . (int) $cart_rule['id_cart_rule'] . '
							AND crc.id_country = ' . (int) $country['id_country']);
                        if (!$id_cart_rule) {
                            unset($result[$key]);
                        }
                    }
                }
            }
        }
        // Retrocompatibility with 1.4 discounts
        foreach ($result as &$cart_rule) {
            $cart_rule['value'] = 0;
            $cart_rule['minimal'] = Tools::convertPriceFull($cart_rule['minimum_amount'], new Currency($cart_rule['minimum_amount_currency']), Context::getContext()->currency);
            $cart_rule['cumulable'] = !$cart_rule['cart_rule_restriction'];
            $cart_rule['id_discount_type'] = false;
            if ($cart_rule['free_shipping']) {
                $cart_rule['id_discount_type'] = Discount::FREE_SHIPPING;
            } elseif ($cart_rule['reduction_percent'] > 0) {
                $cart_rule['id_discount_type'] = Discount::PERCENT;
                $cart_rule['value'] = $cart_rule['reduction_percent'];
            } elseif ($cart_rule['reduction_amount'] > 0) {
                $cart_rule['id_discount_type'] = Discount::AMOUNT;
                $cart_rule['value'] = $cart_rule['reduction_amount'];
            }
        }
        unset($cart_rule);
        return $result;
    }
Ejemplo n.º 2
0
    /**
     * Get CartRules for the given Customer
     *
     * @param int       $id_lang            Language ID
     * @param int       $id_customer        Customer ID
     * @param bool      $active             Active vouchers only
     * @param bool      $includeGeneric     Include generic AND highlighted vouchers, regardless of highlight_only setting
     * @param bool      $inStock            Vouchers in stock only
     * @param Cart|null $cart               Cart
     * @param bool      $free_shipping_only Free shipping only
     * @param bool      $highlight_only     Highlighted vouchers only
     * @return array
     * @throws PrestaShopDatabaseException
     */
    public static function getCustomerCartRules($id_lang, $id_customer, $active = false, $includeGeneric = true, $inStock = false, Cart $cart = null, $free_shipping_only = false, $highlight_only = false)
    {
        if (!CartRule::isFeatureActive()) {
            return array();
        }
        $sql_part1 = '* FROM `' . _DB_PREFIX_ . 'cart_rule` cr
				LEFT JOIN `' . _DB_PREFIX_ . 'cart_rule_lang` crl ON (cr.`id_cart_rule` = crl.`id_cart_rule` AND crl.`id_lang` = ' . (int) $id_lang . ')';
        $sql_part2 = ' AND cr.date_from < "' . date('Y-m-d H:i:s') . '"
				AND cr.date_to > "' . date('Y-m-d H:i:s') . '"
				' . ($active ? 'AND cr.`active` = 1' : '') . '
				' . ($inStock ? 'AND cr.`quantity` > 0' : '');
        if ($free_shipping_only) {
            $sql_part2 .= ' AND free_shipping = 1 AND carrier_restriction = 1';
        }
        if ($highlight_only) {
            $sql_part2 .= ' AND highlight = 1 AND code NOT LIKE "' . pSQL(CartRule::BO_ORDER_CODE_PREFIX) . '%"';
        }
        $sql = '(SELECT SQL_NO_CACHE ' . $sql_part1 . ' WHERE cr.`id_customer` = ' . (int) $id_customer . ' ' . $sql_part2 . ')';
        $sql .= ' UNION (SELECT ' . $sql_part1 . ' WHERE cr.`group_restriction` = 1 ' . $sql_part2 . ')';
        if ($includeGeneric && (int) $id_customer != 0) {
            $sql .= ' UNION (SELECT ' . $sql_part1 . ' WHERE cr.`id_customer` = 0 ' . $sql_part2 . ')';
        }
        $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql, true, false);
        if (empty($result)) {
            return array();
        }
        // Remove cart rule that does not match the customer groups
        $customerGroups = Customer::getGroupsStatic($id_customer);
        foreach ($result as $key => $cart_rule) {
            if ($cart_rule['group_restriction']) {
                $cartRuleGroups = Db::getInstance()->executeS('SELECT id_group FROM ' . _DB_PREFIX_ . 'cart_rule_group WHERE id_cart_rule = ' . (int) $cart_rule['id_cart_rule']);
                foreach ($cartRuleGroups as $cartRuleGroup) {
                    if (in_array($cartRuleGroup['id_group'], $customerGroups)) {
                        continue 2;
                    }
                }
                unset($result[$key]);
            }
        }
        foreach ($result as &$cart_rule) {
            if ($cart_rule['quantity_per_user']) {
                $quantity_used = Order::getDiscountsCustomer((int) $id_customer, (int) $cart_rule['id_cart_rule']);
                if (isset($cart) && isset($cart->id)) {
                    $quantity_used += $cart->getDiscountsCustomer((int) $cart_rule['id_cart_rule']);
                }
                $cart_rule['quantity_for_user'] = $cart_rule['quantity_per_user'] - $quantity_used;
            } else {
                $cart_rule['quantity_for_user'] = 0;
            }
        }
        unset($cart_rule);
        foreach ($result as $key => $cart_rule) {
            if ($cart_rule['shop_restriction']) {
                $cartRuleShops = Db::getInstance()->executeS('SELECT id_shop FROM ' . _DB_PREFIX_ . 'cart_rule_shop WHERE id_cart_rule = ' . (int) $cart_rule['id_cart_rule']);
                foreach ($cartRuleShops as $cartRuleShop) {
                    if (Shop::isFeatureActive() && $cartRuleShop['id_shop'] == Context::getContext()->shop->id) {
                        continue 2;
                    }
                }
                unset($result[$key]);
            }
        }
        if (isset($cart) && isset($cart->id)) {
            foreach ($result as $key => $cart_rule) {
                if ($cart_rule['product_restriction']) {
                    $cr = new CartRule((int) $cart_rule['id_cart_rule']);
                    $r = $cr->checkProductRestrictions(Context::getContext(), false, false);
                    if ($r !== false) {
                        continue;
                    }
                    unset($result[$key]);
                }
            }
        }
        $result_bak = $result;
        $result = array();
        $country_restriction = false;
        foreach ($result_bak as $key => $cart_rule) {
            if ($cart_rule['country_restriction']) {
                $country_restriction = true;
                $countries = Db::getInstance()->ExecuteS('
                    SELECT `id_country`
                    FROM `' . _DB_PREFIX_ . 'address`
                    WHERE `id_customer` = ' . (int) $id_customer . '
                    AND `deleted` = 0');
                if (is_array($countries) && count($countries)) {
                    foreach ($countries as $country) {
                        $id_cart_rule = (bool) Db::getInstance()->getValue('
                            SELECT crc.id_cart_rule
                            FROM ' . _DB_PREFIX_ . 'cart_rule_country crc
                            WHERE crc.id_cart_rule = ' . (int) $cart_rule['id_cart_rule'] . '
                            AND crc.id_country = ' . (int) $country['id_country']);
                        if ($id_cart_rule) {
                            $result[] = $result_bak[$key];
                            break;
                        }
                    }
                }
            } else {
                $result[] = $result_bak[$key];
            }
        }
        if (!$country_restriction) {
            $result = $result_bak;
        }
        // Retrocompatibility with 1.4 discounts
        // TODO: remove? We're at 1.7 now
        foreach ($result as &$cart_rule) {
            $cart_rule['value'] = 0;
            $cart_rule['minimal'] = Tools::convertPriceFull($cart_rule['minimum_amount'], new Currency($cart_rule['minimum_amount_currency']), Context::getContext()->currency);
            $cart_rule['cumulable'] = !$cart_rule['cart_rule_restriction'];
            $cart_rule['id_discount_type'] = false;
            if ($cart_rule['free_shipping']) {
                $cart_rule['id_discount_type'] = Discount::FREE_SHIPPING;
            } elseif ($cart_rule['reduction_percent'] > 0) {
                $cart_rule['id_discount_type'] = Discount::PERCENT;
                $cart_rule['value'] = $cart_rule['reduction_percent'];
            } elseif ($cart_rule['reduction_amount'] > 0) {
                $cart_rule['id_discount_type'] = Discount::AMOUNT;
                $cart_rule['value'] = $cart_rule['reduction_amount'];
            }
        }
        unset($cart_rule);
        return $result;
    }