Ejemplo n.º 1
0
/**
 * Apply promotion rules
 *
 * @param array $data data array (product - for catalog rules, cart - for cart rules)
 * @param string $zone - promotiontion zone (catalog, cart)
 * @param array $cart_products (optional) - cart products array (for car rules)
 * @param array $auth (optional) - auth array (for car rules)
 * @return bool true if rule can be applied, false - otherwise
 */
function fn_promotion_apply($zone, &$data, &$auth = NULL, &$cart_products = NULL)
{
    static $promotions = array();
    $applied_promotions = array();
    if (!isset($promotions[$zone])) {
        $params = array('active' => true, 'expand' => true, 'zone' => $zone, 'sort_by' => 'priority', 'sort_order' => 'asc');
        list($promotions[$zone]) = fn_get_promotions($params);
    }
    // If we're in cart, set flag that promotions available
    if ($zone == 'cart') {
        $_promotion_ids = !empty($data['promotions']) ? array_keys($data['promotions']) : array();
        $data['no_promotions'] = empty($promotions[$zone]);
        $data['promotions'] = array();
        // cleanup stored promotions
        $data['subtotal_discount'] = 0;
        // reset subtotal discount (FIXME: move to another place)
        $data['has_coupons'] = false;
    }
    /**
     * Changes before applying promotion rules
     *
     * @param array  $promotions    List of promotions
     * @param string $zone          - promotiontion zone (catalog, cart)
     * @param array  $data          data array (product - for catalog rules, cart - for cart rules)
     * @param array  $auth          (optional) - auth array (for car rules)
     * @param array  $cart_products (optional) - cart products array (for car rules)
     */
    fn_set_hook('promotion_apply_pre', $promotions, $zone, $data, $auth, $cart_products);
    if (!fn_allowed_for('ULTIMATE:FREE')) {
        if ($zone == 'cart') {
            // Delete obsolete discounts
            foreach ($cart_products as $p_id => $_val) {
                $data['products'][$p_id]['discount'] = !empty($_val['discount']) ? $_val['discount'] : 0;
                $data['products'][$p_id]['promotions'] = !empty($_val['promotions']) ? $_val['promotions'] : array();
            }
            // Summarize discounts
            foreach ($cart_products as $k => $v) {
                if (!empty($v['promotions'])) {
                    foreach ($v['promotions'] as $pr_id => $bonuses) {
                        foreach ($bonuses['bonuses'] as $bonus) {
                            if (!empty($bonus['discount'])) {
                                $data['promotions'][$pr_id]['total_discount'] = (!empty($data['promotions'][$pr_id]['total_discount']) ? $data['promotions'][$pr_id]['total_discount'] : 0) + $bonus['discount'] * $v['amount'];
                            }
                        }
                    }
                }
            }
            $data['no_promotions'] = $data['no_promotions'] && empty($data['promotions']);
        }
    }
    if (empty($promotions[$zone])) {
        return false;
    }
    $_SESSION['promotion_notices']['promotion'] = array('applied' => false, 'messages' => array());
    if (!fn_allowed_for('ULTIMATE:FREE')) {
        // Pre-check coupon
        if ($zone == 'cart' && !empty($data['pending_coupon'])) {
            fn_promotion_check_coupon($data, true);
        }
    }
    foreach ($promotions[$zone] as $promotion) {
        // Rule is valid and can be applied
        if (fn_check_promotion_conditions($promotion, $data, $auth, $cart_products)) {
            if (fn_promotion_apply_bonuses($promotion, $data, $auth, $cart_products)) {
                $applied_promotions[$promotion['promotion_id']] = $promotion;
                // Stop processing further rules, if needed
                if ($promotion['stop'] == 'Y') {
                    break;
                }
            }
        }
    }
    if (!fn_allowed_for('ULTIMATE:FREE')) {
        if ($zone == 'cart') {
            // Post-check coupon
            if (!empty($data['pending_coupon'])) {
                // re-check coupons if some promotion has a coupon code "contains" condition
                if (!empty($data['pending_original_coupon'])) {
                    unset($data['coupons'][$data['pending_coupon']]);
                    $data['pending_coupon'] = $data['pending_original_coupon'];
                    unset($data['pending_original_coupon']);
                    fn_promotion_check_coupon($data, true);
                }
                fn_promotion_check_coupon($data, false, $applied_promotions);
            }
            if (!empty($applied_promotions)) {
                // Display notifications for new promotions
                $_text = array();
                foreach ($applied_promotions as $v) {
                    if (!in_array($v['promotion_id'], $_promotion_ids)) {
                        $_text[] = $v['name'];
                    }
                }
                if (!empty($_text)) {
                    $_SESSION['promotion_notices']['promotion']['applied'] = true;
                    $_SESSION['promotion_notices']['promotion']['messages'][] = 'text_applied_promotions';
                    $_SESSION['promotion_notices']['promotion']['applied_promotions'] = $_text;
                }
                $data['applied_promotions'] = $applied_promotions;
                // Delete obsolete coupons
                if (!empty($data['coupons'])) {
                    foreach ($data['coupons'] as $_coupon_code => $_p_ids) {
                        foreach ($_p_ids as $_ind => $_p_id) {
                            if (!isset($applied_promotions[$_p_id])) {
                                unset($data['coupons'][$_coupon_code][$_ind]);
                            }
                        }
                        if (empty($data['coupons'][$_coupon_code])) {
                            unset($data['coupons'][$_coupon_code]);
                        }
                    }
                }
            } else {
                $data['coupons'] = array();
            }
        }
    }
    return $applied_promotions;
}
Ejemplo n.º 2
0
/**
 * Apply promotion rules
 *
 * @param array $data data array (product - for catalog rules, cart - for cart rules)
 * @param string $zone - promotiontion zone (catalog, cart)
 * @param array $cart_products (optional) - cart products array (for car rules)
 * @param array $auth (optional) - auth array (for car rules)
 * @return bool true if rule can be applied, false - otherwise
 */
function fn_promotion_apply($zone, &$data, &$auth = NULL, &$cart_products = NULL)
{
    static $promotions = array();
    $applied_promotions = array();
    if (!isset($promotions[$zone])) {
        $params = array('active' => true, 'expand' => true, 'zone' => $zone, 'sort_by' => 'priority', 'sort_order' => 'asc');
        list($promotions[$zone]) = fn_get_promotions($params);
    }
    // If we're in cart, set flag that promotions available
    if ($zone == 'cart') {
        $_promotion_ids = !empty($data['promotions']) ? array_keys($data['promotions']) : array();
        $data['no_promotions'] = empty($promotions[$zone]);
        $data['promotions'] = array();
        // cleanup stored promotions
        $data['subtotal_discount'] = 0;
        // reset subtotal discount (FIXME: move to another place)
    }
    if (empty($promotions[$zone])) {
        return false;
    }
    // Pre-check coupon
    if ($zone == 'cart' && !empty($data['pending_coupon'])) {
        fn_promotion_check_coupon($data, true);
    }
    foreach ($promotions[$zone] as $promotion) {
        // Rule is valid and can be applied
        if (fn_promotion_check($promotion['promotion_id'], $promotion['conditions'], $data, $auth, $cart_products)) {
            if (fn_promotion_apply_bonuses($promotion, $data, $auth, $cart_products)) {
                $applied_promotions[$promotion['promotion_id']] = $promotion;
                // Stop processing further rules, if needed
                if ($promotion['stop'] == 'Y') {
                    break;
                }
            }
        }
    }
    if ($zone == 'cart') {
        // Post-check coupon
        if (!empty($data['pending_coupon'])) {
            fn_promotion_check_coupon($data, false, $applied_promotions);
        }
        if (!empty($applied_promotions)) {
            // Display notifications for new promotions
            $_text = array();
            foreach ($applied_promotions as $v) {
                if (!in_array($v['promotion_id'], $_promotion_ids)) {
                    $_text[] = $v['name'];
                }
            }
            if (!empty($_text)) {
                fn_set_notification('N', fn_get_lang_var('notice'), fn_get_lang_var('text_applied_promotions') . ': ' . implode(', ', $_text));
            }
            Registry::get('view')->assign('applied_promotions', $applied_promotions);
            // Delete obsolete coupons
            if (!empty($data['coupons'])) {
                foreach ($data['coupons'] as $_coupon_code => $_p_ids) {
                    foreach ($_p_ids as $_ind => $_p_id) {
                        if (!isset($applied_promotions[$_p_id])) {
                            unset($data['coupons'][$_coupon_code][$_ind]);
                        }
                    }
                    if (empty($data['coupons'][$_coupon_code])) {
                        unset($data['coupons'][$_coupon_code]);
                    }
                }
            }
        } else {
            $data['coupons'] = array();
        }
        // Delete obsolete discounts
        foreach ($cart_products as $p_id => $_val) {
            $data['products'][$p_id]['discount'] = !empty($_val['discount']) ? $_val['discount'] : 0;
            $data['products'][$p_id]['promotions'] = !empty($_val['promotions']) ? $_val['promotions'] : array();
        }
        // Summarize discounts
        foreach ($cart_products as $k => $v) {
            if (!empty($v['promotions'])) {
                foreach ($v['promotions'] as $pr_id => $bonuses) {
                    foreach ($bonuses['bonuses'] as $bonus) {
                        if (!empty($bonus['discount'])) {
                            $data['promotions'][$pr_id]['total_discount'] = (!empty($data['promotions'][$pr_id]['total_discount']) ? $data['promotions'][$pr_id]['total_discount'] : 0) + $bonus['discount'] * $v['amount'];
                        }
                    }
                }
            }
        }
    }
    return !empty($applied_promotions);
}