package nc.itf.sscivm.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.NCLocator;
import nc.bs.sscivm.logger.SSCIVMLogger;
import nc.bs.sscivm.pubconst.SSCIVMPubConst;
import nc.bs.sscivm.util.FileTypeUtil;
import nc.dto.imag.boot.RequestInfo;
import nc.dto.imag.boot.ResponseInfo;
import nc.dto.imag.invoice.PInvoice;
import nc.dto.imag.invoice.ocr.EOCRCommonRequest;
import nc.dto.imag.invoice.ocr.OCRAllInvoiceResponse;
import nc.dto.imag.invoice.ocr.OCRInvoiceData;
import nc.dto.imag.invoice.tax.TaxAllInvoiceRequest;
import nc.dto.imag.invoice.tax.TaxCommonResponse;
import nc.dto.imag.invoice.verify.VerifyCommonRequest;
import nc.dto.imag.invoice.verify.VerifyCommonResponse;
import nc.dto.imag.invoice.verify.VerifyInvoiceData;
import nc.imag.pub.util.ImageServiceUtil;
import nc.itf.sscivm.service.IIVMInvoiceFileService;
import nc.itf.sscivm.service.IInvoiceUploadService;
import nc.itf.sscivm.service.IVMInvoiceQueryService;
import nc.vo.imag.ocr.AllInvoiceTypeEnum;
import nc.vo.imag.ocr.OCRRecordVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.VOStatus;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.sscivm.invoice.IVMInvoiceAggVO;
import nc.vo.sscivm.invoice.IVMInvoiceConstant;
import nc.vo.sscivm.invoice.IVMInvoiceFileVO;
import nc.vo.sscivm.invoice.IVMInvoiceHeadVO;
import nc.vo.sscivm.ivmpub.InvoiceCJFS;
import nc.vo.sscivm.ivmpub.InvoiceTypeEnum;
import nccloud.impl.platform.common.util.StringUtils;
import nccloud.itf.sscivm.ivrec.service.IVRecService;
import nccloud.pubitf.imag.ocrrecord.ISSCOCRRecordService;
import nccloud.pubitf.platform.attachment.IAttachmentService;
import nccloud.util.sscivm.fullface.util.InvoiceExtFullFaceUtil;
import org.apache.commons.codec.binary.Base64;
import uap.pub.fs.client.FileStorageClient;
import uap.pub.fs.domain.basic.FileHeader;
import uap.pub.fs.domain.basic.GetPreViewFileModeEnum;

public class InvoiceUploadServiceImpl implements IInvoiceUploadService {

	@SuppressWarnings("rawtypes")
	@Override
	public Map<String, Object> upload(String pk_org, String pk_bill, String billtype, String tradetype, String fileName,
			String fileContent, boolean isImagScan, String usercode) {
		Map<String, Object> result = new HashMap<String, Object>();

		RequestInfo<EOCRCommonRequest[]> request = new RequestInfo<>();
		request.setPk_org(pk_org);
		request.setBilltype(billtype);
		request.setTransitype(tradetype);
		request.setDatasource(InvocationInfoProxy.getInstance().getUserDataSource());
		request.setUserCode(usercode != null ? usercode : InvocationInfoProxy.getInstance().getUserCode());
		request.setBillid(pk_bill);

		EOCRCommonRequest rep = new EOCRCommonRequest();
		rep.setBillid(pk_bill);
		rep.setFile(fileContent);
		rep.setFileName(fileName);

		request.setData(new EOCRCommonRequest[] { rep });

		PInvoice invoice = null;
		String pk_invoice = "";
		try {
			ResponseInfo<VerifyCommonResponse[]> responseInfo = ImageServiceUtil.doEVerifyAndUpload(request);
			if (!IVMInvoiceConstant.SUCCESS_CODE.equals(responseInfo.getCode())) {
				throw new BusinessException(responseInfo.getMessage());
			}
			VerifyCommonResponse[] res = responseInfo.getData();
			if (!IVMInvoiceConstant.SUCCESS_CODE.equals(res[0].getCode())) {
				throw new BusinessException(res[0].getMsg());
			}
			invoice = (PInvoice) res[0].getInvoice();
			String condition = "fphm = '" + invoice.getFpHm() + "' and fpdm = '" + invoice.getFpDm() + "'"
					+ " and dr=0 and " + IVMInvoiceHeadVO.BILLTYPECODE + "='"
					+ IVMInvoiceConstant.IVREC_SP_TRADETYPECODE + "' and invoice_type =" + invoice.getFplx();
			if (invoice.getFpDm() == null || "".equals(invoice.getFpDm())) {
				condition = "fphm = '" + invoice.getFpHm() + "' and dr=0 and " + IVMInvoiceHeadVO.BILLTYPECODE + "='"
						+ IVMInvoiceConstant.IVREC_SP_TRADETYPECODE + "' and invoice_type =" + invoice.getFplx();
			}
			IVMInvoiceAggVO[] invoices = NCLocator.getInstance().lookup(IVMInvoiceQueryService.class)
					.queryAggVOsByCondition(condition);
			pk_invoice = invoices[0].getHeadVO().getPk_invoice();

			uploadFileToFileSystem(fileName, fileContent, invoices[0], isImagScan);

		} catch (Exception e) {
			Throwable src = ExceptionUtils.unmarsh(e);
			SSCIVMLogger.error(src.getMessage(), src);
			result.put("success", false);
			result.put("message", src.getMessage() == null ? e.getMessage() : src.getMessage());
			invoice = new PInvoice();
		}

		Map<String, Object> data = getInvoiceJSONData(invoice, fileName);

		data.put("pk_invoice", pk_invoice);

		result.put("data", data);

		return result;
	}

	private Map<String, Object> getInvoiceJSONData(PInvoice invoice, String fileName) {
		Map<String, Object> result = new HashMap<>();
		UFDouble jshj = invoice.getJshj() == null ? null : new UFDouble(invoice.getJshj());
		if (jshj != null) {
			jshj.setScale(2, UFDouble.ROUND_HALF_UP);
		} else {
			jshj = new UFDouble(0);
		}

		result.put("file_name", fileName);
		result.put("invoice_code", invoice.getFpDm() == null ? "" : invoice.getFpDm());
		result.put("invoice_number", invoice.getFpHm() == null ? "" : invoice.getFpHm());
		result.put("date", invoice.getKprq() == null ? "" : invoice.getKprq());
		result.put("vat_amount", jshj);
		result.put("name", invoice.getXsfMc());
		return result;
	}

	private void uploadFileToFileSystem(String fileName, String content, IVMInvoiceAggVO agg, boolean isImagScan)
			throws BusinessException {

		try {
			String bucket = IVMInvoiceConstant.SSCIVM_BUCKET;
			int cjfs = InvoiceCJFS.CJFS_1.toIntValue();
			if (isImagScan) {
				cjfs = InvoiceCJFS.CJFS_5.toIntValue();
			}
			Base64 base64 = new Base64();
			// 上传成功后，将文件存储到文件服务器
			FileHeader fileHeader = NCLocator.getInstance().lookup(IAttachmentService.class).upload(fileName,
					new ByteArrayInputStream(base64.decode(content)), false, 0, bucket);
			if (fileHeader == null) {
				throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("1058pub_0",
						"01058pub-0052")/* @res "上传电子发票到文件服务出现错误。" */);
			}
//			NCLocator.getInstance().lookup(IVMInvoiceService.class).update(agg, null);
			new BaseDAO().executeUpdate("update " + IVMInvoiceHeadVO.getDefaultTableName() + " set viewurl = '"
					+ fileHeader.getPath() + "', filename='" + fileHeader.getName() + "', cjfs = " + cjfs
					+ " where pk_invoice = '" + agg.getHeadVO().getPk_invoice() + "'");

		} catch (Exception e) {
			// 新事务删除已经上传的发票
			NCLocator.getInstance().lookup(IVRecService.class)
					.deleteIVMInvoices_RequiresNew(new String[] { agg.getHeadVO().getPk_invoice() });
			throw new BusinessException(e.getMessage(), e);
		}

	}

	@Override
	public IVMInvoiceFileVO uploadFile(String fileContent, String fileName, String pk_org, String type)
			throws BusinessException {

		try {
			String bucket = IVMInvoiceConstant.SSCIVM_BUCKET;
			Base64 base64 = new Base64();
			// 上传成功后，将文件存储到文件服务器
			FileHeader fileHeader = NCLocator.getInstance().lookup(IAttachmentService.class).upload(fileName,
					new ByteArrayInputStream(base64.decode(fileContent)), false, 0, bucket);
			if (fileHeader == null) {
				throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("1058pub_0",
						"01058pub-0052")/* @res "上传电子发票到文件服务出现错误。" */);
			}

			IVMInvoiceFileVO fileVO = new IVMInvoiceFileVO();
			fileVO.setPk_org(pk_org);
			fileVO.setFilename(fileName);
			fileVO.setViewurl(fileHeader.getPath());
			fileVO.setType(type);
			// 因税务云bip版没有ofd服务，所以先走平台的服务。
//			if (SSCIVMPubConst.OFD.equals(type)){
//				 RequestInfo<ViewInvoiceCommonRequest> request = new RequestInfo<>();
//			     request.setPk_org(pk_org);
//			     request.setDatasource(InvocationInfoProxy.getInstance().getUserDataSource());
//			     request.setUserCode(InvocationInfoProxy.getInstance().getUserCode());
//			     ViewInvoiceCommonRequest rep = new ViewInvoiceCommonRequest();
//			     rep.setType("png");
//			     rep.setContent(fileContent);
//			     request.setData(rep);
//			     ResponseInfo<ViewInvoiceCommonResponse> viewResponse =
//			          NCLocator.getInstance().lookup(InvoiceViewInvoiceService.class).viewOFDInvoice(request);
//			     ViewInvoiceCommonResponse responses = viewResponse.getData();
//			     String content = responses.getDatas() == null ? "" : (String)responses.getDatas().get("content");
//			     fileVO.setSliceviewurl(content);
//			}

			IVMInvoiceFileVO[] vos = NCLocator.getInstance().lookup(IIVMInvoiceFileService.class)
					.addVOs(new IVMInvoiceFileVO[] { fileVO });
			return vos[0];
		} catch (Exception e) {
			// 新事务删除已经上传的发票
			SSCIVMLogger.error(e.getMessage(), e);
			throw new BusinessException(e.getMessage(), e);
		}
	}

	@Override
	public List<Map<String, Object>> uploadInvoice(String pk_org, String pk_bill, String billtype, String tradetype,
			String fileName, String fileContent, IVMInvoiceFileVO fileVO) {

		List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
		RequestInfo<EOCRCommonRequest[]> request = new RequestInfo<>();
		request.setPk_org(pk_org);
		request.setBilltype(billtype);
		request.setTransitype(tradetype);
		request.setDatasource(InvocationInfoProxy.getInstance().getUserDataSource());
		request.setUserCode(InvocationInfoProxy.getInstance().getUserCode());
		request.setBillid(pk_bill);
		request.setSubmitter(InvocationInfoProxy.getInstance().getUserCode());
		request.setBusiFlag(getBusiFlag(billtype));

		EOCRCommonRequest rep = new EOCRCommonRequest();
		rep.setBillid(pk_bill);
		rep.setFile(fileContent);
		rep.setFileName(fileName);

		request.setData(new EOCRCommonRequest[] { rep });

		Set<String> invoiceIds = new HashSet<String>();// 需要删除的发票主键
		List<VerifyInvoiceData> dels = new ArrayList<VerifyInvoiceData>();// 需要删除的电票
		try {
			List<IVMInvoiceFileVO> updateVOs = new ArrayList<IVMInvoiceFileVO>();// 更新的VO
			List<IVMInvoiceFileVO> insertVOs = new ArrayList<IVMInvoiceFileVO>();// 新增的VO
			IVMInvoiceFileVO delVO = null;// 删除的VO
			ResponseInfo<VerifyCommonResponse[]> verifyResponse = null;
			ResponseInfo<OCRAllInvoiceResponse> ocrResponse = null;
			if (FileTypeUtil.isDzpj(fileName)) {// 电票走查验解析-保存接口
				verifyResponse = ImageServiceUtil.doEleBillVerifyAndUpload(request);
				VerifyCommonResponse[] responses = verifyResponse.getData();
				Map<String, IVMInvoiceAggVO> hmToVOMap = getInvoices(responses);
				for (VerifyCommonResponse response : responses) {
					// 组装返回值
					Map<String, Object> result = new HashMap<String, Object>();
					result.put(SSCIVMPubConst.SUCCESS, true);
					result.put(IVMInvoiceFileVO.PK_INVOICE_FILE, fileVO.getPk_invoice_file());
					result.put(IVMInvoiceFileVO.VIEWURL, getPreViewUrl(fileVO.getViewurl()));
					result.put(IVMInvoiceFileVO.FILENAME, fileVO.getFilename());

					if (!IVMInvoiceConstant.SUCCESS_CODE.equals(response.getCode())) {// 失败
						result.put(SSCIVMPubConst.SUCCESS, false);
						result.put(SSCIVMPubConst.MESSAGE, response.getMsg());
						result.put(SSCIVMPubConst.IGNORE, true);
						result.put(SSCIVMPubConst.EDIT, false);
						if (response.getInvoice() != null) {
							result.put(SSCIVMPubConst.JOSNDATA, response.getInvoice());
							dels.add((VerifyInvoiceData) response.getInvoice());
						}
					} else { // 成功
						VerifyInvoiceData data = (VerifyInvoiceData) response.getInvoice();
						IVMInvoiceAggVO ivmVO = hmToVOMap.get(data.getFpHm());
						invoiceIds.add(ivmVO.getParentVO().getPk_invoice());
						result.put(IVMInvoiceHeadVO.PK_INVOICE, ivmVO.getParentVO().getPk_invoice());
						result.put(SSCIVMPubConst.IGNORE, false);
						result.put(SSCIVMPubConst.EDIT, false);
						result.put(SSCIVMPubConst.AGGVO, ivmVO);
						fileVO.setStatus(VOStatus.UPDATED);
						updateVOs.add(buildIVMInvoiceFileVO(ivmVO, fileVO));
						updateInvoice(ivmVO, fileVO);
					}
					results.add(result);
				}
			} else {// 纸票走ocr-查验-保存/ocr-保存接口
				ocrResponse = ImageServiceUtil.doPaperBillOCRAndVerifyAndUpload(request);
				OCRAllInvoiceResponse oaresp = ocrResponse.getData();
				if (!IVMInvoiceConstant.SUCCESS_CODE.equals(oaresp.getCode())) {// 失败
					Map<String, Object> result = new HashMap<String, Object>();
					result.put(SSCIVMPubConst.SUCCESS, false);
					result.put(IVMInvoiceFileVO.PK_INVOICE_FILE, fileVO.getPk_invoice_file());
					result.put(IVMInvoiceFileVO.VIEWURL, getPreViewUrl(fileVO.getViewurl()));
					result.put(SSCIVMPubConst.MESSAGE, oaresp.getMsg());
					result.put(IVMInvoiceFileVO.FILENAME, fileVO.getFilename());
					result.put(SSCIVMPubConst.IGNORE, true);
					result.put(SSCIVMPubConst.EDIT, false);
					results.add(result);
				} else {
					Map<String, IVMInvoiceAggVO> hmToVOMap = getInvoices(oaresp);
					OCRInvoiceData[] datas = oaresp.getDatas();
					for (OCRInvoiceData data : datas) {
						Map<String, Object> result = new HashMap<String, Object>();
						result.put(SSCIVMPubConst.SUCCESS, true);
						result.put(IVMInvoiceFileVO.PK_INVOICE_FILE, fileVO.getPk_invoice_file());
						result.put(IVMInvoiceFileVO.FILENAME, fileVO.getFilename());
						IVMInvoiceFileVO newfileVO = (IVMInvoiceFileVO) fileVO.clone();
						if (datas.length > 1) {
							delVO = fileVO;
							newfileVO.setCombination(UFBoolean.TRUE);
							newfileVO.setPk_invoice_file(null);
							// 裁剪并上传到文件服务器
							newfileVO = this.getIIVMInvoiceFileService().sliceFile_RequiresNew(fileContent, newfileVO,
									data);
							newfileVO.setStatus(VOStatus.NEW);
							result.put(IVMInvoiceFileVO.PK_INVOICE_FILE, newfileVO.getPk_invoice_file());
							result.put(IVMInvoiceFileVO.VIEWURL, getPreViewUrl(newfileVO.getSliceviewurl()));
						} else {
							newfileVO = this.getIIVMInvoiceFileService().adjustFileDegree_RequiresNew(fileContent,
									fileVO, data);
							result.put(IVMInvoiceFileVO.VIEWURL, getPreViewUrl(fileVO.getViewurl()));
							newfileVO.setStatus(VOStatus.UPDATED);
						}
						newfileVO.setToken(data.getToken());

						if (!IVMInvoiceConstant.SUCCESS_CODE.equals(data.getCode())) {// 失败
							result.put(SSCIVMPubConst.SUCCESS, false);
							result.put(SSCIVMPubConst.MESSAGE, data.getMessage());
							result.put(SSCIVMPubConst.IGNORE, true);
							result.put(SSCIVMPubConst.EDIT, true);
							if (data.getData() != null) {
								result.put(SSCIVMPubConst.JOSNDATA, data);
							}
						} else {// 成功
							IVMInvoiceAggVO ivmVO = hmToVOMap.get(data.getFpHm());
							invoiceIds.add(ivmVO.getParentVO().getPk_invoice());
							result.put(IVMInvoiceHeadVO.PK_INVOICE, ivmVO.getParentVO().getPk_invoice());
							result.put(SSCIVMPubConst.IGNORE, false);
							if (AllInvoiceTypeEnum.INVOICE.getTypeCode().equals(data.getBillType())) {// 成功增值税不可修改，非增值税可以修改
								result.put(SSCIVMPubConst.EDIT, false);
							} else {
								result.put(SSCIVMPubConst.EDIT, true);
							}
							result.put(SSCIVMPubConst.AGGVO, ivmVO);
							newfileVO = buildIVMInvoiceFileVO(ivmVO, newfileVO);
							updateInvoice(ivmVO, fileVO);
						}
						updateVOs.add(newfileVO);
						results.add(result);
					}
				}
			}

			// 更新文件VO
			if (updateVOs.size() > 0) {
				getIIVMInvoiceFileService().updateVOs_RequiresNew(updateVOs.toArray(new IVMInvoiceFileVO[0]));
			}

			// 删除文件VO
			if (delVO != null) {
				getIIVMInvoiceFileService().deleteVOs(new IVMInvoiceFileVO[] { delVO });
			}
		} catch (Exception e) {

			Throwable src = ExceptionUtils.unmarsh(e);
			SSCIVMLogger.error(src.getMessage(), src);
			Map<String, Object> result = new HashMap<String, Object>();
			result.put(SSCIVMPubConst.SUCCESS, false);
			result.put(IVMInvoiceFileVO.PK_INVOICE_FILE, fileVO.getPk_invoice_file());
			result.put(IVMInvoiceFileVO.VIEWURL, getPreViewUrl(fileVO.getViewurl()));
			result.put(SSCIVMPubConst.MESSAGE, src.getMessage());
			result.put(SSCIVMPubConst.EDIT, false);
			result.put(SSCIVMPubConst.IGNORE, true);
			result.put(IVMInvoiceFileVO.FILENAME, fileVO.getFilename());
			results.add(result);

			// 报错回滚税务云
			try {
				if (invoiceIds.size() > 0) {
					this.getIVRecService().deleteIVMInvoicesByIds(invoiceIds.toArray(new String[0]));
				}

			} catch (BusinessException e1) {
				SSCIVMLogger.error(e1.getMessage(), e1);
			}
		} finally {
			// 删除电票
			try {
				if (dels.size() > 0) {
					this.getIVRecService().deleteIVMInvoices(dels, pk_org);
				}
			} catch (BusinessException e1) {
				SSCIVMLogger.error(e1.getMessage(), e1);
			}
		}

		return results;
	}

	/**
	 * 查询发票信息
	 * 
	 * @param responses
	 * @return
	 * @throws BusinessException
	 */
	private Map<String, IVMInvoiceAggVO> getInvoices(OCRAllInvoiceResponse oaresp) throws BusinessException {
		Map<String, IVMInvoiceAggVO> result = new HashMap<String, IVMInvoiceAggVO>();
		OCRInvoiceData[] datas = oaresp.getDatas();
		// 拼接查询条件
		StringBuffer sql = new StringBuffer("");
		sql.append(" dr=0 and " + IVMInvoiceHeadVO.BILLTYPECODE + "='" + IVMInvoiceConstant.IVREC_SP_TRADETYPECODE
				+ "' and (");
		for (int i = 0; i < datas.length; i++) {
			sql.append(" ( ");
			if (datas[i].getData() != null) {
				if (StringUtils.isEmpty(datas[i].getFpDm())) {
					sql.append(IVMInvoiceHeadVO.FPHM + "='" + datas[i].getFpHm() + "' ");
				} else {
					sql.append(IVMInvoiceHeadVO.FPHM + "='" + datas[i].getFpHm() + "' and " + IVMInvoiceHeadVO.FPDM
							+ "='" + datas[i].getFpDm() + "' ");
				}
			} else {
				sql.append(" 1=2 ");
			}
			sql.append(") ");
			if (i != datas.length - 1) {
				sql.append(" or ");
			}
		}
		sql.append(" ) ");

		// 查询并组装结果
		IVMInvoiceAggVO[] vos = NCLocator.getInstance().lookup(IVMInvoiceQueryService.class)
				.queryAggVOsByCondition(sql.toString());
		if (vos == null || vos.length == 0) {
			return result;
		}
		for (IVMInvoiceAggVO vo : vos) {
			result.put(vo.getParentVO().getFphm(), vo);
		}
		return result;
	}

	/**
	 * 查询发票信息
	 * 
	 * @param responses
	 * @return
	 * @throws BusinessException
	 */
	private Map<String, IVMInvoiceAggVO> getInvoices(VerifyCommonResponse[] responses) throws BusinessException {
		Map<String, IVMInvoiceAggVO> result = new HashMap<String, IVMInvoiceAggVO>();
		// 拼接查询条件
		StringBuffer sql = new StringBuffer("");
		sql.append(" dr=0 and " + IVMInvoiceHeadVO.BILLTYPECODE + "='" + IVMInvoiceConstant.IVREC_SP_TRADETYPECODE
				+ "' and (");
		for (int i = 0; i < responses.length; i++) {
			sql.append(" ( ");
			if (responses[i].getInvoice() != null) {
				VerifyInvoiceData data = (VerifyInvoiceData) responses[i].getInvoice();
				if (StringUtils.isEmpty(data.getFpDm())) {
					sql.append(IVMInvoiceHeadVO.FPHM + "='" + data.getFpHm() + "' ");
				} else {
					sql.append(IVMInvoiceHeadVO.FPHM + "='" + data.getFpHm() + "' and " + IVMInvoiceHeadVO.FPDM + "='"
							+ data.getFpDm() + "' ");
				}
			} else {
				sql.append(" 1=2 ");
			}
			sql.append(") ");
			if (i != responses.length - 1) {
				sql.append(" or ");
			}
		}

		sql.append(" ) ");

		// 查询并组装结果
		IVMInvoiceAggVO[] vos = NCLocator.getInstance().lookup(IVMInvoiceQueryService.class)
				.queryAggVOsByCondition(sql.toString());
		if (vos == null || vos.length == 0) {
			return result;
		}
		for (IVMInvoiceAggVO vo : vos) {
			result.put(vo.getParentVO().getFphm(), vo);
		}
		return result;
	}

	/**
	 * 查询发票信息
	 * 
	 * @param responses
	 * @return
	 * @throws BusinessException
	 */
	private IVMInvoiceAggVO getInvoice(String fpdm, String fphm) throws BusinessException {

		// 拼接查询条件
		StringBuffer sql = new StringBuffer("");
		sql.append(
				" dr=0 and " + IVMInvoiceHeadVO.BILLTYPECODE + "='" + IVMInvoiceConstant.IVREC_SP_TRADETYPECODE + "' ");
		if (fpdm == null || "".equals(fpdm)) {
			sql.append(" and " + IVMInvoiceHeadVO.FPHM + "='" + fphm + "'");
		} else {
			sql.append(" and " + IVMInvoiceHeadVO.FPHM + "='" + fphm + "' and " + IVMInvoiceHeadVO.FPDM + "='" + fpdm
					+ "'");
		}

		// 查询并组装结果
		IVMInvoiceAggVO[] vos = NCLocator.getInstance().lookup(IVMInvoiceQueryService.class)
				.queryAggVOsByCondition(sql.toString());
		if (vos == null || vos.length == 0) {
			return null;
		}

		return vos[0];
	}

	/**
	 * 组装文件VO
	 * 
	 * @param ivmvo
	 * @param filevo
	 * @return
	 */
	private IVMInvoiceFileVO buildIVMInvoiceFileVO(IVMInvoiceAggVO ivmVO, IVMInvoiceFileVO fileVO) {
		IVMInvoiceHeadVO vo = ivmVO.getHeadVO();
		fileVO.setPk_invoice(vo.getPk_invoice());
		fileVO.setFpdm(vo.getFpdm());
		fileVO.setFphm(vo.getFphm());
		fileVO.setFpzl(vo.getInvoice_type());
		fileVO.setKprq(vo.getKprq());
		fileVO.setHjje(vo.getHjje());
		fileVO.setHjje(vo.getJshj());
		return fileVO;
	}

	/**
	 * 更新发票
	 * 
	 * @param ivmVO
	 * @param fileVO
	 * @throws DAOException
	 */
	private void updateInvoice(IVMInvoiceAggVO ivmVO, IVMInvoiceFileVO fileVO) throws DAOException {
		String url = fileVO.getSliceviewurl() == null ? fileVO.getViewurl() : fileVO.getSliceviewurl();
		// zip文件存储，不更新预览url
		if (FileTypeUtil.isZip(fileVO.getFilename())) {
			exeUpdate(IVMInvoiceHeadVO.ZIPURL, url, IVMInvoiceHeadVO.ZIPFILENAME, fileVO.getFilename(), null,
					ivmVO.getHeadVO().getPk_invoice());
		} else if (FileTypeUtil.isXml(fileVO.getFilename())) {// xml文件存储，不更新预览url
			exeUpdate(IVMInvoiceHeadVO.XMLURL, url, IVMInvoiceHeadVO.XMLFILENAME, fileVO.getFilename(), null,
					ivmVO.getHeadVO().getPk_invoice());
		} else if (FileTypeUtil.isOfd(fileVO.getFilename())) { // ofd文件存储
			if (StringUtils.isNotEmpty(ivmVO.getParentVO().getViewurl())) {
				exeUpdate(IVMInvoiceHeadVO.OFDURL, url, IVMInvoiceHeadVO.OFDFILENAME, fileVO.getFilename(), null,
						ivmVO.getHeadVO().getPk_invoice());
			} else {
				exeUpdate(IVMInvoiceHeadVO.OFDURL, url, IVMInvoiceHeadVO.OFDFILENAME, fileVO.getFilename(), url,
						ivmVO.getHeadVO().getPk_invoice());
			}
		} else {// 其他格式文件存储
			exeUpdate(IVMInvoiceHeadVO.VIEWURL, url, IVMInvoiceHeadVO.FILENAME, fileVO.getFilename(), null,
					ivmVO.getHeadVO().getPk_invoice());
		}
	}

	private void exeUpdate(String field1, String value1, String field2, String value2, String viewurl,
			String pk_invoice) throws DAOException {
		String sql = "update " + IVMInvoiceHeadVO.getDefaultTableName() + " set " + field1 + "='" + value1 + "', "
				+ field2 + "='" + value2 + "' ";
		if (viewurl != null) {
			sql += ", viewurl = '" + viewurl + "' ";
		}
		sql += " where pk_invoice = '" + pk_invoice + "' ";
		new BaseDAO().executeUpdate(sql);
	}

	private IIVMInvoiceFileService getIIVMInvoiceFileService() {
		return NCLocator.getInstance().lookup(IIVMInvoiceFileService.class);
	}

	@Override
	public Map<String, Object> reVerifyAnduploadInvoice(String pk_org, String pk_bill, String billtype,
			String tradetype, String fileid, JSONObject data) {
		Map<String, Object> result = new HashMap<String, Object>();

		// 组装查询接口
		RequestInfo<VerifyCommonRequest[]> request = new RequestInfo<VerifyCommonRequest[]>();
		request.setPk_org(pk_org);
		request.setBilltype(billtype);
		request.setTransitype(tradetype);
		request.setDatasource(InvocationInfoProxy.getInstance().getUserDataSource());
		request.setUserCode(InvocationInfoProxy.getInstance().getUserCode());
		request.setBillid(pk_bill);
		request.setSubmitter(InvocationInfoProxy.getInstance().getUserCode());

		VerifyCommonRequest rep = new VerifyCommonRequest();
		rep.setFpDm(data.getString(SSCIVMPubConst.FPDM));
		rep.setFpHm(data.getString(SSCIVMPubConst.FPHM));
		rep.setKprq(data.getString(IVMInvoiceHeadVO.KPRQ));
		rep.setJym(data.getString(IVMInvoiceHeadVO.JYM));
		rep.setHjje(data.getString(IVMInvoiceHeadVO.HJJE));
		rep.setJshj(data.getString(IVMInvoiceHeadVO.JSHJ));
		if (rep.getHjje() == null) {
			rep.setHjje(rep.getJshj());
		}
		rep.setBillid(pk_bill);

		request.setData(new VerifyCommonRequest[] { rep });

		Set<String> invoiceIds = new HashSet<String>();// 需要删除的发票主键
		IVMInvoiceFileVO fileVO = null;
		try {
			fileVO = getIIVMInvoiceFileService().queryByPks(new String[] { fileid })[0];
			result.put(SSCIVMPubConst.SUCCESS, true);
			result.put(IVMInvoiceFileVO.PK_INVOICE_FILE, fileid);
			result.put(IVMInvoiceFileVO.VIEWURL, getPreViewUrl(fileVO.getViewurl()));
			result.put(IVMInvoiceFileVO.FILENAME, fileVO.getFilename());
			ResponseInfo<VerifyCommonResponse[]> verifyResponse = ImageServiceUtil.doPaperBillVerifyAndUpload(request);
			VerifyCommonResponse response = verifyResponse.getData()[0];
			if (!IVMInvoiceConstant.SUCCESS_CODE.equals(response.getCode())) {// 失败
				result.put(SSCIVMPubConst.SUCCESS, false);
				result.put(SSCIVMPubConst.MESSAGE, response.getMsg());
				result.put(SSCIVMPubConst.IGNORE, true);
				result.put(SSCIVMPubConst.EDIT, true);
				result.put(SSCIVMPubConst.JOSNDATA, data);
			} else {// 成功
				IVMInvoiceAggVO ivmVO = getInvoice(rep.getFpDm(), rep.getFpHm());
				invoiceIds.add(ivmVO.getParentVO().getPk_invoice());
				result.put(IVMInvoiceHeadVO.PK_INVOICE, ivmVO.getParentVO().getPk_invoice());
				result.put(SSCIVMPubConst.IGNORE, false);
				result.put(SSCIVMPubConst.EDIT, false);
				result.put(SSCIVMPubConst.AGGVO, ivmVO);
				fileVO = buildIVMInvoiceFileVO(ivmVO, fileVO);
				// 更新发票
				updateInvoice(ivmVO, fileVO);
				// 更新文件
				getIIVMInvoiceFileService().updateVOs(new IVMInvoiceFileVO[] { fileVO });
			}
		} catch (Exception e) {
			Throwable src = ExceptionUtils.unmarsh(e);
			SSCIVMLogger.error(src.getMessage(), src);
			result.put(SSCIVMPubConst.SUCCESS, false);
			result.put(IVMInvoiceFileVO.PK_INVOICE_FILE, fileVO.getPk_invoice_file());
			result.put(IVMInvoiceFileVO.VIEWURL, getPreViewUrl(fileVO.getViewurl()));
			result.put(SSCIVMPubConst.MESSAGE, src.getMessage());
			result.put(SSCIVMPubConst.IGNORE, true);
			result.put(SSCIVMPubConst.EDIT, false);
			if (fileVO != null) {
				result.put(IVMInvoiceFileVO.FILENAME, fileVO.getFilename());
			}

			// 报错回滚税务云
			if (invoiceIds.size() > 0) {
				try {
					this.getIVRecService().deleteIVMInvoicesByIds(invoiceIds.toArray(new String[0]));
				} catch (BusinessException e1) {
					SSCIVMLogger.error(e1.getMessage(), e1);
				}
			}
		}
		return result;
	}

	@Override
	public Map<String, Object> reUploadInvoice(String pk_invoice, String pk_org, String pk_bill, String billtype,
			String tradetype, String fileid, int fplx, JSONObject data) {

		Map<String, Object> result = new HashMap<String, Object>();

		// 组装查询接口
		RequestInfo<TaxAllInvoiceRequest[]> request = new RequestInfo<TaxAllInvoiceRequest[]>();
		request.setPk_org(pk_org);
		request.setBilltype(billtype);
		request.setTransitype(tradetype);
		request.setDatasource(InvocationInfoProxy.getInstance().getUserDataSource());
		request.setUserCode(InvocationInfoProxy.getInstance().getUserCode());
		request.setBillid(pk_bill);
		request.setSubmitter(InvocationInfoProxy.getInstance().getUserCode());

		TaxAllInvoiceRequest rep = new TaxAllInvoiceRequest();

		Set<String> invoiceIds = new HashSet<String>();// 需要删除的发票主键
		IVMInvoiceFileVO fileVO = null;
		OCRRecordVO ocrdata = null;
		try {
			fileVO = getIIVMInvoiceFileService().queryByPks(new String[] { fileid })[0];
			// 删除发票
			if (StringUtils.isNotEmpty(pk_invoice)) {
				getIVRecService().deleteIVMInvoicesByIds(new String[] { pk_invoice });
			}

			// 组装参数
			ocrdata = getISSCOCRRecordService().queryRecords(OCRRecordVO.TOKEN + "='" + fileVO.getToken() + "'")[0];
			JSONObject invoice = buildInvoice(ocrdata, rep, fplx, data);
			rep.setSaveToken(fileVO.getToken());
			request.setData(new TaxAllInvoiceRequest[] { rep });
			result.put(SSCIVMPubConst.SUCCESS, true);
			result.put(IVMInvoiceFileVO.PK_INVOICE_FILE, fileid);
			result.put(IVMInvoiceFileVO.FILENAME, fileVO.getFilename());
			result.put(IVMInvoiceFileVO.VIEWURL, getPreViewUrl(fileVO.getViewurl()));
			ResponseInfo<TaxCommonResponse[]> verifyResponse = ImageServiceUtil.doPaperBillUpload(request);
			TaxCommonResponse response = verifyResponse.getData()[0];
			if (!IVMInvoiceConstant.SUCCESS_CODE.equals(response.getCode())) {// 失败
				result.put(SSCIVMPubConst.SUCCESS, false);
				result.put(SSCIVMPubConst.MESSAGE, response.getMsg());
				result.put(SSCIVMPubConst.IGNORE, true);
				result.put(SSCIVMPubConst.EDIT, true);
				result.put(SSCIVMPubConst.JOSNDATA, ocrdata);
			} else {// 成功
				IVMInvoiceAggVO ivmVO = getInvoice(rep.getFpDm(), rep.getFpHm());
				invoiceIds.add(ivmVO.getParentVO().getPk_invoice());
				result.put(IVMInvoiceHeadVO.PK_INVOICE, ivmVO.getParentVO().getPk_invoice());
				result.put(SSCIVMPubConst.IGNORE, false);
				result.put(SSCIVMPubConst.EDIT, true);
				result.put(SSCIVMPubConst.AGGVO, ivmVO);
				fileVO = buildIVMInvoiceFileVO(ivmVO, fileVO);
				// 更新发票
				updateInvoice(ivmVO, fileVO);
				// 更新文件
				getIIVMInvoiceFileService().updateVOs(new IVMInvoiceFileVO[] { fileVO });
			}
		} catch (Exception e) {
			Throwable src = ExceptionUtils.unmarsh(e);
			SSCIVMLogger.error(src.getMessage(), src);
			result.put(SSCIVMPubConst.SUCCESS, false);
			result.put(IVMInvoiceFileVO.PK_INVOICE_FILE, fileVO.getPk_invoice_file());
			result.put(IVMInvoiceFileVO.VIEWURL, getPreViewUrl(fileVO.getViewurl()));
			result.put(SSCIVMPubConst.MESSAGE, src.getMessage());
			result.put(SSCIVMPubConst.IGNORE, true);
			result.put(SSCIVMPubConst.EDIT, false);
			if (fileVO != null) {
				result.put(IVMInvoiceFileVO.FILENAME, fileVO.getFilename());
			}

			// 上传成功后，ncc报错回滚税务云
			if (invoiceIds.size() > 0) {
				try {
					this.getIVRecService().deleteIVMInvoicesByIds(invoiceIds.toArray(new String[0]));
				} catch (Exception e1) {
					SSCIVMLogger.error(e1.getMessage(), e1);
				}
			}
			// 还原税务云发票数据
			if (StringUtils.isNotEmpty(pk_invoice) && ocrdata != null) {
				try {
					rep.setData(JSONObject.parseObject(ocrdata.getInvoice().toString()));
					request.setData(new TaxAllInvoiceRequest[] { rep });
					ImageServiceUtil.doPaperBillUploadToTax(request);
				} catch (Exception e1) {
					SSCIVMLogger.error(e1.getMessage(), e1);
				}
			}
		}
		return result;
	}

	/**
	 * 构建发票的json 数据
	 * 
	 * @param vo
	 * @param rep
	 * @return
	 * @throws BusinessException
	 */
	private JSONObject buildInvoice(OCRRecordVO vo, TaxAllInvoiceRequest rep, int fplx, JSONObject data)
			throws BusinessException {
		JSONObject invoice = JSONObject.parseObject(vo.getInvoice().toString());
		rep.setImageId(invoice.getString(SSCIVMPubConst.IMAGEID));
		for (String key : data.keySet()) {
			if (!SSCIVMPubConst.ITEMLIST.equals(key)) {
				invoice.put(key, data.get(key));
			}
		}

		// 表体行合并
		if (invoice.containsKey(SSCIVMPubConst.ITEMLIST)) {
			JSONArray dataItemList = data.getJSONArray(SSCIVMPubConst.ITEMLIST);
			invoice.put(SSCIVMPubConst.ITEMLIST, dataItemList);
		}
		rep.setData(invoice);
		rep.setBillType(new InvoiceExtFullFaceUtil().changeInvoiceType(fplx));
		return invoice;
	}

	/**
	 * 获取预览的url
	 * 
	 * @param url
	 * @return
	 */
	private String getPreViewUrl(String url) {
		String preurl = FileStorageClient.getInstance().getPreUrl(IVMInvoiceConstant.SSCIVM_BUCKET, url, null,
				"isView=true&versionno=0&GetPreViewFileMode=" + GetPreViewFileModeEnum.MODE20);
		return preurl.replace("/files/", "/ufiles/");
	}

	/**
	 * 获取业务类型
	 * 
	 * @param billtype
	 * @return
	 */
	private String getBusiFlag(String billtype) {
		String busiflag = "1";
		if (billtype != null && billtype.startsWith(SSCIVMPubConst.BX)) {
			busiflag = "0";
		}
		return busiflag;
	}

	private ISSCOCRRecordService getISSCOCRRecordService() {
		return NCLocator.getInstance().lookup(ISSCOCRRecordService.class);
	}

	private IVRecService getIVRecService() {
		return NCLocator.getInstance().lookup(IVRecService.class);
	}

	@Override
	public List<Map<String, Object>> queryInvoices(String billid) {

		List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
		// 查询发票
		String condition = "pk_invoice in (select pk_invoice " + "from sscivm_invoice_relation where billid = '"
				+ billid + "') and cjfs = 1 ";
		try {
			IVMInvoiceAggVO[] invoices = NCLocator.getInstance().lookup(IVMInvoiceQueryService.class)
					.queryAggVOsByCondition(condition);
			if (invoices == null || invoices.length == 0) {
				return results;
			}

			// 查询文件
			Set<String> ids = new HashSet<String>();
			for (IVMInvoiceAggVO invoice : invoices) {
				ids.add(invoice.getParentVO().getPk_invoice());
			}
			IVMInvoiceFileVO[] vos = this.getIIVMInvoiceFileService().queryByInvoiceIds(ids.toArray(new String[0]));

			// 建立关系
			Map<String, List<IVMInvoiceFileVO>> ivFileMap = new HashMap<String, List<IVMInvoiceFileVO>>();
			if (vos != null && vos.length > 0) {
				for (IVMInvoiceFileVO vo : vos) {
					List<IVMInvoiceFileVO> list = ivFileMap.get(vo.getPk_invoice());
					if (list == null) {
						list = new ArrayList<>();
					}
					list.add(vo);
					ivFileMap.put(vo.getPk_invoice(), list);
				}
			}

			// 组装返回值
			for (IVMInvoiceAggVO invoice : invoices) {
				IVMInvoiceHeadVO headvo = invoice.getHeadVO();
				Map<String, Object> result = new HashMap<String, Object>();
				List<IVMInvoiceFileVO> fileVOS = ivFileMap.get(headvo.getPk_invoice());
				result.put(SSCIVMPubConst.SUCCESS, true);
				if (fileVOS != null && fileVOS.size() > 0) {
					if (fileVOS.size() == 1) {
						result.put(IVMInvoiceFileVO.PK_INVOICE_FILE, fileVOS.get(0).getPk_invoice_file());
						result.put(IVMInvoiceFileVO.FILENAME, fileVOS.get(0).getFilename());
						result.put(IVMInvoiceFileVO.VIEWURL,
								getPreViewUrl(fileVOS.get(0).getSliceviewurl() == null ? fileVOS.get(0).getViewurl()
										: fileVOS.get(0).getSliceviewurl()));
					} else {
						String invoiceFile = "";
						for (int i = 0; i < fileVOS.size() - 1; i++) {
							invoiceFile += fileVOS.get(i).getPk_invoice_file();
							if (i != fileVOS.size() - 1) {
								invoiceFile += ",";
							}
						}
						result.put(IVMInvoiceFileVO.PK_INVOICE_FILE, invoiceFile);
						result.put(IVMInvoiceFileVO.FILENAME, fileName(headvo));
						result.put(IVMInvoiceFileVO.VIEWURL, getPreViewUrl(headvo.getViewurl()));
					}

				} else {
					result.put(IVMInvoiceFileVO.FILENAME, fileName(headvo));
					result.put(IVMInvoiceFileVO.VIEWURL, getPreViewUrl(headvo.getViewurl()));
				}

				result.put(IVMInvoiceHeadVO.PK_INVOICE, headvo.getPk_invoice());
				result.put(SSCIVMPubConst.IGNORE, false);
				if (InvoiceTypeEnum.getVerifyInvoice().contains(String.valueOf(headvo.getInvoice_type()))
						|| (fileVOS != null && fileVOS.size() > 0
								&& FileTypeUtil.isDZType(fileVOS.get(0).getFilename()))) {// 成功增值税，电子票据不可修改，非增值税可以修改
					result.put(SSCIVMPubConst.EDIT, false);
				} else {
					result.put(SSCIVMPubConst.EDIT, true);
				}
				result.put(SSCIVMPubConst.AGGVO, invoice);
				results.add(result);
			}

		} catch (BusinessException e) {
			Throwable src = ExceptionUtils.unmarsh(e);
			SSCIVMLogger.error(src.getMessage(), src);
		}
		return results;
	}

	/**
	 * 获取文件名
	 * 
	 * @param headvo
	 * @return
	 */
	private String fileName(IVMInvoiceHeadVO headvo) {
		String fileName = "";

		// 原始名称
		if (StringUtils.isNotEmpty(headvo.getFilename())) {
			fileName += headvo.getFilename();
		}

		// ofd
		if (StringUtils.isNotEmpty(headvo.getOfdfilename())) {
			if (StringUtils.isNotEmpty(fileName)) {
				fileName += "/";
			}
			fileName += headvo.getOfdfilename();
		}

		// xml
		if (StringUtils.isNotEmpty(headvo.getXmlfilename())) {
			if (StringUtils.isNotEmpty(fileName)) {
				fileName += "/";
			}
			fileName += headvo.getXmlfilename();
		}

		// zip
		if (StringUtils.isNotEmpty(headvo.getZipfilename())) {
			if (StringUtils.isNotEmpty(fileName)) {
				fileName += "/";
			}
			fileName += headvo.getZipfilename();
		}
		return fileName;
	}

	@Override
	public Map<String, Object> upload(String pk_org, String pk_bill, String billtype, String tradetype, String fileName,
			String fileContent) {

		Map<String, Object> result = new HashMap<String, Object>();

		RequestInfo<EOCRCommonRequest[]> request = new RequestInfo<>();
		request.setPk_org(pk_org);
		request.setBilltype(billtype);
		request.setTransitype(tradetype);
		request.setDatasource(InvocationInfoProxy.getInstance().getUserDataSource());
		request.setUserCode(InvocationInfoProxy.getInstance().getUserCode());

		EOCRCommonRequest rep = new EOCRCommonRequest();
		rep.setBillid(pk_bill);
		rep.setFile(fileContent);
		rep.setFileName(fileName);

		request.setData(new EOCRCommonRequest[] { rep });

		PInvoice invoice = null;
		String pk_invoice = "";
		try {
			ResponseInfo<VerifyCommonResponse[]> responseInfo = ImageServiceUtil.doEVerifyAndUpload(request);
			if (!IVMInvoiceConstant.SUCCESS_CODE.equals(responseInfo.getCode())) {
				throw new BusinessException(responseInfo.getMessage());
			}
			VerifyCommonResponse[] res = responseInfo.getData();
			invoice = (PInvoice) res[0].getInvoice();
			// @全电发票@@特殊票种电子凭证@ begin
			String condition = "fphm = '" + invoice.getFpHm() + "' and fpdm = '" + invoice.getFpDm() + "'"
					+ " and dr=0 and " + IVMInvoiceHeadVO.BILLTYPECODE + "='"
					+ IVMInvoiceConstant.IVREC_SP_TRADETYPECODE + "'";
			if (invoice.getFpDm() == null || "".equals(invoice.getFpDm())) {
				condition = "fphm = '" + invoice.getFpHm() + "' and dr=0 and " + IVMInvoiceHeadVO.BILLTYPECODE + "='"
						+ IVMInvoiceConstant.IVREC_SP_TRADETYPECODE + "'";
			}
			// @全电发票@@特殊票种电子凭证@ end
			IVMInvoiceAggVO[] invoices = NCLocator.getInstance().lookup(IVMInvoiceQueryService.class)
					.queryAggVOsByCondition(condition);
			pk_invoice = invoices[0].getHeadVO().getPk_invoice();

			uploadFileToFileSystem(fileName, fileContent, invoices[0]);

		} catch (Exception e) {
			Throwable src = ExceptionUtils.unmarsh(e);
			result.put("success", false);
			result.put("message", src.getMessage() == null ? e.getMessage() : src.getMessage());
			invoice = new PInvoice();
		}

		Map<String, Object> data = getInvoiceJSONData(invoice, fileName);

		data.put("pk_invoice", pk_invoice);

		result.put("data", data);

		return result;
	}

	private void uploadFileToFileSystem(String fileName, String content, IVMInvoiceAggVO agg) throws BusinessException {

		try {
			Base64 base64 = new Base64();
			// 上传成功后，将文件存储到文件服务器
			FileHeader fileHeader = NCLocator.getInstance().lookup(IAttachmentService.class).upload(fileName,
					new ByteArrayInputStream(base64.decode(content)), false, 0, IVMInvoiceConstant.SSCIVM_BUCKET);
			if (fileHeader == null) {
				throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("1058pub_0",
						"01058pub-0052")/* @res "上传电子发票到文件服务出现错误。" */);
			}
//			NCLocator.getInstance().lookup(IVMInvoiceService.class).update(agg, null);
			new BaseDAO().executeUpdate("update " + IVMInvoiceHeadVO.getDefaultTableName() + " set viewurl = '"
					+ fileHeader.getPath() + "' where pk_invoice = '" + agg.getHeadVO().getPk_invoice() + "'");

		} catch (Exception e) {
			// 新事务删除已经上传的发票
			NCLocator.getInstance().lookup(IVRecService.class)
					.deleteIVMInvoices_RequiresNew(new String[] { agg.getHeadVO().getPk_invoice() });
			throw new BusinessException(e.getMessage(), e);
		}

	}
}
