/** * 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; }
/** * 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); }