#include <tc/tc.h>
#include "epm_handler_common.h"
#include <ict/ict_userservice.h>
#include <tccore/custom.h>
#include <epm/epm_toolkit_tc_utils.h>
#include <tccore/aom.h>
#include <tccore/aom_prop.h>
#include <tccore/item.h>
#include <bom/bom.h>
#include "ps/ps.h";
#include "ps/vrule.h"
#include "sstream"
#include <tccore/grm.h>
#include "epm/epm.h"
#include "sa/sa.h"
#include "libxl.h"
#include <map>
#include "epm/signoff.h"
#include <ctime>
#include <vector>
#include <locale>
#include <codecvt>
#include "ae/dataset.h"
#include <iostream>
#include <stdlib.h>
#include <tccore/aom.h>
#include <tc/emh.h>
#include <ict/ict_userservice.h>
#include <tc/tc.h>
#include <tccore/tctype.h>
#include <sa/tcfile.h>
#include <ss/ss_errors.h>
#include <ae/datasettype.h>
// #include "hx_custom.h"
#include "tc_log.h"
// #include "jk_custom.h"
#include "chint_Handler.h"
#include "tc_util.h"
#include <regex>
#include <ics/ics.h>
#include "ocilib.h"
#include <cfm/cfm.h>
#include <me/me.h>
#include <property/nr.h>
#include <tccore/aom.h>
#include <tccore/item.h>
#include <tccore/workspaceobject.h>
using namespace std;

typedef struct {
	string cpxh;//产品型号 低、中、高、调、稳
	string dyxq;
	string zyxq;
	string gyxq;
	string tyxq;
	string wyxq;
}ByqBean;
typedef struct {
	string rgsj;//产品型号 低、中、高、调、稳
	string jqsj;
	string zbsj;
	string zrsczq;
}TimeBean;
typedef struct {
	string temGxCode;
	string temGxName;

}TemGxBean;
struct FlBean
{
	tag_t flTag=NULLTAG;
	string blQty;
};
string getCshVal(string name, string code);

string sqlProTime = "select GYNAME,GXNAME from CHINT_WORKHOUR where \"PRODUCTXH\" = '%s' and GYID = '%s' and COMPANYCODE ='M060' and \"ProCycle\"<1 ";
string sqlProTime2 = "select GYNAME,GXNAME from CHINT_WORKHOUR where \"PRODUCTXH\" = '%s' and GYID = '%s' and JSASK = '%s' and COMPANYCODE ='M060' and \"ProCycle\"<1 ";

string sqlRxfs = "select \"TarGXCODE\", \"TarGXNAME\", \"TemGXCODE\", \"TemGXNAME\" from \"CHINT_WORKHOUR_WhGXName\" where \"WindStyle\" = '%s' and COMPANYCODE ='M060'";
string sqlGyRule = "select GYID from \"CHINT_WORKHOUR_WhGYRule\" where \"ProductZu\" = '%s' and \"TuHao\" = '%s' and COMPANYCODE ='M060'";
string sqlCpxh = "SELECT \"ProductZu\" FROM \"CHINT_WORKHOUR_WhProductXH\" where \"ProductXH\" = '%s' and COMPANYCODE ='M060' ";
string sqlGxTime = "select GXCODE,ARTIFICIALTIME,MACHINETIME,READINESSTIME,\"ProCycle\" from CHINT_WORKHOUR where \"PRODUCTXH\" = '%s' and GYID = '%s' and COMPANYCODE ='M060'";
string sqlGxTime2 = "select GXCODE,ARTIFICIALTIME,MACHINETIME,READINESSTIME,\"ProCycle\" from CHINT_WORKHOUR where \"PRODUCTXH\" = '%s' and GYID = '%s' and JSASK = '%s' and COMPANYCODE ='M060'";
void save_representation2(tag_t primaryTag, tag_t secondTag, char* relationType)
{
	tag_t typeTag = NULLTAG;
	ITKCALL(GRM_find_relation_type(relationType, &typeTag));

	ITKCALL(AOM_refresh(primaryTag, TRUE));
	ITKCALL(AOM_refresh(secondTag, TRUE));
	tag_t relationTag = NULLTAG;
	ITKCALL(GRM_create_relation(primaryTag, secondTag, typeTag, NULLTAG, &relationTag));//如果关系已经存在，那么就是增加对象

	ITKCALL(GRM_save_relation(relationTag));//很必要
	ITKCALL(AOM_save(primaryTag));
	ITKCALL(AOM_save(secondTag));
	ITKCALL(AOM_refresh(primaryTag, FALSE));
	ITKCALL(AOM_refresh(secondTag, FALSE));
}
void updateTemGxCode(tag_t processTag, map<string, TemGxBean> temGxMap) {
	int bvr_count = 0;
	tag_t ebom_window = NULLTAG;
	tag_t bom_line = NULLTAG;
	tag_t item_tag = NULLTAG, *c_line_tags;
	ITKCALL(BOM_create_window(&ebom_window));
	tag_t* bvr_list = NULL;
	ITKCALL(ITEM_rev_list_bom_view_revs(processTag, &bvr_count, &bvr_list));
	printf("bvr_count=%d", bvr_count);

	ITKCALL(BOM_set_window_top_line_bvr(ebom_window, bvr_list[0], &bom_line)); //顶层bom获取
	//bom_line工艺
	int c_line_count;
	ITKCALL(BOM_line_ask_all_child_lines(bom_line, &c_line_count, &c_line_tags)); // 一级工序
	for (int i = 0; i < c_line_count; i++) {
		tag_t oneGxLine = c_line_tags[i], *towGxLines, oneGx, gxItem;
		char* gxbm1;
		AOM_ask_value_string(oneGxLine, "bl_ZT2_FirstOPRevision_zt2_ClassificationCode", &gxbm1);

		printf("gxbm1===>%s\n", gxbm1);
		if (temGxMap.count(gxbm1) > 0) {
			char* oldName;
			TemGxBean temGxBean = temGxMap[gxbm1];
			ITKCALL(AOM_lock(oneGxLine));
			ITKCALL(AOM_set_value_string(oneGxLine, "bl_ZT2_FirstOPRevision_zt2_ClassificationCode", temGxBean.temGxCode.c_str()));
			ITKCALL(AOM_save(oneGxLine));
			AOM_unlock(oneGxLine);
			ITKCALL(AOM_ask_value_tag(oneGxLine, "bl_line_object", &oneGx));
			ITKCALL(ITEM_ask_item_of_rev(oneGx, &gxItem));
			ITKCALL(AOM_lock(gxItem));
			ITKCALL(AOM_ask_value_string(gxItem, "object_name", &oldName));
			ITKCALL(AOM_set_value_string(gxItem, "object_name", temGxBean.temGxName.c_str()));
			ITKCALL(AOM_save(gxItem));
			ITKCALL(AOM_unlock(gxItem));
			ITKCALL(AOM_lock(oneGx));
			ITKCALL(AOM_set_value_string(oneGx, "object_name", temGxBean.temGxName.c_str()));
			ITKCALL(AOM_save(oneGx));
			ITKCALL(AOM_unlock(oneGx));
			printf("oldName===>%s\n", oldName);
			printf("temGxName===>%s\n", temGxBean.temGxName.c_str());
			printf("temGxCode===>%s\n", temGxBean.temGxCode.c_str());
		}

		int c_cnt = 0;
		BOM_line_ask_all_child_lines(oneGxLine, &c_cnt, &towGxLines);
		for (int j = 0; j < c_cnt; j++) {
			tag_t towGxLine = towGxLines[j];
			tag_t towGx, gxItem2;
			char* gxbm2;
			ITKCALL(AOM_ask_value_string(towGxLine, "bl_ZT2_FirstOPRevision_zt2_ClassificationCode", &gxbm2));

			printf("gxbm2===>%s\n", gxbm2);
			if (temGxMap.count(gxbm2) > 0) {
				TemGxBean temGxBean = temGxMap[gxbm2];
				AOM_lock(towGxLine);
				ITKCALL(AOM_set_value_string(towGxLine, "bl_ZT2_FirstOPRevision_zt2_ClassificationCode", temGxBean.temGxCode.c_str()));
				AOM_save(towGxLine);
				AOM_unlock(towGxLine);
				char* oldName, *oldName2;
				ITKCALL(AOM_ask_value_tag(towGxLine, "bl_line_object", &towGx));
				ITKCALL(ITEM_ask_item_of_rev(towGx, &gxItem2));
				ITKCALL(AOM_lock(gxItem2));
				ITKCALL(AOM_ask_value_string(gxItem2, "object_name", &oldName));
				ITKCALL(AOM_set_value_string(gxItem2, "object_name", temGxBean.temGxName.c_str()));
				ITKCALL(AOM_save(gxItem2));
				ITKCALL(AOM_unlock(gxItem2));
				ITKCALL(AOM_ask_value_string(gxItem2, "object_name", &oldName2));
				printf("oldName===>%s\n", oldName);
				printf("oldName2===>%s\n", oldName2);
				printf("temGxName===>%s\n", temGxBean.temGxName.c_str());
				printf("temGxCode===>%s\n", temGxBean.temGxCode.c_str());
				ITKCALL(AOM_lock(towGx));
				ITKCALL(AOM_set_value_string(towGx, "object_name", temGxBean.temGxName.c_str()));
				ITKCALL(AOM_save(towGx));
				ITKCALL(AOM_unlock(towGx));

			}

		}
	}
	BOM_close_window(ebom_window);
}
string getCshVal(string name,string code) {

	string strResult;
	string schVal = "";
	//cmd指令
	char cmd[256] = "";
	strcpy(cmd, "java -jar \"");
	//strcat(cmd, jar_file);
	strcat(cmd, getenv("TC_ROOT"));
	strcat(cmd, "\\bin\\findCshSql.jar");
	strcat(cmd, "\" ");
	strcat(cmd, name.c_str());
	strcat(cmd, "\" ");
	strcat(cmd, code.c_str());
	printf("路径:\n%s\n", cmd);
	char buf[8000] = { 0 };
	FILE* pf = NULL;
	if ((pf = _popen(cmd, "r")) == NULL) {
		printf("接口返回:\n%s", "1");
	}

	while (fgets(buf, sizeof buf, pf)) {
		strResult += buf;
	}
	_pclose(pf);
	vector<string> vec;
	Split(strResult,"CSHVAL:[",vec);
	if (vec.size() > 0) {
		Split(vec[1], "]", vec);
		schVal = vec[0];
	}
	
	return schVal;
}
string getJdbVal(string name,string yqz,string checkcode,string draw,string modelVersion,string code,string checkCode) {
	string drawingno = draw.append("-").append(name);
	string getCode = "select checkno,NUMBEROFCHECKS from CHINT_CHECK_TITLE WHERE drawingno = '%s' and modelversion='%s' order by NUMBEROFCHECKS desc ";
	string getNo = "select NO from CHINT_CHECK_DETAILS_TEMPLATE where code ='%s' and modelversion = '%s' and checkCode = '%s' ";
	string val = "";
	char selectRxfs[500];
	sprintf(selectRxfs, getNo.c_str(), code.c_str(), modelVersion.c_str(), checkCode.c_str());
	int outputColumn1 = 0, outputValueCount1 = 0;
	char*** outputValue1 = NULL;
	QuerySQLNoInputParam(selectRxfs, &outputColumn1, &outputValueCount1, &outputValue1);
	printf("selectRxfs ===>%s\n", selectRxfs);
	if (outputValueCount1 > 0) {
		string no = outputValue1[0][0];
		char selectRxfs2[500];
		outputValueCount1 = 0;
		outputColumn1 = 0;
		outputValue1 = NULL;
		sprintf(selectRxfs2, getCode.c_str(), drawingno.c_str(), modelVersion.c_str());
		printf("selectRxfs2 ===>%s\n", selectRxfs2);
		QuerySQLNoInputParam(selectRxfs2, &outputColumn1, &outputValueCount1, &outputValue1);
		if (outputValueCount1 > 0) {
			string checkNo = outputValue1[0][0];
			string numofCheck = outputValue1[0][1];
			string getNo = "select %s from CHINT_CHECK_DETAILS where no ='%s' and NUMBEROFCHECKS = '%s' and checkno = '%s' and modelversion = '%s' ";
			char selectRxfs3[500];
			sprintf(selectRxfs3, getNo.c_str(), yqz.c_str(), no.c_str(), numofCheck.c_str(), checkNo.c_str(), modelVersion.c_str());
			printf("selectRxfs3 ===>%s\n", selectRxfs3);

			int outputColumn2 = 0, outputValueCount2 = 0;
			char*** outputValue2 = NULL;
			QuerySQLNoInputParam(selectRxfs3, &outputColumn2, &outputValueCount2, &outputValue2);
			if (outputValueCount1 > 0) {
				val = outputValue2[0][0];
			}
		}
	}
	return val;
}
typedef struct {
	string no;//产品型号 低、中、高、调、稳
	string mentNo;
	string mentDesc;
	string mentResult;
}JYXBean;
void setZljyx(string gxbm2, string th,string lastId,string name,tag_t towGx) {

	string code;
	printf("th == >%s \n", th.c_str());
	if (strstr(th.c_str(),"-") != NULL) {
		vector<string> vec;
		Split(th, "-", vec);
		code.append(vec[0]).append("-").append("X");
	}
	else {
		code = th;
	}
	printf("code == >%s \n", code.c_str());
	string sql = "select cqmodelnno,drawingno,cqmanagementno,cqmanagementdesc,cqmanagementresult,datasource, checkline, checkcode, parameterization, code, modelversion from CHINT_QUALITY_MANAGEMENT_SYSTEM where cpcmcode like '%s' and cdrawingno = '%s' order by cqmodelnno asc";
	char selectRxfs[500];
	string gxbmMsg;
	gxbmMsg.append("%").append(gxbm2).append("%");
	sprintf(selectRxfs, sql.c_str(), gxbmMsg.c_str(), code.c_str());
	int outputColumn1 = 0, outputValueCount1 = 0;
	char*** outputValue1 = NULL;
	printf("search3 ===> %s\n", selectRxfs);
	QuerySQLNoInputParam(selectRxfs, &outputColumn1, &outputValueCount1, &outputValue1);
	printf("search result ===> %d\n", outputValueCount1);
	vector< JYXBean> beans;

	for (int num = 0; num < outputValueCount1; num++) {
		//TarGXCODE\", \"TarGXNAME\", \"TemGXCODE\", \"TemGXNAME
		JYXBean bean;
		string cqmodelnno = outputValue1[num][0]; //序号
		string drawingno = outputValue1[num][1]; //校对表图号
		string cqmanagementno = outputValue1[num][2]; //属性no
		string cqmanagementdesc = outputValue1[num][3]; //属性描述
		string cqmanagementresult = outputValue1[num][4]; //属性
		string datasource = outputValue1[num][5]; //校对表或参数化
		string checkline = outputValue1[num][6]; // 要求值，设计值 designresult,PROOFREADRESULT
		string checkcode = outputValue1[num][7]; //checkcode
		string parameterization = outputValue1[num][8]; //code
		string code = outputValue1[num][9]; //校对表模板
		string modelversion = outputValue1[num][10]; //校对表模板版本
		bean.mentDesc = cqmanagementdesc;
		bean.mentNo = cqmanagementno;
		bean.no = cqmodelnno;
		if (cqmanagementresult.empty()) {

			if (datasource.compare("校对表") == 0) {
			//	string getCode = "select code,NUMBEROFCHECKS from CHINT_CHECK_TITLE WHERE drawingno = '?' order by NUMBEROFCHECKS desc ";
				if (checkline.compare("要求值") == 0 && !checkcode.empty()) {
					bean.mentResult = getJdbVal(lastId,"designresult", checkcode, drawingno, modelversion,code, checkcode); //designresult,PROOFREADRESULT
				}
				else if (checkline.compare("设计值") == 0 && !checkcode.empty()) {
					bean.mentResult = getJdbVal(lastId, "PROOFREADRESULT", checkcode, drawingno, modelversion, code, checkcode);
				}
			}
			else if (!parameterization.empty()) {
				string csh = getCshVal(lastId, code);
				bean.mentResult = csh;
			}
		}
		else {
			bean.mentResult = cqmanagementresult;
		}
		beans.push_back(bean);
	}
	tag_t item, rev;
	string objName = "质量检验-";
	objName.append(name);
	
	if (beans.size()>0) {
		tag_t *tableRow;
		ITKCALL(ITEM_create_item(NULL, objName.c_str(), "ZT2_QCHECK", NULL, &item, &rev));
		ITKCALL(AOM_save(item));
		ITKCALL(AOM_save(rev));
		ITKCALL(AOM_lock(item));
		ITKCALL(AOM_lock(rev));
		ITKCALL(AOM_insert_table_rows(rev, "zt2_QCHECKS", 0, beans.size(), &tableRow));
		ITKCALL(AOM_save(rev));
		ITKCALL(AOM_unlock(rev));
		ITKCALL(AOM_save(item));
		ITKCALL(AOM_unlock(item));
		for (int i = 0; i < beans.size(); i++) {
			tag_t table = tableRow[i];
			ITKCALL(AOM_lock(table));
			ITKCALL(AOM_set_value_string(table,"zt2_code", beans[i].no.c_str()));
			ITKCALL(AOM_set_value_string(table, "zt2_jjxbh", beans[i].mentNo.c_str()));
			ITKCALL(AOM_set_value_string(table, "zt2_jyxmc", beans[i].mentDesc.c_str()));
			ITKCALL(AOM_set_value_string(table, "zt2_jyxsjjg", beans[i].mentResult.c_str()));
			ITKCALL(AOM_save(table));
			ITKCALL(AOM_unlock(table));
		}
		ITKCALL(AOM_save(towGx));
		save_representation2(towGx, item, "ZT2_QualityCheckRelation");
	}

}
void getGxbmMap(tag_t processTag, map<string, tag_t>& gxDocMap, map<string, TimeBean > timebeans,
	map<string, vector<FlBean>> flBeanMap,string th,string lastId) {
	int bvr_count = 0;
	tag_t ebom_window = NULLTAG;
	tag_t bom_line = NULLTAG;
	tag_t item_tag = NULLTAG, *c_line_tags;
	ITKCALL(BOM_create_window(&ebom_window));
	tag_t* bvr_list = NULL;
	ITKCALL(ITEM_rev_list_bom_view_revs(processTag, &bvr_count, &bvr_list));
	printf("bvr_count=%d", bvr_count);

	ITKCALL(BOM_set_window_top_line_bvr(ebom_window, bvr_list[0], &bom_line)); //顶层bom获取
	//bom_line工艺
	int c_line_count;
	ITKCALL(BOM_line_ask_all_child_lines(bom_line, &c_line_count, &c_line_tags)); // 一级工序

	//修改工时
	for (int i = 0; i < c_line_count; i++) {
		tag_t oneGx = c_line_tags[i], *towGxLines;
		char* gxbm1;
		ITKCALL(AOM_ask_value_string(oneGx, "bl_ZT2_FirstOPRevision_zt2_ClassificationCode", &gxbm1));
		if (timebeans.count(gxbm1) > 0) {
			ITKCALL(AOM_lock(oneGx));
			TimeBean tbean = timebeans[gxbm1];
			ITKCALL(AOM_set_value_string(oneGx, "bl_ZT2_FirstOPRevision_zt2_ArtificialTime", tbean.rgsj.c_str()));
			ITKCALL(AOM_set_value_string(oneGx, "bl_ZT2_FirstOPRevision_zt2_MachineTime", tbean.jqsj.c_str()));
			ITKCALL(AOM_set_value_string(oneGx, "bl_ZT2_FirstOPRevision_zt2_ReadinessTime", tbean.zbsj.c_str()));
			ITKCALL(AOM_set_value_string(oneGx, "bl_ZT2_FirstOPRevision_zt2_ProCycle", tbean.zrsczq.c_str()));
			ITKCALL(AOM_save(oneGx));
			ITKCALL(AOM_unlock(oneGx));
		}
		int c_cnt = 0;
		ITKCALL(BOM_line_ask_all_child_lines(oneGx, &c_cnt, &towGxLines));
		for (int j = 0; j < c_cnt; j++) {
			tag_t towGxLine = towGxLines[j];
			tag_t towGx;
			char* gxbm2;
			ITKCALL(AOM_ask_value_string(towGxLine, "bl_ZT2_FirstOPRevision_zt2_ClassificationCode", &gxbm2));
			if (timebeans.count(gxbm2) > 0) {
				ITKCALL(AOM_lock(towGxLine));
				TimeBean tbean = timebeans[gxbm2];
				ITKCALL(AOM_set_value_string(towGxLine, "bl_ZT2_FirstOPRevision_zt2_ArtificialTime", tbean.rgsj.c_str()));
				ITKCALL(AOM_set_value_string(towGxLine, "bl_ZT2_FirstOPRevision_zt2_MachineTime", tbean.jqsj.c_str()));
				ITKCALL(AOM_set_value_string(towGxLine, "bl_ZT2_FirstOPRevision_zt2_ReadinessTime", tbean.zbsj.c_str()));
				ITKCALL(AOM_set_value_string(towGxLine, "bl_ZT2_FirstOPRevision_zt2_ProCycle", tbean.zrsczq.c_str()));
				ITKCALL(AOM_save(towGxLine));
				ITKCALL(AOM_unlock(towGxLine));
			}
			char* name = NULL;
			ITKCALL(AOM_ask_value_tag(towGxLine, "bl_line_object", &towGx));
			ITKCALL(AOM_ask_value_string(towGx, "object_name", &name));
			//设置质检项
			setZljyx(gxbm2,th, lastId, name, towGx);
			if (flBeanMap.count(gxbm2) > 0) {
				vector<FlBean> beansVec = flBeanMap[gxbm2];
				printf("beansVec===>%zd\n", beansVec.size());
				if (beansVec.size() > 0) {
					tag_t axqPmatnr;
					ITKCALL(AOM_ask_value_tag(towGxLine, "bl_line_object", &axqPmatnr));
					ITKCALL(ITEM_rev_list_bom_view_revs(axqPmatnr, &bvr_count, &bvr_list));
					printf("bvr_count=%d\n", bvr_count);
					if (bvr_count == 0) {
						tag_t newView, newViewBvr, pitem;
						ITKCALL(ITEM_ask_item_of_rev(axqPmatnr, &pitem));
						ITKCALL(PS_create_bom_view(NULL, NULL, NULL, pitem, &newView));
						ITKCALL(AOM_save(newView));
						ITKCALL(PS_create_bvr(newView, NULL, NULL, FALSE, axqPmatnr, &newViewBvr));
						ITKCALL(AOM_save(newViewBvr));
						ITKCALL(AOM_save(axqPmatnr));
					}
				}
				//投辅料
				for (int n = 0; n < beansVec.size(); n++) {
					tag_t cLine;
					FlBean cBean = beansVec[n];
					if (cBean.flTag == NULLTAG) {
						continue;
					}
					ITKCALL(BOM_line_add(towGxLine, NULL, cBean.flTag, NULL, &cLine));
					ITKCALL(AOM_lock(cLine));
					string num = cBean.blQty;
					ITKCALL(AOM_set_value_string(cLine, "bl_quantity", num.c_str()));
					string seqNo = to_string((n + 1) * 10);
					ITKCALL(AOM_set_value_string(cLine, "bl_sequence_no", seqNo.c_str()));
					ITKCALL(AOM_set_value_string(cLine, "bl_occ_type", "ZT2_FuLiao"));
					ITKCALL(AOM_save(cLine));
					//最后unlock
					ITKCALL(AOM_unlock(cLine));
					ITKCALL(AOM_refresh(cLine, FALSE));
				}
				
			}
			
			gxDocMap[gxbm2] = towGx;
		}
	}
	ITKCALL(BOM_save_window(ebom_window));
	ITKCALL(BOM_close_window(ebom_window));
}
void getGxbmMap(tag_t processTag, map<string, tag_t>& gxDocMap, map<string, TimeBean > timebeans) {
	int bvr_count = 0;
	tag_t ebom_window = NULLTAG, bom_line = NULLTAG, item_tag = NULLTAG, *c_line_tags = NULLTAG;
	ITKCALL(BOM_create_window(&ebom_window));
	tag_t* bvr_list = NULL;
	ITKCALL(ITEM_rev_list_bom_view_revs(processTag, &bvr_count, &bvr_list));
	printf("bvr_count=%d", bvr_count);

	ITKCALL(BOM_set_window_top_line_bvr(ebom_window, bvr_list[0], &bom_line)); //顶层bom获取
	//bom_line工艺
	int c_line_count;
	ITKCALL(BOM_line_ask_all_child_lines(bom_line, &c_line_count, &c_line_tags)); // 一级工序

	for (int i = 0; i < c_line_count; i++) {
		tag_t oneGx = c_line_tags[i], *towGxLines;
		char* gxbm1;
		ITKCALL(AOM_ask_value_string(oneGx, "bl_ZT2_FirstOPRevision_zt2_ClassificationCode", &gxbm1));
		if (timebeans.count(gxbm1) > 0) {
			ITKCALL(AOM_lock(oneGx));
			TimeBean tbean = timebeans[gxbm1];
			ITKCALL(AOM_set_value_string(oneGx, "bl_ZT2_FirstOPRevision_zt2_ArtificialTime", tbean.rgsj.c_str()));
			ITKCALL(AOM_set_value_string(oneGx, "bl_ZT2_FirstOPRevision_zt2_MachineTime", tbean.jqsj.c_str()));
			ITKCALL(AOM_set_value_string(oneGx, "bl_ZT2_FirstOPRevision_zt2_ReadinessTime", tbean.zbsj.c_str()));
			ITKCALL(AOM_set_value_string(oneGx, "bl_ZT2_FirstOPRevision_zt2_ProCycle", tbean.zrsczq.c_str()));
			ITKCALL(AOM_save(oneGx));
			ITKCALL(AOM_unlock(oneGx));
		}
		int c_cnt = 0;
		ITKCALL(BOM_line_ask_all_child_lines(oneGx, &c_cnt, &towGxLines));
		for (int j = 0; j < c_cnt; j++) {
			tag_t towGxLine = towGxLines[j];
			tag_t towGx;
			char* gxbm2;
			ITKCALL(AOM_ask_value_string(towGxLine, "bl_ZT2_FirstOPRevision_zt2_ClassificationCode", &gxbm2));
			if (timebeans.count(gxbm2) > 0) {
				ITKCALL(AOM_lock(towGxLine));
				TimeBean tbean = timebeans[gxbm2];
				ITKCALL(AOM_set_value_string(towGxLine, "bl_ZT2_FirstOPRevision_zt2_ArtificialTime", tbean.rgsj.c_str()));
				ITKCALL(AOM_set_value_string(towGxLine, "bl_ZT2_FirstOPRevision_zt2_MachineTime", tbean.jqsj.c_str()));
				ITKCALL(AOM_set_value_string(towGxLine, "bl_ZT2_FirstOPRevision_zt2_ReadinessTime", tbean.zbsj.c_str()));
				ITKCALL(AOM_set_value_string(towGxLine, "bl_ZT2_FirstOPRevision_zt2_ProCycle", tbean.zrsczq.c_str()));
				ITKCALL(AOM_save(towGxLine));
				ITKCALL(AOM_unlock(towGxLine));
			}
			ITKCALL(AOM_ask_value_tag(towGxLine, "bl_line_object", &towGx));
			gxDocMap[gxbm2] = towGx;
		}
	}
	ITKCALL(BOM_close_window(ebom_window));
}

//查询ID
tag_t * queryItem(char* itemId,tag_t newGx,char *relation) {
	tag_t query_tag = NULLTAG,*tags=NULLTAG;
	ITKCALL(QRY_find("零组件...", &query_tag));
	char* qry_entries[1] = { "零组件 ID" }, *qry_values[1] = { itemId };
	int n_found;
	ITKCALL(QRY_execute(query_tag, 1, qry_entries, qry_values, &n_found, &tags));
	if (n_found > 0) {
		ITKCALL(AOM_set_value_tags(newGx, relation, n_found, tags));
	}
	return tags;
}
//根据数据库获取ID  2023/12/19 新增逻辑
void queryProcessRule(char *windWay, boolean isXq, char *processCode, tag_t &newGx) {

	char selectGyId[200]; //根据工厂M060 二级工序编码 绕线方式(线圈) 获取工时信息
	if (isXq) {
		string sqlRuleId = "select \"processroutefiles\",\"esopfiles\" from CHINT_PROCESS_SOP_RULE where \"companycode\" = 'M060' and \"windway\" = '%s' and \"gxcode\" = '%s' ";
		sprintf(selectGyId, sqlRuleId.c_str(), windWay, processCode);
	}
	else {
		string sqlRuleId = "select \"processroutefiles\",\"esopfiles\" from CHINT_PROCESS_SOP_RULE where \"companycode\" = 'M060' and \"gxcode\" = '%s' ";
		sprintf(selectGyId, sqlRuleId.c_str(), processCode);
	}
	printf("selectGyId %s \n", selectGyId);
	int outputColumn3 = 0, outputValueCount3 = 0;
	char*** outputValue3 = NULL;
	QuerySQLNoInputParam(selectGyId, &outputColumn3, &outputValueCount3, &outputValue3);
	printf("outputValueCount3 %d \n", outputValueCount3);
	string processIds, esopIds;
	for (int j = 0; j < outputValueCount3; j++) {
		char* processId = outputValue3[j][0];
		char* esopId = outputValue3[j][1];
		if (strcmp(processId, "") != 0) {
			processIds.append(processId).append(";");
		}
		if (strcmp(esopId, "") != 0) {
			esopIds.append(esopId).append(";");
		}
	}
	queryItem((char*)processIds.c_str(), newGx,"ZT2_ProcessRuleRelation");
	queryItem((char*)esopIds.c_str(), newGx, "ZT2_ProcGuidBookRelation");
}

tag_t clone_process_from_template(char* process_item_id, boolean isXq, string productZu, string xqfs,string th, string lastId)
{
	tag_t item_tag = NULLTAG;
	ITKCALL(ITEM_find_item(process_item_id, &item_tag));
	if (item_tag == NULLTAG)
	{
		printf("\n MEProcess NOT found! \n");
		return NULLTAG;
	}
	tag_t revision_tag = NULLTAG;
	ITKCALL(ITEM_ask_latest_rev(item_tag, &revision_tag));
	char* nameOld, *item_revision_id;
	ITKCALL(AOM_ask_value_string(revision_tag, "item_revision_id", &item_revision_id));
	ITKCALL(AOM_ask_value_string(revision_tag, "object_name", &nameOld));
	ITKCALL(MEBOM_init_module());

	tag_t window_tag = NULLTAG;
	ITKCALL(ME_create_bop_window(&window_tag));

	tag_t rule_tag = NULLTAG;
	ITKCALL(CFM_find("Latest Working", &rule_tag));

	ITKCALL(BOM_set_window_config_rule(window_tag, rule_tag));
	//AOM_ask
	char* next_id = NULL;
	ITKCALL(NR_next_value("MEProcess", "item_id", NULLTAG, "", "", "",
		NULLTAG, "", "", &next_id));

	tag_t clone_tag = NULLTAG;
	ITKCALL(ME_create_process_from_template(next_id, item_revision_id,
		nameOld, "", revision_tag, rule_tag, window_tag,
		"Process.Template.Mapping_Consumes", &clone_tag));

	if (next_id) MEM_free(next_id);

	ITKCALL(AOM_refresh(clone_tag, TRUE));
	ITKCALL(AOM_save(clone_tag));
	ITKCALL(AOM_refresh(clone_tag, FALSE));

	char* item_id = NULL;
	ITKCALL(WSOM_ask_id_string(clone_tag, &item_id));

	printf("\n\t MEProcess Clone ID: %s\n", item_id);
	ITKCALL(AOM_unload(clone_tag));

	if (item_id != NULL)
		MEM_free(item_id);

	//复制“工艺守则”、“工序作业指导书”

	if (isXq) {
		char selectRxfs[200];
		sprintf(selectRxfs, sqlRxfs.c_str(), xqfs.c_str());
		int outputColumn1 = 0, outputValueCount1 = 0;
		char*** outputValue1 = NULL;
		printf("search3 ===> %s\n", selectRxfs);
		QuerySQLNoInputParam(selectRxfs, &outputColumn1, &outputValueCount1, &outputValue1);
		map<string, TemGxBean> temGxMap;
		printf("search result ===> %d\n", outputValueCount1);
		for (int num = 0; num < outputValueCount1; num++) {
			//TarGXCODE\", \"TarGXNAME\", \"TemGXCODE\", \"TemGXNAME
			string tarGxCode = outputValue1[num][0];
			string tarGxName = outputValue1[num][1];
			string temGxCode = outputValue1[num][2];
			TemGxBean bean;
			bean.temGxCode = tarGxCode;
			bean.temGxName = tarGxName;
			temGxMap[temGxCode] = bean;
		}
		//更新 根据数据库配置更新工序编码和名称
		updateTemGxCode(clone_tag, temGxMap);
	}
	//if (!isXq) {
	map<string, tag_t> tmpProcessMap; //存放的是二级工序编码对应的二级工序版本 模板的
	//vector<string> timeVec;
	//工艺模板
	map<string, TimeBean > beanMap;
	//根据数据库配置修改工时
	getGxbmMap(revision_tag, tmpProcessMap, beanMap);
	map<string, tag_t> newProcessMap;//存放的是二级工序编码对应的二级工序版本 克隆出来的
	char selectGyId[200]; //根据产品族 模板id  绕线方式(线圈) 获取工时信息
	if (isXq) {
		sprintf(selectGyId, sqlGxTime2.c_str(), productZu.c_str(), process_item_id, xqfs.c_str());
	}
	else {
		sprintf(selectGyId, sqlGxTime.c_str(), productZu.c_str(), process_item_id);
	}
	int outputColumn1 = 0, outputValueCount1 = 0;
	char*** outputValue1 = NULL;
	string gyId;
	printf("search3 ===> %s\n", selectGyId);
	QuerySQLNoInputParam(selectGyId, &outputColumn1, &outputValueCount1, &outputValue1);
	//查询结果 四种工时
	for (int num = 0; num < outputValueCount1; num++) {
		string gxbm = outputValue1[num][0];
		string rgsj = outputValue1[num][1];
		if (rgsj.rfind(".", 0) == 0) {
			string a = "0";
			rgsj = a.append(rgsj);
			printf("rgsj === >%s\n", rgsj.c_str());
		}
		string jqsj = outputValue1[num][2];
		if (jqsj.rfind(".", 0) == 0) {
			string a = "0";
			jqsj = a.append(jqsj);
		}
		string zbsj = outputValue1[num][3];
		if (zbsj.rfind(".", 0) == 0) {
			string a = "0";
			zbsj = a.append(zbsj);
			printf("zbsj === >%s\n", zbsj.c_str());
		}
		string zrsczq = outputValue1[num][4];
		if (zrsczq.rfind(".", 0) == 0) {
			string a = "0";
			zrsczq = a.append(zrsczq);
			printf("zrsczq === >%s\n", zrsczq.c_str());
		}
		TimeBean bean;
		bean.rgsj = rgsj;
		bean.jqsj = jqsj;
		bean.zbsj = zbsj;
		bean.zrsczq = zrsczq;
		beanMap[gxbm] = bean;
	}
	//克隆出来的工艺路线
	regex qq_reg22("^1ZDB5.*\\d{2,}000X.*"); //\\d{5,}$
	smatch result;
	bool ret = regex_match(th, result, qq_reg22);
	string searchTh = th;
	if (ret) {
		searchTh = "1ZDB5**000X";
	}
	//查询二级工序编码的信息,更新克隆出来的BOM的工序编码
	string sqlFl = "select \"materialno\",\"EJBM\",\"quantity\",\"xuhao\" from CHINT_GYFL_001 where \"ProductZu\" = '%s' and \"TuHao\" ='%s' and \"quantity\" !='/' ORDER BY CAST(\"xuhao\" AS DECIMAL) asc";
	char selectFlId[600];
	sprintf(selectFlId, sqlFl.c_str(), productZu.c_str(), searchTh);
	printf("selectFlId==>%s\n", selectFlId);
	map<string, vector<FlBean>> flBeanMap;
	{
		int outputColumn3 = 0, outputValueCount3 = 0;
		char*** outputValue3 = NULL;
		QuerySQLNoInputParam(selectFlId, &outputColumn3, &outputValueCount3, &outputValue3);
		for (int j = 0; j < outputValueCount3; j++) {
			string materialno = outputValue3[j][0];
			string ejbm = outputValue3[j][1];
			string quantity = outputValue3[j][2];
			tag_t fltag,flRev;
			ITEM_find_item(materialno.c_str(),&fltag);
			ITEM_ask_latest_rev(fltag,&flRev);
			printf("materialno%s ejbm==%sEnd\n", materialno.c_str(), ejbm.c_str());
			FlBean bean;
			bean.blQty = quantity;
			bean.flTag = flRev;
			if (flBeanMap.count(ejbm) > 0) {
				flBeanMap[ejbm].push_back(bean);
			}
			else {
				vector<FlBean> beansVec;
				beansVec.push_back(bean);
				flBeanMap[ejbm] = beansVec;
			}
		}
	}

	getGxbmMap(clone_tag, newProcessMap, beanMap, flBeanMap,th, lastId);
	map<string, tag_t>::iterator it;
	//复制“工艺守则”、“工序作业指导书” 旧逻辑
	/*for (it = tmpProcessMap.begin(); it != tmpProcessMap.end(); it++) {
		string gxbm = it->first;
		tag_t tmpGx = it->second;
		if (newProcessMap.count(gxbm) != 0) {
			tag_t* procGuidBooks, *processRules;
			int cnt2 = 0, cnt3 = 0;
			tag_t newGx = newProcessMap[gxbm];
			ITKCALL(AOM_ask_value_tags(tmpGx, "ZT2_ProcGuidBookRelation", &cnt2, &procGuidBooks));
			ITKCALL(AOM_ask_value_tags(tmpGx, "ZT2_ProcessRuleRelation", &cnt3, &processRules));
			AOM_lock(newGx);
			if (cnt2 > 0) {
				ITKCALL(AOM_set_value_tags(newGx, "ZT2_ProcGuidBookRelation", cnt2, procGuidBooks));
			}
			if (cnt3 > 0) {
				ITKCALL(AOM_set_value_tags(newGx, "ZT2_ProcessRuleRelation", cnt3, processRules));
			}
			AOM_save(newGx);
			AOM_unlock(newGx);
		}
	}*/
	//复制“工艺守则”、“工序作业指导书”  2023/12/19新增逻辑 CHINT_PROCESS_SOP_RULE 表中查询
	for (it = newProcessMap.begin(); it != newProcessMap.end(); it++) {
		string gxbm = it->first;
		tag_t newGx = it->second;
		queryProcessRule((char*)xqfs.c_str(), isXq, (char*)gxbm.c_str(), newGx);
		/*if (newProcessMap.count(gxbm) != 0) {
			tag_t* procGuidBooks, *processRules;
			int cnt2 = 0, cnt3 = 0;
			if (isXq) {
				sprintf(selectGyId, sqlGxTime2.c_str(), productZu.c_str(), process_item_id, xqfs.c_str());
			}
			tag_t newGx = newProcessMap[gxbm];
			ITKCALL(AOM_ask_value_tags(tmpGx, "ZT2_ProcGuidBookRelation", &cnt2, &procGuidBooks));
			ITKCALL(AOM_ask_value_tags(tmpGx, "ZT2_ProcessRuleRelation", &cnt3, &processRules));
			AOM_lock(newGx);
			if (cnt2 > 0) {
				ITKCALL(AOM_set_value_tags(newGx, "ZT2_ProcGuidBookRelation", cnt2, procGuidBooks));
			}
			if (cnt3 > 0) {
				ITKCALL(AOM_set_value_tags(newGx, "ZT2_ProcessRuleRelation", cnt3, processRules));
			}
			AOM_save(newGx);
			AOM_unlock(newGx);
		}*/
	}
	//}
	return clone_tag;
}
//实体且有BOM往下
boolean isXn(tag_t matnr) {
	int cnt2, numFac, cnt3;
	boolean flag = false;
	char** procureType, ** factorys, ** specialProcureType;
	AOM_ask_value_strings(matnr, "zt2_SZSpecialProcuretype", &cnt3, &specialProcureType); //为/
	AOM_ask_value_strings(matnr, "zt2_SZProcuretype", &cnt2, &procureType); //包含自制
	AOM_ask_value_strings(matnr, "zt2_SZFactory", &numFac, &factorys);
	for (int i = 0; i < numFac; i++) {
		if (strcmp(factorys[i], "M060") == 0 && cnt2 > i && cnt3 > i) {
			if (strstr(procureType[i], "自制") != NULL && strcmp(specialProcureType[i], "/") == 0) {
				flag = true;
			}
		}
	}
	return flag;
}
//获取分类属性 判断是否整除
string getClassVal(tag_t top_rev_tag, string& errMessage, ByqBean &bean) {
	//, string className
	tag_t top_classificationObject = NULLTAG, item = NULLTAG;
	ITKCALL(ITEM_ask_item_of_rev(top_rev_tag, &item));
	ITKCALL(ICS_ask_classification_object(item, &top_classificationObject));
	if (top_classificationObject == NULL_TAG)
	{
		errMessage.append("顶层对象没有发送到分类\n");
		return  "";
	}
	char* top_class_id = NULL, *top_class_name = NULL;
	//ICS_ask_class_of_classification_obj(top_classificationObject, &top_class_tag);
	//ICS_ask_id_name(top_class_tag, &top_class_id, &top_class_name);
	printf("BOM TOP LINE CLASS ID = %s | NAME = %s \n", top_class_id, top_class_name);
	int n_attrs;
	char** attr_names = NULL, ** attr_vals = NULL;
	ITKCALL(ICS_ask_attributes_of_classification_obj(top_classificationObject, &n_attrs, &attr_names, &attr_vals));
	cout << n_attrs << endl;
	//	int num = 1;
	string cpxh;
	for (int ii = 0; ii < n_attrs; ii++)
	{
		if (strcmp(attr_names[ii], "产品型号") == 0) {
			if (strcmp(attr_vals[ii], "") == 0) {
				errMessage.append("分类属性产品型号为空，请检查。\n");
				return "";
			}
			else {
				cpxh = (attr_vals[ii]);
			}
			//break;
		}
		else if (strcmp(attr_names[ii], "低压线圈绕线方式") == 0) {
			if (strcmp(attr_vals[ii], "") == 0) {
				//errMessage.append("分类属性低压线圈绕线方式为空，请检查。\n");
				//return "";
			}
			else {
				bean.dyxq = attr_vals[ii];//cpxh = (attr_vals[ii]);
			}
			//break;
		}
		else if (strcmp(attr_names[ii], "中压线圈绕线方式") == 0) {
			if (strcmp(attr_vals[ii], "") == 0) {
				//errMessage.append("分类属性中压线圈绕线方式为空，请检查。\n");
				//return "";
			}
			else {
				bean.zyxq = attr_vals[ii];//cpxh = (attr_vals[ii]);
			}
			//break;
		}
		else if (strcmp(attr_names[ii], "高压线圈绕线方式") == 0) {
			if (strcmp(attr_vals[ii], "") == 0) {
				//errMessage.append("分类属性高压线圈绕线方式为空，请检查。\n");
				//return "";
			}
			else {
				bean.gyxq = attr_vals[ii];//cpxh = (attr_vals[ii]);
			}
			//break;
		}
		else if (strcmp(attr_names[ii], "调压线圈绕线方式") == 0) {
			if (strcmp(attr_vals[ii], "") == 0) {
				//errMessage.append("分类属性调压线圈绕线方式为空，请检查。\n");
				//return "";
			}
			else {
				bean.tyxq = attr_vals[ii];//cpxh = (attr_vals[ii]);
			}
			//break;
		}
		else if (strcmp(attr_names[ii], "稳压线圈绕线方式") == 0) {
			if (strcmp(attr_vals[ii], "") == 0) {
			//	errMessage.append("分类属性稳压线圈绕线方式为空，请检查。\n");
				//return "";
			}
			else {
				bean.wyxq = attr_vals[ii];//cpxh = (attr_vals[ii]);
			}
			//break;
		}
		//五柱铁心
		cout << attr_names[ii] << "\t"
			<< attr_vals[ii] << endl;
	}
	return cpxh;
}
//包含线圈

//不包含线圈
void Split2(string strArg, string spliter, vector<string>& ans)
{
	ans.clear();
	size_t index0 = 0;
	string one_arg;
	if (strArg.find_first_not_of(' ') == string::npos)
		strArg = "";
	while (strArg.size() > 0)
	{
		index0 = strArg.find_first_of(spliter);
		if (index0 != string::npos)
		{
			one_arg = strArg.substr(0, index0);
			strArg = strArg.substr(index0 + 1);
			ans.push_back(one_arg);
		}
		else
		{
			ans.push_back(strArg);
			break;
		}
	}
}
tag_t getTmpProcess(string cpxh, string th, string& errBuff, string& oldGyId, boolean isXq, string xqfs,string lastId) {
	char selectCPZ[300], selectGyId[200];
	sprintf(selectCPZ, sqlCpxh.c_str(), cpxh.c_str());
	int outputColumn = 0, outputValueCount = 0;
	char*** outputValue = NULL;
	string productZu;
	printf("search1 %s \n", selectCPZ);
	QuerySQLNoInputParam(selectCPZ, &outputColumn, &outputValueCount, &outputValue);
	printf("search11\n");
	if (outputValueCount == 0) {
		string buffMsg = "";
		buffMsg.append("当前变压器产品型号:").append(cpxh).append(",在数据库表中无对应典型产品族值，请联系管理员维护.\n");
		size_t found = errBuff.find(buffMsg);
		if (found == std::string::npos) {
			errBuff.append(buffMsg);
		}
		//errBuff.append("当前变压器产品型号:").append(cpxh).append(",在数据库表中无对应典型产品族值，请联系管理员维护.\n");
		return NULLTAG;
	}
	for (int j = 0; j < outputValueCount; j++) {
		productZu = outputValue[j][0];
		printf("productZu===>%s\n", productZu.c_str());
	}

	sprintf(selectGyId, sqlGyRule.c_str(), productZu.c_str(), th.c_str());

	int outputColumn1 = 0, outputValueCount1 = 0;
	char*** outputValue1 = NULL;
	string gyId;
	printf("search2 %s \n", selectGyId);
	QuerySQLNoInputParam(selectGyId, &outputColumn1, &outputValueCount1, &outputValue1);
	if (outputValueCount1 == 0) {
		errBuff.append("图号:").append(th).append("无对应工艺模板ID,请维护后再指派工艺路线.\n");
		return NULLTAG;
	}
	printf("search22\n");
	for (int j = 0; j < outputValueCount1; j++) {
		gyId = outputValue1[j][0];
		printf("gyId===>%s\n", gyId.c_str());
	}
	oldGyId = gyId;
	//新增逻辑校验时间和绕线方式
	{
		char selectGyId[200];
		if (isXq) {
			sprintf(selectGyId, sqlProTime2.c_str(), productZu.c_str(), (char*)gyId.c_str(), xqfs.c_str());
		}
		else {
			sprintf(selectGyId, sqlProTime.c_str(), productZu.c_str(), (char*)gyId.c_str());
		}
		int outputColumn2 = 0, outputValueCount2 = 0;
		char*** outputValue2 = NULL;
		string gyId;
		printf("search3 ===> %s\n", selectGyId);
		boolean hasErr = false;
		QuerySQLNoInputParam(selectGyId, &outputColumn2, &outputValueCount2, &outputValue2);
		for (int t = 0; t < outputValueCount2; t++) {
			string gyName = outputValue2[t][0];
			string gxName = outputValue2[t][1];
			errBuff.append("一级工序名称:").append(gyName).append(" 对应的二级工序:").append(gxName).append("的自然生产周期数据不正确，请及时维护.\n");
		}
		if (outputValue2>0) {
			hasErr = true;
		}
		if (isXq) {
			char selectRxfs[200];
			sprintf(selectRxfs, sqlRxfs.c_str(), xqfs.c_str());
			int outputColumn3 = 0, outputValueCount3 = 0;
			char*** outputValue3 = NULL;
			printf("search3 ===> %s\n", selectRxfs);
			QuerySQLNoInputParam(selectRxfs, &outputColumn3, &outputValueCount3, &outputValue3);
			printf("search result ===> %d\n", outputValueCount3);
			if (outputValueCount3 == 0) {
				errBuff.append("绕线方式:").append(xqfs).append(" 未在CHINT_WORKHOUR_WhGXName表中配置,请及时维护");
				hasErr = true;
			}
		}
		if (hasErr) {
			return NULLTAG;
		}
	}
	tag_t clone_tag = clone_process_from_template((char*)gyId.c_str(), isXq, productZu, xqfs, th, lastId);
	printf("克隆完成===>\n");
	return clone_tag;
}
boolean isTcmOnNot(tag_t process) {
	int structs = 0;
	boolean flag = false;
	tag_t *structure_revisions;
	AOM_ask_value_tags(process, "structure_revisions", &structs, &structure_revisions);
	if (structs > 0) {
		int statusNum = 0;
		char *revUid;
		tag_t *release_status_list;
		tag_t struct_revision = structure_revisions[0];
		AOM_ask_value_tags(struct_revision, "release_status_list", &statusNum, &release_status_list);
		if (statusNum > 0) {
			flag = true;
		}
	}
	return flag;
}
void readProcessBom(tag_t bom_line, string& errorBuff, boolean &flag, tag_t &topProcess, string &notTcmBuff, string back) {

	int c_line_count;
	tag_t mantr, *c_line_tags;
	ITKCALL(AOM_ask_value_tag(bom_line, "bl_line_object", &mantr));
	ITKCALL(BOM_line_ask_all_child_lines(bom_line, &c_line_count, &c_line_tags));
	char *objName;
	AOM_ask_value_string(mantr, "object_name", &objName);
	if (c_line_count > 0 && (isXn(mantr)|| strstr(objName, "变压器") != NULL)) {
		printf("实体\n");
		flag = true;
		//检查是否有工艺路线
		int n_references = 0;
		int* levels = 0;
		tag_t* references_tag = NULLTAG;
		char** relation_type_name = NULL;
		//通过引用关系查找到变更单
		ITKCALL(WSOM_where_referenced(mantr, 1, &n_references, &levels, &references_tag, &relation_type_name));
		boolean hasProcess = false;
		for (int i = 0; i < n_references; i++)
		{
			char* refType;
			tag_t refTag = references_tag[i];
			ITKCALL(AOM_ask_value_string(refTag, "object_type", &refType));
			if (strcmp(refType, "MEProcessRevision") == 0) {
				hasProcess = true;
				break;
			}
		}
		printf("hasProcess==%d\n", hasProcess);
		if (!hasProcess) {
			char* bl_desc = NULL, * itemID = NULL;
			ITKCALL(AOM_ask_value_string(mantr, "item_id", &itemID));
			printf("back==%zd\n", back.size());
			if (back.size() > 0) {
				vector<string> backs;
				Split2(back, "@", backs);
				tag_t processTag = NULLTAG;
				string tmpGyId;
				processTag = getTmpProcess(backs[0], backs[1], errorBuff, tmpGyId, false, "", "");
				topProcess = processTag;
				if (processTag != NULLTAG) {
					printf("save_representation2\n");
					save_representation2(processTag, mantr, "IMAN_METarget");
				}
			}
			else if (strstr(objName, "变压器") != NULL) {
				tag_t* byqRev = NULLTAG;
				string tmpGyId;
				char* uid = NULL;
				int cnt3 = 0;
				ITKCALL(AOM_ask_value_tags(mantr, "TC_Is_Represented_By", &cnt3, &byqRev));
				ByqBean bean;
				ITK__convert_tag_to_uid(byqRev[0], &uid);
				printf("objName%s %s\n", objName, uid);
				string cpxh = getClassVal(byqRev[0], errorBuff, bean);
				char* thId = NULL;
				ITKCALL(AOM_ask_value_string(byqRev[0], "item_id", &thId));
				printf("cpxh===>%s\n", cpxh.c_str());
				tag_t processTag = NULLTAG;
				if (strstr(objName, "线圈") == NULL) {
					vector<string> idVec;
					Split2(thId, "-", idVec);
					processTag = getTmpProcess(cpxh, "1ZDB300000P", errorBuff, tmpGyId, false, "", idVec[1]);
					topProcess = processTag;
					if (processTag != NULLTAG) {
						save_representation2(processTag, mantr, "IMAN_METarget");
					}
				}
			}
			else {
				ITKCALL(AOM_ask_value_string(bom_line, "bl_rev_object_desc", &bl_desc));
				vector<string> descVec1;
				Split2(bl_desc, " ", descVec1);
				if (descVec1.size() > 1) {
					string drawNos = descVec1[1];
					vector<string> drawNoVec1;
					Split2(drawNos, "-", drawNoVec1);
					if (drawNoVec1.size() > 1) {
						string wordNo = drawNoVec1[1]; //工程号 拼接1ZDB300000P 查找分类属性
						string drawNo = drawNoVec1[0]; //图号
						if (drawNoVec1.size() == 3) {
							drawNo = drawNoVec1[0].append("-").append(drawNoVec1[1]);
							wordNo = drawNoVec1[2];
						}
						string byqId = "1ZDB300000P-", tmpGyId;
						tag_t byqTag = NULLTAG, byqRev = NULLTAG, processTag = NULLTAG;
						byqId.append(wordNo);
						ITKCALL(ITEM_find_item(byqId.c_str(), &byqTag));
						ITKCALL(ITEM_ask_latest_rev(byqTag, &byqRev));
						ByqBean bean;
						string cpxh = getClassVal(byqRev, errorBuff, bean);
						printf("cpxh===>%s\n", cpxh.c_str());
						if (strstr(objName, "线圈") == NULL) {
							processTag = getTmpProcess(cpxh, drawNo, errorBuff, tmpGyId, false, "", wordNo);
							if (processTag != NULLTAG) {
								save_representation2(processTag, mantr, "IMAN_METarget");
							}
						}
						else {
							string xqfs;
							if (strstr(objName, "低压线圈") != NULL) {
								//当前XXX线圈未在变压器参数表中维护绕线方式分类属性，请前往维护
								if (bean.dyxq.empty()) {
									errorBuff.append("当前低压线圈未在变压器参数表中维护绕线方式分类属性，请前往维护\n");
									return;
								}
								xqfs = bean.dyxq;
							}
							else if (strstr(objName, "中压线圈") != NULL) {
								//当前XXX线圈未在变压器参数表中维护绕线方式分类属性，请前往维护
								if (bean.zyxq.empty()) {
									errorBuff.append("当前中压线圈未在变压器参数表中维护绕线方式分类属性，请前往维护\n");
									return;
								}
								xqfs = bean.zyxq;
							}
							else if (strstr(objName, "高压线圈") != NULL) {
								//当前XXX线圈未在变压器参数表中维护绕线方式分类属性，请前往维护
								if (bean.gyxq.empty()) {
									errorBuff.append("当前高压线圈未在变压器参数表中维护绕线方式分类属性，请前往维护\n");
									return;
								}
								xqfs = bean.gyxq;
							}
							else if (strstr(objName, "调压线圈") != NULL) {
								//当前XXX线圈未在变压器参数表中维护绕线方式分类属性，请前往维护
								if (bean.tyxq.empty()) {
									errorBuff.append("当前调压线圈未在变压器参数表中维护绕线方式分类属性，请前往维护\n");
									return;
								}
								xqfs = bean.tyxq;
							}
							else if (strstr(objName, "稳压线圈") != NULL) {
								//当前XXX线圈未在变压器参数表中维护绕线方式分类属性，请前往维护
								if (bean.wyxq.empty()) {
									errorBuff.append("当前稳压线圈未在变压器参数表中维护绕线方式分类属性，请前往维护\n");
									return;
								}
								xqfs = bean.wyxq;
							}
							processTag = getTmpProcess(cpxh, drawNo, errorBuff, tmpGyId, true, xqfs, wordNo);
							if (processTag != NULLTAG) {
								save_representation2(processTag, mantr, "IMAN_METarget");
							}
						}
					}
				}
			}
		}
	}
	printf("sub readProcessBom\n");
	for (int i = 0; i < c_line_count; i++) {
		tag_t c_line_tag = c_line_tags[i];
		readProcessBom(c_line_tag, errorBuff, flag, topProcess, notTcmBuff, "");
	}
}

tag_t getProcess(tag_t designRev) {
	int n_references = 0;
	int* levels = 0;
	tag_t process = NULLTAG;
	tag_t* references_tag = NULLTAG;
	char** relation_type_name = NULL;
	//通过引用关系查找到变更单
	ITKCALL(WSOM_where_referenced(designRev, 1, &n_references, &levels, &references_tag, &relation_type_name));
	boolean hasProcess = false;
	for (int i = 0; i < n_references; i++)
	{
		char* refType;
		tag_t refTag = references_tag[i];
		ITKCALL(AOM_ask_value_string(refTag, "object_type", &refType));
		if (strcmp(refType, "MEProcessRevision") == 0) {
			hasProcess = true;
			process = refTag;
			break;
		}
	}
	return process;
}
int CloneTempProcess(void *returnValue)
{
	int ifail = ITK_ok;
	char* sql = NULL, *revUid;
	tag_t designRev;
	ITKCALL(ifail = USERARG_get_string_argument(&revUid));
	ITK__convert_uid_to_tag(revUid, &designRev);
	int bvr_count = 0, c_line_count;
	tag_t ebom_window = NULLTAG;
	tag_t bom_line = NULLTAG;
	tag_t item_tag = NULLTAG, *c_line_tags = NULLTAG;
	(BOM_create_window(&ebom_window));
	tag_t* bvr_list = NULL;
	ITKCALL(ITEM_rev_list_bom_view_revs(designRev, &bvr_count, &bvr_list));
	printf("bvr_count=%d", bvr_count);

	ITKCALL(BOM_set_window_top_line_bvr(ebom_window, bvr_list[0], &bom_line)); //顶层bom获取
	string errorBuff;
	string notTcmBuff;
	char *bl_desc;
	ITKCALL(AOM_ask_value_string(bom_line, "bl_rev_object_desc", &bl_desc));

	int n_references = 0;
	int* levels = 0;
	tag_t* references_tag = NULLTAG;
	char** relation_type_name = NULL;
	//通过引用关系查找到变更单
	ITKCALL(WSOM_where_referenced(designRev, 1, &n_references, &levels, &references_tag, &relation_type_name));
	boolean hasProcess = false;
	tag_t processTagTop = NULLTAG;
	for (int i = 0; i < n_references; i++)
	{
		char* refType;
		tag_t refTag = references_tag[i];
		ITKCALL(AOM_ask_value_string(refTag, "object_type", &refType));
		if (strcmp(refType, "MEProcessRevision") == 0) {
			hasProcess = true;
			processTagTop = refTag;
			break;
		}
	}
	int url_num = 0;
	char** url_vals = NULL;
	ITKCALL(PREF_ask_char_values("database_tc", &url_num, &url_vals));
	string url = url_vals[0];
	url.append("/").append(url_vals[2]);

	//map<string,
	printf("url ==> %s \n", url.c_str());
	if (ConnServer(url_vals[3], url_vals[4], (char*)url.c_str()) == -1)
	{
		printf("提示:中间数据表访问失败\n");
		ifail = 1;
	}
	boolean isback = false;
	tag_t meProcess = NULLTAG;
	char* objName = NULL, * topId = NULL;
	string backs = "";
	ITKCALL(AOM_ask_value_string(designRev, "object_name", &objName));
	ITKCALL(AOM_ask_value_string(designRev, "item_id", &topId));
	map<string, tag_t> mapByq;
	//如果是产成品的话, 判断是否存在多个P物料
	//20240203备件包工艺路线指派
	int back_num = 0;
	char** back_vals = NULL, * group_name = NULL;
	tag_t group = NULLTAG;
	string tuhao;
	vector<string> group_names;
	ITKCALL(POM_ask_group(&group_name, &group));
	Split(group_name, ".", group_names);
	printf("group_name=======%s\n", group_names[0].c_str());
	ITKCALL(PREF_ask_char_values("CHINT_PROCESS_RULE", &back_num, &back_vals));
	//首选项格式：组名:匹配字段1;匹配字段2
	for (int i = 0; i < back_num; i++) {
		vector<string> group_backs;
		Split(back_vals[i], ":", group_backs);
		if (tc_strcmp(group_backs[0].c_str(), group_names[0].c_str()) == 0) {
			vector<string> backs;
			Split(group_backs[1], ";", backs);
			for (int j = 0; j < backs.size(); j++) {
				if (tc_strstr(objName, backs[j].c_str()) != NULL) {
					tuhao = backs[j];
					isback = true;
					break;
				}
			}
			if(isback)
				break;
		}
	}
	if (isback) {
		isback = false;
		int b_refs = 0;
		int* b_levels = 0;
		tag_t* b_refs_tag = NULLTAG;
		char** b_rel_name = NULL, * pcode = NULL;
		string cpxh = "";
		//判断当前物料对象是否在“产成品”文件夹（ZT2_ProjectFolder）中
		ITKCALL(ITEM_ask_item_of_rev(designRev, &item_tag));
		ITKCALL(WSOM_where_referenced2(item_tag, 1, &b_refs, &b_levels, &b_refs_tag, &b_rel_name));
		for (int i = 0; i < b_refs; i++) {
			char* ref_type = NULL;
			ITKCALL(AOM_ask_value_string(b_refs_tag[i], "object_type", &ref_type));
			printf("ref_type:%s\n", ref_type);
			if (tc_strcmp(ref_type, "ZT2_ProjectFolder") != 0)
				continue;
			int n_projs = 0;
			tag_t* projs = NULLTAG;
			ITKCALL(AOM_ask_value_tags(b_refs_tag[i], "contents", &n_projs, &projs));
			for (int j = 0; j < n_projs; j++) {
				int n_drows = 0;
				tag_t proj_rev = NULLTAG, * drows = NULLTAG;
				ITKCALL(ITEM_ask_latest_rev(projs[j], &proj_rev));
				ITKCALL(AOM_ask_value_tags(proj_rev, "TC_Is_Represented_By", &n_drows, &drows));
				printf("n_drows:%d\n", n_drows);
				if (n_drows == 0)
					continue;
				ByqBean bean;
				cpxh = getClassVal(drows[0], errorBuff, bean);
				isback = true;
				break;
			}
			if (isback)
				break;
		}
		backs.append(cpxh).append("@").append(tuhao);
		/*string sql = "select a.GYID from CHINT_WORKHOUR_WhProductXH a,CHINT_WORKHOUR_WhGYRule b ";
		sql.append("where a.COMPANYCODE=b.COMPANYCODE and a.ProductZu=b.ProductZu ")
			.append("and a.COMPANYCODE='").append(group_name)
			.append("' and a.ProductXH='").append(cpxh)
			.append("' and b.TuHao='").append(tuhao)
			.append("'");
		int outputColumn = 0, outputValueCount = 0;
		char*** outputValue = NULL, sqlc[1024];
		tc_strcpy(sqlc, sql.c_str());
		QuerySQLNoInputParam(sqlc, &outputColumn, &outputValueCount, &outputValue);
		if (outputValueCount > 0) {
			gyid = outputValue[0][0];
		}
		for (int i = 0; i < outputValueCount; i++) {

		}*/
	}
	else if (strstr(objName, "变压器") != NULL) {
		tag_t *topMatnrs,*pMaterials;
		int num = 0, num2=0;
		ITKCALL(AOM_ask_value_tags(designRev, "TC_Is_Represented_By", &num, &topMatnrs));
		printf("num===>%d\n", num);
		if (num >= 1) {
			tag_t tzRev = topMatnrs[0];
			ITKCALL(AOM_ask_value_tags(tzRev, "representation_for", &num2, &pMaterials));
			for (int x = 0; x < num2; x++) {
				char *pId,*zt2_ifpbom;
				tag_t pMatr = pMaterials[x];
				ITKCALL(AOM_ask_value_string(pMatr, "item_id", &pId));
				ITKCALL(AOM_ask_value_string(pMatr, "zt2_ifpbom", &zt2_ifpbom));
				if (strcmp(pId, topId) != 0 && strcmp(zt2_ifpbom,"P")==0) {
					tag_t process = getProcess(pMatr);
					if (process != NULLTAG) {
						meProcess = process;
					}
					else {
						mapByq[pId] = pMatr;
					}
				}
			}
		}
		if (meProcess != NULLTAG) {
			if (!hasProcess) {
				save_representation2(meProcess, designRev, "IMAN_METarget");
			}
			map<string, tag_t>::iterator it;
			//名称模糊匹配
			for (it = mapByq.begin(); it != mapByq.end(); it++) {
				string s = it->first;
				tag_t matnrPrev = mapByq[s];
				save_representation2(meProcess, matnrPrev, "IMAN_METarget");
			}
			printf("=======\n");
			errorBuff = "当前选中的物料已经存在工艺路线.\n";
		}
		else if (processTagTop != NULLTAG) {
			map<string, tag_t>::iterator it;
			printf("=======22\n");
			//名称模糊匹配
			for (it = mapByq.begin(); it != mapByq.end(); it++) {
				string s = it->first;
				tag_t matnrPrev = mapByq[s];
				save_representation2(processTagTop, matnrPrev, "IMAN_METarget");
			}
			errorBuff = "当前选中的物料已经存在工艺路线.\n";
		}
	}
	printf("mapByq===>%zd\n", mapByq.size());
	if (hasProcess) {
		errorBuff = "当前选中的物料已经存在工艺路线.\n";
	}else if ((strcmp(bl_desc, "") == 0 || strstr(bl_desc,"-")==NULL) && strstr(objName, "变压器") == NULL && !isback) {
		errorBuff = "当前选中的物料版本没有图号信息，请检查.\n";
	}
	else {
		POM_AM__set_application_bypass(true);

		tag_t topProcess = NULLTAG;
		boolean flag = false;
		printf("errorBuff==>%s\n", errorBuff.c_str());
		readProcessBom(bom_line, errorBuff, flag, topProcess, notTcmBuff, backs);
		if (topProcess != NULLTAG) {
			map<string, tag_t>::iterator it;
			for (it = mapByq.begin(); it != mapByq.end(); it++) {
				string s = it->first;
				tag_t matnrPrev = mapByq[s];
				save_representation2(topProcess, matnrPrev, "IMAN_METarget");
			}
		}
		if (!flag) {
			errorBuff = "当前选中的PBOM没有实件，无需做工艺路线.";
		}
		POM_AM__set_application_bypass(false);
	}
	DisConnServer();
	errorBuff.append(notTcmBuff);
	if (errorBuff.empty()) {
		errorBuff = "succ";
	}
	printf("errorBuff==>%s\n", errorBuff.c_str());
	ITKCALL(BOM_close_window(ebom_window));
	*((char**)returnValue) = (char*)MEM_alloc((strlen(errorBuff.c_str()) + 1) * sizeof(char));
	tc_strcpy(*((char**)returnValue), errorBuff.c_str());
	return ifail;
}