package com.dev.swms.server.service.interfaceLog.pojo;

import java.io.StringWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import com.dev.swms.server.model.base.Address;
import com.dev.swms.server.model.base.BillType;
import com.dev.swms.server.model.base.Contact;
import com.dev.swms.server.model.base.Item;
import com.dev.swms.server.model.base.Location;
import com.dev.swms.server.model.base.LocationType;
import com.dev.swms.server.model.base.LotInfo;
import com.dev.swms.server.model.base.NewLotInfo;
import com.dev.swms.server.model.base.Structure;
import com.dev.swms.server.model.base.PackageUnit;
import com.dev.swms.server.model.base.Warehouse;
import com.dev.swms.server.model.interfaceLog.AvaliableOrderResponse;
import com.dev.swms.server.model.interfaceLog.InterfaceLog;
import com.dev.swms.server.model.interfaceLog.InterfaceLogConstant;
import com.dev.swms.server.model.interfaceLog.ResponseCode;
import com.dev.swms.server.model.inventory.ProductInventory;
import com.dev.swms.server.model.receiving.ASN;
import com.dev.swms.server.model.receiving.ASNDetail;
import com.dev.swms.server.model.receiving.ASNStatus;
import com.dev.swms.server.model.receiving.MoveDoc;
import com.dev.swms.server.model.receiving.MoveDocDetail;
import com.dev.swms.server.model.shipping.BOL;
import com.dev.swms.server.model.shipping.Package;
import com.dev.swms.server.model.shipping.PickTicket;
import com.dev.swms.server.model.shipping.PickTicketDetail;
import com.dev.swms.server.model.shipping.PickTicketStatus;
import com.dev.swms.server.service.interfaceLog.InterfaceLogManager;
import com.dev.swms.server.service.inventory.InventoryManager;
import com.dev.swms.server.utils.ConnectionHelper;
import com.dev.swms.server.utils.DateUtil;
import com.dev.swms.server.utils.DoubleUtils;
import com.dev.swms.server.utils.ServerUnreachableException;
import com.dev.swms.server.utils.XMLUtils;
import com.dev.energy.server.exception.BusinessException;
import com.dev.energy.server.service.pojo.DefaultBaseManager;

public class DefaultInterfaceLogManager extends DefaultBaseManager implements
		InterfaceLogManager {
	protected Log log = LogFactory.getLog(DefaultInterfaceLogManager.class);
	public static final int TIMES_PER = 20;
	
	protected InventoryManager inventoryManager;
	protected ConnectionHelper connectionHelper;
	

	public DefaultInterfaceLogManager(InventoryManager manager, ConnectionHelper helper) {
		super();
		this.inventoryManager = manager;
		this.connectionHelper = helper;
	}

	public String receive(final String xml) {
		//System.out.println(new Date() + "[RRRRRRRRRRRRRRRRReceived] :"+xml);
		String xmlContent = xml;
		
		if(xml == null || "".equals(xml.trim())) {
			return XMLUtils.genFailureResultHelper("request content is null");
		}
		Document xmlDoc;
		try {
			xmlDoc = DocumentHelper.parseText(xmlContent.trim());
		} catch (DocumentException e) {
			if(logger.isDebugEnabled()) {
				e.printStackTrace();
			} 
			return XMLUtils.genFailureResultHelper(e.getMessage());
		}
		
		String errorMSG = "ErrorMessage:\r\n";// 错误信息
		boolean hasError = false;
		Element root = xmlDoc.getRootElement();
		Element head = root.element("MESSAGEHEAD");
		String fromSys = head.elementTextTrim("FROM");
		String sender = head.elementTextTrim("SENDER");
		String toSys = head.elementTextTrim("TO");
		String reciever = head.elementTextTrim("RECIEVER");
		String contentType = head.elementTextTrim("CONTENTTYPE");
		String function = head.elementTextTrim("FILEFUNCTION");
		String sendTime = head.elementTextTrim("SENDTIME");
		String fileName = head.elementTextTrim("FILENAME");
		String reference = head.elementTextTrim("REFERENCE");
		String logID = head.elementTextTrim("LOG_ID");

		if (StringUtils.isEmpty(fromSys)) {
			errorMSG += "fromSys is null\r\n";
			hasError = true;
		}
		if(StringUtils.isEmpty(sender)) {
			errorMSG += "sender is null\r\n";
			hasError = true;
		}
		if (StringUtils.isEmpty(toSys)) {
			errorMSG += "toSys is null\r\n";
			hasError = true;
		}
		if(StringUtils.isEmpty(reciever)) {
			errorMSG += "reciever is null\r\n";
			hasError = true;
		}
		if(StringUtils.isEmpty(contentType)) {
			errorMSG += "contentType is null\r\n";
			hasError = true;
		}
		if (StringUtils.isEmpty(logID)) {
			errorMSG += "logID is null\r\n";
			hasError = true;
		}
		
		InterfaceLog ifl = new InterfaceLog();
		if (XMLUtils.getWMSCode().equals(fromSys)) {
			//发送给外部系统接口消息的反馈处理结果
			if (!StringUtils.isEmpty(logID)) {
				ifl = this.commonDao.load(InterfaceLog.class, Long.valueOf(logID));
			}
			if (ifl == null) {
				errorMSG += "can't find InterfaceLog by logID in swms Sys.\r\n";
				hasError = true;
			} else {
				String responseTime = head.elementText("RESPONSETIME");
				String responseContent = root.elementText("MESSAGEDETAIL");
				ifl.setResponseTime(DateUtil.formatDateHMS(responseTime));
				ifl.setResponseContent(responseContent);
				if (StringUtils.isEmpty(responseContent)) {
					errorMSG += "RESPONSECONTENT is null\r\n";
					hasError = true;
				}
				if (!hasError) {
					ifl.setStatus(InterfaceLogConstant.RECEIVE);
					commonDao.store(ifl);
				}
			}

		} else {
			String requestContent = root.elementText("MESSAGEDETAIL");
			if (StringUtils.isEmpty(requestContent)) {
				errorMSG += "REQUESTCONTENT is null\r\n";
				hasError = true;
			}
			if(StringUtils.isEmpty(sendTime)) {
				errorMSG += "sendTime is null\r\n";
				hasError = true;
			}
			if(hasError) {
				return XMLUtils.genFailureResultHelper(errorMSG);
			} else {
				ifl.setFromSYS(fromSys);
				ifl.setRequest(sender);
				ifl.setToSYS(toSys);
				ifl.setResponse(reciever);
				ifl.setRequestTime(DateUtil.formatDateHMS(sendTime));
				ifl.setType(contentType);
				ifl.setFunction(function);
				ifl.setRequestContent(requestContent);
				ifl.setStatus(InterfaceLogConstant.RECEIVE);
				ifl.setFileName(fileName);
				ifl.setReference(reference);
				ifl.setLogID(Long.valueOf(logID));
				commonDao.store(ifl);
			}
		}
		if (hasError) {
			return XMLUtils.genFailureResultHelper(errorMSG);
		} else {
			return XMLUtils.genSuccessResultHelper("SUCCESS");
		}
	}

	/**
	 * 调用接口发送数据
	 * @param log
	 * @return
	 */
	public boolean send(InterfaceLog log, String type) {
		boolean successToConnectServer = false;//如果成功连接服务器
		try{
			String response = connectionHelper.sendMessage(buildXML(log, type));
			if(!ResponseCode.SUCCESS.equals(response)) {
				log.setErrorLog(response);
				log.setStatus(InterfaceLogConstant.ERROR);
			} else {
				if (InterfaceLogConstant.REQUEST.equals(type)) {
					log.setStatus(InterfaceLogConstant.SEND);
				} else {
					log.setStatus(InterfaceLogConstant.FINISH);
				}
			}
			successToConnectServer = true;
		} catch (ServerUnreachableException e) {
			log.setResponseContent(e.getMessage());
			log.setStatus(InterfaceLogConstant.ERROR);
		} catch (Exception e) {
			log.setResponseContent(e.getMessage());
			log.setStatus(InterfaceLogConstant.ERROR);
			successToConnectServer = true;
		}
		
		log.setDealTime(new Date());
		commonDao.store(log);
		return successToConnectServer;
	}

	protected String buildXML(InterfaceLog log, String type) {
		DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");		
		String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
		xml += "<XML>"+"\r\n";
		xml += "<MESSAGEHEAD>"+"\r\n";
		xml += "  <FROM>" + (log.getFromSYS() == null ? "" : log.getFromSYS()) + "</FROM>"+"\r\n";
		xml += "  <SENDER>" + (log.getRequest() == null ? "" : log.getRequest()) + "</SENDER>"+"\r\n";
		xml += "  <TO>" + (log.getToSYS() == null ? "" : log.getToSYS()) + "</TO>"+"\r\n";
		xml += "  <RECIEVER>" + (log.getResponse() == null ? "" : log.getResponse()) + "</RECIEVER>"+"\r\n";  
		xml += "  <FILETYPE>XML</FILETYPE> "+"\r\n";
		xml += "  <CONTENTTYPE>" + log.getType() + "</CONTENTTYPE>"+"\r\n";
		xml += "  <FILEFUNCTION>" + log.getFunction() + "</FILEFUNCTION>"+"\r\n";
		xml += "  <SENDTIME>" + DateUtil.formatDateToStr(new Date()) + "</SENDTIME>"+"\r\n";
		xml += "  <ISBASE64>FALSE</ISBASE64>\r\n";
		xml += "  <FILENAME>" + "" + "</FILENAME>\r\n";
		xml += "  <REFERENCE>" + log.getReference() + "</REFERENCE>\r\n";
		xml += "  <LOG_ID>" + log.getLogID() + "</LOG_ID>\r\n";
		xml += "</MESSAGEHEAD>\r\n";
		xml += "<MESSAGEDETAIL> \r\n";
		xml += "<![CDATA[\r\n";	
		if (InterfaceLogConstant.REQUEST.equals(type)) {
			xml += log.getRequestContent();
		} else {
			xml += log.getResponseContent();
		}
		xml += "]]>\r\n";	
		xml += "</MESSAGEDETAIL> \r\n";	
		xml += "</XML>";
		//System.out.println(xml);
		return xml;
	}
	
	public void inventoryResponse(InterfaceLog log) throws Exception {
		List<String> products = new ArrayList<String>();
		
		String str = log.getRequestContent();
		String newStr = XMLUtils.del_r(str);
		Document message = DocumentHelper.parseText(newStr.trim());
		Element root = message.getRootElement();
		
		//获取发送方和接收方代码
		String receiver = log.getResponse();	//仓库代码

		Element xml = root.element("CONTENTLIST");
		Element content = xml.element("CONTENT");
		Element inventories = content.element("INVENTORIES");
		Iterator inventory = inventories.elementIterator("INVENTORY");
		while (inventory.hasNext()) {
			Element node = (Element) inventory.next();
			String lot = node.elementText("LOT"); 					//批次号
			products.add(receiver + "|" + node.elementText("CUSTOMER")
					+ "|" + node.elementText("PRODUCT") 
					+ (StringUtils.isEmpty(lot) ? "" : ("|" + lot)));
		}
		if (products.size() == 0) {
			log.setStatus(InterfaceLogConstant.ERROR);
			log.setErrorLog("no product need to query inventory!");
			commonDao.store(log);
		} else {
			//调用查询接口得到库存情况
			List<ProductInventory> pinvs = inventoryManager.getProductInventories(products, receiver);
			//回调OMS/TMS接口，发送库存查询结果数据
			pushInventoryResponse(log, pinvs);
		}
	}


	private void pushInventoryResponse(InterfaceLog log,
			List<ProductInventory> pinvs) {
		//更新日志状态
		log.setResponseContent(getInventoryResponse(pinvs));
		log.setResponseTime(new Date());
		commonDao.store(log);
		
		//调用方法发送接口数据
		send(log, InterfaceLogConstant.RESPONSE);
	}

	private String getInventoryResponse(List<ProductInventory> pinvs) {
		// 明细内甙xml
		Document _doc = DocumentHelper.createDocument();
		Element _root = _doc.addElement("XML");
		Element contentList = _root.addElement("CONTENTLIST");
		Element content = contentList.addElement("CONTENT");
		Element inventories = content.addElement("INVENTORIES");
		for (ProductInventory pinv : pinvs) {
			// 内甙头
			Element header = inventories.addElement("INVENTORY");
			Element customer = header.addElement("CUSTOMER");
			Element product = header.addElement("PRODUCT");
			Element lot = header.addElement("LOT");
			Element quantity = header.addElement("QUANTITY");
			
			customer.setText(pinv.getCustomer());
			product.setText(pinv.getProduct());			
			lot.setText(pinv.getLot() == null ? "":pinv.getLot());
			quantity.setText(String.valueOf(pinv.getQuantity()));
		}

		return _doc.asXML();
	}

	public void availableOrderResponse(InterfaceLog log) throws Exception {
		String str = log.getRequestContent();
		
		AvaliableOrderResponse aor = null;
		String newStr = XMLUtils.del_r(str);
		Document message = DocumentHelper.parseText(newStr.trim());
		Element xml = message.getRootElement();
		//获取发送方和接收方代码
		Element contentList = xml.element("CONTENTLIST");
		Element contents = contentList.element("CONTENT");
		Iterator orderIterator = contents.elementIterator("ORDER");
		while (orderIterator.hasNext()) {
			Element order = (Element) orderIterator.next();
			Element head = order.element("HEAD");
			Element customerCode = head.element("CUSTOMER_CODE"); 		// 客户代码
			Element code = head.element("CODE"); 						// 订单编号
			Element orderTypeCode = head.element("ORDERTYPE"); 			// 单据类型编码
			Element relateBillCode1 = head.element("RELATEBILL1");		// 销售、采购订单号
			Element fromLocationCode = head.element("FROMLOCATION"); 	// 出发运输地代码
			Element toLocationCode = head.element("TOLOCATION"); 		// 目的运输地代码
			Element shipmentType = head.element("SHIPMENT_TYPE"); 		// 运输类型代码
			Element shipmentMethod = head.element("SHIPMENT_METHOD"); 	// 运输方式代码
			Element planArriveTime = head.element("PLAN_ARRIVE_TIME");	// 要求到货日期
			Element orderDate = head.element("ORDERDATE");				// 订单日期

			Element fromCode = head.element("FROM_CODE"); 				// 发货人代码
			Element fromName = head.element("FROM_NAME"); 				// 发货人名称
			Element fromContact = head.element("FROM_LINKMAN"); 		// 发货联系人
			Element fromPhone = head.element("FROM_PHONE"); 			// 发货人电话
			Element fromFax = head.element("FROM_FAX"); 				// 发货人传真
			Element fromEmail = head.element("FROM_EMAIL"); 			// 发货人邮箱
			Element fromAddress = head.element("FROM_ADDRESS"); 		// 发货人地址
			Element fromPostcode = head.element("FROM_POSTCODE"); 		// 发货人地址
			
			Element toCode = head.element("TO_CODE");					// 收货人代码,收货客户代码
			Element toName = head.element("TO_NAME"); 					// 收货人名称
			Element toContact = head.element("TO_LINKMAN");				// 收货联系人
			Element toPhone = head.element("TO_PHONE"); 				// 收货人电话
			Element toFax = head.element("TO_FAX"); 					// 收货人传真
			Element toEmail = head.element("TO_EMAIL");					// 收货人邮箱
			Element toAddress = head.element("TO_ADDRESS"); 			// 收货人地址
			Element toPostcode = head.element("TO_POSTCODE"); 			// 收货人地址

			Element priority = head.element("PRIORITY");				// 优先级
			Element description = head.element("DESCRIPTION");			// 备注
			
			Element details = order.element("DETAILS");					// 单据明细
			Iterator detail = details.elementIterator("DETAIL");		// 单据明细Iterator

			if (InterfaceLogConstant.AVAILABLE_ORDER_PO.equals(log.getType())) {
				//创建ASN收货单
				ASN asn = new ASN();
				if (!StringUtils.isEmpty(log.getRequest())) {
					asn.setWarehouse((Warehouse) commonDao.findByNamedQueryUniqueResult("getWarehouseByCode", 
							new String[] {"code"}, new Object[] {log.getRequest()}));
				}
				if (!StringUtils.isEmpty(customerCode.getTextTrim())) {
					asn.setCompany((Structure) commonDao.findByNamedQueryUniqueResult("getCompanyByCode", 
							new String[] {"code"}, new Object[] {customerCode.getTextTrim()}));
				}
				if (!StringUtils.isEmpty(orderTypeCode.getTextTrim())) { 
					asn.setBillType((BillType) commonDao.findByNamedQueryUniqueResult("getBillTypeByCompanyAndCode", 
							new String[] {"companyId","code"}, new Object[] {asn.getCompany().getId(), orderTypeCode.getTextTrim()}));
				}
				//asn.setCode(codeManager.generateASNDocCode(new HashMap()));
				asn.setCode(code.getTextTrim());
				asn.setRelatedBill1(code.getTextTrim());			//记录TMS订单号
				asn.setRelatedBill2(relateBillCode1.getTextTrim());	//记录客户订单号
				asn.setRelatedBill3(log.getRequest());				//记录发送平台代码
				if (!StringUtils.isEmpty(planArriveTime.getTextTrim())) {
					asn.setEstimateDate(DateUtil.formatStrToDate(planArriveTime.getTextTrim()));
				}
				asn.setFromName(fromName.getTextTrim());
				asn.setFromAddress(new Address(fromAddress.getTextTrim(), fromPostcode.getTextTrim()));
				asn.setFromContact(new Contact(fromContact.getTextTrim(), 
						fromPhone.getTextTrim(),	fromFax.getTextTrim(), fromEmail.getTextTrim()));
				asn.setOrderDate(new Date());
				asn.setStatus(ASNStatus.ACTIVE);
				asn.setAsnDetails(new HashSet<ASNDetail>());
				addAsnDetails(asn, detail);
				commonDao.store(asn);
				
				aor = new AvaliableOrderResponse(asn.getCompany().getCode(), InterfaceLogConstant.AVAILABLE_ORDER_PO, asn.getRelatedBill1(), asn.getCode(),	new Date());
			} else if (InterfaceLogConstant.AVAILABLE_ORDER_SO.equals(log.getType())) {
				//创建PickTicket发货单
				PickTicket pickTicket = new PickTicket();
				if (!StringUtils.isEmpty(log.getResponse())) {
					pickTicket.setWarehouse((Warehouse) commonDao.findByNamedQueryUniqueResult("getWarehouseByCode", 
							new String[] {"code"}, new Object[] {log.getResponse()}));
				}
				if (!StringUtils.isEmpty(customerCode.getTextTrim())) {
					pickTicket.setCompany((Structure) commonDao.findByNamedQueryUniqueResult("getCompanyByCode", 
							new String[] {"code"}, new Object[] {customerCode.getTextTrim()}));
				}
				if (!StringUtils.isEmpty(orderTypeCode.getTextTrim())) { 
					pickTicket.setBillType((BillType) commonDao.findByNamedQueryUniqueResult("getBillTypeByCompanyAndCode", 
							new String[] {"companyId","code"}, new Object[] {pickTicket.getCompany().getId(), orderTypeCode.getTextTrim()}));
				}
				pickTicket.setCode(code.getTextTrim());
				pickTicket.setRelatedBill1(code.getTextTrim());				//记录TMS订单号
				pickTicket.setRelatedBill2(relateBillCode1.getTextTrim());	//记录客户订单号
				pickTicket.setRelatedBill3(log.getRequest());				//记录发送平台代码
				pickTicket.setRequireArriveDate(DateUtil.formatStrToDate(planArriveTime.getTextTrim()));
				pickTicket.setCustomer((Structure) commonDao.findByNamedQueryUniqueResult("getCustomerByCode", 
						new String[] {"code"}, new Object[] {toCode.getTextTrim()}));
				pickTicket.setShipToName(toName.getTextTrim());
				pickTicket.setShipToAddress(new Address(toAddress.getTextTrim(), toPostcode.getTextTrim()));
				pickTicket.setShipToContact(new Contact(toContact.getTextTrim(), 
						toPhone.getTextTrim(), toFax.getTextTrim(), toEmail.getTextTrim()));
				pickTicket.setOrderDate(new Date());
				pickTicket.setStatus(PickTicketStatus.ACTIVE);
				List<Location> shipLocs = commonDao.findByNamedQuery("getLocationsByType", 
						new String[] {"type", "warehouseId"}, 
						new Object[] {LocationType.SHIP, pickTicket.getWarehouse().getId()});
				if (shipLocs != null && shipLocs.size() > 0) {
					pickTicket.setDock(shipLocs.get(0));
				}
				addPickTicketDetails(pickTicket, detail);
				commonDao.store(pickTicket);
				
				aor = new AvaliableOrderResponse(pickTicket.getCompany().getCode(),	InterfaceLogConstant.AVAILABLE_ORDER_SO, pickTicket.getRelatedBill1(), pickTicket.getCode(), new Date());
			}
			
			//将创建的订单写入集合，回调STMS接口发送订单生效反馈消息
			pushAvaliableOrderResponse(log, aor);
		}
	}
	
	private void addPickTicketDetails(PickTicket pickTicket, Iterator details) {
		int seq = 1000;
		while (details.hasNext()) {
			Element detail = (Element) details.next();
			
			Element lineNo = detail.element("LINE");// 行号（序号）
			Element productCode = detail.element("PRODUCT");// 货物编号
			Element lot = detail.element("LOT");// 货物批次
			Element quantity = detail.element("QUANTITY");// 货物数量
			Element unit = detail.element("UNIT");// 包装单位名称
			
			PickTicketDetail orderDetail = new PickTicketDetail();
			
			Item item = null;
			if (!StringUtils.isEmpty(productCode.getText().trim())) {
				// 货物编号
				String pCode = XMLUtils.trimLeftZero(productCode.getText().trim());
				item = (Item) this.commonDao.findByNamedQueryUniqueResult("getItemByCompanyAndCode",
								new String[] { "code", "companyId" },
								new Object[] { productCode.getText().trim(), pickTicket.getCompany().getId()});
				orderDetail.setItem(item);
				// 包装单位
				if (!StringUtils.isEmpty(unit.getText().trim())) {
					PackageUnit packageUnit = (PackageUnit) this.commonDao.findByNamedQueryUniqueResult("getPackageUnitByItemAndUnit",
							new String[] { "unit", "itemId" },
							new Object[] { unit.getText().trim(), item.getId()});
					orderDetail.setPackageUnit(packageUnit);
				}
				// 货物批次
				//TODO 这里为什么是这样的  创建一个新的NewLotInfo
				NewLotInfo lotInfo = new NewLotInfo();
				if (!StringUtils.isEmpty(lot.getText().trim())) {
					lotInfo.setPropC1(lot.getText().trim());
				}
				lotInfo.setPropN1("0.0");
				lotInfo.setPropN2("0.0");
				lotInfo.setPropN3("0.0");
				orderDetail.setNewLotInfo(lotInfo);
				// 货物数量
				if (!StringUtils.isEmpty(quantity.getText().trim())) {
					orderDetail.addOrderQuantity(Double.parseDouble(quantity.getText().trim()), orderDetail.getPackageUnit());
				}
				pickTicket.addPickTicketDetail(orderDetail);
			} else {
				//直接丢弃数据
				//buf.append("行号为[" + lineNo.getText() + "]的产品代码[" +  
				//		productCode.getText().trim() + "]不存在 \r\n");
			}
		}
	}

	private void addAsnDetails(ASN asn, Iterator details) {
		int seq = 1000;
		while (details.hasNext()) {
			Element detail = (Element) details.next();
			
			Element lineNo = detail.element("LINE");// 行号（序号）
			Element productCode = detail.element("PRODUCT");// 货物编号
			Element lot = detail.element("LOT");// 货物批次
			Element quantity = detail.element("QUANTITY");// 货物数量
			Element unit = detail.element("UNIT");// 包装单位名称
			
			ASNDetail orderDetail = new ASNDetail();
			
			Item item = null;
			if (!StringUtils.isEmpty(productCode.getText().trim())) {
				// 行号（序号）
				if (!StringUtils.isEmpty(lineNo.getText().trim())) {
					orderDetail.setLineNo(Integer.parseInt(lineNo.getText().trim()));
				} else {
					orderDetail.setLineNo(seq++);
				}
				// 货物编号
				String pCode = XMLUtils.trimLeftZero(productCode.getText().trim());
				item = (Item) this.commonDao.findByNamedQueryUniqueResult("getItemByCompanyAndCode",
								new String[] { "code", "companyId" },
								new Object[] { productCode.getText().trim(), asn.getCompany().getId()});
				orderDetail.setItem(item);
				// 包装单位
				if (!StringUtils.isEmpty(unit.getText().trim())) {
					PackageUnit packageUnit = (PackageUnit) this.commonDao.findByNamedQueryUniqueResult("getPackageUnitByItemAndUnit",
							new String[] { "unit", "itemId" },
							new Object[] { unit.getText().trim(), item.getId()});
					orderDetail.setPackageUnit(packageUnit);
				}
				// 货物批次
				LotInfo lotInfo = new LotInfo();
				if (!StringUtils.isEmpty(lot.getText().trim())) {
					lotInfo.setPropC1(lot.getText().trim());
				}
				lotInfo.setPropN1(0);
				lotInfo.setPropN2(0);
				lotInfo.setPropN3(0);
				orderDetail.setLotInfo(lotInfo);
				// 货物数量
				if (!StringUtils.isEmpty(quantity.getText().trim())) {
					orderDetail.addExpectedQuantity(Double.parseDouble(quantity.getText().trim()));
				}
				asn.addASNDetail(orderDetail);
			} else {
				//直接丢弃数据
				//buf.append("行号为[" + lineNo.getText() + "]的产品代码[" +  
				//		productCode.getText().trim() + "]不存在 \r\n");
			}
		}
	}
	
	/**
	 * 发送生效订单反馈接口内容
	 * @param avaliableOrders
	 * @return
	 */
	private void pushAvaliableOrderResponse(InterfaceLog log, AvaliableOrderResponse aor) {
		//更新日志状态
		try {
			log.setResponseContent(formatXml(getAvaliableOrderResponse(aor)));
		} catch (Exception e) {
			e.printStackTrace();
		}
		log.setResponseTime(new Date());

		//调用方法发送接口数据
		boolean isSend = send(log, InterfaceLogConstant.RESPONSE);
		if (!isSend) {
			throw new BusinessException("orders.avaliable.response.error!");
		}
	}

	private Document getAvaliableOrderResponse(AvaliableOrderResponse aor) {
		// 明细内甙xml
		Document _doc = DocumentHelper.createDocument();
		Element _root = _doc.addElement("XML");
		Element contentList = _root.addElement("CONTENTLIST");
		Element content = contentList.addElement("CONTENT");
		// 内甙头
		Element header = content.addElement("ORDER");
		Element customerCode = header.addElement("CUSTOMER_CODE");
		Element omsCode = header.addElement("OMS_CODE");
		Element code = header.addElement("CODE");
		Element receiveTime = header.addElement("RECEIVE_TIME");
		customerCode.setText(aor.getCustomer());
		omsCode.setText(aor.getOmsCode());
		code.setText(aor.getWmsCode());
		receiveTime.setText(DateUtil.formatDateToStr(aor.getReceiveTime()));

		return _doc;
	}
	
	public void asnReceiveResponse(ASN asn) {
		//ASN关闭时生成收货接口文档，写入interfaceLog，并调用http接口往STMS发送单据收货确认消息
		if (StringUtils.isEmpty(asn.getRelatedBill3())) {
			//当WMS单独启动创建的ASN不进行接口处理
			return;
		}
		asn = commonDao.load(ASN.class, asn.getId());
		InterfaceLog log = new InterfaceLog();
		log.setType(InterfaceLogConstant.RECEIVE_REPORT);
		log.setFromSYS(InterfaceLogConstant.WMS);
		log.setRequest(asn.getWarehouse().getCode());
		log.setRequestTime(new Date());
		try {
			log.setRequestContent(formatXml(generateAsnReceiveContent(asn)));
		} catch (Exception e) {
			e.printStackTrace();
		}
		log.setToSYS(InterfaceLogConstant.TMS);
		log.setResponse(asn.getRelatedBill3());
		log.setFunction("");
		log.setStatus(InterfaceLogConstant.READY);
		log.setFileName("");
		log.setReference("");
		commonDao.store(log);
		//发送ASN收货反馈消息
		log.setLogID(log.getId());
	}

	private Document generateAsnReceiveContent(ASN asn) {
		Document _doc = DocumentHelper.createDocument();
		Element _root = _doc.addElement("XML");
		Element contentList = _root.addElement("CONTENTLIST");
		Element content = contentList.addElement("CONTENT");
		Element order = content.addElement("ORDER");
		//内嵌头
		Element head = order.addElement("HEAD");
		Element customerCode = head.addElement("CUSTOMER_CODE");
		Element code = head.addElement("CODE");
		Element omsCode = head.addElement("OMS_CODE");
		Element finishTime = head.addElement("FINISH_TIME");
		finishTime.setText(DateUtil.formatDateToStr(new Date()));
		customerCode.setText(asn.getCompany().getCode());
		code.setText(asn.getCode());
		omsCode.setText(asn.getRelatedBill1());
		//内嵌明细
		Element details = order.addElement("DETAILS");
		for (ASNDetail asnDetail : asn.getAsnDetails()) {
			Element detail = details.addElement("DETAIL");
			Element product = detail.addElement("PRODUCT");
			Element lot = detail.addElement("LOT");
			Element quantity = detail.addElement("QUANTITY");
			Element unit = detail.addElement("UNIT");
			product.setText(asnDetail.getItem().getCode());
			lot.setText(asnDetail.getLotInfo().getPropC1() == null ? "" : asnDetail.getLotInfo().getPropC1());
			unit.setText(asnDetail.getPackageUnit().getUnit());
			//收货包装数量，折算时保留3位有效小数
			quantity.setText(String.valueOf(DoubleUtils.formatByPrecision(
					asnDetail.getReceivedQuantity()/asnDetail.getPackageUnit().getConvertFigure(), 3)));
		}
		
		return _doc;
	}

	public void putawayResponse(MoveDoc moveDoc) {
//		//ASN关闭时生成收货接口文档，写入interfaceLog，并调用http接口往STMS发送单据收货确认消息
//		moveDoc = commonDao.load(MoveDoc.class, moveDoc.getId());
//		if (!MoveDocType.PUTAWAY.equals(moveDoc.getType())) {
//			//排除移位计划
//			return;
//		}
//		//取得上架计划关联的ASN对象
//		ASN asn = (ASN) commonDao.findByQueryUniqueResult("FROM ASN asn WHERE asn.warehouse.id = :warehouseId AND asn.code = :code", 
//				new String[] {"warehouseId", "code"}, 
//				new Object[] {moveDoc.getWarehouse().getId(), moveDoc.getSoi()});
//		if (asn == null || StringUtils.isEmpty(asn.getRelatedBill3())) {
//			//未定义接口信息收货单不做处理
//			return;
//		}
//		InterfaceLog log = new InterfaceLog();
//		log.setType(InterfaceLogConstant.PUTAWAY_REPORT);
//		log.setFromSYS(InterfaceLogConstant.WMS);
//		log.setRequest(asn.getWarehouse().getCode());
//		log.setRequestTime(new Date());
//		try {
//			log.setRequestContent(formatXml(generateputawayContent(asn, moveDoc.getDetails())));
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//		log.setToSYS(InterfaceLogConstant.TMS);
//		log.setResponse(asn.getRelatedBill3());
//		log.setFunction("");
//		log.setStatus(InterfaceLogConstant.READY);
//		log.setFileName("");
//		log.setReference("");
//		commonDao.store(log);
//		//发送ASN收货反馈消息
//		log.setLogID(log.getId());
    }

	private Document generateputawayContent(ASN asn, Set<MoveDocDetail> moveDocDetails) {
		Document _doc = DocumentHelper.createDocument();
		Element _root = _doc.addElement("XML");
		Element contentList = _root.addElement("CONTENTLIST");
		Element content = contentList.addElement("CONTENT");
		Element order = content.addElement("ORDER");
		//内嵌头
		Element head = order.addElement("HEAD");
		Element customerCode = head.addElement("CUSTOMER_CODE");
		Element code = head.addElement("CODE");
		Element omsCode = head.addElement("OMS_CODE");
		Element finishTime = head.addElement("FINISH_TIME");
		finishTime.setText(DateUtil.formatDateToStr(new Date()));
		customerCode.setText(asn.getCompany().getCode());
		code.setText(asn.getCode());
		omsCode.setText(asn.getRelatedBill1());
		//内嵌明细
		Element details = order.addElement("DETAILS");
		for (MoveDocDetail moveDocDetail : moveDocDetails) {
			Element detail = details.addElement("DETAIL");
			Element product = detail.addElement("PRODUCT");
			Element lot = detail.addElement("LOT");
			Element quantity = detail.addElement("QUANTITY");
			Element unit = detail.addElement("UNIT");
			product.setText(moveDocDetail.getItemKey().getItem().getCode());
			lot.setText(moveDocDetail.getItemKey().getLotInfo().getPropC1() == null ? "" : moveDocDetail.getItemKey().getLotInfo().getPropC1());
			unit.setText(moveDocDetail.getPackageUnit().getUnit());
			//上架包装数量，折算时保留3位有效小数
			quantity.setText(String.valueOf(DoubleUtils.formatByPrecision(
					moveDocDetail.getMoveQuantity()/moveDocDetail.getPackageUnit().getConvertFigure(), 3)));
		}
		
		return _doc;
	}

	public void pickResponse(PickTicket pickTicket) {
		//ASN关闭时生成收货接口文档，写入interfaceLog，并调用http接口往STMS发送单据收货确认消息
		pickTicket = commonDao.load(PickTicket.class, pickTicket.getId());
		if (StringUtils.isEmpty(pickTicket.getRelatedBill3())) {
			//发货单上未定义接口信息时，不发送接口消息
			return;
		}
		InterfaceLog log = new InterfaceLog();
		log.setType(InterfaceLogConstant.PICKING_REPORT);
		log.setFromSYS(InterfaceLogConstant.WMS);
		log.setRequest(pickTicket.getWarehouse().getCode());
		log.setRequestTime(new Date());
		try {
			log.setRequestContent(formatXml(generatePickContent(pickTicket)));
		} catch (Exception e) {
			e.printStackTrace();
		}
		log.setToSYS(InterfaceLogConstant.TMS);
		log.setResponse(pickTicket.getRelatedBill3());
		log.setFunction("");
		log.setStatus(InterfaceLogConstant.READY);
		log.setFileName("");
		log.setReference("");
		commonDao.store(log);
		//发送ASN收货反馈消息
		log.setLogID(log.getId());
	}

	private Document generatePickContent(PickTicket pickTicket) {
		Document _doc = DocumentHelper.createDocument();
		Element _root = _doc.addElement("XML");
		Element contentList = _root.addElement("CONTENTLIST");
		Element content = contentList.addElement("CONTENT");
		Element order = content.addElement("ORDER");
		//内嵌头
		Element head = order.addElement("HEAD");
		Element customerCode = head.addElement("CUSTOMER_CODE");
		Element code = head.addElement("CODE");
		Element omsCode = head.addElement("OMS_CODE");
		Element finishTime = head.addElement("FINISH_TIME");
		finishTime.setText(DateUtil.formatDateToStr(new Date()));
		customerCode.setText(pickTicket.getCompany().getCode());
		code.setText(pickTicket.getCode());
		omsCode.setText(pickTicket.getRelatedBill1());
		//内嵌明细
		Element details = order.addElement("DETAILS");
		for (PickTicketDetail pickTicketDetail : pickTicket.getPickTicketDetails()) {
			Element detail = details.addElement("DETAIL");
			Element product = detail.addElement("PRODUCT");
			Element lot = detail.addElement("LOT");
			Element quantity = detail.addElement("QUANTITY");
			Element unit = detail.addElement("UNIT");
			product.setText(pickTicketDetail.getItem().getCode());
			lot.setText(pickTicketDetail.getLotInfo().getPropC1() == null ? "" : pickTicketDetail.getLotInfo().getPropC1());
			unit.setText(pickTicketDetail.getPackageUnit().getUnit());
			//拣货包装数量，折算时保留3位有效小数
			quantity.setText(String.valueOf(DoubleUtils.formatByPrecision(
					pickTicketDetail.getPickedQuantity()/pickTicketDetail.getPackageUnit().getConvertFigure(), 3)));
		}
		
		return _doc;
	}

	public void bolShipResponse(BOL bol) {
		//ASN关闭时生成收货接口文档，写入interfaceLog，并调用http接口往STMS发送单据收货确认消息
		bol = commonDao.load(BOL.class, bol.getId());
		PickTicket pickTicket = bol.getPickTicket();
		if (StringUtils.isEmpty(pickTicket.getRelatedBill3())) {
			//发货单上未定义接口信息时，不发送接口消息
			return;
		}
		InterfaceLog log = new InterfaceLog();
		log.setType(InterfaceLogConstant.SHIPPING_REPORT);
		log.setFromSYS(InterfaceLogConstant.WMS);
		log.setRequest(pickTicket.getWarehouse().getCode());
		log.setRequestTime(new Date());
		try {
			log.setRequestContent(formatXml(generateBolShipContent(pickTicket, bol.getPackages())));
		} catch (Exception e) {
			e.printStackTrace();
		}
		log.setToSYS(InterfaceLogConstant.TMS);
		log.setResponse(pickTicket.getRelatedBill3());
		log.setFunction("");
		log.setStatus(InterfaceLogConstant.READY);
		log.setFileName("");
		log.setReference("");
		commonDao.store(log);
		//发送ASN收货反馈消息
		log.setLogID(log.getId());
	}

	private Document generateBolShipContent(PickTicket pickTicket,
			Set<Package> bolDetails) {
		Document _doc = DocumentHelper.createDocument();
		Element _root = _doc.addElement("XML");
		Element contentList = _root.addElement("CONTENTLIST");
		Element content = contentList.addElement("CONTENT");
		Element order = content.addElement("ORDER");
		//内嵌头
		Element head = order.addElement("HEAD");
		Element customerCode = head.addElement("CUSTOMER_CODE");
		Element code = head.addElement("CODE");
		Element omsCode = head.addElement("OMS_CODE");
		Element finishTime = head.addElement("FINISH_TIME");
		finishTime.setText(DateUtil.formatDateToStr(new Date()));
		customerCode.setText(pickTicket.getCompany().getCode());
		code.setText(pickTicket.getCode());
		omsCode.setText(pickTicket.getRelatedBill1());
		//内嵌明细
		Element details = order.addElement("DETAILS");
//		for (BOLDetail bolDetail : bolDetails) {
//			Element detail = details.addElement("DETAIL");
//			Element product = detail.addElement("PRODUCT");
//			Element lot = detail.addElement("LOT");
//			Element quantity = detail.addElement("QUANTITY");
//			Element unit = detail.addElement("UNIT");
//			product.setText(bolDetail.getPickedRecord().getItemKey().getItem().getCode());
//			lot.setText(bolDetail.getPickedRecord().getItemKey().getLotInfo().getPropC1() == null ? "" : bolDetail.getPickedRecord().getItemKey().getLotInfo().getPropC1());
//			unit.setText(bolDetail.getPackageUnit().getUnit());
//			//拣货包装数量，折算时保留3位有效小数
//			quantity.setText(String.valueOf(DoubleUtils.formatByPrecision(
//					bolDetail.getShippedQuantity()/bolDetail.getPackageUnit().getConvertFigure(), 3)));
//		}
		
		return _doc;
	}
	
	private String formatXml(Document doc) throws Exception {
		StringWriter writer = new StringWriter();
		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding("UTF-8");
		XMLWriter xmlWriter = new XMLWriter(writer, format);

		xmlWriter.write(doc);

		return writer.toString();
	}
	
	@SuppressWarnings("unchecked")
	public List<InterfaceLog> getLogsByConditions(List<String> types, String status) {
		List<InterfaceLog> logs = commonDao
		.findByQuery(
				"from InterfaceLog log where log.type in (:types) and log.status = :status",
				new String[] { "types", "status"}, 
				new Object[] { types, status });
		
		List<InterfaceLog> todo = new ArrayList<InterfaceLog>();
		int i = 0;
		for (InterfaceLog log : logs) {
			todo.add(log);
			i++;
			if (i <= TIMES_PER) {
				break;
			}
		}
		return todo;
	}
}
