#pragma warning (disable: 4996) 
#pragma warning (disable: 4819) 
#include <cstdio>
#include <io.h>
#include <epm/epm.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 <tccore/workspaceobject.h>
#include <tccore//grm.h>
#include <tccore/grmtype.h>
#include <bom/bom.h>
#include <fclasses/tc_date.h>
#include <ics/ics.h>
#include <ics/ics2.h>
#include "tc_util.h"
#include "tc_log.h"
#include <vector>
#include <epm/signoff.h>
#include <iostream>
#include "string_utils.h"
#include "tinyxml.h"
#include "ado.h"
#include <stdio.h>
#include <time.h>
using namespace std;
extern "C" int POM_AM__set_application_bypass(logical bypass);
string readBOMXML(map<string, map<vector<string>, vector<string>>> &xmlMap, string xmlPath) {
	time_t currentTime;
	struct tm *timeInfo;
	char timeString[80];
	// 获取当前时间
	time(&currentTime);
	// 将时间转换为本地时间
	timeInfo = localtime(&currentTime);
	TiXmlDocument* pDoc = new TiXmlDocument();
	pDoc->LoadFile(xmlPath.c_str());
	//pDoc->Print();
	//char labelName[50]="";
	//获取根节点
	TiXmlElement* pRoot = pDoc->RootElement();
	string rootName = pRoot->Value();
	TiXmlElement* itemElement = pRoot->FirstChildElement("BOMCONTENTS");//
	string t_Item_info = rootName;//
	string itemLable = itemElement->Value();//中间表表名
											//循环遍历根节点下的兄弟节点
	char type[50] = "";
	char sessionId[50] = "";
	char transNowTime[50] = "";
	char transStatus[50] = "";
	char itemId[50] = "";
	char itemRev[50] = "";
	char itemName[50] = "";
	char itemRelease[50] = "";
	map<vector<string>, vector<string>> propertyMap;//字段名集合，值的集合
	vector<string> nameVec;
	vector<string> valueVec;
	TiXmlElement* pChild = itemElement->FirstChildElement();
	const char* attribute_value = NULL;
	if (pChild != NULL) {
		string childLabnelName = pChild->Value();
		attribute_value = pChild->Attribute("val");
		if (attribute_value == NULL) {
			strcpy(sessionId, " ");
		}
		else {
			strcpy(sessionId, attribute_value);
		}
		string tempValue = sessionId;
		nameVec.push_back(childLabnelName);
		valueVec.push_back(tempValue);
	}
	pChild = pChild->NextSiblingElement();
	while (true) {
		if (pChild != NULL) {
			string childLabnelName = pChild->Value();
			attribute_value = pChild->Attribute("val");
			if (attribute_value == NULL) {
				strcpy(sessionId, " ");
			}
			else {
				strcpy(sessionId, attribute_value);
			}
			string tempValue = sessionId;
			//propertyMap[childLabnelName]=tempValue;
			if (strcmp("TRANSNO", childLabnelName.c_str()) == 0) {
				//转换时间, 将时间按照指定格式转换为字符串
				strftime(timeString, sizeof(timeString), sessionId, timeInfo);
				// 打印转换后的时间字符串
				tempValue = timeString;
			}
			else 	if (strcmp("SONPZLIST", childLabnelName.c_str()) == 0) {
			}
			if (strcmp("SONPZLIST", childLabnelName.c_str()) != 0) {
				nameVec.push_back(childLabnelName);;
				valueVec.push_back(tempValue);
			}
			pChild = pChild->NextSiblingElement();
			if (pChild == NULL) {
				break;
			}
		}
	}
	propertyMap[nameVec] = valueVec;
	xmlMap["父"] = propertyMap;
	pChild = itemElement->FirstChildElement("SONPZLIST");
	vector<string> childNameVec;
	vector<string> childValueVec;
	map<vector<string>, vector<string>> childPropertyMap;//字段名集合，值的集合
	TiXmlElement* sonChild = pChild;
	TiXmlElement* cChild = sonChild->FirstChildElement();
	if (cChild != NULL) {
		string LabnelName = cChild->Value();
		attribute_value = cChild->Attribute("val");
		strcpy(sessionId, attribute_value);  // 将 str 复制给 copy
		string tempValue = sessionId;
		childNameVec.push_back(LabnelName);
		childValueVec.push_back(tempValue);
	}
	cChild = cChild->NextSiblingElement();
	while (true) {
		if (cChild != NULL) {
			string LabnelName = cChild->Value();
			attribute_value = cChild->Attribute("val");
			if (attribute_value == NULL) {
				strcpy(sessionId, " ");  // 将 str 复制给 copy
			}
			else {
				strcpy(sessionId, attribute_value);  // 将 str 复制给 copy
			}
			string tempValue = sessionId;
			childNameVec.push_back(LabnelName);
			childValueVec.push_back(tempValue);
		}
		cChild = cChild->NextSiblingElement();
		if (cChild == NULL) {
			break;
		}
	}
	childPropertyMap[childNameVec] = childValueVec;
	xmlMap["子"] = childPropertyMap;
	delete pDoc;//应该是必要的
	return t_Item_info;
}
int JD_BOMInfoToMediDatabase(EPM_action_message_t msg) {
	bool showError = false;
	nowTime();
	time_t now;
	struct tm *p;
	//获取当前时间
	time(&now);
	//本地化时间，可以细分为年月日时分秒等
	p = localtime(&now);
	createDir();//创建日志目录
	char TC_LOG_FILE[128] = "";
	// 把日志名称赋予给某变量
	sprintf_s(TC_LOG_FILE, "%s\\tmplog\\JD_BOMInfoToMediDatabase_log_[%d-%d-%d-%d-%02d-%02d].txt", getenv("TEMP"), 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);
	ECHO("创建日志文件[%s]\n", TC_LOG_FILE);
	CreateLogFile(TC_LOG_FILE);
	//流程节点相关
	tag_t root_task = NULLTAG, *sub_tasks = NULL, current_task = NULLTAG, type_tag = NULLTAG;
	int arg_cnt = 0, ifail = 0;
	char arg1value[1024] = "";//物料类型
	char *argflag = NULL, *argvalue = NULL, *arg = NULL;
	//得到触发此函数的节点
	current_task = msg.task;
	WriteLog("=========================================================\n");
	WriteLog("JD_BOMInfoToMediDatabase 开始执行\n");
	WriteLog("=========================================================\n");
	//获取handler的参数的个数
	arg_cnt = TC_number_of_arguments(msg.arguments);
	WriteLog("参数个数为：%d\n", arg_cnt);
	if (arg_cnt > 0)
	{
		for (int 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, "PartItem") == 0)
			{
				if (argvalue != NULL)
				{
					strcpy(arg1value, argvalue);
				}
			}
		}
		MEM_free(argflag);
		MEM_free(argvalue);
	}
	//先获取首选项Jd_Erp_Info_Connect，解析其中的用户名，密码，配置文件等信息
	vector<string>		pref_vec1;
	getPrefStrings1("Jd_Erp_Info_Connect_Test", TC_preference_site, pref_vec1);
	string ip = pref_vec1[0];
	string databaseName = pref_vec1[1];
	string user = pref_vec1[2];
	string password = pref_vec1[3];
	string xmlUid = pref_vec1[5];
	WriteLog("ip:%s\n", ip.c_str());
	WriteLog("databaseName:%s\n", databaseName.c_str());
	WriteLog("user:%s\n", user.c_str());
	WriteLog("password:%s\n", password.c_str());
	WriteLog("xmlUid:%s\n", xmlUid.c_str());
	ado ado0;
	char userName[100];
	strcpy(userName, user.c_str());
	char pwd[100];
	strcpy(pwd, password.c_str());
	string info = "Provider=SQLOLEDB.1;Persist Security Info=False;Initial Catalog=";
	info.append(databaseName).append(";Data Source=").append(ip);
	WriteLog("连接信息：%s\n", info.c_str());
	bool log = ado0.open(userName, pwd, info.c_str());
	tag_t bomInfoXml = NULL;
	ITK__convert_uid_to_tag(xmlUid.c_str(), &bomInfoXml);
	//获取文件
	char *temp_dir = getenv("temp");//获得缓存路径
	char output_file_xml_temp[SS_MAXPATHLEN] = "";
	strcpy(output_file_xml_temp, temp_dir);
	strcat(output_file_xml_temp, "\\");
	strcat(output_file_xml_temp, xmlUid.c_str());
	strcat(output_file_xml_temp, ".xml");
	if (access(output_file_xml_temp, 0) == 0) {//存在
		if (remove(output_file_xml_temp) == 0) {
			cout << "exist" << output_file_xml_temp << "delete" << endl;
		}
	}
	POM_AM__set_application_bypass(true);
	ITKCALL(AE_export_named_ref(bomInfoXml, "XMLRendering", output_file_xml_temp));
	POM_AM__set_application_bypass(false);
	string path = output_file_xml_temp;
	//解析xml文件
	//创建一个XML结构并载入文件内容
	map<string, map<vector<string>, vector<string>>> xmlMap;//物料类型，<字段名，属性取值>
	string tableName = readBOMXML(xmlMap, path);
	map<vector<string>, vector<string>> parentPropertyMap = xmlMap["父"];//父级
	vector<string> parentNameVec;
	vector<string> parentValueVec;
	map<vector<string>, vector<string>>::iterator rev_it2;
	for (rev_it2 = parentPropertyMap.begin(); rev_it2 != parentPropertyMap.end(); rev_it2++) {
		parentNameVec = rev_it2->first;
		parentValueVec = rev_it2->second;
	}
	map<vector<string>, vector<string>> childPropertyMap = xmlMap["子"];//子级
	vector<string> childNameVec;
	vector<string> childValueVec;
	map<vector<string>, vector<string>>::iterator rev_it;
	for (rev_it = childPropertyMap.begin(); rev_it != childPropertyMap.end(); rev_it++) {
		childNameVec = rev_it->first;
		childValueVec = rev_it->second;
	}
	//遍历map所有层级
	string revType = arg1value;
	vector<string> revTypeVec;
	Split(revType, ";", revTypeVec);
	int att_cnt = 0;
	tag_t *attachments = NULL;
	//获取根流程节点
	tag_t task_tag = msg.task;
	tag_t rootTask_tag = NULL;
	ifail = EPM_ask_root_task(task_tag, &rootTask_tag);
	vector<string> updateVec;
	vector<string> selectVec;
	vector<string> insertVec;
	vector<string> selectAfterUpdateVec;
	//获取目标引用对象
	ifail = EPM_ask_attachments(rootTask_tag, EPM_target_attachment, &att_cnt, &attachments);
	for (int i = 0; i < att_cnt; i++) {
		char *object_TYPE_1 = NULL;
		ifail = AOM_ask_value_string(attachments[i], "object_type", &object_TYPE_1);//对象类型
		WriteLog("当前类型对象为   %s\n", object_TYPE_1);
		string partType = object_TYPE_1;
		if (hasElement(revTypeVec, partType) == 0) {
			//
			string sqlStr = "insert into ";
			string updateStr = "update ";
			string selectStr = "select * from  ";
			string selectAfterUpdateStr = "select * from  ";
			string updateWhere = "";
			sqlStr = sqlStr.append(tableName).append("(");
			selectStr = selectStr.append(tableName).append(" ");
			selectAfterUpdateStr = selectAfterUpdateStr.append(tableName).append(" ");
			string valueStr = " VALUES (";
			//包含类型,连接数据库
			if (log == false) {
				WriteLog("登录成功\n");
				tag_t partItem = NULL;
				ITEM_ask_item_of_rev(attachments[i], &partItem);
				char *itemType = NULL;
				AOM_ask_value_string(partItem, "object_type", &itemType);
				//TODO 获取BOM结构
				//获取版本下的bom视图
				int bom_num = 0;
				tag_t * bom_tags = NULLTAG;
				AOM_ask_value_tags(attachments[i], "structure_revisions", &bom_num, &bom_tags);
				if (bom_num > 0)
				{
					tag_t only_bom = bom_tags[0];
					tag_t bom_window_tag = NULLTAG, top_bom_line_tag = NULLTAG, rev_tag = NULLTAG, item_tag = NULLTAG;
					ITKCALL(ifail = BOM_create_window(&bom_window_tag));
					ITKCALL(ifail = BOM_set_window_top_line_bvr(bom_window_tag, only_bom, &top_bom_line_tag));
					//获取父属性
					string parentColumnStr = "insert into ";
					parentColumnStr = parentColumnStr.append(tableName).append(" (");
					string parentValueStr = " values(";
					for (int j = 0; j < parentNameVec.size(); j++)
					{
						string columnName = parentNameVec[j];
						parentColumnStr = parentColumnStr.append(columnName);
						if (j < parentNameVec.size() - 1) {
							parentColumnStr = parentColumnStr.append(",");
						}
						string propertyName = parentValueVec[j];
						string tempValue = " ";
						string updateValue = "";
						if (strcmp(columnName.c_str(), "SESSIONID") == 0) {
							tempValue = propertyName;//固定值
						}
						else if (strcmp(columnName.c_str(), "TRANSNO") == 0) {
							tempValue = propertyName;//已处理
							if (updateWhere.length() == 0) {
								updateWhere = updateWhere.append(" where ");
								updateWhere = updateWhere.append(columnName).append("='").append(tempValue).append("' and ");
								selectStr = selectStr.append(" where ");
								selectStr = selectStr.append(columnName).append("='").append(tempValue).append("' and ");
								selectAfterUpdateStr = selectAfterUpdateStr.append(" where ");
								selectAfterUpdateStr = selectAfterUpdateStr.append(columnName).append("='").append(tempValue).append("' and ");
							}
							else {
								updateWhere = updateWhere.append(columnName).append("='").append(tempValue).append("' and ");
								selectStr = selectStr.append(columnName).append("='").append(tempValue).append("' and ");
								selectAfterUpdateStr = selectAfterUpdateStr.append(columnName).append("='").append(tempValue).append("' and ");
							}
						}
						else if (strcmp(columnName.c_str(), "TRANSSTATUS") == 0) {
							//首次传递空值

							updateValue = propertyName;
							updateStr = updateStr.append(tableName).append(" set ").append(columnName).append("='").append(updateValue).append("'  ");
							selectAfterUpdateStr = selectAfterUpdateStr.append(columnName).append("='").append(updateValue).append("' and ");
						}
						else if (strcmp(columnName.c_str(), "PPUID") == 0) {
							char *puid = NULL;
							ITK__convert_tag_to_uid(attachments[i], &puid);
							tempValue = puid;
							//selectStr = selectStr.append(columnName).append("='").append(tempValue).append("' and ");
							if (updateWhere.length() == 0) {
								updateWhere = updateWhere.append(" where ");
								updateWhere = updateWhere.append(columnName).append("='").append(puid).append("' and ");
								selectStr = selectStr.append(" where ");
								selectStr = selectStr.append(columnName).append("='").append(tempValue).append("' and ");
								selectAfterUpdateStr = selectAfterUpdateStr.append(" where ");
								selectAfterUpdateStr = selectAfterUpdateStr.append(columnName).append("='").append(tempValue).append("' and ");
							}
							else {
								updateWhere = updateWhere.append(columnName).append("='").append(puid).append("' and ");
								selectStr = selectStr.append(columnName).append("='").append(puid).append("' and ");
								selectAfterUpdateStr = selectAfterUpdateStr.append(columnName).append("='").append(puid).append("' and ");
							}
							DOFREE(puid);
						}
						else {
							vector<string> propertyVec;
							Split(propertyName, ".", propertyVec);
							if (propertyVec.size() == 2) {
								string propertyPosition = propertyVec[0];
								tag_t propertyTag = NULL;
								if (strcmp("item", propertyPosition.c_str()) == 0) {
									propertyTag = partItem;
								}
								else if (strcmp("rev", propertyPosition.c_str()) == 0) {
									propertyTag = attachments[i];
								}
								else if (strcmp("bomline", propertyPosition.c_str()) == 0) {
									propertyTag = top_bom_line_tag;
								}
								string propertyName = propertyVec[1];
								char *propertyValue = NULL;
								ITKCALL(ifail = AOM_UIF_ask_value(propertyTag, propertyName.c_str(), &propertyValue));
								EMH_clear_errors();
								if (ifail == 0) {
									tempValue = propertyValue;
								}
								else {
									showError = true;
									WriteLog("属性异常：%s\n", propertyName.c_str());
									tempValue = " ";
								}
								DOFREE(propertyValue);
							}

						}
						parentValueStr = parentValueStr.append("'").append(tempValue).append("'");
						if (j < parentNameVec.size() - 1) {
							parentValueStr = parentValueStr.append(",");
						}
					}
					int child_count = 0; tag_t *child_tags = NULLTAG;
					ITKCALL(ifail = BOM_line_ask_all_child_lines(top_bom_line_tag, &child_count, &child_tags));
					for (int n = 0; n < child_count; n++)
					{
						string childColumnStr = "";
						string childSelectStr = "";
						string childUpdateSelectStr = "";
						string childUpdateWhere = "";
						string childValueStr = "";
						tag_t rev_tag = NULL;
						ITKCALL(ifail = AOM_ask_value_tag(child_tags[n], "bl_line_object", &rev_tag));
						tag_t childItem = NULL;
						ITEM_ask_item_of_rev(rev_tag, &childItem);
						for (int j = 0; j < childNameVec.size(); j++)
						{
							string columnName = childNameVec[j];
							childColumnStr = childColumnStr.append(columnName);
							if (j < childNameVec.size() - 1) {
								childColumnStr = childColumnStr.append(",");
							}

							string propertyName = childValueVec[j];
							string tempValue = " ";
							if (strcmp(columnName.c_str(), "CPUID") == 0) {
								char *puid = NULL;
								ITK__convert_tag_to_uid(rev_tag, &puid);
								tempValue = puid;

								childSelectStr = childSelectStr.append(columnName).append("='").append(tempValue).append("'  ");
								childUpdateSelectStr = childUpdateSelectStr.append(columnName).append("='").append(tempValue).append("'  ");
								childUpdateWhere = childUpdateWhere.append(columnName).append("='").append(tempValue).append("'");
								DOFREE(puid);
							}
							else {
								vector<string> propertyVec;
								Split(propertyName, ".", propertyVec);
								if (propertyVec.size() == 2) {
									string propertyPosition = propertyVec[0];
									tag_t propertyTag = NULL;
									if (strcmp("item", propertyPosition.c_str()) == 0) {
										propertyTag = childItem;
									}
									else if (strcmp("rev", propertyPosition.c_str()) == 0) {
										propertyTag = rev_tag;
									}
									else if (strcmp("bomline", propertyPosition.c_str()) == 0) {
										propertyTag = child_tags[n];
									}
									string propertyName = propertyVec[1];
									char *propertyValue = NULL;
									ITKCALL(ifail = AOM_UIF_ask_value(propertyTag, propertyName.c_str(), &propertyValue));
									EMH_clear_errors();
									if (ifail == 0) {
										tempValue = propertyValue;
									}
									else {
										showError = true;
										WriteLog("属性异常：%s\n", propertyName.c_str());
										tempValue = " ";
									}
									DOFREE(propertyValue);
								}
								else {
									tempValue = " ";

								}

							}
							childValueStr = childValueStr.append("'").append(tempValue);
							if (j < childNameVec.size() - 1) {
								childValueStr = childValueStr.append("',");
							}
							else {
								childValueStr = childValueStr.append("'");
							}
						}
						string insertSql = "";
						string selectSql = "";
						string updateSelectSql = "";
						string updateSql = "";
						if (childColumnStr.size() > 0) {
							insertSql = insertSql.append(parentColumnStr).append(",").append(childColumnStr).append(")").append(parentValueStr).append(",").append(childValueStr).append(")");
						}
						else {
							insertSql = insertSql.append(parentColumnStr).append(")").append(parentValueStr).append(")");
						}
						selectSql = selectSql.append(selectStr).append(childSelectStr);
						updateSelectSql = updateSelectSql.append(selectAfterUpdateStr).append(childUpdateSelectStr);
						updateSql = updateSql.append(updateStr).append(updateWhere).append(childUpdateWhere);
						//updateStr = updateStr.append(updateWhere);

						insertSql = Utf8ToGbk(insertSql.c_str());
						updateSql = Utf8ToGbk(updateSql.c_str());
						selectSql = Utf8ToGbk(selectSql.c_str());
						updateSelectSql = Utf8ToGbk(updateSelectSql.c_str());
						WriteLog("插入语句：%s\n", insertSql.c_str());
						WriteLog("更新语句：%s\n", updateSql.c_str());
						WriteLog("查询语句：%s\n", selectSql.c_str());
						WriteLog("更新后查询语句：%s\n", updateSelectSql.c_str());
						insertVec.push_back(insertSql);
						updateVec.push_back(updateSql);
						selectVec.push_back(selectSql);
						selectAfterUpdateVec.push_back(updateSelectSql);
						char sendChar[200] = "";
						strcpy(sendChar, insertSql.c_str());
						char sendChar2[200] = "";
						strcpy(sendChar2, selectSql.c_str());
						int result = ado0.ado_QuerySQLNoInputParam(sendChar2);
						bool resultSql = ado0.executeInsert(sendChar2, sendChar, result);
					}
					ITKCALL(ifail = BOM_close_window(bom_window_tag));//有开必有关
				}
				DOFREE(bom_tags);
			}
			else {
				WriteLog("登录失败====\n");
			}
		}
		DOFREE(object_TYPE_1);
	}
	//更新数据库
	for (int i = 0; i < updateVec.size(); i++) {
		string updateSql = updateVec[i];
		string selectSql = selectVec[i];
		string insertSql = insertVec[i];
		string selectUpdate = selectAfterUpdateVec[i];
		char sendChar[200] = "";
		char sendChar2[200] = "";
		char sendChar3[200] = "";
		strcpy(sendChar, updateSql.c_str());
		strcpy(sendChar2, selectSql.c_str());
		strcpy(sendChar3, selectUpdate.c_str());
		int result = ado0.ado_QuerySQLNoInputParam(sendChar2);
		if (result == 0) {
			showError = true;
			WriteLog("插入失败：%s\n", insertSql.c_str());
		}
		else {
			bool resultSql = ado0.execute2(sendChar2, sendChar, result);
			result = ado0.ado_QuerySQLNoInputParam(sendChar3);
			if (result == 0) {
				showError = true;
				WriteLog("更新失败：%s\n", updateSql.c_str());
			}
		}
	}
	ado0.close();
	//EMH_clear_errors();
	DOFREE(attachments);
	//if (showError == true) {
	//	string logName = "数据异常，详见服务器日志：";
	//	logName = logName.append(TC_LOG_FILE);
	//	EMH_store_error_s1(EMH_severity_warning, EMH_AE_error_base, logName.c_str());
	//}
	WriteLog("=========================================================\n");
	WriteLog("JD_BOMInfoToMediDatabase 完成\n");
	WriteLog("=========================================================\n");
	return 0;
}