ruleRepository = $ruleRepository; } /** * Apply dynamic pricing to a product price */ public function applyDynamicPricing($price, $product) { $price = $this->normalizePrice($price); $rules = $this->getEnabledRules(); $matchedRule = null; foreach ($rules as $rule) { if ($this->ruleMatches($rule, $product)) { if ($matchedRule === null || $rule->priority > $matchedRule->priority) { $matchedRule = $rule; } } } if ($matchedRule) { $price = $this->applyActions($matchedRule, $price); } return max(0, $price); } public function shouldApplyFreeShipping() { $rules = $this->getEnabledRules(); foreach ($rules as $rule) { if ($this->ruleMatches($rule, null) && $this->ruleHasFreeShipping($rule)) { return true; } } return false; } public function resetFreeShippingFlag() { $this->freeShipping = false; } private function getEnabledRules() { if ($this->rulesCache === null) { $this->rulesCache = $this->ruleRepository->getEnabled(); } return $this->rulesCache; } private function normalizePrice($price) { if ($price === '' || $price === null) { return 0.0; } return floatval($price); } private function getUserType() { if (!is_user_logged_in()) { return 'guest'; } $user_id = get_current_user_id(); $order_count = wc_get_customer_order_count($user_id); return $order_count > 0 ? 'returning' : 'new'; } private function ruleMatches($rule, $product = null) { if (!$this->isRuleActive($rule)) { return false; } foreach ($rule->conditions as $condition) { if (!$this->evaluateCondition($condition, $product)) { return false; } } return true; } private function isRuleActive($rule) { if (!$rule->enabled) { return false; } $now = current_time('Y-m-d H:i:s'); if (!empty($rule->start_date) && $now < $rule->start_date) { return false; } if (!empty($rule->end_date) && $now > $rule->end_date) { return false; } return true; } private function evaluateCondition($condition, $product = null) { $type = $condition['type'] ?? ''; $value = $condition['value'] ?? null; switch ($type) { case 'user_type': return $this->getUserType() === $value; case 'cart_total_min': return $this->getCartTotal() >= floatval($value); case 'cart_total_max': return $this->getCartTotal() <= floatval($value); case 'cart_item_count_min': return $this->getCartItemCount() >= intval($value); case 'cart_item_count_max': return $this->getCartItemCount() <= intval($value); case 'product_category': return $this->productHasCategory($product, (array) $value); case 'product_ids': return $this->productIsInIds($product, (array) $value); default: return true; } } private function getCartTotal() { if (!WC()->cart) { return 0; } return floatval(WC()->cart->get_cart_contents_total()); } private function getCartItemCount() { if (!WC()->cart) { return 0; } return WC()->cart->get_cart_contents_count(); } private function productHasCategory($product, $categories) { if (!$product || empty($categories)) { return false; } $product_cats = wp_get_post_terms($product->get_id(), 'product_cat', ['fields' => 'ids']); return (bool) array_intersect($product_cats, $categories); } private function productIsInIds($product, $ids) { if (!$product || empty($ids)) { return false; } return in_array($product->get_id(), $ids, true); } private function applyActions($rule, $price) { foreach ($rule->actions as $action) { $price = $this->applyAction($action, $price); if (($action['type'] ?? '') === 'free_shipping') { $this->freeShipping = true; } } return $price; } private function ruleHasFreeShipping($rule) { foreach ($rule->actions as $action) { if (($action['type'] ?? '') === 'free_shipping') { return true; } } return false; } private function applyAction($action, $price) { $type = $action['type'] ?? ''; $value = isset($action['value']) ? floatval($action['value']) : 0; switch ($type) { case 'discount_percent': if ($value <= 0) { return $price; } return $price * (1 - $value / 100); case 'discount_fixed': if ($value <= 0) { return $price; } return $price - $value; case 'free_shipping': return $price; default: return $price; } } }