protected function doExecute() { $id = $this->get('_id'); $rule = Rule::findById($id); if ($rule) { $ruleCondition = RuleCondition::create($this->get('ruleCondition')); $exists = false; if ($ruleCondition->condId) { if (is_array($rule->conditions)) { foreach ($rule->conditions as $key => $rc) { if ($rc->condId == $ruleCondition->condId) { $exists = true; $rule->conditions[$key] = $ruleCondition; break; } } } } else { $ruleCondition->condId = ObjectUtil::guid(); } if (!$exists) { $rule->conditions[] = $ruleCondition; } $ret = $rule->save(); if ($ret) { return $this->success($ret); } else { return $this->error(ErrorInfo::ERROR_NO_DB_OPERATION_ERROR, 'add ruleCondition failed'); } } else { return $this->error(ErrorInfo::ERROR_NO_DATA_NOT_FOUND, 'rule not found for _id=' . $id); } }
public static function createFromArray(array $array) { ActiveRecordModel::getApplication()->loadPluginClass('application.model.businessrule.action', $array['actionClass']); $inst = new $array['actionClass'](); if (!empty($array['condition'])) { $condition = isset($array['instance']) ? $array['instance'] : RuleCondition::createFromArray($array['condition'], true); $inst->setCondition($condition); } unset($array['condition']); $inst->setParams($array); return $inst; }
/** * 将Rule转成完全的对象形式 * @param $rule */ public static function covertToFullObject(&$rule) { $rule->_id = $rule->_id->{'$id'}; if (is_array($rule->conditions)) { foreach ($rule->conditions as $idx => $rc) { $ruleCondition = RuleCondition::create($rc); if (is_array($ruleCondition->expressions)) { foreach ($ruleCondition->expressions as $idxExp => $exp) { $rce = RuleConditionExpression::create($exp); if (is_array($rce->left)) { $rce->left = RuleConditionExpressionOperand::create($rce->left); } if (is_array($rce->right)) { $rce->right = RuleConditionExpressionOperand::create($rce->right); } $ruleCondition->expressions[$idxExp] = $rce; } } $rule->conditions[$idx] = $ruleCondition; } } }
public function testIsProductMatching() { $condition = DiscountCondition::getNewInstance(); $condition->isEnabled->set(true); $condition->conditionClass->set('RuleConditionContainsProduct'); $condition->save(); $record = DiscountConditionRecord::getNewInstance($condition, $this->product1); $record->save(); $condition->loadAll(); $ruleCondition = RuleCondition::createFromArray($condition->toArray()); $this->assertFalse($ruleCondition->isProductMatching($this->product2)); $this->assertTrue($ruleCondition->isProductMatching($this->product1)); // check matching by manufacturer $manufacturer = Manufacturer::getNewInstance('testing'); $manufacturer->save(); $this->product2->manufacturer->set($manufacturer); $record = DiscountConditionRecord::getNewInstance($condition, $manufacturer); $record->save(); $condition->loadAll(); $ruleCondition = RuleCondition::createFromArray($condition->toArray()); $this->assertTrue($ruleCondition->isProductMatching($this->product2)); // check matching by category $newCategory = Category::getNewInstance(Category::getRootNode()); $newCategory->save(); $newSubCategory = Category::getNewInstance($newCategory); $newSubCategory->save(); $newProduct = Product::getNewInstance($newSubCategory); $newProduct->save(); $newProduct->reload(); $record = DiscountConditionRecord::getNewInstance($condition, $newCategory); $record->save(); $this->assertFalse($ruleCondition->isProductMatching($newProduct)); $condition->loadAll(); $ruleCondition = RuleCondition::createFromArray($condition->toArray()); $this->assertTrue($ruleCondition->isProductMatching($newProduct)); // sub-condition $sub = DiscountCondition::getNewInstance($condition); $sub->isEnabled->set(true); $sub->conditionClass->set('RuleConditionContainsProduct'); $sub->save(); $condition->isAllSubconditions->set(true); $condition->save(); $condition->loadAll(); $manufacturer = Manufacturer::getNewInstance('new one'); $manufacturer->save(); $record = DiscountConditionRecord::getNewInstance($sub, $manufacturer); $record->save(); $sub->loadAll(); $subCondition = RuleCondition::createFromArray($sub->toArray()); $this->assertFalse($subCondition->isProductMatching($newProduct)); $ruleCondition = RuleCondition::createFromArray($condition->toArray()); $this->assertFalse($ruleCondition->isProductMatching($newProduct)); $newProduct->manufacturer->set($manufacturer); $newProduct->save(); $this->assertTrue($ruleCondition->isProductMatching($newProduct)); // sub-sub condition $sub->isAllSubconditions->set(false); $sub->save(); for ($k = 1; $k <= 2; $k++) { $subs[$k] = DiscountCondition::getNewInstance($sub); $subs[$k]->isEnabled->set(true); $subs[$k]->conditionClass->set('RuleConditionContainsProduct'); } // false $subs[1]->save(); $someManufacturer = Manufacturer::getNewInstance('Manufacturer without products'); $someManufacturer->save(); $record = DiscountConditionRecord::getNewInstance($subs[1], $someManufacturer); $record->save(); $subs[1]->loadAll(); $sub->loadAll(); $condition->loadAll(); $this->assertFalse(RuleCondition::create($subs[1])->isProductMatching($newProduct)); $this->assertFalse(RuleCondition::create($condition)->isProductMatching($newProduct)); // true $subs[2]->save(); $record = DiscountConditionRecord::getNewInstance($subs[2], $newProduct); $record->save(); $subs[2]->loadAll(); $sub->loadAll(); $condition->loadAll(); $this->assertTrue(RuleCondition::create($condition)->isProductMatching($newProduct)); }
public function testDiscountByAdditionalCategories() { $product = $this->products[1]; $condition = DiscountCondition::getNewInstance(); $condition->isEnabled->set(true); $condition->save(); $actionCondition = DiscountCondition::getNewInstance(); $actionCondition->isEnabled->set(true); $actionCondition->conditionClass->set('RuleConditionContainsProduct'); $actionCondition->save(); $action = DiscountAction::getNewInstance($condition); $action->actionCondition->set($actionCondition); $action->isEnabled->set(true); $action->type->set(DiscountAction::TYPE_ITEM_DISCOUNT); $action->amount->set(10); $action->actionClass->set('RuleActionPercentageDiscount'); $action->save(); $randomCategory = Category::getNewInstance(Category::getRootNode()); $randomCategory->save(); DiscountConditionRecord::getNewInstance($actionCondition, $randomCategory)->save(); $this->order->addProduct($product, 1, true); $this->order->save(); Category::recalculateProductsCount(); $product->reload(); $this->assertFalse(RuleCondition::create($actionCondition)->isProductMatching($product)); $customCategory = Category::getNewInstance(Category::getRootNode()); $customCategory->save(); ProductCategory::getNewInstance($product, $customCategory)->save(); DiscountConditionRecord::getNewInstance($actionCondition, $customCategory)->save(); Category::recalculateProductsCount(); $product->reload(); $actionCondition->loadAll(); $this->assertTrue(RuleCondition::create($actionCondition)->isProductMatching($product)); $this->assertEquals(count($this->order->getDiscountActions(true)), 1); $this->assertEquals($this->products[1]->getPrice($this->usd) * 0.9, $this->order->getTotal(true)); ActiveRecordModel::clearPool(); $order = CustomerOrder::getInstanceByID($this->order->getID()); $order->loadAll(); $this->assertEquals($this->products[1]->getPrice($this->usd) * 0.9, $this->order->getTotal(true)); }
private function updateRuleCache() { $paths = array(); $app = ActiveRecordModel::getApplication(); foreach (array('condition', 'action') as $type) { $path = 'application.model.businessrule.' . $type; foreach ($app->getPluginClasses($path) as $class) { $paths[$class] = $app->getPluginClassPath($path, $class); } } $f = select(eq('DiscountCondition.isEnabled', true)); $f->setOrder(f('DiscountCondition.position')); $conditions = ActiveRecord::getRecordSetArray('DiscountCondition', $f); $idMap = array(); foreach ($conditions as &$condition) { $idMap[$condition['ID']] =& $condition; } // get condition records foreach (ActiveRecord::getRecordSetArray('DiscountConditionRecord', select(), array('Category')) as $record) { $idMap[$record['conditionID']]['records'][] = $record; } // get actions $f = select(); $f->setOrder(f('DiscountAction.position')); foreach (ActiveRecord::getRecordSetArray('DiscountAction', $f) as $action) { if (!empty($action['actionConditionID'])) { $action['condition'] =& $idMap[$action['actionConditionID']]; } $idMap[$action['conditionID']]['actions'][] = $action; } foreach ($conditions as &$condition) { if (!$condition['parentNodeID'] || !isset($idMap[$condition['parentNodeID']]) || !empty($condition['isActionCondition'])) { continue; } $idMap[$condition['parentNodeID']]['sub'][] =& $condition; } $rootCond = RuleCondition::createFromArray($idMap[DiscountCondition::ROOT_ID]); file_put_contents(self::getRuleFile(), '<?php $paths = ' . var_export($paths, true) . '; foreach ($paths as $path) { include_once($path); } return ' . var_export(serialize($rootCond->getConditions()), true) . '; ?>'); }