/**
 * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.modules.sg.financial.erpcredit.web;

import com.jeeplus.common.json.AjaxJson;
import com.jeeplus.common.utils.DateUtils;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.common.utils.excel.ExportExcel;
import com.jeeplus.core.persistence.Page;
import com.jeeplus.core.web.BaseController;
import com.jeeplus.modules.sg.audit.information.entity.Information;
import com.jeeplus.modules.sg.audit.information.service.InformationService;
import com.jeeplus.modules.sg.financial.erpcredit.entity.*;
import com.jeeplus.modules.sg.financial.erpcredit.service.ErpCreditService;
import com.jeeplus.modules.sg.financial.erpcredit.util.*;
import com.jeeplus.modules.sg.financial.expense.entity.Expense;
import com.jeeplus.modules.sg.financial.expense.service.ExpenseService;
import com.jeeplus.modules.sg.financial.settlement.entity.MaintainData;
import com.jeeplus.modules.sg.financial.settlement.service.DataMaintenanceService;
import com.jeeplus.modules.sg.managementcenter.project.entity.Project;
import com.jeeplus.modules.sg.managementcenter.project.service.ProjectService;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 数据维护
 */
@Controller
@RequestMapping(value = "${adminPath}/sg/financial/erpCredit")
public class ErpCreditController extends BaseController {

	@Autowired
	private ErpCreditService erpCreditService;
	@Autowired
	private DataMaintenanceService dataMaintenanceService;
	@Autowired
	private ExpenseService expenseService;
	@Autowired
	private ProjectService projectService;
	@Autowired
	private InformationService informationService;

	@ModelAttribute
	public ErpCredit get(@RequestParam(required=false) String id) {
		ErpCredit entity = null;
		if (StringUtils.isNotBlank(id)){
			entity = erpCreditService.get(id);
		}
		if (entity == null){
			entity = new ErpCredit();
		}
		return entity;
	}
	/**
	 * 表单列表页面
	 */
	@RequiresPermissions("sg:financial:erpCredit:list")
	@RequestMapping(value = {"list", ""})
	public String list(ErpCredit erpCredit, Model model) {
		model.addAttribute("erpCredit", erpCredit);
		return "modules/sg/financial/erp/erpCreditList";
	}

	/**
	 * 表单列表数据
	 */
	@ResponseBody
	@RequiresPermissions("sg:financial:erpCredit:list")
	@RequestMapping(value = "data")
	public Map<String, Object> data(ErpCredit erpCredit, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception{
		Page<ErpCredit> page = null;
		page = erpCreditService.findPage(new Page<ErpCredit>(request, response), erpCredit);
		return getBootstrapData(page);
	}

	/**
	 * 查看，增加，编辑表单表单页面
	 */
	@RequiresPermissions(value={"sg:financial:erpCredit:view","sg:financial:erpCredit:add","sg:financial:erpCredit:edit"},logical= Logical.OR)
	@RequestMapping(value = "form")
	public String form(ErpCredit erpCredit, Model model) {
		model.addAttribute("erpCredit", erpCredit);
		return "modules/sg/financial/erp/erpCreditForm";
	}

	/**
	 * 项目明细账对应甲供材、费用入账信息存在性验证不通过提示页面
	 * @param model
	 * @param request
	 * @param response
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	@RequestMapping(value = "tips")
	public String Tips(Model model, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
//		String ftpErpList = erpCreditService.getFtpErpList(request);
//		String[] split = ftpErpList.split(",");
//		List<ErpJudgeAccount> erpJudgeAccounts = new ArrayList<ErpJudgeAccount>();
//		ErpJudgeAccount erpJudgeAccount = null;
//		for (int i = 0; i < split.length; i+=4) {
//			erpJudgeAccount = new ErpJudgeAccount();
//			erpJudgeAccount.setItemId(split[i]);
//			erpJudgeAccount.setItemName(split[i+1]);
//			erpJudgeAccount.setFlagItem(split[i+2]);
////			erpJudgeAccount.setItemSupplierName(split[i+3]);
//			erpJudgeAccounts.add(erpJudgeAccount);
//		}
//		List<ErpJudgeAccount> judgeAccountList = ValidationUtils.getJudgeList(request);
		List<ErpJudgeAccount> judgeAccountList = ValidationUtils.getSessionRedisList(request,ValidationUtils.JUDGE_KEY_PREFIX,ErpJudgeAccount.class);
		model.addAttribute("erpJudgeAccounts",judgeAccountList);
		return "modules/sg/financial/erp/erpCreditTips";
	}

	/**
	 *费用入账 应付金额>实付金额 提示页面
	 * @param model
	 * @param request
	 * @param response
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	@RequestMapping(value = "tips1")
	public String Tips1(Model model, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
//		String ftpErpList = erpCreditService.getFtpErpList(request);
//		String[] split = ftpErpList.split(",");
//		List<ErpJudgeArtificial> erpJudgeArtificials = new ArrayList<ErpJudgeArtificial>();
//		ErpJudgeArtificial erpJudgeArtificial = null;
//		for (int i = 0; i < split.length; i+=2) {
//			erpJudgeArtificial = new ErpJudgeArtificial();
//			erpJudgeArtificial.setItemId(split[i]);
//			erpJudgeArtificial.setNotTheSame(split[i+1]);
//			erpJudgeArtificials.add(erpJudgeArtificial);
//		}
		List<ErpJudgeArtificial> erpJudgeArtificials = ValidationUtils.getSessionRedisList(request,ValidationUtils.ARTIFICIAL_KEY_PREFIX,ErpJudgeArtificial.class);
		model.addAttribute("erpJudgeArtificials",erpJudgeArtificials);
		return "modules/sg/financial/erp/erpTipsUserJudge";
	}
	/**
	 * 保存表单
	 */
	@ResponseBody
	@RequiresPermissions(value={"sg:financial:erpCredit:add","sg:financial:erpcredit:edit"},logical=Logical.OR)
	@RequestMapping(value = "save")
	public AjaxJson save(ErpCredit erpCredit, Model model,HttpServletRequest request, HttpServletResponse response) throws Exception{
		AjaxJson j = new AjaxJson();
		/**
		 * 后台hibernate-validation插件校验
		 */
		String errMsg = beanValidator(erpCredit);
		if (StringUtils.isNotBlank(errMsg)){
			j.setSuccess(false);
			j.setMsg(errMsg);
			return j;
		}
		//新增或编辑表单保存
		erpCreditService.save(erpCredit);
		j.setSuccess(true);
		j.setMsg("保存表单成功");
		return j;
	}

	/**
	 * 删除表单
	 */
	@ResponseBody
	@RequiresPermissions("sg:financial:erpCredit:del")
	@RequestMapping(value = "delete")
	public AjaxJson delete(ErpCredit erpCredit) {
		AjaxJson j = new AjaxJson();
		erpCreditService.delete(erpCredit);
		j.setMsg("删除表单成功");
		return j;
	}

	/**
	 * 批量表单
	 */
	@ResponseBody
	@RequiresPermissions("sg:financial:erpCredit:del")
	@RequestMapping(value = "deleteAll")
	public AjaxJson deleteAll(String ids) {
		AjaxJson j = new AjaxJson();
		String idArray[] =ids.split(",");
		for(String id : idArray){
			erpCreditService.delete(erpCreditService.get(id));
		}
		j.setMsg("删除表单成功");
		return j;
	}

    /**
	 * 导出excel列表文件
	 */
	@ResponseBody
	@RequiresPermissions("sg:financial:erpCredit:export")
	@RequestMapping(value = "exportList")
	public Result exportFileList(ErpCredit erpCredit,HttpServletRequest request, HttpServletResponse response){
		Result j = new Result();
		try {
			String fileName = "送审决算信息"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
			Page<ErpCredit> page = erpCreditService.findPage(new Page<ErpCredit>(request, response, -1), erpCredit);
			new ExportExcel("送审决算信息", ErpCredit.class).setDataList(page.getList()).write(response, fileName).dispose();

			j.setSuccess(true);
			j.setMsg("导出成功！");
		}catch (Exception e){
			j.setSuccess(false);
			j.setMsg("导出失败！失败信息："+e.getMessage());
		}
		return j;
	}
	/**
	 * 导出费用入账验证中 实付金额>应付金额 部分的信息
	 */
	@ResponseBody
	@RequestMapping(value = "exportYesStatus")
	public Result exportYesStatus(ErpCredit erpCredit,HttpServletRequest request, HttpServletResponse response){
		Result j = new Result();
		try {
			String fileName = "费用入账差异信息"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
//			String ftpErpList = erpCreditService.getFtpErpList(request);
//			List<ErpJudgeExport> erpJudgeExport = ValidationUtils.getErpJudgeExport(ftpErpList);
			List<ErpJudgeExport> exportList = ValidationUtils.getSessionRedisList(request,ValidationUtils.EXPENSE_KEY_PREFIX,ErpJudgeExport.class);
			new ExportExcel("费用入账差异信息", ErpJudgeExport.class).setDataList(exportList).write(response, fileName).dispose();
			j.setSuccess(true);
			j.setMsg("导出成功！");
		}catch (Exception e){
			j.setSuccess(false);
			j.setMsg("导出失败！失败信息："+e.getMessage());
		}
		return j;
	}
	@RequestMapping(value = "clearFileAllSession")
	public void clearFileAllFtp(HttpServletRequest request, HttpServletResponse response){
		HttpSession session = request.getSession();
		Object erpCreditsList = session.getAttribute("erpCreditsList");
		if (null!=erpCreditsList&&erpCreditsList!=""){
			session.removeAttribute("erpCreditsList");
		}
	}

	/**
	 * 导出excel文件
	 */
	@ResponseBody
	@RequiresPermissions("sg:financial:erpCredit:export")
	@RequestMapping(value = "export")
	public Result exportFile(HttpServletRequest request, HttpServletResponse response){
		Result j = new Result();
		HttpSession session = request.getSession();
		try {
//			List<ErpCredit> erpCreditsList = (List<ErpCredit>)session.getAttribute("erpCreditsList");
//			erpCreditService.getExport(erpCreditsList,response);
			erpCreditService.getExport(request,response);
			j.setSuccess(true);
			j.setMsg("导出成功！");
		}catch (Exception e){
			j.setSuccess(false);
			j.setMsg("导出失败！失败信息："+e.getMessage());
		}
		Object erpCreditsList = session.getAttribute("erpCreditsList");
		if (null!=erpCreditsList&&erpCreditsList!=""){
			session.removeAttribute("erpCreditsList");
		}
		return j;
	}


	/**
	 * 获取erpCredit完整信息（包括设备、物料）
	 * @param id
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "detail")
	public ErpCredit detail(String id) {
		return erpCreditService.get(id);
	}


	/**
	 * 导入erp明细账
	 */
	@ResponseBody
	@RequiresPermissions("sg:financial:erpCredit:import")
	@RequestMapping(value = "import")
	public Result importFile (@RequestParam("file")MultipartFile file, HttpServletResponse response, HttpServletRequest request,Model model){
		Result j = new Result();
		String str = "";
		try {
//			int successNum = 0;
//			int failureNum = 0;
			StringBuilder failureMsg = new StringBuilder();
//			读取第一个页签 根据表头两个字段判断是否符合规范。。
			ImportUtil importUtil = new ImportUtil(file, 0, 0);
            Boolean erpJugde = ErpInfo.getErpJugde(importUtil);
            if (erpJugde){
                j.setSuccess(false);
                j.setMsg("导入失败！失败信息："+"表不符合规范");
                return j;
            }
//            获取明细账数据 一个ErpAccount对象表示一行有效数据
			List<ErpAccount> erpAccounts = ErpInfo.getErpAccount(importUtil);
//            获取明细账处理数据 对应送审决算列表页面
			List<ErpCredit> erpCredits = ErpInfo.getAllErpCreditList(erpAccounts);//获取单条数据
			//可导出判断标志，只要概预算信息存在，且全都是资本项目就可以导出
//			boolean exportAble = true;
			//不能导出原因  同时验证所有项目都是资本项目
			String unExportMsg = ValidationUtils.verifyCapital(erpCredits);
			if(!"".equals(unExportMsg)){
				j.setSuccess(false);
				j.setMsg(unExportMsg);
				return j;
			}
			//根据credits的id查找对应概预算信息 若找到的概预算数量少于credits数量，说明存在无概预算信息项目
			List<String> ids = ValidationUtils.getItemIds(erpCredits);
			List<MaintainData> maintainDataList = erpCreditService.getFindListMain(ids);
			unExportMsg = ValidationUtils.verifyMaintain(ids,maintainDataList);
			if(!"".equals(unExportMsg)){
				j.setSuccess(false);
				j.setMsg(unExportMsg);
				return j;
			}
			ValidationUtils.storeListToRedis(request,erpCredits,ValidationUtils.CREDIT_KEY_PREFIX);
			erpCreditService.replaceAll(erpCredits);

            //需求基本信息验证
//            List<Project> project1s = projectService.findList(new Project());
//			String projectJudge = ValidationUtils.getProjectJudge(erpCredits, project1s);
//            if (!"".equals(projectJudge)){
//                erpCreditService.getFtpList(request,projectJudge);
////                j.setSuccess(false);
//                j.setSuccess(true);
//                j.setFlag(true);
//                j.setMsg("无需求基本信息数据");
//                return j;
//            }
            //项目资本和成本验证
//			String theCostOfCapital = ValidationUtils.getTheCostOfCapital(erpCredits, project1s);
//			if (theCostOfCapital.equals("3")){
//				j.setSuccess(false);
//				j.setMsg("导入失败,项目不能同时存在资本和成本!");
//				return j;
//			}
//			//验证概预算信息方法
//			List<MaintainData> maintainDatas = dataMaintenanceService.getJudge();//所有概预算信息
//			String dataMainJudge = ValidationUtils.getDataMainJudge(erpCredits, maintainDatas);
//            if (!"".equals(dataMainJudge)){
//                erpCreditService.getFtpList(request,dataMainJudge);
////                j.setSuccess(false);
//                j.setSuccess(false);
//                j.setFlag(true);
//                j.setMsg("概预算信息没有项目数据");
//                return j;
//            }
//			if(!"".equals(dataMainJudge)){
//				exportAble = false;
//				unExportMsg = "概预算信息没有项目数据";
//			}
			//查询费用入账所有信息
//			List<Expense> expenses = expenseService.findList(new Expense());
//			String expenseJudge = ValidationUtils.getExpenseJudge(erpCredits, expenses);
//            if (!"".equals(expenseJudge)){
//                erpCreditService.getFtpList(request,expenseJudge);
//                j.setSuccess(false);
//                j.setFlag(true);
//                j.setMsg("费用入账没有项目信息数据");
//                return j;
//            }
//			//验证甲供材
//			List<Information> informationList = informationService.findList(new Information());
//			String informationJudge = ValidationUtils.getInformationJudge(erpCredits, informationList);
//            if (!"".equals(informationJudge)){
//                erpCreditService.getFtpList(request,informationJudge);
//                j.setSuccess(false);
//                j.setFlag(true);
//                j.setMsg("甲供物资核实没有项目信息数据");
//                return j;
//            }
//			List<Information> infoFlag = erpCreditService.getInfoFlag(erpCredits);
//			String informationJudge1 = ValidationUtils.getInformationJudge1(erpCredits, infoFlag);
//            if (!"".equals(informationJudge1)){
//                erpCreditService.getFtpList(request,informationJudge1);
//                j.setSuccess(false);
//                j.setFlag(true);
//                j.setMsg("甲供物资核实没有完成施工项目");
//                return j;
//            }

            Map<String,ErpJudgeAccount> judgeAccountMap = new HashMap<>();
            //验证费用入账信息 若明细账中项目找不到费用入账信息 则生成一个验证信息对象存入map
            List<Expense> expenseList = expenseService.getFindListMain(ids);
            ValidationUtils.verifyExpense(erpCredits,expenseList,judgeAccountMap);
            //验证甲供材信息 无甲供材信息、有但为完成领退料 分别验证
            List<Information> hasInfosList = informationService.getFindListMain(ids);
            List<Information> notFinishList = informationService.findNoFinishList(ids);
			ValidationUtils.verifyInformation(erpCredits,hasInfosList,notFinishList,judgeAccountMap);
			if(judgeAccountMap.size()>0){
				List<ErpJudgeAccount> judgeList = new ArrayList<>(judgeAccountMap.values());
				ValidationUtils.storeListToRedis(request,judgeList,ValidationUtils.JUDGE_KEY_PREFIX);
				j.setSuccess(true);
				j.setFlag(true);//flag为true表示 费用入账或甲供材存在性验证不通过
				return j;
			}

			//整合 验证费用入账模块
//			List<Expense> expenseList = CostAccountUnits.getQCExpense(erpCredits,expenses);//库存信息区分2020年前和年后
//			CostAccountUnits.judgeTime(expenseList);
			//得到验证数据
//			Map<String, List<ErpCredit>> judgeEnterAccount = CostAccountUnits.getJudgeEnterAccount(erpCredits, expenseList, informationList, maintainDatas);
			//若应付金额（不含税价）<实付金额（不含税价）,需要导出差异情况，同时费用入账核实存在问题。
//			List<ErpCredit> listThree = judgeEnterAccount.get("judgeEnterAccountThree");
//			String judgeThree = ValidationUtils.getJudgeThree(listThree);
//			if (!"".equals(listThree)){
//				erpCreditService.getFtpList(request,judgeThree);
//				j.setSuccess(false);
//				j.setYesStatus(true);
//				j.setMsg("导入失败：费用入账存在差异信息，正在导出差异信息");
//				return j;
//			}
			Map<String, List<ErpCredit>> judgeMap = CostAccountUnits.getJudgeMap(erpCredits, expenseList, hasInfosList, maintainDataList);
			List<ErpCredit> overpayCredits = judgeMap.get(CostAccountUnits.OVER_PAY_LIST_KEY);
			List<ErpJudgeExport> overpayExports = ValidationUtils.getOverPayExportList(overpayCredits);
			if(overpayExports.size()>0){
				ValidationUtils.storeListToRedis(request,overpayExports,ValidationUtils.EXPENSE_KEY_PREFIX);
				j.setSuccess(true);
				j.setFlag(false);
				j.setYesStatus(true);//这里yesStatus为true表示有实际付款>应付金额的情况存在
				j.setMsg("费用入账存在差异信息，正在导出差异信息");
				return j;
			}
			List<ErpCredit> paylessCredits = judgeMap.get(CostAccountUnits.PAY_LESS_LIST_KEY);
			List<ErpJudgeArtificial> paylessArtificials = ValidationUtils.getPayLessArtificialList(paylessCredits);
			if(paylessArtificials.size()>0){
				ValidationUtils.storeListToRedis(request,paylessArtificials,ValidationUtils.ARTIFICIAL_KEY_PREFIX);
				j.setSuccess(true);
				j.setFlag(false);
				j.setYesStatus(false);
				j.setNoStatus(true);//这里nostatus为true表示有应付金额>实付金额的情况存在
				j.setMsg("");
				return j;
			}
//			if ("".equals(judgeTwo)){
//				erpCreditService.getFtpList(request,judgeTwo);
//				j.setSuccess(false);
//				j.setFlag(false);
//				j.setNoStatus(true);
//				j.setMsg("部分数据（应付金额>实付金额）,请人工判断");
//				return j;
//			}
//
//			request.getSession().setAttribute("erpCreditsList",erpCredits);
//			String random  = ErpInfo.getStatus();
//            erpCreditService.deleteAll();//清空原来表数据
//			for (int i = 0; i < erpCredits.size()/1000+1; i++) {
//				int end=(i+1)*1000;
//				if (end>erpCredits.size()){
//					end=erpCredits.size();
//				}
//				List<ErpCredit> erpCredits1 = erpCredits.subList(i * 1000, end);
//				erpCreditService.saveList(erpCredits1,random);
//			}
////			若应付金额（不含税价）>实付金额（不含税价）,需要进入人工判断，若人工判断通过，则费用入账核实无问题，若人工判断不通过则费用入账核实存在问题
//			List<ErpCredit> listTwo = judgeEnterAccount.get("judgeEnterAccountTwo");
//			String judgeTwo = ValidationUtils.getJudgeTwo(listTwo);
//			if ("".equals(judgeTwo)){
//				erpCreditService.getFtpList(request,judgeTwo);
//				j.setSuccess(false);
//				j.setFlag(false);
//				j.setNoStatus(true);
//				j.setMsg("部分数据（应付金额>实付金额）,请人工判断");
//				return j;
//			}
////			允许项目关闭
//			if (theCostOfCapital.equals("0")){
//				j.setSuccess(true);
//				j.setMsg("导入成功：允许项目关闭");
//				return j;
//			}
//			if (failureNum>0){
//				failureMsg.insert(0, "，失败 "+erpCredits.size()+" 条送审决算记录。");
//			}
			j.setMsg( "已成功导入 "+erpCredits.size()+" 条送审决算记录"+failureMsg);
		} catch (Exception e) {
			j.setSuccess(false);
			j.setMsg("导入送审决算失败！失败信息："+e.getMessage());
		}
		return j;
	}
}