
#include "epm_handler_common.h"
#include <unidefs.h>
#include <tc/tc_macros.h>
#include <ict/ict_userservice.h>
#include <qry/qry.h>
#include <tccore/aom_prop.h>
#include <map>
#include "cJSON.h"
#include "tc_log.h"
#include "tc_util.h"
using namespace std;

/**
* 判断是不是外购件
*
* @param material 物料
* @return 是否外购件
*/
boolean isOutBuy(tag_t material) {
	int factory = 0, procure = 0;
	char **zt2_SZFactory = NULL, **zt2_SZProcuretype = NULL;
	ITKCALL(AOM_UIF_ask_values(material, "zt2_SZFactory", &factory, &zt2_SZFactory));
	ITKCALL(AOM_UIF_ask_values(material, "zt2_SZProcuretype", &procure, &zt2_SZProcuretype));
	for (int i = 0; i < factory; i++) {
		if (tc_strcmp(zt2_SZFactory[i], "M060") == 0 && procure > i && tc_strcmp(zt2_SZProcuretype[i], "外购") == 0) {
			return true;
		}
	}
	return false;
}

/**
* 遍历工艺BOM获取辅料信息
*
* @param parentLine       父BOM行
* @param itemRevOfBOMLine BOM行对应的版本
* @param materialMap      Map 物料编码-数量
* @param qty              数量累乘
* @param level            BOM层级
*/
void getProcessBomMsg(tag_t parentLine, tag_t itemRevOfBOMLine, map<string, double>& materialMap, vector<string>& materialVec, double qty, int level) {

	char *material = NULL;
	//ITKCALL(AOM_UIF_ask_value(itemRevOfBOMLine, "zt2_MaterialNo", &material));
	ITK__convert_tag_to_uid(itemRevOfBOMLine, &material);
	WriteTcLog("GetBomDetails getProcessBomMsg = %s", material);
	char *blQty = NULL;
	double qtyDouble = 1.0;
	ITKCALL(AOM_UIF_ask_value(parentLine, "bl_quantity", &blQty));
	if (blQty && tc_strlen(blQty) > 0) {
		qtyDouble = atof(blQty);
	}
	// 0为工艺层，1、2为工序层，3为辅料层
	if (level == 3) {
		char *bl_occ_type = NULL;
		ITKCALL(AOM_UIF_ask_value(parentLine, "bl_occ_type", &bl_occ_type));
		if (tc_strcmp(bl_occ_type, "Fu Liao") != 0)
			return;
		char *materialNo = NULL;
		ITKCALL(AOM_UIF_ask_value(itemRevOfBOMLine, "zt2_MaterialNo", &materialNo));
		if (materialMap.count(materialNo) > 0) {
			double q = materialMap[materialNo];
			materialMap[materialNo] = q + qty * qtyDouble;
		}
		else {
			materialVec.push_back(materialNo);
			materialMap[materialNo] = qty * qtyDouble;
		}
	}
	else {
		//获取当前层级数量，然后累乘
		int c_line_count = 0;
		tag_t* c_line_tags = NULLTAG;
		ITKCALL(BOM_line_ask_all_child_lines(parentLine, &c_line_count, &c_line_tags));
		for (int i = 0; i < c_line_count; i++) {
			tag_t rev2 = NULLTAG;
			ITKCALL(AOM_ask_value_tag(c_line_tags[i], "bl_line_object", &rev2));
			getProcessBomMsg(c_line_tags[i], rev2, materialMap, materialVec, qty * qtyDouble, level + 1);
		}
	}
}

/**
* 遍历BOM获取底层信息
*
* @param parentLine       父BOM行
* @param itemRevOfBOMLine BOM行对应的版本
* @param materialMap      Map 物料编码-数量
* @param qty              数量累乘
*/
void getChildBomMsg(tag_t parentLine, tag_t itemRevOfBOMLine, map<string, double>& materialMap, vector<string>& materialVec, double qty) {

	char *material = NULL;
	ITKCALL(AOM_UIF_ask_value(itemRevOfBOMLine, "zt2_MaterialNo", &material));
	//ITK__convert_tag_to_uid(itemRevOfBOMLine, &material);
	WriteTcLog("GetBomDetails getChildBomMsg = %s", material);
	int n_references = 0;
	int* levels = 0;
	tag_t* references_tag;
	char** relation_type_name = NULL;
	//通过出厂编号查找到图纸
	ITKCALL(WSOM_where_referenced(itemRevOfBOMLine, 1, &n_references, &levels, &references_tag, &relation_type_name));
	tag_t procModel = NULLTAG;
	for (int i = 0; i < n_references; i++) {
		if (tc_strcmp(relation_type_name[i], "IMAN_METarget") == 0) {
			procModel = references_tag[i];
			break;
		}
	}
	if (procModel != NULLTAG) {
		WriteTcLog("procModel != NULLTAG");
		tag_t bom_window = NULLTAG, topLine = NULLTAG;
		ITKCALL(BOM_create_window(&bom_window));
		ITKCALL(BOM_set_window_top_line(bom_window, NULL, procModel, NULLTAG, &topLine));
		getProcessBomMsg(topLine, procModel, materialMap, materialVec, 1.0, 0);
		ITKCALL(BOM_close_window(bom_window));
	}
	char *blQty = NULL;
	double qtyDouble = 1.0;
	ITKCALL(AOM_UIF_ask_value(parentLine, "bl_quantity", &blQty));
	if (blQty && tc_strlen(blQty) > 0) {
		qtyDouble = atof(blQty);
	}
	// 数量为0，为底层数据
	int c_line_count = 0;
	tag_t* c_line_tags = NULLTAG;
	ITKCALL(BOM_line_ask_all_child_lines(parentLine, &c_line_count, &c_line_tags));
	WriteTcLog("GetBomDetails c_line_count = %d", c_line_count);
	if (c_line_count == 0) {
		if (!isOutBuy(itemRevOfBOMLine))
			return;
		if (materialMap.count(material) > 0) {
			double q = materialMap[material];
			materialMap[material] = q + qty * qtyDouble;
		}
		else {
			materialVec.push_back(material);
			materialMap[material] = qty * qtyDouble;
		}
	}
	else {
		WriteTcLog("GetBomDetails 开始遍历");
		for (int i = 0; i < c_line_count; i++) {
			tag_t rev2 = NULLTAG;
			ITKCALL(AOM_ask_value_tag(c_line_tags[i], "bl_line_object", &rev2));
			getChildBomMsg(c_line_tags[i], rev2, materialMap, materialVec, qty * qtyDouble);
		}
		WriteTcLog("GetBomDetails 结束遍历");
	}
}

//武汉组织BOM汇总清单接口改为C组织数据
int getBomDetails(void *returnValue) {
	string log_path = getenv("TEMP");
	log_path.append("\\getBomDetails").append(getNow("yyyyMMddHHmmss")).append(".log");
	CreateTcLogFile(log_path.c_str());
	WriteTcLog("*******************   getBomDetails start2 %s   *******************", getNow("LOG").c_str());

	int ifail = ITK_ok;
	char* jsonObject = NULL;
	ITKCALL(USERARG_get_string_argument(&jsonObject));
	WriteTcLog("GetBomDetails 入参===>%s", jsonObject);
	cJSON* jsonObject1 = cJSON_Parse(jsonObject);
	//产成品物料编码 WBS号
	char* wbsNo = cJSON_GetObjectItem(jsonObject1, "wbsno")->valuestring;
	char* materialNo = cJSON_GetObjectItem(jsonObject1, "ccpmaterialno")->valuestring;
	//从左到右，从第一个非0的数字开始
	while (*materialNo == '0')
		materialNo++;
	//返回信息
	cJSON* result = cJSON_CreateObject();
	cJSON_AddStringToObject(result, "wbsno", wbsNo);
	cJSON_AddStringToObject(result, "ccpmaterialno", materialNo);
	//查询物料
	tag_t query_tag = NULLTAG;
	ITKCALL(QRY_find2("chint_query_material_getbomdetails", &query_tag));//chint_query_material_test
	if (query_tag == NULL) {
		printf("Could not found query:chint_query_material_getbomdetails\n");
		cJSON_AddStringToObject(result, "code", "500");
		cJSON_AddStringToObject(result, "msg", "Could not found query:chint_query_material_getbomdetails");
		return ifail;
	}
	char **qkey = NULL, **qvalue = NULL;
	int num_found = 0;//查询结果数量
	tag_t *modelObjects = NULL;//查询结果集
	const char *key1 = "materialno", *key2 = "wbsno";//WBS No//WBS号
	qkey = (char **)MEM_alloc(2 * sizeof(char*));
	qvalue = (char **)MEM_alloc(2 * sizeof(char*));
	qkey[0] = (char *)MEM_alloc((tc_strlen(key1) + 1)*sizeof(char));
	qvalue[0] = (char *)MEM_alloc((tc_strlen(materialNo) + 1)*sizeof(char));
	tc_strcpy(qkey[0], key1);
	tc_strcpy(qvalue[0], materialNo);
	qkey[1] = (char *)MEM_alloc((tc_strlen(key2) + 1)*sizeof(char));
	qvalue[1] = (char *)MEM_alloc((tc_strlen(wbsNo) + 1)*sizeof(char));
	tc_strcpy(qkey[1], key2);
	tc_strcpy(qvalue[1], wbsNo);
	ITKCALL(QRY_execute(query_tag, 2, qkey, qvalue, &num_found, &modelObjects));
	WriteTcLog("GetBomDetails 查询===>%d", num_found);
	if (num_found == 0) {
		//没有查询到产成品 返回500
		cJSON_AddStringToObject(result, "code", "500");
		cJSON_AddStringToObject(result, "msg", "数据组织失败");
	}
	else {
		//查询到产成品 返回200 如果有P物料，获取P物料
		cJSON_AddStringToObject(result, "code", "200");
		cJSON_AddStringToObject(result, "msg", "成功组织数据");
		//BOM全展开 获取到底层物料 数量累乘 相同物料合并数量  物料查询查的版本
		tag_t ccpRevision = NULLTAG;
		//如果有P物料遍历P物料的BOM
		for (int i = 0; i < num_found; i++) {
			char *os = NULL, *ifPbom = NULL;
			//ITKCALL(AOM_UIF_ask_value(modelObjects[i], "object_string", &os));
			ITK__convert_tag_to_uid(modelObjects[i], &os);
			WriteTcLog("GetBomDetails 查询===>%s", os);
			ITKCALL(AOM_UIF_ask_value(modelObjects[i], "zt2_ifpbom", &ifPbom));
			if (tc_strcmp(ifPbom, "P") == 0) {
				ccpRevision = modelObjects[i];
				break;
			}
		}
		if (ccpRevision == NULLTAG)
			ccpRevision = modelObjects[0];
		//遍历
		char *ztQuantity = NULL;
		ITKCALL(AOM_UIF_ask_value(ccpRevision, "zt2_Quantity", &ztQuantity));
		if (!ztQuantity || tc_strlen(ztQuantity) == 0) {
			DOFREE(ztQuantity);
			ztQuantity = (char *)MEM_alloc(2 * sizeof(char));
			tc_strcpy(ztQuantity, "1");
		}
		tag_t bom_window = NULLTAG, topLine = NULLTAG;
		ITKCALL(BOM_create_window(&bom_window));
		ITKCALL(BOM_set_window_top_line(bom_window, NULL, ccpRevision, NULLTAG, &topLine));
		map<string, double> materialMap;
		vector<string> materialVec;
		getChildBomMsg(topLine, ccpRevision, materialMap, materialVec, 1.0);
		ITKCALL(BOM_close_window(bom_window));
		//信息搭建JSON
		cJSON* array = cJSON_CreateArray();
		cJSON_AddStringToObject(result, "ccpquantity", ztQuantity);
		cJSON* factoryno = cJSON_GetObjectItem(jsonObject1, "factoryno");
		if (factoryno) {
			cJSON_AddStringToObject(result, "factoryno", factoryno->valuestring);
		}
		else {
			cJSON_AddStringToObject(result, "factoryno", "");
		}
		WriteTcLog("GetBomDetails materialVec===>%zd", materialVec.size());
		//map<string, double>::iterator it;
		//for (it = materialMap.begin(); it != materialMap.end(); it++) {
		for (int i = 0; i < materialVec.size(); i++) {
			//string key = it->first;
			string key = materialVec[i];
			double qty = materialMap[key];
			cJSON* object = cJSON_CreateObject();
			char no_str[4] = "";
			sprintf(no_str, "%03d", i + 1);
			cJSON_AddStringToObject(object, "no", no_str);
			cJSON_AddStringToObject(object, "materialno", key.c_str());
			char qty_str[16] = "";
			sprintf(qty_str, "%.3f", qty);
			cJSON_AddStringToObject(object, "quantity", qty_str);
			cJSON_AddItemToArray(array, object);
		}
		cJSON_AddItemToObject(result, "contents", array);
	}
	char *json_to_char = cJSON_Print(result);
	string msg = "GetBomDetails json_to_char===>";
	msg.append(json_to_char);
	WriteTcLog2(msg);

	//string buff = "";
	*((char**)returnValue) = (char*)MEM_alloc((tc_strlen(json_to_char) + 1) * sizeof(char));
	tc_strcpy(*((char**)returnValue), json_to_char);
	//WriteTcLog("GetBomDetails 返回");
	cJSON_Delete(result);
	cJSON_Delete(jsonObject1);
	//WriteTcLog("GetBomDetails log关闭");
	CloseTcLog();
	//printf("GetBomDetails end");
	return ifail;
}