public function testRun() { //Create workflow $workflow = new Workflow(); $workflow->setDescription('aDescription'); $workflow->setIsActive(true); $workflow->setOrder(5); $workflow->setModuleClassName('WorkflowsTest2Module'); $workflow->setName('myFirstWorkflow'); $workflow->setTriggerOn(Workflow::TRIGGER_ON_NEW_AND_EXISTING); $workflow->setType(Workflow::TYPE_ON_SAVE); $workflow->setTriggersStructure('1'); //Add action that is missing required owner $action = new ActionForWorkflowForm('WorkflowModelTestItem2', Workflow::TYPE_ON_SAVE); $action->type = ActionForWorkflowForm::TYPE_CREATE; $action->relation = 'hasMany2'; $attributes = array('string' => array('shouldSetValue' => '1', 'type' => WorkflowActionAttributeForm::TYPE_STATIC, 'value' => 'jason'), 'lastName' => array('shouldSetValue' => '1', 'type' => WorkflowActionAttributeForm::TYPE_STATIC, 'value' => 'jason')); $action->setAttributes(array(ActionForWorkflowForm::ACTION_ATTRIBUTES => $attributes)); $workflow->addAction($action); //Create the saved Workflow $savedWorkflow = new SavedWorkflow(); SavedWorkflowToWorkflowAdapter::resolveWorkflowToSavedWorkflow($workflow, $savedWorkflow); $saved = $savedWorkflow->save(); $this->assertTrue($saved); $this->assertEquals(0, count(Notification::getAll())); $job = new WorkflowValidityCheckJob(); $this->assertTrue($job->run()); $notifications = Notification::getAll(); $this->assertEquals(1, count($notifications)); }
/** * @param WorkflowMessageInQueue $workflowMessageInQueue * @param RedBeanModel $model */ protected function processWorkflowMessageInQueue(WorkflowMessageInQueue $workflowMessageInQueue, RedBeanModel $model) { $workflow = SavedWorkflowToWorkflowAdapter::makeWorkflowBySavedWorkflow($workflowMessageInQueue->savedWorkflow); if (!$workflow->getIsActive()) { return; } WorkflowEmailMessagesUtil::processOnWorkflowMessageInQueueJob($workflow, $model, self::resolveTriggeredByUser($workflowMessageInQueue)); }
protected function makeSampleOnSaveWorkflow() { Yii::app()->user->userModel = User::getByUsername('super'); $emailTemplate = new EmailTemplate(); $emailTemplate->type = EmailTemplate::TYPE_WORKFLOW; $emailTemplate->builtType = EmailTemplate::BUILT_TYPE_BUILDER_TEMPLATE; $emailTemplate->subject = 'We closed a deal'; $emailTemplate->name = 'We closed a deal - Sample Email Template'; $emailTemplate->textContent = 'Hello!!! We just closed new deal, please check details: [[MODEL^URL]] Thanks!'; $emailTemplate->htmlContent = '<p>Hello!!!</p> <p>We just closed new deal, please check details: [[MODEL^URL]]</p> <p>Thanks!</p>'; $emailTemplate->modelClassName = 'Opportunity'; $emailTemplate->isDraft = false; $emailTemplate->save(); $trigger = new TriggerForWorkflowForm('OpportunitiesModule', 'Opportunity', Workflow::TYPE_ON_SAVE); $trigger->attributeIndexOrDerivedType = 'stage'; $trigger->value = 'Closed Won'; $trigger->operator = OperatorRules::TYPE_BECOMES; $trigger->relationFilter = TriggerForWorkflowForm::RELATION_FILTER_ANY; $message = new EmailMessageForWorkflowForm('Opportunity', Workflow::TYPE_ON_SAVE); $message->sendAfterDurationInterval = 0; $message->sendAfterDurationType = TimeDurationUtil::DURATION_TYPE_MINUTE; $message->emailTemplateId = $emailTemplate->id; $message->sendFromType = EmailMessageForWorkflowForm::SEND_FROM_TYPE_DEFAULT; $recipients = array(array('type' => WorkflowEmailMessageRecipientForm::TYPE_STATIC_ADDRESS, 'audienceType' => EmailMessageRecipient::TYPE_TO, 'toName' => 'The Sales Team', 'toAddress' => '*****@*****.**')); $message->setAttributes(array(EmailMessageForWorkflowForm::EMAIL_MESSAGE_RECIPIENTS => $recipients)); $workflow = new Workflow(); $workflow->setDescription('This will send an email to recipients that you choose when you close a deal!'); $workflow->setIsActive(false); $workflow->setOrder(2); $workflow->setModuleClassName('OpportunitiesModule'); $workflow->setName('Closed won Opportunity alert'); $workflow->setTriggerOn(Workflow::TRIGGER_ON_NEW_AND_EXISTING); $workflow->setType(Workflow::TYPE_ON_SAVE); $workflow->setTriggersStructure('1'); $workflow->addTrigger($trigger); $workflow->addEmailMessage($message); $savedWorkflow = new SavedWorkflow(); SavedWorkflowToWorkflowAdapter::resolveWorkflowToSavedWorkflow($workflow, $savedWorkflow); $savedWorkflow->save(); }
/** * A test to show that the modifiedByUser works ok as a trigger with 'equals' on a newly created model. * @see testProcessBeforeSaveOnCreatedByUserEquals */ public function testProcessBeforeSaveOnModifiedByUserEquals() { Yii::app()->user->userModel = User::getByUsername('super'); //Create workflow $workflow = new Workflow(); $workflow->setDescription('aDescription'); $workflow->setIsActive(true); $workflow->setOrder(5); $workflow->setModuleClassName('AccountsModule'); $workflow->setName('myFirstWorkflow'); $workflow->setTriggerOn(Workflow::TRIGGER_ON_NEW_AND_EXISTING); $workflow->setType(Workflow::TYPE_ON_SAVE); $workflow->setTriggersStructure('1'); //Add trigger $trigger = new TriggerForWorkflowForm('AccountsTestModule', 'Account', $workflow->getType()); $trigger->attributeIndexOrDerivedType = 'modifiedByUser'; $trigger->value = Yii::app()->user->userModel->id; $trigger->operator = 'equals'; $workflow->addTrigger($trigger); //Add action $action = new ActionForWorkflowForm('Account', Workflow::TYPE_ON_SAVE); $action->type = ActionForWorkflowForm::TYPE_UPDATE_SELF; $attributes = array('name' => array('shouldSetValue' => '1', 'type' => WorkflowActionAttributeForm::TYPE_STATIC, 'value' => 'jason')); $action->setAttributes(array(ActionForWorkflowForm::ACTION_ATTRIBUTES => $attributes)); $workflow->addAction($action); //Create the saved Workflow $savedWorkflow = new SavedWorkflow(); SavedWorkflowToWorkflowAdapter::resolveWorkflowToSavedWorkflow($workflow, $savedWorkflow); $saved = $savedWorkflow->save(); $this->assertTrue($saved); //Confirm that the workflow processes and the attribute gets updated $model = new Account(); $model->name = 'aValue'; $this->assertTrue($model->save()); $this->assertEquals('jason', $model->name); }
/** * @param ByTimeWorkflowInQueue $byTimeWorkflowInQueue * @param RedBeanModel $model * @throws FailedToSaveModelException */ protected function processByTimeWorkflowInQueue(ByTimeWorkflowInQueue $byTimeWorkflowInQueue, RedBeanModel $model) { $workflow = SavedWorkflowToWorkflowAdapter::makeWorkflowBySavedWorkflow($byTimeWorkflowInQueue->savedWorkflow); if (!$workflow->getIsActive()) { return; } $workflow->setTimeTriggerRequireChangeToProcessToFalse(); if (WorkflowTriggersUtil::areTriggersTrueOnByTimeWorkflowQueueJob($workflow, $model)) { WorkflowActionsUtil::processOnByTimeWorkflowInQueueJob($workflow, $model, Yii::app()->user->userModel); WorkflowEmailMessagesUtil::processAfterSave($workflow, $model, Yii::app()->user->userModel); if ($model->isModified()) { $saved = $model->save(); if (!$saved) { throw new FailedToSaveModelException(); } } } }
protected function resolveSavedWorkflowAndWorkflowByPostData(array $postData, &$savedWorkflow, &$workflow, $type, $id = null, $isBeingCopied = false) { if ($id == null) { $this->resolveCanCurrentUserAccessWorkflows(); $savedWorkflow = new SavedWorkflow(); $workflow = new Workflow(); $workflow->setType($type); } elseif ($isBeingCopied) { $savedWorkflow = new SavedWorkflow(); $oldWorkflow = SavedWorkflow::getById(intval($id)); ControllerSecurityUtil::resolveAccessCanCurrentUserReadModel($oldWorkflow); ZurmoCopyModelUtil::copy($oldWorkflow, $savedWorkflow); $workflow = SavedWorkflowToWorkflowAdapter::makeWorkflowBySavedWorkflow($savedWorkflow); } else { $savedWorkflow = SavedWorkflow::getById(intval($id)); ControllerSecurityUtil::resolveAccessCanCurrentUserWriteModel($savedWorkflow); $workflow = SavedWorkflowToWorkflowAdapter::makeWorkflowBySavedWorkflow($savedWorkflow); } DataToWorkflowUtil::resolveWorkflowByWizardPostData($workflow, $postData, WorkflowToWizardFormAdapter::getFormClassNameByType($type)); }
/** * @depends testResolveAfterSaveByModel */ public function testResolveAfterSaveByModelForByTime() { //Create workflow $workflow = new Workflow(); $workflow->setDescription('aDescription'); $workflow->setIsActive(true); $workflow->setOrder(5); $workflow->setModuleClassName('WorkflowsTestModule'); $workflow->setName('myFirstWorkflow'); $workflow->setTriggerOn(Workflow::TRIGGER_ON_NEW_AND_EXISTING); $workflow->setType(Workflow::TYPE_BY_TIME); $workflow->setTriggersStructure('1'); $workflow->setIsActive(true); //Add time trigger $trigger = new TimeTriggerForWorkflowForm('WorkflowsTestModule', 'WorkflowModelTestItem', $workflow->getType()); $trigger->attributeIndexOrDerivedType = 'date'; $trigger->durationSeconds = '500'; $trigger->valueType = 'Is Time For'; $workflow->setTimeTrigger($trigger); //Create the saved Workflow $savedWorkflow = new SavedWorkflow(); SavedWorkflowToWorkflowAdapter::resolveWorkflowToSavedWorkflow($workflow, $savedWorkflow); $saved = $savedWorkflow->save(); $this->assertTrue($saved); $workflow->setId($savedWorkflow->id); //set Id back. $model = new WorkflowModelTestItem(); $model->lastName = 'something'; $model->string = 'aValue'; $model->date = '2013-03-03'; $saved = $model->save(); $this->assertTrue($saved); $model->addWorkflowToProcessAfterSave($workflow); $this->assertEquals(0, count(ByTimeWorkflowInQueue::getAll())); SavedWorkflowsUtil::resolveAfterSaveByModel($model, Yii::app()->user->userModel); $this->assertEquals(1, count(ByTimeWorkflowInQueue::getAll())); }
public function testWorkflowDoesLinkRelatedModelWhenPermissionsIsSetToOwner() { $super = $this->logoutCurrentUserLoginNewUserAndGetByUsername('super'); $contactStates = ContactState::getAll(); $this->assertEquals(0, Contact::getCount()); //Create workflow $workflow = new Workflow(); $workflow->setDescription('aDescription'); $workflow->setIsActive(true); $workflow->setOrder(5); $workflow->setModuleClassName('AccountsModule'); $workflow->setName('myFirstWorkflow'); $workflow->setTriggerOn(Workflow::TRIGGER_ON_NEW_AND_EXISTING); $workflow->setType(Workflow::TYPE_ON_SAVE); $workflow->setTriggersStructure('1'); //Add action $action = new ActionForWorkflowForm('Account', Workflow::TYPE_ON_SAVE); $action->type = ActionForWorkflowForm::TYPE_CREATE; $action->relation = 'contacts'; $attributes = array('lastName' => array('shouldSetValue' => '1', 'type' => WorkflowActionAttributeForm::TYPE_STATIC, 'value' => 'smith'), 'firstName' => array('shouldSetValue' => '1', 'type' => WorkflowActionAttributeForm::TYPE_STATIC, 'value' => 'john'), 'owner__User' => array('shouldSetValue' => '1', 'type' => WorkflowActionAttributeForm::TYPE_STATIC, 'value' => Yii::app()->user->userModel->id), 'state' => array('shouldSetValue' => '1', 'type' => WorkflowActionAttributeForm::TYPE_STATIC, 'value' => $contactStates[0]->id)); $action->setAttributes(array(ActionForWorkflowForm::ACTION_ATTRIBUTES => $attributes)); $workflow->addAction($action); //Create the saved Workflow $savedWorkflow = new SavedWorkflow(); SavedWorkflowToWorkflowAdapter::resolveWorkflowToSavedWorkflow($workflow, $savedWorkflow); $saved = $savedWorkflow->save(); $this->assertTrue($saved); $account = new Account(); $account->name = 'myTestAccount'; $account->owner = $super; $account->save(); RedBeanModel::forgetAll(); $contacts = Contact::getAll(); $this->assertCount(1, $contacts); $this->assertEquals('myTestAccount', $contacts[0]->account->name); $this->assertEquals('john smith', strval($account->contacts[0])); $this->assertTrue($account->contacts[0]->id > 0); }
public function testProcessAfterSaveWhenSendIsInFuture() { $this->assertEquals(0, count(WorkflowMessageInQueue::getAll())); $workflow = new Workflow(); $workflow->setId(self::$savedWorkflow->id); $workflow->type = Workflow::TYPE_ON_SAVE; $emailMessageForm = new EmailMessageForWorkflowForm('WorkflowModelTestItem', Workflow::TYPE_ON_SAVE); $emailMessageForm->sendAfterDurationSeconds = 86400; $recipients = array(array('type' => WorkflowEmailMessageRecipientForm::TYPE_DYNAMIC_TRIGGERED_MODEL_USER, 'audienceType' => EmailMessageRecipient::TYPE_TO, 'dynamicUserType' => DynamicTriggeredModelUserWorkflowEmailMessageRecipientForm::DYNAMIC_USER_TYPE_CREATED_BY_USER)); $emailMessageForm->setAttributes(array(EmailMessageForWorkflowForm::EMAIL_MESSAGE_RECIPIENTS => $recipients)); $workflow->addEmailMessage($emailMessageForm); $model = new WorkflowModelTestItem(); $model->lastName = 'lastName'; $model->string = 'string'; $this->assertTrue($model->save()); $compareDateTime = DateTimeUtil::convertTimestampToDbFormatDateTime(time() + 86400); WorkflowEmailMessagesUtil::processAfterSave($workflow, $model, Yii::app()->user->userModel); $workflowMessageInQueues = WorkflowMessageInQueue::getAll(); $this->assertEquals(1, count($workflowMessageInQueues)); $this->assertTrue($workflowMessageInQueues[0]->savedWorkflow->isSame(self::$savedWorkflow)); $this->assertTrue($workflowMessageInQueues[0]->triggeredByUser->isSame(Yii::app()->user->userModel)); $this->assertEquals($model->getClassId('Item'), $workflowMessageInQueues[0]->modelItem->getClassId('Item')); $this->assertEquals('WorkflowModelTestItem', $workflowMessageInQueues[0]->modelClassName); $this->assertEquals($compareDateTime, $workflowMessageInQueues[0]->processDateTime); $emailMessageData = SavedWorkflowToWorkflowAdapter::makeArrayFromEmailMessageForWorkflowFormAttributesData(array($emailMessageForm)); $this->assertEquals(serialize($emailMessageData), $workflowMessageInQueues[0]->serializedData); $this->assertTrue($workflowMessageInQueues[0]->delete()); }
/** * @depends testProcessBeforeSave */ public function testProcessAfterSave() { //Save everyone group $group = Group::getByName(Group::EVERYONE_GROUP_NAME); $this->assertTrue($group->save()); //Create workflow $workflow = new Workflow(); $workflow->setDescription('aDescription'); $workflow->setIsActive(true); $workflow->setOrder(5); $workflow->setModuleClassName('WorkflowsTestModule'); $workflow->setName('myFirstWorkflow'); $workflow->setTriggerOn(Workflow::TRIGGER_ON_NEW_AND_EXISTING); $workflow->setType(Workflow::TYPE_ON_SAVE); $workflow->setTriggersStructure('1'); $workflow->setIsActive(true); //Add trigger $trigger = new TriggerForWorkflowForm('WorkflowsTestModule', 'WorkflowModelTestItem', $workflow->getType()); $trigger->attributeIndexOrDerivedType = 'string'; $trigger->value = 'aValue'; $trigger->operator = 'equals'; $workflow->addTrigger($trigger); //Add action $action = new ActionForWorkflowForm('WorkflowModelTestItem', Workflow::TYPE_ON_SAVE); $action->type = ActionForWorkflowForm::TYPE_CREATE; $action->relation = 'hasOne'; $attributes = array('name' => array('shouldSetValue' => '1', 'type' => WorkflowActionAttributeForm::TYPE_STATIC, 'value' => 'jason'), 'permissions' => array('shouldSetValue' => '1', 'type' => ExplicitReadWriteModelPermissionsWorkflowActionAttributeForm::TYPE_DYNAMIC_EVERYONE_GROUP)); $action->setAttributes(array(ActionForWorkflowForm::ACTION_ATTRIBUTES => $attributes)); $workflow->addAction($action); //Create the saved Workflow $savedWorkflow = new SavedWorkflow(); SavedWorkflowToWorkflowAdapter::resolveWorkflowToSavedWorkflow($workflow, $savedWorkflow); $saved = $savedWorkflow->save(); $this->assertTrue($saved); $model = new WorkflowModelTestItem(); $model->string = 'aValue'; $saved = $savedWorkflow->save(); $this->assertTrue($saved); $this->assertEquals(0, WorkflowModelTestItem2::getCount()); WorkflowActionsUtil::processAfterSave($workflow, $model, Yii::app()->user->userModel); $workflowModelTestItem2s = WorkflowModelTestItem2::getAll(); $this->assertEquals(1, count($workflowModelTestItem2s)); //Confirm permissions are on the everyone group $explicitReadWriteModelPermissions = ExplicitReadWriteModelPermissionsUtil::makeBySecurableItem($workflowModelTestItem2s[0]); $this->assertEquals(1, $explicitReadWriteModelPermissions->getReadWritePermitablesCount()); $readWritePermitables = $explicitReadWriteModelPermissions->getReadWritePermitables(); $everyoneGroup = Group::getByName(Group::EVERYONE_GROUP_NAME); $this->assertTrue(isset($readWritePermitables[$everyoneGroup->getClassId('Permitable')])); }
/** * Given a RedBeanModel, query workflow rules and process any beforeSave triggers for either on-save or * by-time workflows. Called from @see WokflowsObserver->processWorkflowBeforeSave * @param Item $model * @param User $triggeredByUser * @throws NotSupportedException if the workflow type is not valid */ public static function resolveBeforeSaveByModel(Item $model, User $triggeredByUser) { $savedWorkflows = SavedWorkflow::getActiveByModuleClassNameAndIsNewModel($model::getModuleClassName(), $model->getIsNewModel()); foreach ($savedWorkflows as $savedWorkflow) { $workflow = SavedWorkflowToWorkflowAdapter::makeWorkflowBySavedWorkflow($savedWorkflow); if (WorkflowTriggersUtil::areTriggersTrueBeforeSave($workflow, $model)) { if ($workflow->getType() == Workflow::TYPE_BY_TIME) { $model->addWorkflowToProcessAfterSave($workflow); } elseif ($workflow->getType() == Workflow::TYPE_ON_SAVE) { WorkflowActionsUtil::processBeforeSave($workflow, $model, $triggeredByUser); $model->addWorkflowToProcessAfterSave($workflow); } else { throw new NotSupportedException(); } } } }
/** * @depends testResolveWorkflowToSavedWorkflow */ public function testMakeWorkflowBySavedWorkflow() { $savedWorkflows = SavedWorkflow::getAll(); $this->assertEquals(1, count($savedWorkflows)); $savedWorkflow = $savedWorkflows[0]; $workflow = SavedWorkflowToWorkflowAdapter::makeWorkflowBySavedWorkflow($savedWorkflow); $triggers = $workflow->getTriggers(); $this->assertEquals('WorkflowsTestModule', $workflow->getModuleClassName()); $this->assertEquals('myFirstWorkflow', $workflow->getName()); $this->assertEquals('aDescription', $workflow->getDescription()); $this->assertTrue($workflow->getIsActive()); $this->assertEquals(5, $workflow->getOrder()); $this->assertEquals(Workflow::TRIGGER_ON_NEW, $workflow->getTriggerOn()); $this->assertEquals(Workflow::TYPE_ON_SAVE, $workflow->getType()); $this->assertEquals('1 and 2 or 3 or 4', $workflow->getTriggersStructure()); $this->assertCount(4, $triggers); }
/** * Tests that a bug involving creating a required custom picklist on projects causes the workflow * to break when creating a task */ public function testProcessWorkflowForTaskWhenProjectAsARequiredCustomPicklist() { Yii::app()->user->userModel = User::getByUsername('super'); //Create a required picklist for projects ModulesSearchWithDataProviderTestHelper::createDropDownAttribute(new Project(), 'pick', true); //Create workflow $workflow = new Workflow(); $workflow->setDescription('aDescription'); $workflow->setIsActive(true); $workflow->setOrder(5); $workflow->setModuleClassName('TasksModule'); $workflow->setName('myFirstWorkflow'); $workflow->setTriggerOn(Workflow::TRIGGER_ON_NEW_AND_EXISTING); $workflow->setType(Workflow::TYPE_BY_TIME); $workflow->setTriggersStructure('1'); //Add trigger $trigger = new TimeTriggerForWorkflowForm('TasksModule', 'Task', $workflow->getType()); $trigger->attributeIndexOrDerivedType = 'dueDateTime'; $trigger->valueType = MixedDateTypesSearchFormAttributeMappingRules::TYPE_IS_TIME_FOR; $trigger->durationInterval = 5; $trigger->durationType = TimeDurationUtil::DURATION_TYPE_MONTH; $trigger->durationSign = TimeDurationUtil::DURATION_SIGN_NEGATIVE; $workflow->setTimeTrigger($trigger); //Create the saved Workflow $savedWorkflow = new SavedWorkflow(); SavedWorkflowToWorkflowAdapter::resolveWorkflowToSavedWorkflow($workflow, $savedWorkflow); $saved = $savedWorkflow->save(); $this->assertTrue($saved); //Confirm that the workflow processes $model = new Task(); $model->name = 'aTask'; $model->dueDateTime = DateTimeUtil::convertTimestampToDbFormatDateTime(time()); $this->assertTrue($model->save()); }
public static function getWorkflowsMissingRequiredActionAttributes() { $savedWorkflows = SavedWorkflow::getAll(); $workflows = array(); foreach ($savedWorkflows as $savedWorkflow) { $workflow = SavedWorkflowToWorkflowAdapter::makeWorkflowBySavedWorkflow($savedWorkflow); $missingRequired = false; foreach ($workflow->getActions() as $action) { if ($action->isModelActionVariant() && !$action->isTypeAnUpdateVariant() && $action->isMissingRequiredActionAttributes()) { $missingRequired = true; break; } } if ($missingRequired) { $workflows[] = $workflow; } } return $workflows; }
public function testRunWithMissingTriggerMultiselectPicklistValue() { $this->clearNotificationsWorkflowsAndEmailMessages(); $this->createStageValues(); //Create workflow $workflow = new Workflow(); $workflow->setDescription('bDescription'); $workflow->setIsActive(true); $workflow->setOrder(5); $workflow->setModuleClassName('OpportunitiesModule'); $workflow->setName('mySecondWorkflow'); $workflow->setTriggerOn(Workflow::TRIGGER_ON_NEW_AND_EXISTING); $workflow->setType(Workflow::TYPE_ON_SAVE); $workflow->setTriggersStructure('1'); $trigger = new TriggerForWorkflowForm('OpportunitiesModule', 'Opportunity', Workflow::TYPE_ON_SAVE); $trigger->attributeIndexOrDerivedType = 'stage'; $trigger->value = 'Closed Won,Negotiating'; $trigger->operator = OperatorRules::TYPE_ONE_OF; $trigger->relationFilter = TriggerForWorkflowForm::RELATION_FILTER_ANY; $workflow->addTrigger($trigger); //Create the saved Workflow $savedWorkflow = new SavedWorkflow(); SavedWorkflowToWorkflowAdapter::resolveWorkflowToSavedWorkflow($workflow, $savedWorkflow); $saved = $savedWorkflow->save(); $this->assertTrue($saved); $this->assertEquals(0, Notification::getCount()); $this->assertEquals(0, EmailMessage::getCount()); $job = new WorkflowValidityCheckJob(); $this->assertTrue($job->run()); $this->assertEquals(0, Notification::getCount()); $this->assertEquals(0, EmailMessage::getCount()); $this->clearNotificationsWorkflowsAndEmailMessages(); $workflow = new Workflow(); $workflow->setDescription('cDescription'); $workflow->setIsActive(true); $workflow->setOrder(5); $workflow->setModuleClassName('OpportunitiesModule'); $workflow->setName('mySecondWorkflow'); $workflow->setTriggerOn(Workflow::TRIGGER_ON_NEW_AND_EXISTING); $workflow->setType(Workflow::TYPE_ON_SAVE); $workflow->setTriggersStructure('1'); $trigger = new TriggerForWorkflowForm('OpportunitiesModule', 'Opportunity', Workflow::TYPE_ON_SAVE); $trigger->attributeIndexOrDerivedType = 'stage'; $trigger->value = 'Closed Won,Unexisting state'; $trigger->operator = OperatorRules::TYPE_BECOMES; $trigger->relationFilter = TriggerForWorkflowForm::RELATION_FILTER_ANY; $workflow->addTrigger($trigger); //Create the saved Workflow $savedWorkflow = new SavedWorkflow(); SavedWorkflowToWorkflowAdapter::resolveWorkflowToSavedWorkflow($workflow, $savedWorkflow); $saved = $savedWorkflow->save(); $this->assertTrue($saved); $this->assertEquals(0, Notification::getCount()); $this->assertEquals(0, EmailMessage::getCount()); $job = new WorkflowValidityCheckJob(); $this->assertTrue($job->run()); $this->assertEquals(1, Notification::getCount()); $this->assertEquals(1, EmailMessage::getCount()); }
/** * Check if picklist modification caused some issues with workflow triggers and if yes notify users * @return array * @throws NotSupportedException */ public static function getWorkflowsWithInvalidTriggerCustomFieldValue() { $savedWorkflows = SavedWorkflow::getAll(); $workflows = array(); foreach ($savedWorkflows as $savedWorkflow) { $workflow = SavedWorkflowToWorkflowAdapter::makeWorkflowBySavedWorkflow($savedWorkflow); $hasInvalidCustomFieldValue = false; foreach ($workflow->getTriggers() as $trigger) { $modelClassName = $trigger->getModelClassName(); $customFieldAttributeNames = CustomFieldUtil::getCustomFieldAttributeNames($modelClassName); $triggerAttributeName = $trigger->getAttribute(); if (in_array($triggerAttributeName, $customFieldAttributeNames)) { $customFieldData = CustomFieldDataModelUtil::getDataByModelClassNameAndAttributeName($modelClassName, $triggerAttributeName); $allCustomFieldValues = unserialize($customFieldData->serializedData); // Check with triggers that allow single value if (in_array($trigger->getOperator(), array(OperatorRules::TYPE_EQUALS, OperatorRules::TYPE_DOES_NOT_EQUAL, OperatorRules::TYPE_BECOMES, OperatorRules::TYPE_WAS))) { if (!in_array($trigger->value, $allCustomFieldValues)) { $hasInvalidCustomFieldValue = true; break; } } elseif (in_array($trigger->getOperator(), array(OperatorRules::TYPE_BECOMES_ONE_OF, OperatorRules::TYPE_WAS_ONE_OF, OperatorRules::TYPE_ONE_OF))) { $triggerSelectedCustomFieldValues = MultiSelectDropDownSanitizerUtil::getCustomFieldValuesFromValueString($trigger->value); foreach ($triggerSelectedCustomFieldValues as $triggerValue) { if (!in_array($triggerValue, $allCustomFieldValues)) { $hasInvalidCustomFieldValue = true; break 2; } } } } } if ($hasInvalidCustomFieldValue) { $workflows[] = $workflow; } } return $workflows; }
/** * @param Workflow $workflow * @param EmailMessageForWorkflowForm $emailMessage * @param RedBeanModel $model * @param User $triggeredByUser * @throws FailedToSaveModelException */ protected static function processEmailMessageAfterSave(Workflow $workflow, EmailMessageForWorkflowForm $emailMessage, RedBeanModel $model, User $triggeredByUser) { if ($emailMessage->sendAfterDurationInterval == 0) { $helper = new WorkflowEmailMessageProcessingHelper($emailMessage, $model, $triggeredByUser); $helper->process(); } else { $emailMessageData = SavedWorkflowToWorkflowAdapter::makeArrayFromEmailMessageForWorkflowFormAttributesData(array($emailMessage)); $workflowMessageInQueue = new WorkflowMessageInQueue(); $workflowMessageInQueue->processDateTime = DateTimeUtil::convertTimestampToDbFormatDateTime($emailMessage->resolveNewTimeStampForDuration(time())); $workflowMessageInQueue->savedWorkflow = SavedWorkflow::getById((int) $workflow->getId()); $workflowMessageInQueue->modelClassName = get_class($model); $workflowMessageInQueue->modelItem = $model; $workflowMessageInQueue->serializedData = serialize($emailMessageData); $workflowMessageInQueue->triggeredByUser = $triggeredByUser; $saved = $workflowMessageInQueue->save(); if (!$saved) { throw new FailedToSaveModelException(); } } }
public function testUpdateRelatedCatalogItemOnAProductBySellPriceCriteria() { $super = User::getByUsername('super'); $contactStates = ContactState::getAll(); //Create workflow $workflow = new Workflow(); $workflow->setDescription('aDescription'); $workflow->setIsActive(true); $workflow->setOrder(1); $workflow->setModuleClassName('ProductsModule'); $workflow->setName('myFirstProductWorkflow'); $workflow->setTriggerOn(Workflow::TRIGGER_ON_NEW_AND_EXISTING); $workflow->setType(Workflow::TYPE_ON_SAVE); $workflow->setTriggersStructure('1'); //Add Trigger $trigger = new TriggerForWorkflowForm('ProductsModule', 'Product', Workflow::TYPE_ON_SAVE); $trigger->attributeIndexOrDerivedType = 'sellPrice'; $trigger->value = 600; $trigger->operator = 'greaterThanOrEqualTo'; $workflow->addTrigger($trigger); //Add action $currencies = Currency::getAll(); $action = new ActionForWorkflowForm('Product', Workflow::TYPE_ON_SAVE); $action->type = ActionForWorkflowForm::TYPE_UPDATE_RELATED; $action->relation = 'productTemplate'; $attributes = array('description' => array('shouldSetValue' => '1', 'type' => WorkflowActionAttributeForm::TYPE_STATIC, 'value' => 'Set Price'), 'priceFrequency' => array('shouldSetValue' => '1', 'type' => WorkflowActionAttributeForm::TYPE_STATIC, 'value' => 2), 'listPrice' => array('shouldSetValue' => '1', 'type' => WorkflowActionAttributeForm::TYPE_STATIC, 'value' => 800, 'currencyId' => $currencies[0]->id), 'cost' => array('shouldSetValue' => '1', 'type' => WorkflowActionAttributeForm::TYPE_STATIC, 'value' => 700, 'currencyId' => $currencies[0]->id)); $action->setAttributes(array(ActionForWorkflowForm::ACTION_ATTRIBUTES => $attributes)); $workflow->addAction($action); //Create the saved Workflow $savedWorkflow = new SavedWorkflow(); SavedWorkflowToWorkflowAdapter::resolveWorkflowToSavedWorkflow($workflow, $savedWorkflow); $saved = $savedWorkflow->save(); $this->assertTrue($saved); $productTemplate = ProductTemplateTestHelper::createProductTemplateByName('superProductTemplate'); $productTemplates = ProductTemplate::getByName('superProductTemplate'); $product = ProductTestHelper::createProductByNameForOwner('Test Product', $super); $this->assertTrue($product->id > 0); $product->productTemplate = $productTemplates[0]; //Change product sell price $product->sellPrice->value = 650; $this->assertTrue(WorkflowTriggersUtil::areTriggersTrueBeforeSave($workflow, $product)); $saved = $product->save(); $this->assertTrue($saved); $productId = $product->id; $product->forget(); $product = Product::getById($productId); $this->assertEquals('Set Price', $product->productTemplate->description); $this->assertEquals(2, $product->productTemplate->priceFrequency); $this->assertEquals(700, $product->productTemplate->cost->value); $this->assertEquals(800, $product->productTemplate->listPrice->value); }