/*===================================================================================================
                    Copyright(c) 2011 Siemens PLM Software Corp. All rights reserved.
                             Unpublished - All rights reserved
====================================================================================================
File description:
    
    Filename : epm_autosign_hander.cpp

    This file describes action handler function : PLA8-signoff

	将流程签审信息写入表单

====================================================================================================
Date               Name                  Description of Change
19-Jan-2013       Ray Li        creation

$HISTORY$
==================================================================================================*/
#pragma warning (disable: 4996) 
#pragma warning (disable: 4819) 
/**
* @headerfile			tcua 头文件
*/

#include <epm/epm.h>
#include <epm/epm_toolkit_tc_utils.h>
#include <ict/ict_userservice.h>
#include <tccore/item.h>
#include <ae/ae.h>
#include <tc/folder.h>
#include <tccore/aom.h>
#include <sa/sa.h>
#include <tccore/aom_prop.h>
#include <property/prop_errors.h>
#include <tccore/workspaceobject.h>
#include <tc/preferences.h>
#include <tccore/imantype.h>
#include <tccore//grm.h>
#include <tccore/grmtype.h>
#include <sa/am.h>
#include <cfm/cfm.h>
#include <bom/bom.h>
#include <tccore/uom.h>
#include <ps/ps.h>
#include <epm/signoff.h>
#include <fclasses/tc_date.h>

/**
* @headerfile			standard c & cpp header files
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
//#include <time.h>
//#include <math.h>
#include <string>
#include <vector>
#include <map>
#include <fstream>
#include <iostream>
#include <algorithm>
using namespace std;

/**
* @headerfile			user's header files
*/
#include "epm_handler_common.h"
#include "error_handling.h"
#include "common_itk_util.h"
#include "string_utils.h"
#include "epm_sign_rev.h"

//流程节点信息
struct FLOWNODEINFOS
{
	char taskname[128];
	char username[128];
	char timeinfo[128];
	char group[128];
}flownode_s[64];

//参数人员信息
struct USERINFOS
{
	char taskname[128];
	char propertyname[128];
	char group[128];
}userinfo_s[64];

//参数日期信息
struct TIMEINFOS
{
	char taskname[128];
	char propertyname[128];
	char group[128];
}timeinfo_s[64];

////会签信息
//struct SIGNCOUNTERINFO
//{
//	char taskname[128];
//	char group[128];
//	char propertyname[128];
//}counter_s[64];

int nodecount = 0;
int userinfoscount = 0;
int timeinfoscount = 0;

typedef struct{
	string TaskUserName;
	string TaskTimeName;
	string UserName;
	string TimeStr;
	string GroupName;
	string PropUserName;
	string PropTimeName;
}NOTICE_NODE;

 
//int counterinfocount = 0;
#define DOFREE(obj)								\
{												\
	if(obj)										\
	{											\
		MEM_free(obj);							\
		obj = NULL;								\
	}											\
}
//struct SIGN_INFO_STRUCT
//{
//	string userid;
//	string username;
//	string taskname;
//	string signdate;
//};
//struct SIGN_PROPS_STRUCT
//{
//	string taskname;
//	string propname;
//};
//struct SIGN_TIME_STRUCT
//{
//	string taskname;
//	string propname;
//};
extern "C" int POM_AM__set_application_bypass(logical bypass);




int ORIGIN_ask_sign_info(tag_t task_node, char *output_str,char *task_name,char *arg3value)
{
	int ifail = ITK_ok;
	tag_t cur_perform_task = NULLTAG,tempTask = NULLTAG;
	char cur_task_name[WSO_name_size_c+1]="",buf[128] = "";
	//编制判断变量
	int s = 0;
	EPM_decision_t decision = EPM_nogo;
	char* userName;
	char *timeinfo1 = "",person_name[SA_name_size_c+1]="",*prop_name = "last_mod_date";
	tag_t aUserTag = NULLTAG,responsibleParty = NULLTAG;
	date_t decision_date;
	//其他节点相关
	int perform_count = 0;
	int *attach_type;
	tag_t *perform_attaches = NULLTAG;
	tag_t memberTag = NULLTAG;
	SIGNOFF_TYPE_t memberType;
	CR_signoff_decision_t signoff_decision;
	char comments[CR_comment_size_c+1],*timeinfo="",*group_full_name = NULL;
	tag_t user_tag=NULLTAG, group_tag = NULLTAG;
	//循环判断变量
	int i=0;

	 EPM_ask_name( task_node, cur_task_name ) ; 
	ECHO("cur_task_name = %s\n",cur_task_name);
	if ( stricmp( cur_task_name, "perform-signoffs" ) == 0 )
	{
		cur_perform_task = task_node;
		//得到父节点
		EPM_ask_parent_task( cur_perform_task, &tempTask );
		EPM_ask_name( tempTask, cur_task_name );
	}
	else if( strcmp( cur_task_name, "编制" ) == 0 || strcmp( cur_task_name, "设计" ) == 0)
	{
		cur_perform_task = task_node;
	}
	else
	{
		EPM_ask_sub_task(task_node, "perform-signoffs", &cur_perform_task) ;
		if ( cur_perform_task != NULLTAG )
		{
			EPM_ask_name( task_node, cur_task_name  );

			ECHO( "--------->		cur_task_name = %s\n" , cur_task_name );

		}
	}
	if(cur_perform_task != NULLTAG )
	{
		if( strcmp( cur_task_name, "编制" ) == 0||strcmp( cur_task_name, "设计" ) == 0 )
		{
			tag_t owner = NULLTAG;
			ECHO("task_name=%s\n",task_name);
			s = EPM_ask_responsible_party(cur_perform_task,&responsibleParty);
			if(responsibleParty != NULLTAG)
			{
				decision = EPM_go;
			}
			AOM_ask_owner( cur_perform_task, &owner);
			//s = POM_get_user(&userName,&aUserTag);
			if( owner != NULLTAG )
			SA_ask_user_person_name(owner, person_name);
			ECHO("person_name=%s\n",person_name);
			strcat(output_str, cur_task_name);
			strcat(output_str, "=");
			strcat(output_str, person_name);
			strcat(output_str, "|");
			strcat(output_str, cur_task_name);
			strcat(output_str, "日期=");
			AOM_ask_value_date(cur_perform_task,prop_name,&decision_date);
			DATE_date_to_string(decision_date,arg3value,&timeinfo1);
			ECHO("\n-------\ntimeinfo 111 : %s\n------------\n",timeinfo1);
			//ITK_date_to_string (decision_date, &timeinfo1);  2017.11.23 编制时间覆盖掉了,注掉
			strcat( output_str, timeinfo1 );
			strcat(output_str,"|");
			ECHO("timeinfo : %s",timeinfo1);
			strcpy(flownode_s[nodecount].taskname,cur_task_name);
			strcpy(flownode_s[nodecount].username,person_name);
			strcpy(flownode_s[nodecount].timeinfo,timeinfo1);
			nodecount = nodecount + 1;
			//MEM_free(userName);
		}
		else
		{
			//发起人即所有者
			tag_t owner = NULLTAG;
			date_t date;
			logical is_valid;
			char *d_value = NULL;
			AOM_ask_owner( cur_perform_task, &owner);
			if( owner != NULLTAG )
				SA_ask_user_person_name(owner, person_name);
			AOM_ask_value_date(cur_perform_task,"creation_date", &date);//fnd0StartDate
			DATE_date_to_string(date,arg3value,&d_value);
			//ITKCALL(AOM_UIF_ask_value( cur_perform_task, "fnd0StartDate", &d_value));
			ECHO("d_value : %s",d_value);
			strcat(output_str, "设计");
			strcat(output_str, "=");
			strcat(output_str, person_name);
			strcat(output_str, "|");
			strcat(output_str, "设计日期=");
			//CALL(DATE_date_to_string(date,arg3value,&timeinfo));
			//ITKCALL(DATE_string_to_date_t(d_value, &is_valid,&date)); 
			//CALL(DATE_date_to_string(date,arg3value,&timeinfo));
			//ECHO("timeinfo : %s",timeinfo);
			//vector<string> ans;
			//if( d_value != NULL )
			//{
			//	Split(d_value, ' ', ans);
			//	if(ans.size() > 1)
			//		strcat(output_str,ans[0].c_str());
			//}
			strcat(output_str,d_value);
			//DOFREE(timeinfo);
			strcat(output_str, "|");
					strcpy(flownode_s[nodecount].taskname,"设计");
					strcpy(flownode_s[nodecount].username,person_name);
			//if(ans.size() > 1)
					strcpy(flownode_s[nodecount].timeinfo,d_value);
					nodecount = nodecount + 1;
			ECHO("output_str=%s",output_str);
			EPM_ask_all_attachments(cur_perform_task,&perform_count,&perform_attaches,&attach_type);
			ECHO("EPM_signoff_attachment Counts = %d", perform_count);
			
			for(i=0;i<perform_count;i++)
			{
				EPM_ask_signoff_member(perform_attaches[i], &memberTag, &memberType);
				CR_ask_signoff_decision(perform_attaches[i], &signoff_decision, comments, &decision_date);
				if(memberType == SIGNOFF_GROUPMEMBER)
				{
					ECHO("cur_task_name = %s",cur_task_name);
					SA_ask_groupmember_user(memberTag, &user_tag);
					SA_ask_user_person_name(user_tag, person_name);
					strcat(output_str, cur_task_name);
					strcat(output_str, "=");
					strcat(output_str, person_name);
					strcat(output_str, "|");
					strcat(output_str, cur_task_name);
					strcat(output_str, "日期=");
					char date_buf[128]="";
					DATE_date_to_string(decision_date,arg3value,&timeinfo);
					//ITKCALL(ITK_date_to_string(decision_date, &timeinfo));
					//sprintf( date_buf, "%4d-%02d-%02d", decision_date.year, decision_date.month+1, decision_date.day );
					ECHO("\n--------\ntimeinfo : %s\n---------\n",timeinfo);
					strcat(output_str,timeinfo);
					strcat(output_str, "|");
					strcpy(flownode_s[nodecount].taskname,cur_task_name);
					strcpy(flownode_s[nodecount].username,person_name);
					strcpy(flownode_s[nodecount].timeinfo,timeinfo);
					nodecount = nodecount + 1;
				}
			}
		}
	}
	ECHO("output_str=%s",output_str);
	return ifail;
}
//
void SplitUserInfo(char *userinfo)
{
	char* token = NULL, *ptr = NULL, temp[512] = "";

    token = strtok( userinfo, ";");
    while( token != NULL )
    {
        /* While there are tokens in "string" */
		strcpy(temp,token);
        ECHO( "token=%s\n", token );
		ptr = strstr(temp, "=");
		if (ptr != NULL)
		{	
			strcpy(userinfo_s[userinfoscount].propertyname, ptr +1);
			strcpy(ptr,"\0");
			strcpy(userinfo_s[userinfoscount].taskname ,temp);
			ECHO("\nuserinfo_s[userinfoscount].taskname=%s,userinfo_s[userinfoscount].propertyname=%s\n",
				userinfo_s[userinfoscount].taskname,userinfo_s[userinfoscount].propertyname);
		}
		userinfoscount ++;
        /* Get next token: */
        token = strtok( NULL, ";");
    }
}

void SplitTimeInfo(char *userinfo)
{
	char* token = NULL, *ptr = NULL, temp[512] = "";

    token = strtok( userinfo, ";");
    while( token != NULL )
    {
        /* While there are tokens in "string" */
		strcpy(temp,token);
        ECHO( "token=%s\n", token );
		ptr = strstr(temp, "=");
		if (ptr != NULL)
		{	
			strcpy(timeinfo_s[timeinfoscount].propertyname, ptr +1);
			strcpy(ptr,"\0");
			strcpy(timeinfo_s[timeinfoscount].taskname ,temp);
			ECHO("\ntimeinfo_s[timeinfoscount].taskname=%s,timeinfo_s[timeinfoscount].propertyname=%s\n",timeinfo_s[timeinfoscount].taskname,timeinfo_s[timeinfoscount].propertyname);
			
		}
		timeinfoscount ++;
        /* Get next token: */
        token = strtok( NULL, ";");
    }
}
//获取参数1
void getUserinfo(char *userinfo)
{
	int ulen = 0,i=0,tempcount=0;
	char temp[128]="";
	BOOL has =FALSE;
	ulen = strlen(userinfo);
	for(i=0;i < ulen;i++)
	{
		if(userinfo[i] == '=')
		{
			temp[tempcount] = '\0';
			strcpy(userinfo_s[userinfoscount].taskname,temp);
			strcpy(temp,"");
			tempcount = 0;
			has = TRUE;
		}
		else if(userinfo[i] == ';' && has)
		{
			temp[tempcount] = '\0';
			strcpy(userinfo_s[userinfoscount].propertyname,temp);
			strcpy(temp,"");
			tempcount = 0;
			userinfoscount = userinfoscount + 1;
			has = FALSE;
		}
		else
		{
			temp[tempcount] = userinfo[i];
			tempcount = tempcount + 1;
		}
	}
}

//获取参数2
void getTimeinfo(char *timeinfo)
{
	int ulen = 0,i=0,tempcount=0;
	char temp[128]="";
	BOOL has =FALSE;
	ulen = strlen(timeinfo);
	for(i=0;i < ulen;i++)
	{
		if(timeinfo[i] == '=')
		{
			temp[tempcount] = '\0';
			if(strcmp(temp,"") == 0)
				continue;
			strcpy(timeinfo_s[timeinfoscount].taskname,temp);
			strcpy(temp,"");
			tempcount = 0;
			has = TRUE;
		}
		else if(timeinfo[i] == ';' && has)
		{
			temp[tempcount] = '\0';
			strcpy(timeinfo_s[timeinfoscount].propertyname,temp);
			strcpy(temp,"");
			tempcount = 0;
			timeinfoscount = timeinfoscount + 1;
			has = FALSE;
		}
		else
		{
			temp[tempcount] = timeinfo[i];
			tempcount = tempcount + 1;
		}
	}
}



/*************************************************************************************************
* jf_sign_ir_master()
*
* Description:
*    This handler will set signoff infomation to properties of form
*
* Syntax:
*         jf-signoff   [-debug=true|false]
*
*		  -SignUserName: 编制=c7Formation;设计=c7Design;审核=c7Review
*              
*         -SignDate: 编制=c7Formationtime;校对=c7DesignTime;审核=c7ReviewTime
*
*		  -SignDateFormate: %Y-%m-%d
*         
*		  -bypass
*		
*		  -setboth 是否一起签
*		
*         
* Placement:
*    no request
*
**************************************************************************************************/
int jf_sign_ir_master(EPM_action_message_t msg)
{
	//EPM_rule_message_t rul_msg;
	int ifail = ITK_ok, rcode = 0;
	//参数相关
	char arg1value[1024] = "",arg2value[1024] = "",arg3value[1024]="",arg4value[1024]="",
		signcounter_info[1024] = "";
	char *argflag =NULL,*argvalue=NULL ,*arg = NULL;
	BOOL bypass = FALSE,setboth = TRUE;
	int arg_cnt = 0;
	//流程节点相关
	tag_t root_task = NULLTAG,*sub_tasks = NULL,current_task = NULLTAG,type_tag = NULLTAG;
	int sub_task_count = 0;
	char root_task_name[128]="",task_name[128] = "";
	int occur_of_counts = 0;
	tag_t *taskAttches = NULLTAG;
	char tgt_type[WSO_name_size_c+1]="",type_class[TCTYPE_class_name_size_c+1]="";
	////循环内部变量
	tag_t cur_task = NULLTAG;
	char task_type[WSO_name_size_c+1] = "";
	//循环变量
	int i=0, j=0, k=0, count = 0, n = 0;
	//节点信息变量
	char sign_info[2048]="";
	//节点循环处理变量
	tag_t itemrevision = NULLTAG,master_form_rel_type = NULLTAG;
	char rev_id[ITEM_id_size_c+1]="";
	char item_id[ITEM_id_size_c+1]="";
	int form_count = 0;
	tag_t *form_list = NULL,master_form = NULLTAG;
	char local_path[128]="";
	//编制节点
	int s=0;
	char *timeinfo2="";
	EPM_decision_t decision = EPM_nogo;
	tag_t aUserTag,responsibleParty;
	char *userName;
	date_t decision_date;
	char person_name[SA_name_size_c + 1] = "";
	char *prop_name="last_mod_date";
	////登录信息
	//char *user_name = NULL, *group_full_name = NULL;
	//tag_t user_tag = NULLTAG, group_tag = NULLTAG;

	//char *txtfile = NULL;
	//会签相关
	int n_prop=0, q = 0;
	char **prop_names=NULL, hq_name[128] = "", hq_time_name[128] = "", *hq_value=NULL;
	char exclude_type[256]="", item_type[ITEM_type_size_c+ 1]= "";
	tag_t item = NULLTAG;
	logical is_sign = false;

	//得到触发此函数的节点
	current_task = msg.task;
	//CreateLogFile("PLA8_signoff",&txtfile);
	ECHO("=========================================================\n");
	ECHO("jf_sign_ir_master 开始执行\n");
	ECHO("=========================================================\n");
	//获取handler的参数的个数
	arg_cnt = TC_number_of_arguments(msg.arguments);
	ECHO("参数个数为：%d\n",arg_cnt);
	if (arg_cnt > 0)
	{
		for (i=0;i<arg_cnt;i++)
		{
			//获取下一个参数（从0开始）
			arg = TC_next_argument(msg.arguments);
			//获取参数的名称和值
			ifail = ITK_ask_argument_named_value((const char*)arg, &argflag, &argvalue);
			if (stricmp(argflag, "SignUserName") == 0)
			{
				//strcmp("","");
				if(argvalue != NULL)
				{
					strcpy(arg1value,argvalue);
				}
			}
			else if(stricmp(argflag, "SignDate") == 0)
			{
				if(argvalue != NULL)
				{
					strcpy(arg2value,argvalue);
				}
			}
			else if(stricmp(argflag,"SignDateFormate") == 0)
			{
				if(argvalue != NULL)
				{
					strcpy(arg3value,argvalue);
				}
			}
			else if(stricmp(argflag,"bypass") == 0)
			{
				bypass = TRUE;
			}else if(stricmp(argflag,"setboth") == 0){
				setboth = FALSE;
			}
			//else if(stricmp(argflag,"exclude_type") == 0)
			//{
			//	if(argvalue != NULL)
			//	{
			//		strcpy(exclude_type,argvalue);
			//	}
			//} 

		}
		MEM_free(argflag);
		MEM_free(argvalue);
	}
	//if(bypass)
	//AM__set_application_bypass(TRUE);
	ITK_set_bypass(TRUE);
	ECHO("SignUserName : %s\n",arg1value);
	ECHO("SignDate : %s\n",arg2value);
	//ECHO("SignDateFormat : %s\n",arg3value);
	ECHO("11111\n");
	//ECHO("exclude_type : %s",exclude_type);
	//getUserinfo(arg1value);
	SplitUserInfo(arg1value);
	ECHO("2222\n");
	//getTimeinfo(arg2value);
	SplitTimeInfo(arg2value);
	//getCounterinfo(signcounter_info);
	ECHO("3333\n");
	vector<string> type_vec;

	//Split(exclude_type,";",type_vec);

	ECHO("参数1个数：%d\n",userinfoscount);
	ECHO("参数2个数：%d\n",timeinfoscount);
	
	//得到触发handler的节点
	msg.task;
	//通过节点获取根流程
	 EPM_ask_root_task( msg.task, &root_task );
	//得到根流程下的所有的一级节点
	 EPM_ask_sub_tasks( root_task, &sub_task_count, &sub_tasks); 
	//得到根流程的名称
	 EPM_ask_name( root_task, root_task_name );
	 //
	ECHO("root_task_name=%s\n",root_task_name);
	 EPM_ask_name( current_task, task_name  );
	ECHO( "sub_task_count = %d\n", sub_task_count );

//test==========================
	//tag_t user = NULLTAG, *tasks = NULL;
	//int n_task= 0;
	//ITKCALL(SA_find_user( "admin", &user ));
	//ITKCALL(SA_ask_user_work_contexts ( user, &n_task, &tasks)); 
	//ECHO("==========n_task=%d",n_task);
//==============================

	//单独处理DO节点
	if(strcmp(task_name,"编制") == 0||strcmp(task_name,"设计") == 0)
	{
		ECHO("task_name:%s",task_name);
		//获取责任人
		s = EPM_ask_responsible_party(current_task,&responsibleParty);
		if(responsibleParty != NULLTAG)
		{
			decision = EPM_go;
		}
		//获取当前的用户
		s = POM_get_user(&userName,&aUserTag);
		//获取personname
		SA_ask_user_person_name(aUserTag,person_name);
		strcat(sign_info,task_name);
		strcat(sign_info,"=");
		strcat(sign_info,person_name);
		strcat(sign_info,"|");
		strcat(sign_info,task_name);
		strcat(sign_info,"日期=");
		//POM_ask_v
		//获取对象的时间属性，参数1，对象，参数2，属性名称，属性3，获取到的时间属性值
		AOM_ask_value_date(current_task,prop_name,&decision_date);
		//AOM_UIF_ask_value(current_task,prop_name, &timeinfo2);
		//将时间结构体转换成为某种时间格式的字符串
		DATE_date_to_string(decision_date,arg3value,&timeinfo2);
		ECHO("\n--------------\n timeinfo2=%s\n------------\n",timeinfo2);
		strcat(sign_info,timeinfo2);
		strcat(sign_info,"|");
		strcpy(flownode_s[nodecount].taskname,task_name);
		strcpy(flownode_s[nodecount].username,person_name);
		strcpy(flownode_s[nodecount].timeinfo,timeinfo2);
		nodecount = nodecount + 1;

	}
	else //perform节点
	{
		for(i=0;i<sub_task_count;i++)
		{
			cur_task = sub_tasks[i];
			//char * obj_type =NULL;
			//通过AOM获取属性，从而获取类型
			//AOM_ask_value_string(cur_task,"object_type",&obj_type);
			//获取对象的类型，参数1，对象，参数2，类型值
			//AOM与WSOM的区别，WSOM可以理解为在AOM的基础上封装的一些功能函数，
			//通过WSOM的功能大多数时候可以避免使用多层的AOM嵌套，WSOM封装的更加完善.
			//AOM是对对象的属性进行操作（包括关系属性，和一些基本的属性），可以set和get
			//POM是更加偏底层的一种属性操作，是直接操作数据库的，AOM可以理解为是在POM的基础上封装的，一般如非必要不推荐使用POM
			WSOM_ask_object_type(cur_task,task_type);
			ECHO("current task type = %s\n", task_type);
			ORIGIN_ask_sign_info( cur_task, sign_info, task_name,arg3value); 
		}
	}

	ECHO("sign_info = %s\n", sign_info);
	ECHO("the node number is %d",nodecount);
	if(current_task != NULLTAG)
	{
		//获取流程目标EPM_target_attachment(流程目标)/EPM_reference_attachment（流程引用）
		//第一个参数：跟流程，
		//参数2，获取的关系类型（有两种，1，目标：EPM_target_attachment ；2，引用：EPM_reference_attachment ）
		//参数3，返回的个数
		//参数4，返回关系下面的所有的对象
		EPM_ask_attachments(root_task, EPM_target_attachment, &occur_of_counts, &taskAttches);
		ECHO("%d target attachment found",occur_of_counts);
		
		for( count=0; count<occur_of_counts; count++ )
		{
			ECHO("the %dth work",count);
			//获取类型的第三种方法
			TCTYPE_ask_object_type(taskAttches[count], &type_tag);
			ifail = TCTYPE_ask_class_name(type_tag, type_class);
			ECHO("type_class : %s",type_class);
			
			//过滤掉非版本对象
			if (((strstr(type_class,"Revision") != NULL) || (strstr(type_class,"revision") != NULL))
				&&(strstr(type_class,"Master") == NULL) &&(strstr(type_class,"master") == NULL)
				&& (strstr(type_class,"BOM") ==NULL) && (strstr(type_class,"bom") ==NULL) && (strstr(type_class,"Bom") == NULL))
			{
				ECHO("==================WORKING======================");
				is_sign = true;
				itemrevision = taskAttches[count];
				//获取版本ID
				ITEM_ask_rev_id(itemrevision,rev_id);
				//通过版本得到对象
				ITEM_ask_item_of_rev( itemrevision, &item);
				//ITKCALL(ITEM_ask_type( item, item_type));
				//for( q = 0; q <type_vec.size(); q++)
				//{
				//	if( type_vec[q].compare(item_type) == 0)
				//	{
				//		is_sign = false;
				//	}
				//}
				//if( !is_sign )
				//{
				//	ECHO("item_type=%s, don't sign.",item_type);
				//	continue;
				//}
				//GRM对关系操作
				//先找到关系，参数1，关系名称，参数2，返回关系对象
				GRM_find_relation_type( TC_master_form_rtype, &master_form_rel_type );
				//获取某个对象下的某种关系下的所有的对象，参数1，需要操作的对象，参数2，关系，参数3，返回数量，参数4，返回对象数组
				GRM_list_secondary_objects_only(itemrevision, master_form_rel_type, &form_count, &form_list );
				if( form_count ==0 )
				{
					ECHO("未找到签名form,继续...");
					continue;
				}
				master_form = itemrevision;//form_list[0]; //属性写到版本上

				ECHO("Begin set properties for name\n");
				AOM_load (master_form);
				//if(bypass)
				//开启超级管理员权限，使用的时候必须先声明，必须要成对使用，true开启，false关闭
				POM_AM__set_application_bypass(true);
				
				if(setboth){
					ECHO("Begin set both\n");
				for(j=0; j<userinfoscount; j++)
				{
					//ECHO("userinfo_s[j].taskname:%s",userinfo_s[j].taskname);
					char t_tt_name[1024] = "";
					for(k=0; k<nodecount; k++)
					{
						ECHO("userinfo_s[%d].taskname=%s, flownode_s[%d].taskname=%s, flownode_s[%d].username=%s\n",j,userinfo_s[j].taskname,k,flownode_s[k].taskname,k,flownode_s[k].username);
						
						if(strcmp(userinfo_s[j].taskname,flownode_s[k].taskname) == 0)
						{
							char  t_name[512]="\0";
							sprintf(t_name,"c:\\电子签名\\%s.png",flownode_s[k].username);
							
							if(strcmp(t_tt_name,"\0")==0){
								strcat(t_tt_name,t_name);
							}else{
								strcat(t_tt_name,",");
								strcat(t_tt_name,t_name);
							}

							
						}
						else if (strcmp(userinfo_s[j].taskname,flownode_s[k].taskname) != 0 
							//&& strstr(flownode_s[k].taskname, userinfo_s[j].taskname) != NULL
							//&& strstr(userinfo_s[j].taskname,group_full_name) != NULL
							&& strstr(userinfo_s[j].taskname,flownode_s[k].group) != NULL)
						{
							//printf("flownode_s[k].username=%s\n",flownode_s[k].username);
							//set_bypass(true);
						//	CALL(AOM_lock(master_form));
						//	CALL( AOM_set_value_string( master_form, userinfo_s[j].propertyname, flownode_s[k].username) );
						//	CALL( AOM_save( master_form ) );
						//	CALL( AOM_unlock( master_form ) );	
							//break;
						}
					}
					
							//POM_AM__set_application_bypass(true);
							//先lock
					if(strcmp(t_tt_name,"")!=0){
						    ECHO("t_tt_name_________= %s\n",t_tt_name);
							AOM_lock(master_form);
							ECHO("set prop %s=%s\n",userinfo_s[j].propertyname,userinfo_s[j].taskname);
							//再set
							
							AOM_set_value_string( master_form, userinfo_s[j].propertyname, t_tt_name) ;
							//再save
							AOM_save( master_form ) ;
							//最后unlock
							AOM_unlock( master_form ) ;
							//break;
					}
				}
				ECHO("Begin set properties for time\n");
				POM_AM__set_application_bypass(true);
				
				for(j=0;j< timeinfoscount;j++)
				{

					//ECHO("%s : ",timeinfo_s[j].taskname);
					for(k=0;k<nodecount;k++)
					{
						//printf("group_full_name =%s, timeinfo_s[j].taskname=%s\n",group_full_name,timeinfo_s[j].taskname);
						ECHO("timeinfo_s[%d].taskname=%s, flownode_s[%d].taskname=%s,flownode_s[%d].username=%s\n",j,timeinfo_s[j].taskname,k, flownode_s[k].taskname,k,flownode_s[k].username);
						if(strcmp(timeinfo_s[j].taskname,flownode_s[k].taskname) == 0)
						{
							ECHO("set time prop:%s value:%s\n",timeinfo_s[j].propertyname,flownode_s[k].timeinfo);
							//POM_AM__set_application_bypass(true);
							AOM_lock(master_form);
							PROP_value_type_t valtype;
							char *valtype_n = NULL;
							AOM_ask_value_type( master_form, timeinfo_s[j].propertyname, &valtype, &valtype_n);
							if( valtype == PROP_date )
							{
								date_t a_date;
								ITK_string_to_date(flownode_s[k].timeinfo, &a_date);
								EMH_clear_errors();
								AOM_set_value_date(master_form, timeinfo_s[j].propertyname, a_date);
								//ITKCALL(AOM_UIF_set_value(itemrevision, timeinfo_s[j].propertyname,flownode_s[k].timeinfo));
							}
							else
								AOM_set_value_string( master_form, timeinfo_s[j].propertyname, flownode_s[k].timeinfo);
							DOFREE(valtype_n);
							 AOM_save( master_form );
							 AOM_unlock( master_form );
							//break;
						}
						else if(strcmp(timeinfo_s[j].taskname,flownode_s[k].taskname) != 0
							//&& strstr(flownode_s[k].taskname,timeinfo_s[j].taskname) != NULL
							//&& strstr(timeinfo_s[j].taskname,group_full_name ) != NULL
							&& strstr(timeinfo_s[j].taskname,flownode_s[k].group ) != NULL)
						{
							ECHO("222 set prop:%s value:%s",timeinfo_s[j].propertyname,flownode_s[k].timeinfo);
							//set_bypass(true);
						//	ITKCALL(AOM_lock(master_form));
						//	ITKCALL( AOM_set_value_string( master_form, timeinfo_s[j].propertyname, flownode_s[k].timeinfo) );
						//	ITKCALL( AOM_save( master_form ) );
						//	ITKCALL( AOM_unlock( master_form ) );
							//break;				
						}
					}
				}
				}else{
					ECHO("Begin not set both\n");
				for(j=0; j<userinfoscount; j++)
				{
					//ECHO("userinfo_s[j].taskname:%s",userinfo_s[j].taskname);
					for(k=0; k<nodecount; k++)
					{
						ECHO("userinfo_s[%d].taskname=%s, flownode_s[%d].taskname=%s, flownode_s[%d].username=%s\n",j,userinfo_s[j].taskname,k,flownode_s[k].taskname,k,flownode_s[k].username);
						
						if(strcmp(userinfo_s[j].taskname,flownode_s[k].taskname) == 0)
						{
							char propbothvalue[600] ="\0"; 
							//POM_AM__set_application_bypass(true);
							AOM_lock(master_form);
							ECHO("set prop %s=%s\n",userinfo_s[j].propertyname,flownode_s[k].username);
							ECHO("set time prop:%s value:%s\n",timeinfo_s[j].propertyname,flownode_s[k].timeinfo);
							//特殊处理
							strcat(propbothvalue,flownode_s[k].username);
							strcat(propbothvalue,"/");
							strcat(propbothvalue,flownode_s[k].timeinfo);
							AOM_set_value_string( master_form, userinfo_s[j].propertyname, propbothvalue );
							//ITKCALL( AOM_set_value_string( master_form, userinfo_s[j].propertyname, flownode_s[k].username) );
							AOM_save( master_form );
						 AOM_unlock( master_form  );
							//break;
						}
						else if (strcmp(userinfo_s[j].taskname,flownode_s[k].taskname) != 0 
							//&& strstr(flownode_s[k].taskname, userinfo_s[j].taskname) != NULL
							//&& strstr(userinfo_s[j].taskname,group_full_name) != NULL
							&& strstr(userinfo_s[j].taskname,flownode_s[k].group) != NULL)
						{
							//printf("flownode_s[k].username=%s\n",flownode_s[k].username);
							//set_bypass(true);
							char propbothvalue[600] ="\0";
							CALL(AOM_lock(master_form));
							ECHO("set prop %s=%s\n",userinfo_s[j].propertyname,flownode_s[k].username);
							ECHO("set time prop:%s value:%s\n",timeinfo_s[j].propertyname,flownode_s[k].timeinfo);
							//特殊处理
							strcat(propbothvalue,flownode_s[k].username);
							strcat(propbothvalue,"/");
							strcat(propbothvalue,flownode_s[k].timeinfo);
							//CALL( AOM_set_value_string( master_form, userinfo_s[j].propertyname, propbothvalue) );
							//CALL( AOM_save( master_form ) );
							//CALL( AOM_unlock( master_form ) );	
							////break;
						}
					}
				}
				
				
				
				}
				ECHO("==================WORK  END====================\n");
			}
		}
		ECHO("close bypass...\n");
		//AM__set_application_bypass(FALSE);
		POM_AM__set_application_bypass(false);
	}
	EMH_clear_errors();
	MEM_free(form_list);
	//CloseLog();
	nodecount = 0;
	userinfoscount = 0;
	timeinfoscount = 0;
end_handler:
	//CloseLog();
	DOFREE(taskAttches);
	//DOFREE(pref_values);

	//if (debug)
	{
		printf("=========================================================\n");
		printf("hander jf_sign_ir_master 执行完成\n");
		printf("=========================================================\n");
	}
	return rcode;
}

/**
*	时间表流程显示时间表名称
*/
int tm_show_object_name(EPM_action_message_t msg){

	//msg.task;
	printf("===================================\n");
	printf("设置时间表名称 开始\n");
	printf("===================================\n");
	printf("开超级权限\n");
	POM_AM__set_application_bypass(true);
	int ifail = ITK_ok;
	tag_t tast_tag = NULL_TAG;
	tast_tag = msg.task;
	if(tast_tag != NULL_TAG){
		char * task_name = NULL;
		int count = 0 ;
		tag_t * schdule_task_nodes = NULL;
		AOM_ask_value_string(tast_tag,"object_name",&task_name);
		printf("开始获取SCHDULE任务 \n");
		AOM_ask_value_tags(tast_tag,"project_task_attachments",&count,&schdule_task_nodes);
		printf("获取SCHDULE任务 count =[%d] \n",count);
		if(count >0 ){

			char * schdule_task_node_type = NULL;
			AOM_ask_value_string(schdule_task_nodes[0],"object_type",&schdule_task_node_type);
			if(strcmp(schdule_task_node_type,"ScheduleTask")==0){
				tag_t schdule = NULL_TAG;
				date_t finish_date ;
				AOM_ask_value_tag(schdule_task_nodes[0],"schedule_tag",&schdule);
				AOM_ask_value_date(schdule_task_nodes[0],"finish_date",&finish_date);
				char finish_date_str[300] = "";
				
				if(schdule != NULL_TAG){
					char * schdule_name = NULL;
					AOM_ask_value_string(schdule,"object_name",&schdule_name);
					sprintf(finish_date_str,"%s[%d年%d月%d日]",schdule_name,finish_date.year,finish_date.month+1,finish_date.day);
					AOM_lock(tast_tag);
					AOM_set_value_string(tast_tag,"object_name",finish_date_str);
					
					printf("设置属性\n");
					AOM_save(tast_tag);
					AOM_unlock(tast_tag);
					AOM_refresh(tast_tag,0);
					if(schdule_name !=NULL){
						MEM_free(schdule_name);
						schdule_name = NULL;
					}
				}
			}
			if(schdule_task_node_type !=NULL){
				MEM_free(schdule_task_node_type);
				schdule_task_node_type = NULL;
			}
		}
		if(task_name != NULL){
			MEM_free(task_name);
			task_name = NULL;
		}
		if(schdule_task_nodes != NULL){
			MEM_free(schdule_task_nodes);
			schdule_task_nodes = NULL;
		}
	
	}
	printf("关超级权限\n");
	POM_AM__set_application_bypass(false);
	printf("===================================\n");
	printf("设置时间表名称 结束\n");
	printf("===================================\n");

	return ifail;

}

/**
* 
* Description:
*    This handler will set signoff infomation to properties of form
*
* Syntax:
*         jf-sign-tongzhi   [-debug=true|false]
*
*		  -SignUserName: 编制=c7Formation;设计=c7Design;审核=c7Review
*              
*         -SignDate: 编制=c7Formationtime;校对=c7DesignTime;审核=c7ReviewTime
*
*		  -SignDateFormate: %Y-%m-%d
*         
*		  -bypass
*		
*		  -include_type 需要签名的表单类型
*		
*/
int tm_sign_tongzhi(EPM_action_message_t msg)
{
	printf("======================================================\n");
	printf("开始通知节点签名\n");
	printf("======================================================\n");
	int ifail = ITK_ok ;
	//参数相关
	char arg1value[1024] = "",arg2value[1024] = "",arg3value[1024]="",arg4value[1024]="",
		signcounter_info[1024] = "",include_type[1024]="";
	char *argflag =NULL,*argvalue=NULL ,*arg = NULL;
	BOOL setboth = TRUE ,bypass;
	int arg_cnt = 0;

	//流程节点相关
	tag_t root_task = NULLTAG ,current_task = NULLTAG,type_tag = NULLTAG;
	char tgt_type[WSO_name_size_c+1]="",type_class[TCTYPE_class_name_size_c+1]="";
	tag_t cur_task = NULLTAG;
	char task_type[WSO_name_size_c+1] = "";
	int i=0, j=0, k=0, count = 0, n = 0;
	tag_t itemrevision = NULLTAG,master_form_rel_type = NULLTAG;
	int form_count = 0;
	tag_t *form_list = NULL,master_form = NULLTAG;
	char *prop_name="last_mod_date";
	
	current_task = msg.task;
	arg_cnt = TC_number_of_arguments(msg.arguments);
	ECHO("参数个数为：%d\n",arg_cnt);
	if (arg_cnt > 0)
	{
		for (i=0;i<arg_cnt;i++)
		{
			arg = TC_next_argument(msg.arguments);
			ITKCALL(ifail = ITK_ask_argument_named_value((const char*)arg, &argflag, &argvalue));
			if (stricmp(argflag, "SignUserName") == 0)
			{
				if(argvalue != NULL)
				{
					strcpy(arg1value,argvalue);
				}
			}
			else if(stricmp(argflag, "SignDate") == 0)
			{
				if(argvalue != NULL)
				{
					strcpy(arg2value,argvalue);
				}
			}
			else if(stricmp(argflag,"SignDateFormate") == 0)
			{
				if(argvalue != NULL)
				{
					strcpy(arg3value,argvalue);
				}
			}
			else if(stricmp(argflag,"bypass") == 0)
			{
				bypass = TRUE;
			}else if(stricmp(argflag,"setboth") == 0){
				setboth = FALSE;
			}
			else if(stricmp(argflag,"include_type") == 0)
			{
				if(argvalue != NULL)
				{
					strcpy(include_type,argvalue);
				}
			} 

		}
		MEM_free(argflag);
		MEM_free(argvalue);
	}

	ECHO("SignUserName : %s\n",arg1value);
	ECHO("SignDate : %s\n",arg2value);
	ECHO("SignDateFormat : %s\n",arg3value);

	vector<string> include_type_vec;
	vector<string> signoff_name_info;
	vector<string> signoff_time_info;
	vector<NOTICE_NODE> notice_node_vec;

	Split(include_type,";",include_type_vec);
	Split(arg1value,";",signoff_name_info);
	Split(arg2value,";",signoff_time_info);

	if(signoff_name_info.size() != signoff_time_info.size()){
		printf("签名异常结束\n");
		return 0;
	}

	for(i = 0 ;i < signoff_name_info.size();i++){
		vector<string> name_sub_vec;
		vector<string> tiem_sub_vec;
		Split(signoff_name_info[i],"=",name_sub_vec);
		Split(signoff_time_info[i],"=",tiem_sub_vec);
		if(name_sub_vec.size()==2 && tiem_sub_vec.size() ==2 ){
			NOTICE_NODE node ;
			node.TaskTimeName.assign(tiem_sub_vec[0]);
			node.TaskUserName.assign(name_sub_vec[0]);
			node.PropTimeName.assign(tiem_sub_vec[1]);
			node.PropUserName.assign(name_sub_vec[1]);
			notice_node_vec.push_back(node);
		}
		name_sub_vec.clear();
		tiem_sub_vec.clear();
	}
	
	ITKCALL( EPM_ask_root_task( msg.task, &root_task ) );
	
	int valid_signoffs_count = 0;
	tag_t * valid_signoffs_tags = NULL;
	ITKCALL(AOM_ask_value_tags(msg.task,"valid_signoffs",&valid_signoffs_count,&valid_signoffs_tags));
	if(valid_signoffs_count !=0){
		for(int ii = 0 ;ii < valid_signoffs_count;ii++){
			date_t decision_date ;
			char * decision_str = NULL;
			char * assign_user_name = NULL;
			char * group_name = NULL;
			char * role_name = NULL;
			char * timeinfo1 = NULL;
			char * o_group_name = NULL;
			tag_t assign_user = NULL_TAG;
			tag_t assign_goup_mem = NULL_TAG;
			tag_t role_tag = NULL_TAG;
			tag_t o_group_tag = NULL_TAG;
			//获取时间
			AOM_ask_value_date(valid_signoffs_tags[ii],"decision_date",&decision_date);
			//完成情况
			AOM_UIF_ask_value(valid_signoffs_tags[ii],"decision",&decision_str);
			//通知人
			AOM_ask_value_tag(valid_signoffs_tags[ii],"fnd0Assignee",&assign_user);
			if(assign_user!=NULL_TAG){
				AOM_UIF_ask_value(assign_user,"user_name",&assign_user_name);
			}
			//通知人所在的组
			ITKCALL(AOM_ask_value_tag(valid_signoffs_tags[ii],"group_member",&assign_goup_mem));
			if(assign_goup_mem!=NULL_TAG){
				AOM_UIF_ask_value(assign_goup_mem,"object_name",&group_name);
				//role_tag
				AOM_ask_value_tag(assign_goup_mem,"role",&role_tag);
				if(role_tag!= NULL_TAG){
					AOM_UIF_ask_value(role_tag,"object_name",&role_name);
				}
				AOM_ask_value_tag(assign_goup_mem,"group",&o_group_tag);
				if(role_tag!= NULL_TAG){
					AOM_UIF_ask_value(o_group_tag,"name",&o_group_name);
				}

			}
			DATE_date_to_string(decision_date,arg3value,&timeinfo1);
			printf("通知人：[%s] 组织：[%s] 角色：[%s] 时间：[%d-%d-%d] 状态：[%s]\n",assign_user_name,o_group_name,role_name,decision_date.year,decision_date.month,decision_date.day,decision_str);
			
			BOOL is_used = FALSE;
			for( i = 0 ;i < notice_node_vec.size();i++){
				//string sign_task_name;
				//sign_task_name.assign(notice_node_vec[i].TaskUserName.c_str());
				//string temp_task_name;
				//temp_task_name.assign(group_name);
				if(strcmp(role_name,notice_node_vec[i].TaskUserName.c_str())==0){
					printf("role_name = %s / TaskUserName = %s \n",role_name,notice_node_vec[i].TaskUserName.c_str());
					notice_node_vec[i].UserName.assign(assign_user_name);
					notice_node_vec[i].TimeStr.assign(timeinfo1);
					is_used = TRUE;
					break;
				}else if(strcmp(o_group_name,notice_node_vec[i].TaskUserName.c_str())==0){
					printf("group_name=%s / TaskUserName = %s \n",o_group_name,notice_node_vec[i].TaskUserName.c_str());
					notice_node_vec[i].UserName.assign(assign_user_name);
					notice_node_vec[i].TimeStr.assign(timeinfo1);
					is_used = TRUE;
					break;
				}else{
					printf("Other Group / TaskUserName = %s\n",notice_node_vec[i].TaskUserName.c_str());
				}
			}
			if(!is_used)
				for( i = 0 ;i < notice_node_vec.size();i++){
					if(strcmp(notice_node_vec[i].TaskUserName.c_str(),"工程技术中心")==0){
						printf("group =工程技术中心 / TaskUserName = %s \n",notice_node_vec[i].TaskUserName.c_str());
						notice_node_vec[i].UserName.assign(assign_user_name);
						notice_node_vec[i].TimeStr.assign(timeinfo1);
						break;
					}
				}


			if(decision_str!=NULL){
				MEM_free(decision_str);
				decision_str = NULL;
			}
			if(assign_user_name!=NULL){
				MEM_free(assign_user_name);
				assign_user_name = NULL;
			}
			if(group_name!=NULL){
				MEM_free(group_name);
				group_name = NULL;
			}
			if(role_name!=NULL){
				MEM_free(role_name);
				role_name = NULL;
			}
			if(timeinfo1!=NULL){
				MEM_free(timeinfo1);
				timeinfo1 = NULL;
			}
			if(o_group_name!=NULL){
				MEM_free(o_group_name);
				o_group_name = NULL;
			}
		}
	}

	int occur_of_counts = 0;
	tag_t * taskAttches =NULL;
	ECHO("the node number is %d",nodecount);
	if(current_task != NULLTAG)
	{
		EPM_ask_attachments(root_task, EPM_target_attachment, &occur_of_counts, &taskAttches);
		ECHO("%d target attachment found",occur_of_counts);
		for( count=0; count<occur_of_counts; count++ )
		{
			ECHO("the %dth work",count);
			TCTYPE_ask_object_type(taskAttches[count], &type_tag);
			ifail = TCTYPE_ask_class_name(type_tag, type_class);
			ECHO("type_class : %s",type_class);
			
			//过滤掉非版本对象
			if (((strstr(type_class,"Revision") != NULL) || (strstr(type_class,"revision") != NULL))
				&&(strstr(type_class,"Master") == NULL) &&(strstr(type_class,"master") == NULL)
				&& (strstr(type_class,"BOM") ==NULL) && (strstr(type_class,"bom") ==NULL) && (strstr(type_class,"Bom") == NULL))
			{
				ECHO("==================WORKING======================");
				itemrevision = taskAttches[count];
				GRM_find_relation_type( TC_master_form_rtype, &master_form_rel_type );
				GRM_list_secondary_objects_only(itemrevision, master_form_rel_type, &form_count, &form_list );
				if( form_count ==0 )
				{
					ECHO("未找到签名form,继续...");
					continue;
				}
				master_form = form_list[0]; //属性写到版本上
				char * master_form_type = NULL;
				BOOL is_include =FALSE;
				AOM_ask_value_string(master_form,"object_type",&master_form_type);
				for(i = 0 ;i < include_type_vec.size();i++){
					if(strcmp(master_form_type,include_type_vec[i].c_str())==0){
						is_include = TRUE;
						break;
					}
				}
				if(master_form_type!=NULL){
					MEM_free(master_form_type);
					master_form_type =NULL;
				
				}

				if(!is_include){
					continue;
				}



				AOM_load (master_form);
				POM_AM__set_application_bypass(true);
				for(j=0; j<notice_node_vec.size(); j++)
				{
					ITKCALL(AOM_lock(master_form));
					ECHO("set prop %s=%s\n",notice_node_vec[j].PropUserName.c_str(),notice_node_vec[j].UserName.c_str());
					ECHO("set prop %s=%s\n",notice_node_vec[j].PropTimeName.c_str(),notice_node_vec[j].TimeStr.c_str());
					 AOM_set_value_string( master_form, notice_node_vec[j].PropUserName.c_str(),notice_node_vec[j].UserName.c_str()) ;
					 AOM_set_value_string( master_form, notice_node_vec[j].PropTimeName.c_str(),notice_node_vec[j].TimeStr.c_str() );
					 AOM_save( master_form  );
					 AOM_unlock( master_form  );
					
				}
				
				POM_AM__set_application_bypass(false);
				
				ECHO("==================WORK  END====================\n");
			}
		}
	}
	EMH_clear_errors();
	MEM_free(form_list);
	nodecount = 0;
	userinfoscount = 0;
	timeinfoscount = 0;
end_handler:
	DOFREE(taskAttches);

	
	printf("======================================================\n");
	printf("结束通知节点签名\n");
	printf("======================================================\n");
	return 0;
}
