package nc.impl.th;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import nc.bs.framework.adaptor.IHttpServletAdaptor;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.NCLocator;
import nc.bs.framework.server.ISecurityTokenCallback;
import nc.bs.pu.plugin.DataUtils.QueryDataUtil;
import nc.bs.servlet.service.BaseServlet;
import nc.itf.pu.m25.IInvoiceApprove;
import nc.itf.pu.m25.IInvoiceMaintain;
import nc.itf.uap.IUAPQueryBS;
import nc.itf.uap.pf.IPFBusiAction;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.log.NcLog;
import nc.vo.pu.m25.entity.InvoiceHeaderVO;
import nc.vo.pu.m25.entity.InvoiceItemVO;
import nc.vo.pu.m25.entity.InvoiceVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDateTime;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pub.workflownote.WorkflownoteVO;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class InvoiceAddImpl extends BaseServlet implements IHttpServletAdaptor {
	IUAPQueryBS iuap = (IUAPQueryBS) NCLocator.getInstance().lookup(IUAPQueryBS.class.getName());

	@Override
	public void doAction(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
		try {
			//InvocationInfoProxy.getInstance().setUserDataSource("NC6337");
			NCLocator.getInstance().lookup(ISecurityTokenCallback.class).token("NCSystem".getBytes(),"pfxx".getBytes());
			String createStr = buildJson(req, resp, this.getClass().getName());
			JSONObject json = JSONObject.fromObject(createStr);
			NcLog.info(json.toString());
			String vbillcode = "";
			vbillcode = json.getString("vbillcode");
			checkJson(json);//非空判断
			InvocationInfoProxy.getInstance().setGroupId(SqlexecuteQuery("pk_group", "org_group", "code", "00"));
		 	InvocationInfoProxy.getInstance().setUserId(SqlexecuteQuery("cuserid", "sm_user", "cuserid", json.getString("billmaker")));
			PrintWriter out = resp.getWriter();
			InvoiceVO[] aggvos = new InvoiceVO[1];
			InvoiceVO aggvo = new InvoiceVO();
			aggvos[0] = aggvo;
			//表头
			InvoiceHeaderVO  parentVO=new InvoiceHeaderVO();
			//表体
			InvoiceItemVO[] childrenVO = new InvoiceItemVO[json.getJSONArray("childrenVO").size()];
			//封装表头VO
			parentVO.setPk_group(SqlexecuteQuery("pk_group", "org_group", "code", "00"));//所属集团 	
			parentVO.setPk_org(SqlexecuteQuery2("pk_financeorg", "org_financeorg", "code", json.getString("pk_org")));//财务组织
			parentVO.setPk_org_v(SqlexecuteQuery2("pk_vid", "org_financeorg_v", "code", json.getString("pk_org")));//财务组织最新版本
			parentVO.setCreator(SqlexecuteQuery("cuserid", "sm_user", "cuserid", json.getString("billmaker")));//创建人			
			parentVO.setCreationtime(new UFDateTime(json.getString("dbilldate")));//创建时间	
			parentVO.setBillmaker(SqlexecuteQuery("cuserid", "sm_user", "cuserid", json.getString("billmaker")));//制单人
			parentVO.setDmakedate(new UFDate(json.getString("dbilldate")));//制单日期
			parentVO.setVtrantypecode(json.getString("vtrantypecode"));//发票类型编码
			parentVO.setCtrantypeid(SqlexecuteQuery("pk_billtypeid", "bd_billtype", "pk_billtypecode", json.getString("ctrantypeid")));//发票类型
			parentVO.setFinvoiceclass(json.getInt("finvoiceclass"));//发票分类(0=增值税发票，10=普通发票，20=其它发票)
			parentVO.setVbillcode(vbillcode);//发票号
			parentVO.setDbilldate(new UFDate(json.getString("dbilldate")));//发票日期
			parentVO.setPk_supplier(SqlexecuteQuery("pk_supplier", "bd_supplier", "code", json.getString("pk_supplier")));//供应商
			parentVO.setPk_bankaccbas(SqlexecuteQuery("pk_bankaccsub", "bd_bankaccsub", "accnum", json.getString("pk_bankaccbas")));//银行账户
			parentVO.setPk_bizpsn(SqlexecuteQuery("pk_psndoc", "sm_user", "cuserid", json.getString("pk_bizpsn")));//采购员
			parentVO.setPk_dept_v(SqlexecuteQuery("pk_vid", "org_dept_v", "code", json.getString("pk_dept_v")));//采购部门
			parentVO.setPk_busitype(SqlexecuteQuery("pk_busitype", "bd_busitype", "busicode", json.getString("pk_busitype")));//业务流程
			parentVO.setPk_stockorg_v(SqlexecuteQuery("pk_vid", "org_stockorg_v", "code", json.getString("pk_stockorg_v")));//库存组织
			parentVO.setPk_paytosupplier(SqlexecuteQuery("pk_supplier", "bd_supplier", "code", json.getString("pk_paytosupplier")));//付款单位
			parentVO.setNtotalastnum(new UFDouble(json.getString("ntotalastnum")));//总数量
			parentVO.setNtotalorigmny(new UFDouble(json.getString("ntotalorigmny")));//价税合计
			parentVO.setFtaxtypeflagh(Integer.parseInt(json.getString("ftaxtypeflagh")));//整单扣税类别(1=应税外加，0=应税内含)
			parentVO.setVmemo(json.getString("vmemo"));//备注
			parentVO.setDarrivedate(new UFDate(json.getString("darrivedate")));//票到日期
			parentVO.setCcurrencyid(SqlexecuteQuery("pk_currtype", "bd_currtype", "code", json.getString("ccurrencyid")));//本币币种
			parentVO.setCorigcurrencyid(SqlexecuteQuery("pk_currtype", "bd_currtype", "code", json.getString("corigcurrencyid")));//币种
			parentVO.setNexchangerate(new UFDouble(json.getString("nexchangerate")));//汇率
			parentVO.setCrececountryid(SqlexecuteQuery("pk_country", "bd_countryzone", "code","CN"));//收货国
			parentVO.setCsendcountryid(SqlexecuteQuery("pk_country", "bd_countryzone", "code","CN"));//发货国
			parentVO.setCtaxcountryid(SqlexecuteQuery("pk_country", "bd_countryzone", "code","CN"));//报税国
			parentVO.setFbuysellflag(2);//购销类型(1=国内销售，2=国内采购，3=出口，4=进口，5=不区分)
			parentVO.setVdef18(json.getString("vdef18"));//是否一致 	
			
			aggvo.setParentVO(parentVO);
			
			//封装表体VO
			JSONArray bodyArray = json.getJSONArray("childrenVO");
			int i=0;
			for (Object Object : bodyArray) {
				JSONObject bodyObject = JSONObject.fromObject(Object);
				InvoiceItemVO invoiceItemVO = new InvoiceItemVO();
				invoiceItemVO.setPk_group(SqlexecuteQuery("pk_group", "org_group", "code", "00"));//所属集团
				invoiceItemVO.setPk_org(SqlexecuteQuery2("pk_financeorg", "org_financeorg", "code", json.getString("pk_org")));//财务组织
				invoiceItemVO.setPk_org_v(SqlexecuteQuery2("pk_vid", "org_financeorg_v", "code", json.getString("pk_org")));//财务组织
				invoiceItemVO.setDbilldate(new UFDate(json.getString("dbilldate")));//发票日期
				invoiceItemVO.setCrowno(bodyObject.getString("crowno"));//行号
//				invoiceItemVO.setVbdef13(bodyObject.getString("vbdef13"));//发票参照
				invoiceItemVO.setVbdef11(bodyObject.getString("vbdef11"));//发票查看
				invoiceItemVO.setVbdef12(bodyObject.getString("vbdef12"));//必填  OCR识别发票号
				invoiceItemVO.setPk_material(SqlexecuteQuery("pk_material", "bd_material", "code", bodyObject.getString("pk_material")));//物料编码
				invoiceItemVO.setPk_srcmaterial(SqlexecuteQuery("pk_source", "bd_material_v", "code", bodyObject.getString("pk_srcmaterial"))); //物料
				invoiceItemVO.setCtaxcodeid(SqlexecuteQuery("pk_taxcode", "bd_taxcode", "code", bodyObject.getString("ctaxcodeid")));//税码
				invoiceItemVO.setNtaxrate(new UFDouble(bodyObject.getString("ntaxrate")));//税率
				invoiceItemVO.setNastorigprice(new UFDouble(bodyObject.getString("nastorigprice")));//无税单价
				invoiceItemVO.setNmny(new UFDouble(bodyObject.getString("nmny")));//本币无税金额
				invoiceItemVO.setNorigmny(new UFDouble(bodyObject.getString("norigmny")));//无税金额
				invoiceItemVO.setNtax(new UFDouble(bodyObject.getString("ntax")));//税额
				invoiceItemVO.setNastorigtaxprice(new UFDouble(bodyObject.getString("nastorigtaxprice")));//含税单价
				invoiceItemVO.setNorigtaxmny(new UFDouble(bodyObject.getString("norigtaxmny")));//价税合计
				invoiceItemVO.setVbdef17(bodyObject.getString("vbdef17"));//发票分类(0=增值税发票，10=普通发票，20=其它发票)
				invoiceItemVO.setVbdef15(bodyObject.getString("vbdef15"));//销售分公司
				invoiceItemVO.setVbdef14(bodyObject.getString("vbdef14"));//是否一致
				invoiceItemVO.setPk_apfinanceorg_v(SqlexecuteQuery("pk_vid", "org_financeorg_v", "code", bodyObject.getString("pk_apfinanceorg_v")));//应付财务组织
				invoiceItemVO.setVmemob(bodyObject.getString("vmemob"));//备注
				invoiceItemVO.setFrowtype(0);//行类型(0=货物行，1=折扣行，2=劳务行，3=零数量行)
				invoiceItemVO.setFtaxtypeflag(Integer.parseInt(json.getString("ftaxtypeflagh")));//扣税类别(1=应税外加，0=应税内含)
				invoiceItemVO.setVchangerate("1/1");//换算率
				invoiceItemVO.setVbdef16(bodyObject.getString("vbdef16"));
				invoiceItemVO.setCunitid(SqlexecuteQuery("pk_measdoc", "bd_measdoc", "code", bodyObject.getString("cunitid")));//主单位
				invoiceItemVO.setCastunitid(invoiceItemVO.getCunitid());//单位
				Map<String,String> map = new HashMap<String,String>();
				String vfirstcode = bodyObject.getString("vfirstcode");
				if(!"vfirstcode".equals(vfirstcode)) {
					String vfirstrowno = bodyObject.getString("vfirstrowno");
					String cfirsttypecode = bodyObject.getString("cfirsttypecode");
					map = QueryDataUtil.getDataMap(cfirsttypecode, vfirstcode, vfirstrowno);
					invoiceItemVO.setVfirstcode(vfirstcode);//源头单据号  
					invoiceItemVO.setVfirstrowno(vfirstrowno);//源头单据行号
					invoiceItemVO.setCfirstid(map.get("pk_id"));  //源头单据主键
					invoiceItemVO.setCfirstbid(map.get("pk_id_b"));//源头单据行主键
					invoiceItemVO.setCfirsttypecode(cfirsttypecode);//源头单据类型
					invoiceItemVO.setVfirsttrantype(SqlexecuteQuery("pk_billtypeid", "bd_billtype", "pk_billtypecode",bodyObject.getString("vfirsttrantype")));//源头交易类型
				}
				invoiceItemVO.setVctcode(bodyObject.getString("vctcode"));//合同号
				
				String vordercode = bodyObject.getString("vordercode");
				if(!"".equals(vordercode)) {
					String vorderrowno = bodyObject.getString("vorderrowno");//订单行号
					map = QueryDataUtil.getDataMap("21", vordercode, vorderrowno);
					invoiceItemVO.setVordercode(vordercode);//订单号
					invoiceItemVO.setPk_order(map.get("pk_id"));//订单主键
					invoiceItemVO.setPk_order_b(map.get("pk_id_b"));//订单行主键
					invoiceItemVO.setVordertrantype(bodyObject.getString("vordertrantype"));//订单交易类型
				}
				
				String vsourcecode = bodyObject.getString("vsourcecode");
				if(!"".equals(vsourcecode)) {
					String vsourcerowno = bodyObject.getString("vsourcerowno");
					String csourcetypecode = bodyObject.getString("csourcetypecode");
					map = QueryDataUtil.getDataMap(csourcetypecode, vsourcecode, vsourcerowno);
					invoiceItemVO.setVsourcecode(vsourcecode);//来源单据号
					invoiceItemVO.setVsourcerowno(vsourcerowno);//来源单据行号
					invoiceItemVO.setCsourceid(map.get("pk_id"));//来源单据主键
					invoiceItemVO.setCsourcebid(map.get("pk_id_b"));//来源单据行主键
					invoiceItemVO.setCsourcetypecode(csourcetypecode);//来源单据类型
					invoiceItemVO.setVsourcetrantype(SqlexecuteQuery("pk_billtypeid", "bd_billtype", "pk_billtypecode",bodyObject.getString("vsourcetrantype")));//来源交易类型
				}
				if(bodyObject.opt("vbatchcode")!=null){
					invoiceItemVO.setVbatchcode(bodyObject.getString("vbatchcode"));
				}
				childrenVO[i] = invoiceItemVO;
				i++;
			}
			aggvo.setChildrenVO(childrenVO);
			// 线程设置业务日期
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			Object dateTimeString  = parentVO.getDbilldate();
			if(dateTimeString != null) {
			    Date date = format.parse(dateTimeString.toString());
			    long timestamp = date.getTime();
			    InvocationInfoProxy.getInstance().setBizDateTime(timestamp);
			 }
			IInvoiceMaintain iInvoiceMaintain = (IInvoiceMaintain)NCLocator.getInstance().lookup(IInvoiceMaintain.class);
			InvoiceVO[] invoiceVO = iInvoiceMaintain.insert(aggvos, null);
			IPFBusiAction service = NCLocator.getInstance().lookup(IPFBusiAction.class);
			service.processAction("APPROVE","25", null, invoiceVO[0], null, null);
			out.print(formatRSJsonData("成功","",vbillcode)); 
		} catch (Exception e) {
			resp.getWriter().write(formatRSJsonData("失败", e.getMessage().toString(), "").toString());
			StringWriter stringWriter = new StringWriter();
			e.printStackTrace(new PrintWriter(stringWriter));
			// 获取详细信息
			String msg = stringWriter.getBuffer().toString();	
			NcLog.info(msg);
		}
	}
	
	
	/*
	 * 非空判断
	 */
	private void checkJson(JSONObject json) throws Exception {
		
		StringBuffer mags = new StringBuffer();
		Boolean empty = true;
		
		String vbillcode = "vbillcode";//单据号
		String pk_org = "pk_org";//组织编码
		String billmaker = "billmaker";//创建人
		String vdef18 = "vdef18";//vdef18是否一致
		
		String body = "childrenVO";//表体
 
		String[] HeadKey = {vbillcode,pk_org,billmaker,body,vdef18};
		
		for (String as : HeadKey) {
			if (json.getString(as).isEmpty()) {
				empty = false;
				mags.append("'" + as + "'");
			}
		}
		
		if (json.getJSONArray(body)==null) {
			empty = false;
			mags.append("表体不存在！ ");
		}
		
		JSONArray oprepObjectBs = json.getJSONArray("childrenVO");
		
		if (oprepObjectBs == null || oprepObjectBs.size() == 0) {
			throw new Exception("表体内容不可为空！");
		}
		
		String crowno = "crowno";//行号

		for(int i = 0; i < oprepObjectBs.size(); i++) {
			
			JSONObject oprepJsonObjectB = oprepObjectBs.getJSONObject(i);
			String[] BodyKey = {crowno};
			int num = i+1;
			
			mags.append("第"+num+"块表体：{");
			for (String as : BodyKey) {
				if (oprepJsonObjectB.getString(as).isEmpty()) {
					empty = false;
					mags.append("'" + as + "' ");
				}
			}
			mags.append("}");
		}
		if (!empty) {
			throw new Exception("以下字段不可为空："+mags);
		}
	}
	
	
	
	/*
	 * 数据库查询
	 */
	private String SqlexecuteQuery(String out,String table,String key,String value) throws Exception {
		String sql = "select "+out+" from "+table+" where "+key+" = '"+value+"' and nvl(dr,0)=0";	
		Object object;
			object = iuap.executeQuery(sql, new ColumnProcessor());
			if (object==null) {
				throw new Exception("未查询到数据！请检查编码"+value+"是否正确！");
			}	
			return object.toString();
	}
	
	
	private String SqlexecuteQuery2(String out,String table,String key,String value) throws Exception {
		String sql = "select "+out+" from "+table+" where "+key+" = '"+value+"' and nvl(dr,0)=0 and enablestate = '2'";	
		Object object;
			object = iuap.executeQuery(sql, new ColumnProcessor());
			if (object==null) {
				throw new Exception("未查询到数据！请检查编码"+value+"是否正确！");
			}
			return object.toString();
	}
	
}
