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);
     }
 }
Пример #2
0
 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;
 }
Пример #3
0
 /**
  * 将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;
         }
     }
 }
Пример #4
0
 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));
 }
Пример #5
0
 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));
 }
Пример #6
0
 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) . '; ?>');
 }