You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

599 lines
18 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "SB_handler.h"
#include "string_helper.h"
using namespace std;
#include <string>
#include <vector>
#include <map>
#include <sstream>
#include <cstring>
#include <iostream>
#define debug true
#define ITK_err 919012
bool inArrays(const std::vector<std::string>& vec, const std::string& value) {
for (const auto& item : vec) {
if (item == value) {
return true;
}
}
return false;
}
void getVector(const char* value, std::vector<std::string>& targetVector, char delimiter) {
std::string strValue(value);
std::stringstream ss(strValue);
std::string item;
// 尝试用指定的分隔符分割字符串
if (std::getline(ss, item, delimiter)) {
// 如果能成功分割,则继续分割剩余部分
targetVector.push_back(item);
while (std::getline(ss, item, delimiter)) {
targetVector.push_back(item);
}
}
else {
// 如果不能分割则将整个字符串添加到vector中
targetVector.push_back(strValue);
}
}
int getPrefStrings(const char* preference, TC_preference_search_scope_t scope, vector<string>& pref_vec)
{
int ifail = ITK_ok, i = 0, j = 0, k = 0, num = 0;
char** values;
TC_preference_search_scope_t old_scope;
//ITKCALL(ifail = PREF_ask_search_scope(&old_scope));
//ITKCALL(ifail = PREF_set_search_scope(scope));
//ITKCALL(ifail = PREF_ask_char_values(preference, &num, &values));
ITKCALL(ifail = PREF_ask_char_values_at_location(preference, scope, &num, &values));
if (ifail != ITK_ok) {
return ifail;
}
for (i = 0; i < num; i++)
{
pref_vec.push_back(values[i]);
}
MEM_free(values);
//ITKCALL(ifail = PREF_set_search_scope(old_scope));
return ifail;
}
void setProcessPointUser(std::string uerID) {
tag_t subtask; //流程节点
string id;//用户id
POM_AM__set_application_bypass(true);
tag_t tmp_select_signoff_task = NULLTAG;
ITKCALL(EPM_ask_sub_task(subtask, EPM_select_signoff_team_task, &tmp_select_signoff_task));
tag_t user;
ITKCALL(SA_find_user2(uerID.c_str(), &user));
int signoff_cnt = 0;
tag_t* signoffs = NULL;
tag_t member = NULL;
SIGNOFF_TYPE_t type;
ITKCALL(EPM_ask_signoff_member(tmp_select_signoff_task, &member, &type));
ITKCALL(EPM_remove_signoffs(tmp_select_signoff_task, 1, &member));
ITKCALL(EPM_create_adhoc_signoff(tmp_select_signoff_task, user, &signoff_cnt, &signoffs));
ITKCALL(EPM_set_adhoc_signoff_selection_done(tmp_select_signoff_task, true));
if (signoffs)
{
MEM_free(signoffs);
signoffs = NULL;
}
POM_AM__set_application_bypass(false);
}
int SB6_PR_AutoAssign(EPM_action_message_t msg) {
printf("========================= SB6_PR_AutoAssign Start ===================\n");
int ifail = ITK_ok;
char* argName = NULL, * argValue = NULL, * arg = NULL;
char objTypes[1024] = "", props[1024] = "",pre_str[1024] = "";
bool isExistRev = false;
int arg_cnt = TC_number_of_arguments(msg.arguments);
printf("参数个数为:%d\n", arg_cnt);
if (arg_cnt > 0)
{
for (int i = 0; i < arg_cnt; i++)
{
arg = TC_next_argument(msg.arguments);
ifail = ITK_ask_argument_named_value((const char*)arg, &argName, &argValue);
if (strcmp(argName, "type") == 0)
{
if (argValue != NULL)
{
strcpy(objTypes, argValue);
}
}
else if (stricmp(argName, "property") == 0)
{
if (argValue != NULL)
{
strcpy(props, argValue);
}
}
else if (stricmp(argName, "Option") == 0)
{
if (argValue != NULL)
{
strcpy(pre_str, argValue);
}
}
}
}
MEM_free(argName);
MEM_free(argValue);
std::vector<std::string> typeVector, propVector;
getVector(objTypes, typeVector, ';');
getVector(props, propVector, ';');
int prop_cnt = propVector.size();
vector<string> pre_values;
if (pre_str != "") {
getPrefStrings(pre_str, TC_preference_site, pre_values);
}
else {
EMH_store_error_s1(EMH_severity_error, ITK_err, "SB6_PR_AutoAssign流程Handler下Option配置的首选项为空!");
return ITK_err;
}
std::vector<std::vector<std::string>> preVectors;
int pre_cnt = 0;
for (const auto& value : pre_values) {
printf("首选项配置值为: %s\n", value.c_str());
std::vector<std::string> preVector;
getVector(value.c_str(), preVector, ';');
if (pre_cnt == 0) {
pre_cnt = preVector.size();
}
else if(prop_cnt != pre_cnt || pre_cnt != preVector.size()) {
EMH_store_error_s1(EMH_severity_error, ITK_err, "SB6_PR_AutoAssign流程Handler下Option的首选项配置长度不一致!");
return ITK_err;
}
preVectors.push_back(preVector);
}
tag_t attachmentTag = NULLTAG;
int attachmentCount = 0;
tag_t rootTask = NULLTAG, * attachmentTags = NULLTAG;
ITKCALL(ifail = EPM_ask_root_task(msg.task, &rootTask));
ITKCALL(ifail = EPM_ask_attachments(rootTask, EPM_target_attachment, &attachmentCount, &attachmentTags));
//遍历所有的流程目标下的对象
char* itemType = NULL;
for (int i = 0; i < attachmentCount; i++) {
attachmentTag = attachmentTags[i];
ITKCALL(ifail = AOM_ask_value_string(attachmentTag, "object_type", &itemType));
printf("当前遍历目标下的对象类型为: %s\n", itemType);
if (inArrays(typeVector, itemType)) {
ITKCALL(ifail = AOM_lock(attachmentTag));
//ITKCALL(ifail = AOM_set_value_string(attachmentTag, targetPropertyName, &propertyValue));
std::vector<std::string> valueVector;
char* tempValue = NULL;
for (const auto& prop : propVector) {
printf("==>获取属性: %s\n", prop);
ITKCALL(ifail = AOM_UIF_ask_value(attachmentTag, prop.c_str(), &tempValue));
printf("属性值为: %s\n", tempValue);
if (tempValue != NULL) {
valueVector.push_back(tempValue);
}
else {
valueVector.push_back("");
}
}
MEM_free(tempValue);
std::string userID;
boolean isMatch = false;
for (const auto& preVector : preVectors) {
printf("preVector: %d\n", preVector.size());
// 对比每个属性值是否匹配
for (size_t i = 0; i < preVector.size(); ++i) {
printf("比对属性值: %s || %s\n", preVector[i], valueVector[i]);
if (i == preVector.size() - 1) {
// 替换为分割逻辑:
std::string keyValuePair = preVector.back();
std::vector<std::string> tempVector;
getVector(keyValuePair.c_str(), tempVector, '=');
if (tempVector.size() == 2) {
if (tempVector[0] == valueVector[i]) {
userID = tempVector[1]; // 取等号后的部分
isMatch = true;
break;
}
}
else {
// 错误处理(根据需要添加)
userID = "";
printf("错误用户ID格式不正确: %s\n", keyValuePair.c_str());
EMH_store_error_s1(EMH_severity_error, ITK_err, "用户ID格式不正确");
return ITK_err;
}
}
else if (preVector[i] != valueVector[i]) {
break;
}
}
if (isMatch) {
break;
}
}
if (userID.empty()) {
continue;
}
printf("UserId : %s\n", userID);
//setProcessPointUser(userID);
POM_AM__set_application_bypass(true);
int mem_cnt = 0, signoff_cnt = 0, signmem_count = 0, * attach_type;
tag_t user_tag = NULLTAG, login_group = NULLTAG, * members = NULLTAG, * signoffs = NULLTAG, select_signoff_tag = NULLTAG, * attachmentTags = NULLTAG;
EPM_ask_sub_task(msg.task, EPM_select_signoff_team_task, &select_signoff_tag);
EPM_ask_all_attachments(select_signoff_tag, &signmem_count, &attachmentTags, &attach_type);
if (signmem_count == 0) {
ITKCALL(SA_find_user2(userID.c_str(), &user_tag));
if (user_tag != NULLTAG) {
ITKCALL(SA_ask_user_login_group(user_tag, &login_group));
ITKCALL(SA_find_groupmembers(user_tag, login_group, &mem_cnt, &members));
ITKCALL(EPM_create_adhoc_signoff(select_signoff_tag, user_tag, &signoff_cnt, &signoffs));
ITKCALL(EPM_set_adhoc_signoff_selection_done(select_signoff_tag, true));
printf("分配成功");
break;
}
else {
printf("nulll\n");
ITKCALL(EPM_promote_task(msg.task, ""));
}
}
POM_AM__set_application_bypass(false);
MEM_free(members);
MEM_free(signoffs);
ITKCALL(ifail = AOM_unlock(attachmentTag));
}
}
MEM_free(attachmentTags);
MEM_free(itemType);
return ifail;
}
#define DOFREE(obj) \
{ \
if(obj) \
{ \
MEM_free(obj); \
obj = NULL; \
} \
}
/**
* 判断某个对象是否是类或者子类
*
* @param objtag 要判断的对象
* @param type_name 类型的名称
*
*/
int checkIsTypeOrSubtype(tag_t objtag, char* type_name) {
tag_t type = NULLTAG,
item_type = NULLTAG;
int is_type = 0;
char* tag_name = NULL;
ITKCALL(AOM_ask_value_string(objtag, "object_name", &tag_name));
if (tag_name == NULL)
{
tag_name = "NULL";
}
ITKCALL(TCTYPE_ask_object_type(objtag, &type));
ITKCALL(TCTYPE_find_type(type_name, "", &item_type));
logical isok = false;
if (item_type != NULLTAG) {
logical isok = FALSE;
ITKCALL(TCTYPE_is_type_of(type, item_type, &isok));
if (isok)
{
//LOG_ECHO(("是子类%s\n", type_name));
printf("%s是子类%s\n", tag_name, type_name);
is_type = 1;
}
else
{
//LOG_ECHO(("不是子类%s\n", type_name));
printf("%s不是子类%s\n", tag_name, type_name);
is_type = 0;
}
}
DOFREE(tag_name);
return is_type;
}
/**
* 判断俩入参是否同源
*/
bool isTypeOf1(tag_t objtag, const char* type_name) {
tag_t type = NULLTAG;
TCTYPE_ask_object_type(objtag, &type);
tag_t item_type = NULLTAG;
TCTYPE_find_type(type_name, "", &item_type);
bool is_type = false;
if (item_type != NULLTAG) {
logical isok = FALSE;
TCTYPE_is_type_of(type, item_type, &isok);
if (isok) {
is_type = true;
}
}
return is_type;
}
/**
* @brief 根据不确定类型的tag_t对象获取item和itemRev对象
* @param check_tag
* @param item_tag
* @param rev_tag
* @return
*/
int get_item_and_rev(tag_t check_tag, tag_t* item_tag, tag_t* rev_tag) {
int ifail = ITK_ok;
if (isTypeOf1(check_tag, "Item")) {
printf("====当前处理的对象是item对象\n");
*item_tag = check_tag;
ITEM_ask_latest_rev(*item_tag, rev_tag);
}
else if (isTypeOf1(check_tag, "ItemRevision")) {
printf("====当前处理的对象是Revision对象\n");
*rev_tag = check_tag;
ITEM_ask_item_of_rev(*rev_tag, item_tag);
}
return ifail;
}
/*=============================================================================*
* FUNCTION: Origin_CheckTask_handler2
* PURPOSE : 校验交付物文件夹下数据是否发布
* INPUT:
* EPM_rule_message_t msg
*
* RETURN:
* int
*============================================================================*/
int Origin_CheckTask_handler2(EPM_rule_message_t msg)
{
EPM_decision_t err = EPM_go;
int ifail = ITK_ok;
int project_attachment_cnt = 0,
deliverable_cnt = 0,
sc_cnt = 0,
fold_cnt = 0,
fold_content_cnt = 0,
status_cnt = 0;
bool allowPass = true;
bool noItem = false;
bool status_is_configured = false;
tag_t* project_attachments = NULLTAG,
* deliverable_list = NULLTAG,
deliverable = NULLTAG,
* folds = NULLTAG,
* fold_contents = NULLTAG,
* status_list = NULLTAG,
item_tag = NULLTAG,
check_item = NULLTAG;
char* object_type = NULL;
//状态名称
char* status_name = NULL;
//流程下配置的状态参数
char status_config[1024] = "";
char *arg = NULL,
*argName = NULL,
*argValue = NULL;
/*LOG_ECHO(("*******************************************************************************\n"));
LOG_ECHO(("* Origin_CheckTask_handler is comming ! *\n"));
LOG_ECHO(("*******************************************************************************\n"));*/
printf("*******************************************************************************\n");
printf("* Origin_CheckTask_handler is comming ! *\n");
printf("*******************************************************************************\n");
//TODO 获取流程下配置的参数记得更新status_is_configured属性值为true
int arg_cnt = TC_number_of_arguments(msg.arguments);
if (arg_cnt > 0) {
printf("流程下配置的参数个数为:%d\n", arg_cnt);
for (int i = 0; i < arg_cnt; i++)
{
arg = TC_next_argument(msg.arguments);
ITKCALL(ITK_ask_argument_named_value((const char*)arg, &argName, &argValue));
printf("参数名称-配置值 = [%s - %s]\n", argName, argValue);
if (argName != NULL && argValue != NULL && strcmp(argName, "status") == 0) {
printf("状态名称:%s\n", argValue);
strcpy(status_config, argValue);
status_is_configured = true;
}
DOFREE(argName);
DOFREE(argValue);
}
}
else
{
printf("流程下没有配置参数\n");
}
ITKCALL(AOM_ask_value_tags(msg.task, "project_task_attachments", &project_attachment_cnt, &project_attachments));
if (project_attachment_cnt > 0)
{
ITKCALL(AOM_ask_value_tags(project_attachments[0], "sch_task_deliverable_list", &deliverable_cnt, &deliverable_list));
if (deliverable_cnt > 0)
{
ITKCALL(AOM_ask_value_tag(deliverable_list[0], "schedule_deliverable", &deliverable));
if (deliverable != NULL)
{
ITKCALL(AOM_ask_value_tags(deliverable, "deliverable_inst", &fold_cnt, &folds));
if (fold_cnt > 0)
{
allowPass = false;
ITKCALL(AOM_ask_value_tags(folds[0], "contents", &fold_content_cnt, &fold_contents));//获取交付物文件夹下的内容
//LOG_ECHO(("交付物文件夹内容数量:%d\n", fold_content_cnt));
printf("交付物文件夹内容数量:%d\n", fold_content_cnt);
if (status_is_configured) {//流程参数下配置了状态
int hi_cnt = 0;
printf("流程参数下配置了状态\n");
//遍历文件夹下的交付物
for (int i = 0; i < fold_content_cnt; i++)
{
ITKCALL(AOM_ask_value_string(fold_contents[i], "object_type", &object_type));
//根据交付物的类型获取check_item
if (checkIsTypeOrSubtype(fold_contents[i], "Item") == 1
|| checkIsTypeOrSubtype(fold_contents[i], "ItemRevision") == 1)
{
hi_cnt++;
ITKCALL(get_item_and_rev(fold_contents[i], &item_tag, &check_item));
printf("1 \n");
}
else {
continue;
}
//判断交付物对应的check_item是否发布
if (check_item != NULL)
{
printf("获取最新版本对象成功!\n");
ITKCALL(AOM_ask_value_tags(check_item, "release_status_list", &status_cnt, &status_list));
if (status_cnt > 0)
{
for (int j = 0; j < status_cnt; j++)
{
//status_list[j];//发布状态对象
ITKCALL(AOM_ask_value_string(status_list[j], "object_name", &status_name));
if (status_name == NULL) {
ITKCALL(EMH_store_error_s1(EMH_severity_user_error, ITK_err, "交付物没有发布,请先进行发布!"));
err = EPM_nogo;
break;
}
if (status_name == NULL) {
continue;
}
if (strcmp(status_name, status_config) == 0)
{
printf("交付物发布状态:[%s]与配置的发布状态[%s]相同!\n", status_name, status_config);
allowPass = true;
}
else
{
printf("交付物发布状态:[%s]与配置的发布状态[%s]不相同!\n", status_name, status_config);
allowPass = false;
string err_msg = "交付物文件夹下的对象或版本状态与要求的"+ string(status_config) +"不一致!";
ITKCALL(EMH_store_error_s1(EMH_severity_user_error, ITK_err, err_msg.c_str()));
err = EPM_nogo;
break;
}
}
}
else
{//文件夹下存在未发布的对象
ITKCALL(EMH_store_error_s1(EMH_severity_user_error, ITK_err, "交付物没有发布,请先进行发布!"));
err = EPM_nogo;
break;
}
}
else
{
printf("获取check_item 失败!");
continue;
}
DOFREE(status_name);
DOFREE(status_list);
}
if (hi_cnt == 0) {//配置状态情况下交付物文件夹下没有item\rev的子类
ITKCALL(EMH_store_error_s1(EMH_severity_user_error, ITK_err, "交付物没有提交,请先进行提交!"));
err = EPM_nogo;
}
}
else
{//流程参数下未配置状态
printf("流程参数下未配置状态\n");
int ir_cnt = 0;
if (fold_content_cnt > 0)
{
//没有配置状态参数的时候检查文件夹下是否存在item\rev的子类存在则通过不存在则提示
for (int j = 0; j < fold_content_cnt; j++) {
if (checkIsTypeOrSubtype(fold_contents[j], "Item") == 1
|| checkIsTypeOrSubtype(fold_contents[j], "ItemRevision") == 1) {
ir_cnt++;
}
}
if (ir_cnt == 0) {
ITKCALL(EMH_store_error_s1(EMH_severity_user_error, ITK_err, "交付物没有提交,请先进行提交!"));
allowPass = false;
err = EPM_nogo;
}
else {
allowPass = true;//交付物文件夹
}
}else {//未配置流程参数,交付物文件夹下也没有内容
printf("校验通过,未配置流程参数且交付物文件夹下没有内容!\n");
ITKCALL(EMH_store_error_s1(EMH_severity_user_error, ITK_err, "交付物没有提交,请先进行提交!"));
err = EPM_nogo;
}
}
}
}
}
}
//if (!allowPass && status_is_configured == false)
//{
// //LOG_ECHO(("校验不通过,存在交付物未发布!\n"));
// printf("校验不通过,存在交付物未提交!\n");
// ITKCALL(EMH_store_error_s1(EMH_severity_user_error, ITK_err, "交付物没有提交,请先进行提交!"));
// err = EPM_nogo;
//}
//else if (!allowPass) {
// printf("校验不通过,存在交付物未发布!\n");
// ITKCALL(EMH_store_error_s1(EMH_severity_user_error, ITK_err, "交付物没有发布,请先进行发布!"));
// err = EPM_nogo;
//}
//LOG_ECHO(("*******************************************************************************\n"));
//LOG_ECHO(("* Origin_CheckTask_handler is end ! *\n"));
//LOG_ECHO(("*******************************************************************************\n"));
printf("*******************************************************************************\n");
printf("* Origin_CheckTask_handler is end ! *\n");
printf("*******************************************************************************\n");
//DOFREE(status_config);
DOFREE(object_type);
DOFREE(fold_contents);
DOFREE(folds);
DOFREE(project_attachments);
DOFREE(project_attachments);
return err;
}