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

import com.google.common.collect.Maps;
import com.jeeplus.common.persistence.Page;
import com.jeeplus.common.service.CrudService;
import com.jeeplus.common.utils.Collections3;
import com.jeeplus.common.utils.MenuStatusEnum;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.common.websocket.onchat.ChatServerPool;
import com.jeeplus.common.websocket.utils.Constant;
import com.jeeplus.modules.act.entity.Act;
import com.jeeplus.modules.act.service.ActTaskService;
import com.jeeplus.modules.act.utils.ActUtils;
import com.jeeplus.modules.act.utils.ProcessDefCache;
import com.jeeplus.modules.projectrecord.entity.ProjectRecords;
import com.jeeplus.modules.serialnum.service.SerialNumTplService;
import com.jeeplus.modules.sys.entity.Office;
import com.jeeplus.modules.sys.entity.User;
import com.jeeplus.modules.sys.service.OfficeService;
import com.jeeplus.modules.sys.utils.UserUtils;
import com.jeeplus.modules.workactivity.dao.WorkActivityProcessDao;
import com.jeeplus.modules.workactivity.entity.Activity;
import com.jeeplus.modules.workactivity.entity.WorkActivityProcess;
import com.jeeplus.modules.workactivity.entity.WorkActivityProcessUser;
import com.jeeplus.modules.workactivity.service.ActivityService;
import com.jeeplus.modules.workactivity.service.WorkActivityProcessService;
import com.jeeplus.modules.workactivitymenu.entity.WorkActivityMenu;
import com.jeeplus.modules.workactivitymenu.service.WorkActivityMenuService;
import com.jeeplus.modules.workclientinfo.dao.WorkClientAttachmentDao;
import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
import com.jeeplus.modules.workloan.dao.WorkLoanDao;
import com.jeeplus.modules.workloan.entity.WorkLoan;
import com.jeeplus.modules.workloan.service.WorkLoanService;
import com.jeeplus.modules.workofficechange.entity.WorkOfficeChange;
import com.jeeplus.modules.workofficechange.entity.WorkOfficeChangeUser;
import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
import com.jeeplus.modules.workprojectnotify.util.UtilNotify;
import com.jeeplus.modules.projectrecord.dao.WorkProjectUserDao;
import com.jeeplus.modules.workreimbursement.dao.ReimbursementVATTaxDao;
import com.jeeplus.modules.workreimbursement.dao.WorkAccountDao;
import com.jeeplus.modules.workreimbursement.dao.WorkReimbursementDao;
import com.jeeplus.modules.workreimbursement.entity.ReimbursementVATTax;
import com.jeeplus.modules.workreimbursement.entity.WorkAccount;
import com.jeeplus.modules.workreimbursement.entity.WorkAccountAudit;
import com.jeeplus.modules.workreimbursement.entity.WorkReimbursement;
import com.jeeplus.modules.workreimbursement.utils.VarStr;
import com.jeeplus.modules.workreimbursementback.dao.WorkReimbursementBackDao;
import com.jeeplus.modules.workreimbursementback.entity.WorkReimbursementBack;
import com.jeeplus.modules.workrepay.dao.WorkRepayDao;
import com.jeeplus.modules.workrepay.entity.WorkRepay;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.java_websocket.WebSocket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.method.P;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 财务报销Service
 * @author 孟祥越
 * @version 2017-05-02
 */
@Service
@Transactional(readOnly = true)
public class WorkReimbursementService extends CrudService<WorkReimbursementDao, WorkReimbursement> {
    @Autowired
    private WorkRepayDao workRepayDao;
    @Autowired
    private WorkReimbursementDao workReimbursementDao;
    @Autowired
    private WorkAccountDao workAccountDao;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    protected TaskService taskService;
    @Autowired
    protected HistoryService historyService;
    @Autowired
    protected RepositoryService repositoryService;
    @Autowired
    private IdentityService identityService;
    @Autowired
    private WorkClientAttachmentDao workClientAttachmentDao;
    @Autowired
    private WorkLoanService workLoanService;

    @Autowired
    private ActTaskService actTaskService;

    @Autowired
    private WorkProjectNotifyService workProjectNotifyService;
    @Autowired
    private WorkActivityMenuService workActivityMenuService;
    @Autowired
    private WorkActivityProcessService workActivityProcessService;
    @Autowired
    private ActivityService activityService;
    @Autowired
    private ReimbursementVATTaxDao reimbursementVATTaxDao;
    @Autowired
    private WorkActivityProcessDao workActivityProcessDao;
    @Autowired
    private WorkProjectUserDao workProjectUserDao;
    @Autowired
    private SerialNumTplService serialNumTplService;
    @Autowired
    private OfficeService officeService;
    @Autowired
    private WorkReimbursementBackDao workReimbursementBackDao;
    @Autowired
    private WorkLoanDao workLoanDao;

    @SuppressWarnings("unchecked")
    public WorkReimbursement get(String id) {
        WorkReimbursement workReimbursement = super.get(id);
        List<WorkAccount> workAccounts = workAccountDao.findList(new WorkAccount(workReimbursement));
        for (WorkAccount workAccount:workAccounts){
            List<WorkAccountAudit> workAccountAudits = workAccountDao.findByWorkAccount(workAccount);
            if (workAccountAudits!=null && workAccountAudits.size()!=0){
                workAccount.setWorkAccountAuditList(workAccountAudits);
            }
            if (StringUtils.isNotBlank(workReimbursement.getExt()) && workReimbursement.getExt().equals("1")){
                workAccount.setFinancialSubjectss(workAccount.getFinancialSubjects());
                workAccount.setFinancialSubjects("");
            }
        }
        workReimbursement.setWorkAccountList(workAccounts);
        workReimbursement.setReimbursementVATTaxes(reimbursementVATTaxDao.findList(new ReimbursementVATTax(workReimbursement)));
        WorkClientAttachment workClientAttachment = new WorkClientAttachment();
        workClientAttachment.setAttachmentId(id);
        workClientAttachment.setAttachmentFlag(VarStr.attachmentFlag[1]);
        workReimbursement.setWorkAttachments(workClientAttachmentDao.findList(workClientAttachment));
        if (workReimbursement!=null && StringUtils.isNotBlank(workReimbursement.getSubmitterId())){
            workReimbursement.setSubmitterName(UserUtils.get(workReimbursement.getSubmitterId()).getName());
        }
        if (workReimbursement!=null && StringUtils.isNotBlank(workReimbursement.getOfficeId())){
            workReimbursement.setOfficeName(UserUtils.getOfficeById(workReimbursement.getOfficeId()).getName());
        }
        //暂存状态不操作流程
		/*if(!"1".equals(workReimbursement.getStatus())){
            Map<String,Object> variables=null;
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(workReimbursement.getProcessInstanceId()).singleResult();
            if(historicProcessInstance!=null) {
                variables = Collections3.extractToMap(historyService.createHistoricVariableInstanceQuery().processInstanceId(historicProcessInstance.getId()).list(), "variableName", "value");
            } else {
                variables = runtimeService.getVariables(runtimeService.createProcessInstanceQuery().processInstanceId(workReimbursement.getProcessInstanceId()).active().singleResult().getId());
            }
            workReimbursement.setVariables(variables);
        }*/
        if (workReimbursement.getProject()!=null && StringUtils.isNotBlank(workReimbursement.getProject().getId())){
            List<User> users = workProjectUserDao.queryProjectUsers(workReimbursement.getProject().getId(), "1");
            String projectMasterName = "";
            if(users!=null && users.size()!=0){
                for (int i = 0; i < users.size(); i++) {
                    if(i == users.size() -1){
                        projectMasterName += UserUtils.get(users.get(i).getId()).getName();
                    }else{
                        projectMasterName += UserUtils.get(users.get(i).getId()).getName()+",";
                    }
                }
                workReimbursement.setProjectMasterName(projectMasterName);
            }
        }
        WorkReimbursementBack workReimbursementBack=new WorkReimbursementBack();
        workReimbursementBack.setWorkReimbursementId(id);
        workReimbursementBack.setAchivesId(workReimbursement.getAchivesId());
        List<WorkReimbursementBack> list=workReimbursementBackDao.findList(workReimbursementBack);
        List<WorkReimbursementBack> newList=new ArrayList<>();
        if(list!=null&&list.size()>0){
            for(WorkReimbursementBack workReimbursementBack1:list){
               if(workReimbursementBack1.getWorkLoan()!=null){
                   List<WorkRepay> workRepayList= workRepayDao.findWorkRepayView(workReimbursementBack1.getWorkLoan().getId(),id);
                   if(workRepayList!=null&&workRepayList.size()>0){
                   }else{
                       WorkLoan workLoan=workLoanService.getLon(workReimbursementBack1.getWorkLoan().getId());
                       if(workLoan.getType().equals("1")){
                           workLoan.setType("行政借款");
                       }else{
                           workLoan.setType("项目借款");
                       }
                       workReimbursementBack1.setWorkLoan(workLoan);
                       newList.add(workReimbursementBack1);
                   }
               }
            }
        }
        workReimbursement.setReimbursementBackList( workReimbursementBackDao.findList(workReimbursementBack));
        return workReimbursement;
    }

    public List<WorkReimbursement> findList(WorkReimbursement workReimbursement) {
        List<WorkReimbursement> list = super.findList(workReimbursement);
        List<WorkReimbursement> lists = new ArrayList<>();
        /*for (WorkReimbursement reimbursement:list){
            ProjectRecords records = reimbursement.getProject();
            if (records!=null && StringUtils.isNotBlank(records.getId())){
                List<User> users = workProjectUserDao.queryProjectUsers(records.getId(), "1");
                records.setProjectLeaders(users);
                records.setLeaderNameStr(Collections3.extractToString(users, "name", ","));
            }
            reimbursement.setProject(records);
            lists.add(reimbursement);
        }*/
        return list;
    }

    public Page<WorkReimbursement> findPage(Page<WorkReimbursement> page, WorkReimbursement workReimbursement) {
        workReimbursement.getSqlMap().put("dsf", dataScopeFilter(workReimbursement.getCurrentUser(), "o", "u","s", MenuStatusEnum.WORK_REIMBURSEMENT.getValue()));
        int count = dao.queryCount(workReimbursement);
        page.setCount(count);
        page.setCountFlag(false);
        workReimbursement.setPage(page);
        page.setList(findList(workReimbursement));
        return page;
    }

    /**
     * 暂存
     * @param workReimbursement
     */
    @Transactional(readOnly = false)
    public  void save(WorkReimbursement workReimbursement){
        if (StringUtils.isBlank(workReimbursement.getNumber())) {
            User user = UserUtils.getUser();
            workReimbursement.setNumber(serialNumTplService.genSerialNum(user.getCompany(), WorkReimbursement.SERIAL_BIZCODE));
        }
        super.save(workReimbursement);
        updateWorkReimbursementInfo(workReimbursement);
    }

    /**
     * 提交存储
     * @param workReimbursement
     * @param variables
     */
    @Transactional(readOnly = false)
    public String save(WorkReimbursement workReimbursement,Map<String, Object> variables,String processInstanceId) {
        User user = UserUtils.getUser();
        if (StringUtils.isBlank(workReimbursement.getNumber())) {
            workReimbursement.setNumber(serialNumTplService.genSerialNum(user.getCompany(), WorkReimbursement.SERIAL_BIZCODE));
        }
        super.save(workReimbursement);
        String str = "";
        Office office = officeService.get(workReimbursement.getOfficeId());
        if (workReimbursement.getProject()!= null && StringUtils.isNotBlank(workReimbursement.getProject().getId())){
            str =  "报销申请编号:"+workReimbursement.getNumber()+",报销项目:"+workReimbursement.getProject().getProjectName()+",报销费用合计:"+workReimbursement.getMoney()+",报销人:"+user.getName()+",所属部门:"+office.getName();
        }else {
            str =  "报销申请编号:"+workReimbursement.getNumber()+",非项目报销,报销费用合计:"+workReimbursement.getMoney()+",报销人:"+user.getName()+",所属部门:"+office.getName();
        }
        String title = "报销人:"+user.getName();
        updateWorkReimbursementInfo(workReimbursement);
        // 用来设置启动流程的人员ID，引擎会自动把用户ID保存到activiti:initiator中
        identityService.setAuthenticatedUserId(user.getId());
        // 启动流程
        String businessKey = workReimbursement.getId().toString();
        WorkActivityMenu workActivityMenu = workActivityMenuService.findByParentAndOffice("ggh3125f1f194c82bdea93555c750906", office);
        // 启动流程
        String processType = workActivityMenu.getProcessType();
        StringBuffer buffer = new StringBuffer();
        Activity activity = new Activity();
        WorkProjectNotify workProjectNotify = UtilNotify
                .saveNotify(workReimbursement.getId(),
                        null,
                        workReimbursement.getCompanyId(),
                        title,
                        str,
                        "13",
                        "0",
                        "待审批",
                        ""
                );
        List<User> users = new ArrayList<>();
        List<User> bmzrs = UserUtils.getByRoleActivityEnname("bmzr",2,office.getId(),"8",workReimbursement.getCreateBy());
        List<User> fglds = UserUtils.getByRoleActivityEnname("fgld",2,office.getId(),"8",workReimbursement.getCreateBy());
        List<User> cws = UserUtils.getByRoleActivityEnname("cwzg",3,office.getId(),"8",workReimbursement.getCreateBy());
        List<User> zjls = UserUtils.getByRoleActivityEnname("zjl",3,office.getId(),"8",workReimbursement.getCreateBy());
        List<User> cwzjs = UserUtils.getByRoleActivityEnname("cwfgld",3,office.getId(),"8",workReimbursement.getCreateBy());
        List<User> cns = UserUtils.getByRoleActivityEnname("cn",3,office.getId(),"8",workReimbursement.getCreateBy());
        if (StringUtils.isNotBlank(workActivityMenu.getId())) {
            workProjectNotify.setNotifyRole("");
            workActivityMenu = workActivityMenuService.get(workActivityMenu.getId());
            List<Activity> activities = workActivityMenu.getActivities();
            for (Activity a : activities) {
                String encount = a.getEncount();
                String enlist = a.getEnlist();
                if (a.getRole()!=null && StringUtils.isNotBlank(a.getRole().getEnname())){
                    List enusers = UserUtils.getByRoleActivityEnnames(a.getRole().getEnname(),office.getId(),"8",workReimbursement.getCreateBy());
                    if (enusers.size()==0){
                       /* workReimbursementDao.delete(workReimbursement);
                        for (WorkAccount workAccount : workReimbursement.getWorkAccountList()){
                            workAccountDao.delete(workAccount);
                        }
                        for (ReimbursementVATTax reimbursementVATTax:workReimbursement.getReimbursementVATTaxes()){
                            reimbursementVATTaxDao.delete(reimbursementVATTax);
                        }
                        for (WorkClientAttachment workClientAttachment : workReimbursement.getWorkAttachments()) {
                            workClientAttachmentDao.delete(workClientAttachment);
                        }*/
                        workReimbursement.setStatus("1");
                        super.save(workReimbursement);
                        return "流程审批人不能为空,角色"+a.getRole().getName()+"下无用户,请联系管理员！";
                    }
                    variables.put(enlist, enusers);
                    variables.put(encount, enusers.size());
                }
                if (a.getDelFlag().equals("0") && a.getCount() == 1) {
                    activity = a;
                }
            }
            buffer.append(activity.getRole().getEnname());
            if (activity != null && StringUtils.isNotBlank(activity.getId())) {
                //角色审批
                if (StringUtils.isNotBlank(activity.getRole().getEnname())) {
                    users = UserUtils.getByRoleActivityEnnames(activity.getRole().getEnname(),office.getId(),"8",workReimbursement.getCreateBy());
                }
                //人员审批
                if (StringUtils.isNotBlank(activity.getUser().getId())) {
                    users.add(activity.getUser());
                }
            }
            workProjectNotify.setId("");
        } else {
           //variables.put("bmzrList", bmzrs);
            /*variables.put("fgldList", fglds);
            variables.put("cwList", cws);
            variables.put("zjlList", zjls);
            variables.put("cwzjList", cwzjs);
            variables.put("cnList", cns);*/
            //|| fglds.size()==0 || cws.size()==0 || zjls.size()==0 || cwzjs.size()==0 || cns.size()==0
            if (bmzrs.size()==0 ){
                workReimbursement.setStatus("1");
                super.save(workReimbursement);
            }
            if (bmzrs.size()==0){
                return "流程审批人不能为空,角色部门负责人下无用户,请联系管理员！";
            }
           /* if (fglds.size()==0){
                return "流程审批人不能为空,角色分管领导下无用户,请联系管理员！";
            }
            if (cws.size()==0){
                return "流程审批人不能为空,角色财务主管下无用户,请联系管理员！";
            }
            if (zjls.size()==0){
                return "流程审批人不能为空,角色总经理下无用户,请联系管理员！";
            }
            if (cwzjs.size()==0){
                return "流程审批人不能为空,角色财务分管领导下无用户,请联系管理员！";
            }
            if (cns.size()==0){
                return "流程审批人不能为空,角色出纳下无用户,请联系管理员！";
            }*/
            //variables.put("bmzrcount",bmzrs.size());
            /*variables.put("fgldcount",fglds.size());
            variables.put("cwcount",cws.size());
            variables.put("zjlcount",zjls.size());
            variables.put("cwzjcount",cwzjs.size());
            variables.put("cncount",cns.size());*/
            processType = "reimbursement";
            users.addAll(bmzrs);
        }
        for (User u : users){
            workProjectNotify.setUser(u);
            workProjectNotify.setId("");
            workProjectNotify.setNotifyRole("部门负责人审批");
            workProjectNotifyService
                    .save(workProjectNotify);
               /* List<WebSocket> toUserConns = ChatServerPool.getWebSocketByUser(u.getId());
                for (WebSocket toUserConn:toUserConns) {
                   String message = "{\"to\":\""+u.getId()+"\"," +
                            "\"msg\":\"审批信息 报销人:" + user.getName() + ",报销编号:"+ workReimbursement.getNumber() + " 待审批!\"," +
                            "\"useType\":\"sys\"}";
                    ChatServerPool.sendMessageToUser(toUserConn, message);//同时向本人发送消息
                }*/
            Map<String,Object> extras = new HashMap<>();
            extras.put("type","7002");
            extras.put("id",workProjectNotify.getId());
            extras.put("procDefKey","13");
            UserUtils.pushInfoToApp(title,str,extras,u.getId());
            UserUtils.pushIm(u.getId(),str);
        }
        variables.put("type", processType);
        variables.put("busId", businessKey);
        variables.put("title", "审批单：" + workReimbursement.getNumber());//设置标题；

        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processType, businessKey, variables);
        workReimbursement.setProcessInstance(processInstance);
        if (StringUtils.isNotBlank(processInstanceId)) {
            workActivityProcessService.updateProcessInstanceId(processInstance.getId(),processInstanceId);
            workActivityProcessService.deleteProcessInstanceId(processInstanceId);
            workActivityProcessService.deleteProcessIdAuditUsers(processInstanceId);
        }
        // 更新流程实例ID
        workReimbursement.setProcessInstanceId(processInstance.getId());
        workReimbursementDao.updateProcessInstanceId(workReimbursement);
        List<Activity> list = workActivityMenu.getActivities();
        if (list != null && list.size() != 0) {
            workActivityProcessService.saveList(list, processInstance.getId());
        } else {
            WorkActivityProcess workActivityProcess = new WorkActivityProcess();
            workActivityProcess.setProcessKey("reimbursement");
            workActivityProcess.setCount(1);
            workActivityProcess.setProcessInstanceId(processInstance.getId());
            workActivityProcess.setIsApproval("0");
            workActivityProcessService.save(workActivityProcess);
            workActivityProcess.setCount(2);
            workActivityProcess.setId("");
            workActivityProcessService.save(workActivityProcess);
            workActivityProcess.setCount(3);
            workActivityProcess.setId("");
            workActivityProcessService.save(workActivityProcess);
            workActivityProcess.setCount(4);
            workActivityProcess.setId("");
            workActivityProcessService.save(workActivityProcess);
            workActivityProcess.setCount(5);
            workActivityProcess.setId("");
            workActivityProcessService.save(workActivityProcess);
            workActivityProcess.setCount(6);
            workActivityProcess.setId("");
            workActivityProcessService.save(workActivityProcess);
            workActivityProcessService.insertAuditsByType(bmzrs,processInstance.getId(),1,1);
            workActivityProcessService.insertAuditsByType(fglds,processInstance.getId(),2,0);
            workActivityProcessService.insertAuditsByType(cws,processInstance.getId(),3,0);
            workActivityProcessService.insertAuditsByType(zjls,processInstance.getId(),4,0);
            workActivityProcessService.insertAuditsByType(cwzjs,processInstance.getId(),5,0);
            workActivityProcessService.insertAuditsByType(cns,processInstance.getId(),6,0);
        }
        logger.debug("start process of {key={}, bkey={}, pid={}, variables={}}", new Object[]{
                ActUtils.PD_REIMBURSEMENT[0], businessKey, processInstance.getId(), variables});
        return "";
    }

    @Transactional(readOnly = false)
    public void delete(WorkReimbursement workReimbursement) {
        super.delete(workReimbursement);
        for (WorkAccount workAccount : workReimbursement.getWorkAccountList()){
            workAccountDao.delete(workAccount);
        }
        for (ReimbursementVATTax reimbursementVATTax:workReimbursement.getReimbursementVATTaxes()){
            reimbursementVATTaxDao.delete(reimbursementVATTax);
        }
        for (WorkClientAttachment workClientAttachment : workReimbursement.getWorkAttachments()) {
            workClientAttachmentDao.delete(workClientAttachment);
        }
        for (WorkReimbursementBack workReimbursementBack : workReimbursement.getReimbursementBackList()) {
            workReimbursementBackDao.delete(workReimbursementBack);
        }
        //删除报销还款
        workRepayDao.deleteRepay(workReimbursement.getId());
        WorkProjectNotify notify = new WorkProjectNotify();
        notify.setNotifyId(workReimbursement.getId());
        List<User> users = workProjectNotifyService.readByNotifyId(notify);
        if (users!=null && users.size()!=0){
            for (User user:users){
                UserUtils.pushMeIm(user.getId());
            }
        }
    }
    @Transactional(readOnly = false)
    public void updateWorkReimbursementInfo(WorkReimbursement workReimbursement) {
        try {
            for (WorkAccount workAccount : workReimbursement.getWorkAccountList()) {
                if (WorkAccount.DEL_FLAG_NORMAL.equals(workAccount.getDelFlag())) {
                    List<WorkAccountAudit> workAccountAudits = workAccount.getWorkAccountAuditList();
                    List<WorkAccountAudit> workAccountAuditList = new ArrayList<>();
                    if (workAccountAudits != null && workAccountAudits.size() != 0) {
                        for (WorkAccountAudit workAccountAudit : workAccountAudits) {
                            if (StringUtils.isNotBlank(workAccountAudit.getCheckSubjects())
                                    || workAccountAudit.getCheckMoney() != null||StringUtils.isNotBlank(workAccountAudit.getU8Subjects())) {
                                workAccountAuditList.add(workAccountAudit);
                            }
                        }
                        workAccount.setWorkAccountAuditList(workAccountAuditList);
                        workAccountDao.deleteAudits(workAccount);
                        workAccountDao.insertAudits(workAccount);
                    }
                    if (StringUtils.isNotBlank(workReimbursement.getExt()) && workReimbursement.getExt().equals("1")) {
                        workAccount.setFinancialSubjects(workAccount.getFinancialSubjectss());
                    }
                    workAccount.setWorkReimbursement(workReimbursement);
                    if (StringUtils.isBlank(workAccount.getId()) && workAccount.getMoney() != null) {
                        workAccount.preInsert();
                        workAccountDao.insert(workAccount);
                    } else {
                        workAccount.preUpdate();
                        workAccountDao.update(workAccount);
                    }

                } else {
                    workAccountDao.delete(workAccount);
                }
            }
            for (ReimbursementVATTax reimbursementVATTax : workReimbursement.getReimbursementVATTaxes()) {
                if (ReimbursementVATTax.DEL_FLAG_NORMAL.equals(reimbursementVATTax.getDelFlag())) {
                    reimbursementVATTax.setWorkReimbursement(workReimbursement);
                    if (StringUtils.isBlank(reimbursementVATTax.getId()) && StringUtils.isNotBlank(reimbursementVATTax.getInvoiceCode())) {
                        reimbursementVATTax.preInsert();
                        reimbursementVATTaxDao.insert(reimbursementVATTax);
                    } else {
                        reimbursementVATTax.preUpdate();
                        reimbursementVATTaxDao.update(reimbursementVATTax);
                    }
                } else {
                    reimbursementVATTaxDao.delete(reimbursementVATTax);
                }
            }
            //附件信息
            for (WorkClientAttachment workClientAttachment : workReimbursement.getWorkAttachments()) {
                if (workClientAttachment.getId() == null) {
                    continue;
                }
                if (WorkClientAttachment.DEL_FLAG_NORMAL.equals(workClientAttachment.getDelFlag())) {
                    workClientAttachment.setAttachmentId(workReimbursement.getId());
                    workClientAttachment.setAttachmentFlag(VarStr.attachmentFlag[1]);
                    workClientAttachment.setAttachmentUser(UserUtils.getUser().getId());
                    if (StringUtils.isBlank(workClientAttachment.getId()) || "null".equals(workClientAttachment.getId())) {
                        workClientAttachment.preInsert();
                        workClientAttachmentDao.insert(workClientAttachment);
                    } else {
                        workClientAttachment.preUpdate();
                        workClientAttachmentDao.update(workClientAttachment);
                    }
                } else {
                    workClientAttachmentDao.delete(workClientAttachment);
                }
            }
            if(workReimbursement.getReimbursementBackList()!=null&&workReimbursement.getReimbursementBackList().size()>0){
                WorkReimbursementBack w=new WorkReimbursementBack();
                w.setAchivesId(workReimbursement.getAchivesId());
                w.setWorkReimbursementId(workReimbursement.getId());
                workReimbursementBackDao.deleteLoan(w);
                //删除报销还款
                workRepayDao.deleteRepay(workReimbursement.getId());
                for (WorkReimbursementBack reimbursementBack :workReimbursement.getReimbursementBackList()) {
                    if (StringUtils.isBlank(reimbursementBack.getId()) ) {
                        reimbursementBack.preInsert();
                        reimbursementBack.setAchivesId(workReimbursement.getAchivesId());
                        reimbursementBack.setWorkReimbursementId(workReimbursement.getId());
                        workReimbursementBackDao.insert(reimbursementBack);
                    } else {
                        if(StringUtils.isNotBlank(reimbursementBack.getId())){
                            reimbursementBack.preUpdate();
                            reimbursementBack.setAchivesId(workReimbursement.getAchivesId());
                            reimbursementBack.setWorkReimbursementId(workReimbursement.getId());
                            workReimbursementBackDao.update(reimbursementBack);
                        }
                    }
                   //增加还款明细

                   if(reimbursementBack.getMoney()!=null&&!"".equals(reimbursementBack.getMoney())&&!"0".equals(reimbursementBack.getMoney())){
                       WorkRepay workRepay=new WorkRepay();
                       workRepay.preInsert();
                       workRepay.setWorkLoan(reimbursementBack.getWorkLoan());
                       workRepay.setOfficeId(workReimbursement.getOfficeId());
                       workRepay.setCompanyId(workReimbursement.getCompanyId());
                       workRepay.setRepayDate(new Date());
                       workRepay.setSource("1");
                       workRepay.setStatus("2");
                       workRepay.setMoney(reimbursementBack.getMoney());
                       workRepay.setWorkReimbursement(workReimbursement);
                       workRepayDao.insert(workRepay);
                   }

                }

            }
        }catch (Exception e){
            logger.info("Exception e:"+ e);
            return;
        }
    }

    public Page<ProjectRecords> findPageByproject(Page<ProjectRecords> page, ProjectRecords project) {
        project.getSqlMap().put("dsf", dataScopeFilter(project.getCurrentUser(), "o", "u","s", MenuStatusEnum.WORK_REIMBURSEMENT.getValue()));
        project.setPage(page);
        page.setList(dao.findListByprojectt(project));
        return page;
    }

    /**
     * 审核流程
     * @param workReimbursement
     */
    @Transactional(readOnly = false)
    public String auditSave(WorkReimbursement workReimbursement,List<User> auditUsers) {
        String str = "";
        String userName = UserUtils.get(workReimbursement.getCreateBy().getId()).getName();
        Office office = officeService.get(workReimbursement.getOfficeId());
        String title = "报销人:"+userName;
        if (workReimbursement.getProject()!= null && StringUtils.isNotBlank(workReimbursement.getProject().getId())){
            str =  "报销申请编号:"+workReimbursement.getNumber()+",报销项目:"+workReimbursement.getProject().getProjectName()+",报销费用合计:"+workReimbursement.getMoney()+",报销人:"+userName+",所属部门:"+office.getName();
        }else {
            str =  "报销申请编号:"+workReimbursement.getNumber()+",非项目报销,报销费用合计:"+workReimbursement.getMoney()+",报销人:"+userName+",所属部门:"+office.getName();
        }
        // 对不同环节的业务逻辑进行操作
        String taskDefKey = workReimbursement.getAct().getTaskDefKey();
        if (!"modifyApply".equals(taskDefKey) && !taskDefKey.contains("audit") && !taskDefKey.contains("cw") ) {
            actTaskService.claim(workReimbursement.getAct().getTaskId(), UserUtils.getUser().getId());
        }else if(taskDefKey.contains("cw")) {
            updateWorkReimbursementInfo(workReimbursement);
        }else{
            workReimbursement.getAct().setFlag("yes");
            updateWorkReimbursementInfo(workReimbursement);
        }
        String comment = "";
        if (workReimbursement.getStatus().equals("4")){
            comment = ("yes".equals(workReimbursement.getAct().getFlag())?"[重新申请] ":"[已撤销] ");
        }else {
            comment = ("yes".equals(workReimbursement.getAct().getFlag())?"[同意] ":"[驳回] ")+workReimbursement.getAct().getComment();
        }
        //yes 的时候状态为审核通过 否则为未通过
        //1 审核中 2 未通过
        workReimbursement.setStatus(("yes".equals(workReimbursement.getAct().getFlag()) ? "2" : "4"));
        Map<String, Object> vars = Maps.newHashMap();
        //业务逻辑对应的条件表达式
        String exp = "";
        String taskCount = "";
        String notifyRole = "";
        int key = 0;
        String enname = "";
        List<Activity> activitieList = activityService.getByProcessInstanceId(workReimbursement.getProcessInstanceId());
        WorkActivityMenu workActivityMenu = new WorkActivityMenu();
        if (activitieList != null && activitieList.size() != 0) {
            workActivityMenu.setProcessType(activitieList.get(0).getProcessKey());
            workActivityMenu.setActivities(activitieList);
        }

        WorkActivityProcess workActivityProcess = new WorkActivityProcess();
        WorkActivityProcess selectProcess = new WorkActivityProcess();
        selectProcess.setProcessInstanceId(workReimbursement.getProcessInstanceId());
        List<WorkActivityProcess> workActivityProcesses = workActivityProcessService.findList(selectProcess);
        List<Activity> activities = workActivityMenu.getActivities();
        if (StringUtils.isNotBlank(workActivityMenu.getProcessType()) && !workActivityMenu.getProcessType().equals("reimbursement")) {
            key = 1;
            for (int i = 0; i < workActivityProcesses.size(); i++) {
                WorkActivityProcess activityProcess = workActivityProcesses.get(i);
                if (taskDefKey.equals(activityProcess.getActivityTask()) && !taskDefKey.equals("modifyApply")) {
                    taskCount = activityProcess.getCount()+"";
                    workActivityProcess = activityProcess;
                    if (!workActivityProcess.getIsApproval().equals("0")) {
                        workActivityProcess.setId("");
                    }
                    exp = "pass";
                    if (!"yes".equals(workReimbursement.getAct().getFlag())) {
                        workReimbursement.setStatus("4");
                        workActivityProcess.setIsApproval("2");
                        String returnBack = "-1";
                        for (Activity activity : activities) {
                            if (activity.getCount() == activityProcess.getCount()) {
                                returnBack = activity.getReturnBack();
                                notifyRole = activity.getName();
                                break;
                            }
                        }
                        if (returnBack.equals("0")) {
                            workActivityProcess.setId("");
                        }

                    } else {
                        workActivityProcess.setIsApproval("1");
                    }
                }else if(taskDefKey.equals("modifyApply")){
                    notifyRole = "调整报销";
                    taskCount = "0";
                    exp = "pass";
                    workActivityProcess.setId("");
                    workActivityProcess.setCount(0);
                    if (!"yes".equals(workReimbursement.getAct().getFlag())) {
                        workReimbursement.setStatus("3");
                        workActivityProcess.setIsApproval("2");
                    } else {
                        workActivityProcess.setIsApproval("1");
                    }
                    break;
                }
            }
        } else {
            workActivityMenu.setProcessType("reimbursement");
            for (int i = 0; i < workActivityProcesses.size(); i++) {
                WorkActivityProcess activityProcess = workActivityProcesses.get(i);
                String count = activityProcess.getCount() + "";
                workActivityProcess = activityProcess;
                if (!workActivityProcess.getIsApproval().equals("0")) {
                    workActivityProcess.setId("");
                }
                // 审核环节
                if ("bmzr".equals(taskDefKey) && count.contains("1")) {
                    taskCount = "1";
                    exp = "pass";
                    if ("yes".equals(workReimbursement.getAct().getFlag())) {
                        workActivityProcessService.insertAuditsByType(auditUsers,workReimbursement.getProcessInstanceId(),2,1);
                        workActivityProcess.setIsApproval("1");
                        notifyRole = "分管领导审核";
                        enname = "fgld";
                    } else {
                        notifyRole = "调整申请";
                        workActivityProcess.setIsApproval("2");
                    }
                    break;
                } else if ("fgld".equals(taskDefKey) && count.contains("2")) {
                    taskCount = "2";
                    exp = "pass";
                    if ("yes".equals(workReimbursement.getAct().getFlag())) {
                        workActivityProcessService.insertAuditsByType(auditUsers,workReimbursement.getProcessInstanceId(),3,1);
                        notifyRole = "财务审核";
                        workActivityProcess.setIsApproval("1");
                        enname = "cwzg";
                    } else {
                        notifyRole = "调整报销";
                        workActivityProcess.setIsApproval("2");
                    }
                    break;
                } else if ("cw".equals(taskDefKey) && count.contains("3")) {
                    taskCount = "3";
                    exp = "pass";
                    if ("yes".equals(workReimbursement.getAct().getFlag())) {
                        workActivityProcessService.insertAuditsByType(auditUsers,workReimbursement.getProcessInstanceId(),4,1);
                        notifyRole = "总经理审核";
                        workActivityProcess.setIsApproval("1");
                        enname = "zjl";
                    } else {
                        notifyRole = "调整报销";
                        workActivityProcess.setIsApproval("2");
                    }
                    break;
                } else if ("zjl".equals(taskDefKey) && count.contains("4")) {
                    taskCount = "4";
                    exp = "pass";
                    if ("yes".equals(workReimbursement.getAct().getFlag())) {
                        notifyRole = "财务分管领导审核";
                        workActivityProcessService.insertAuditsByType(auditUsers,workReimbursement.getProcessInstanceId(),5,1);

                        workActivityProcess.setIsApproval("1");
                        enname = "cwfgld";
                    } else {
                        workActivityProcess.setIsApproval("2");
                        notifyRole = "调整报销";
                    }
                    break;
                } else if ("cwzj".equals(taskDefKey) && count.contains("5")) {
                    taskCount = "5";
                    exp = "pass";
                    if ("yes".equals(workReimbursement.getAct().getFlag())) {
                        workActivityProcessService.insertAuditsByType(auditUsers,workReimbursement.getProcessInstanceId(),6,1);
                        notifyRole = "报销付款";
                        workActivityProcess.setIsApproval("1");
                        enname = "cn";
                    } else {
                        workActivityProcess.setIsApproval("2");
                        notifyRole = "调整报销";
                    }
                    break;
                } else if ("cn".equals(taskDefKey) && count.contains("6")) {
                    taskCount = "6";
                    exp = "pass";
                    if ("yes".equals(workReimbursement.getAct().getFlag())) {
                        notifyRole = "审批通过";
                        workActivityProcess.setIsApproval("1");
                    } else {
                        notifyRole = "调整报销";
                        workActivityProcess.setIsApproval("2");
                    }
                    break;
                } else if ("modifyApply".equals(taskDefKey)&& count.contains("0")) {
                    taskCount = "0";
                    notifyRole = "部门负责人审批";
                    exp = "pass";
                    workActivityProcess.setCount(0);
                    enname = "bmzr";
                    if (!"yes".equals(workReimbursement.getAct().getFlag())) {
                        workReimbursement.setStatus("3");
                    }
                    break;
                } else if ("apply_end".equals(taskDefKey)) {
                }

            }
        }
        // 设置意见
        workReimbursement.getAct().setComment(("yes".equals(workReimbursement.getAct().getFlag()) ? "[同意] " : "[驳回] ") + workReimbursement.getAct().getComment());
        workReimbursement.preUpdate();
        // 提交流程任务
        vars.put(exp, "yes".equals(workReimbursement.getAct().getFlag()) ? true : false);
        workActivityProcessService.updateProcess(workActivityProcess,workActivityMenu,key,taskCount,workReimbursement.getProcessInstanceId(),taskDefKey,"modifyApply",workReimbursement.getAct().getFlag(),comment, activities);
        // 提交流程任务
        actTaskService.complete(workReimbursement.getAct().getTaskId(), workReimbursement.getAct().getProcInsId(), workReimbursement.getAct().getComment(), vars);
        workReimbursement.setLimitCond("1");
        boolean state = actTaskService.isProcessEnd(workReimbursement.getAct().getProcInsId());
        List<User> users = new ArrayList<>();
        List<User> userList = new ArrayList<>();
        if (!state) {
            title =  "报销申请编号"+workReimbursement.getNumber()+",报销费用合计："+workReimbursement.getMoney();
//            str = "yes".equals(workReimbursement.getAct().getFlag())?"您的报销单审核：已通过":"您的报销单审核：未通过";
            if (workReimbursement.getProject()!= null && StringUtils.isNotBlank(workReimbursement.getProject().getId())){
                str =  "报销申请编号:"+workReimbursement.getNumber()+",报销项目:"+workReimbursement.getProject().getProjectName()+",报销费用合计:"+workReimbursement.getMoney();
            }else {
                str =  "报销申请编号:"+workReimbursement.getNumber()+",非项目报销,报销费用合计:"+workReimbursement.getMoney();
            }
            users.add(workReimbursement.getCreateBy());
            if ("yes".equals(workReimbursement.getAct().getFlag())) {
                workReimbursement.setStatus("5");
                WorkProjectNotify notify = new WorkProjectNotify();
                notify.setNotifyId(workReimbursement.getId());
                userList = workProjectNotifyService.readByNotifyId(notify);
                workProjectNotifyService
                        .save(UtilNotify
                                .saveNotify(workReimbursement.getId(),
                                        workReimbursement.getCreateBy(),
                                        workReimbursement.getCompanyId(),
                                        title,
                                        str,
                                        "13",
                                        "0",
                                        "待通知",
                                        notifyRole));
                //修改还款
                if(workReimbursement.getReimbursementBackList()!=null&&workReimbursement.getReimbursementBackList().size()>0){
                    for(WorkReimbursementBack workReimbursementBack:workReimbursement.getReimbursementBackList()){
                        if(StringUtils.isNotBlank(workReimbursementBack.getMoney())||!"0".equals(workReimbursementBack.getMoney())){
                            WorkLoan loan=new WorkLoan();
                            double backMoney=Double.parseDouble(workReimbursementBack.getMoney());//本次还款
                            WorkLoan workLoan =workLoanDao.get(workReimbursementBack.getWorkLoan().getId());
                            loan.setId(workLoan.getId());
                            loan.setUpdateBy(UserUtils.getUser());
                            loan.setUpdateDate(new Date());
                            if(workLoan.getRepay()==null){
                                workLoan.setRepay("0");
                            }
                            double repay=Double.parseDouble(workLoan.getRepay());//还款金额
                            double money=Double.parseDouble(workLoan.getMoney());//借款金额
                            if(!"1".equals(workLoan.getRepayState())){//未还款
                                if((backMoney+repay)>=money){
                                    loan.setRepay(String.valueOf(money));
                                    loan.setRepayState("1");

                                }else{
                                    loan.setRepay(String.valueOf(repay+backMoney));
                                    loan.setRepayState("2");

                                }
                                workLoanDao.updateReay(loan);
                                workRepayDao.updateReay(workReimbursementBack.getWorkLoan().getId(),workReimbursement.getId());
                            }
                        }
                    }
                }

            } else {
                WorkProjectNotify notify = new WorkProjectNotify();
                notify.setNotifyId(workReimbursement.getId());
                userList = workProjectNotifyService.readByNotifyId(notify);
                if (StringUtils.isNotBlank(workReimbursement.getStatus()) && !workReimbursement.getStatus().equals("3")){
                    workReimbursement.setStatus("4");
                    workProjectNotifyService
                            .save(UtilNotify
                                    .saveNotify(workReimbursement.getId(),
                                            workReimbursement.getCreateBy(),
                                            workReimbursement.getCompanyId(),
                                            title,
                                            str,
                                            "13",
                                            "0",
                                            "待通知",
                                            notifyRole));
                }
            }
            workActivityProcessService.deleteProcessIdAuditUsers(workReimbursement.getProcessInstanceId());
        } else {
            if (StringUtils.isNotBlank(workActivityMenu.getProcessType()) && !workActivityMenu.getProcessType().equals("reimbursement")) {
                WorkProjectNotify notify = new WorkProjectNotify();
                notify.setNotifyId(workReimbursement.getId());
                userList = workProjectNotifyService.readByNotifyId(notify);
                //users.addAll(userList);
                WorkProjectNotify workProjectNotify = UtilNotify
                        .saveNotify(workReimbursement.getId(),
                                new User(),
                                workReimbursement.getCompanyId(),
                                title,
                                str,
                                "13",
                                "0",
                                "待审批",
                                notifyRole);
                List<WorkProjectNotify> workProjectNotifys = activityService.getByFlagAndTaskDefKeyList(
                        activities,
                        workProjectNotify,
                        taskDefKey,
                        workReimbursement.getAct().getFlag(),
                        taskCount,
                        workReimbursement.getCreateBy(),
                        workReimbursement.getOfficeId(),
                        "8");
                for (WorkProjectNotify workProjectNotify1:workProjectNotifys){
                    users.add(workProjectNotify1.getUser());
                    workProjectNotify1.setId("");
                    workProjectNotify1.setIsNewRecord(false);
                    workProjectNotifyService
                            .save(workProjectNotify1);
                    if (!"modifyApply".equals(taskDefKey)){
                        Map<String,Object> extras = new HashMap<>();
                        if ("cw".equals(taskDefKey) || "cn".equals(taskDefKey) ){
                            extras.put("type","7001");
                        }else {
                            extras.put("type","7002");
                        }
                        extras.put("id",workProjectNotify.getId());
                        extras.put("procDefKey","13");
                        UserUtils.pushInfoToApp(title,str,extras,workProjectNotify1.getUser().getId());

                    }
                }

            } else {
                if (!"yes".equals(workReimbursement.getAct().getFlag())) {
                    WorkProjectNotify notify = new WorkProjectNotify();
                    notify.setNotifyId(workReimbursement.getId());
                    userList = workProjectNotifyService.readByNotifyId(notify);
                    //users.addAll(userList);
                    workProjectNotifyService
                            .save(UtilNotify
                                    .saveNotify(workReimbursement.getId(),
                                            workReimbursement.getCreateBy(),
                                            workReimbursement.getCompanyId(),
                                            title,
                                            str,
                                            "13",
                                            "0",
                                            "重新申请",
                                            notifyRole));
                    users.add( workReimbursement.getCreateBy());
                } else {
                    if (StringUtils.isNotBlank(enname)) {
                        WorkProjectNotify notify = new WorkProjectNotify();
                        notify.setNotifyId(workReimbursement.getId());
                        userList = workProjectNotifyService.readByNotifyId(notify);
                        //users.addAll(userList1);
                        WorkProjectNotify workProjectNotify = UtilNotify
                                .saveNotify(workReimbursement.getId(),
                                        new User(),
                                        workReimbursement.getCompanyId(),
                                        title,
                                        str,
                                        "13",
                                        "0",
                                        "待审批",
                                        notifyRole);
                        users.addAll(auditUsers);
                        for (User user1:auditUsers){
                            workProjectNotify.setId("");
                            workProjectNotify.setUser(user1);
                            workProjectNotify.setIsNewRecord(false);
                            workProjectNotifyService
                                    .save(workProjectNotify);
                            if (!"modifyApply".equals(taskDefKey)){
                                Map<String,Object> extras = new HashMap<>();
                                if ("cw".equals(taskDefKey) || "cn".equals(taskDefKey) ){
                                    extras.put("type","7001");
                                }else {
                                    extras.put("type","7002");
                                }
                                extras.put("id",workProjectNotify.getId());
                                extras.put("procDefKey","13");
                                UserUtils.pushInfoToApp(title,str,extras,user1.getId());

                            }
                        }
                    }else {
                        WorkProjectNotify notify = new WorkProjectNotify();
                        notify.setNotifyId(workReimbursement.getId());
                        userList = workProjectNotifyService.readByNotifyId(notify);
                        users.addAll(userList);
                        users.add(workReimbursement.getCreateBy());
                        workProjectNotifyService
                                .save(UtilNotify
                                        .saveNotify(workReimbursement.getId(),
                                                workReimbursement.getCreateBy(),
                                                workReimbursement.getCompanyId(),
                                                title,
                                                str,
                                                "13",
                                                "0",
                                                "重新申请",
                                                notifyRole));
                    }
                }
            }
        }
        if (users!=null && users.size()!=0) {
            for (User u : users) {
                UserUtils.pushIm(u.getId(),str);
            }
        }
        if (userList!=null && userList.size()!=0) {
            for (User u : userList) {
                UserUtils.pushMeIm(u.getId());
            }
        }

        workReimbursementDao.update(workReimbursement);
        return "保存审核意见成功！";
    }


    /**
     * 查询待办任务
     * @param userId 依据用户的角色和编号查询
     * @return
     */
    public List<WorkReimbursement> findTodoTasks(Act act,String userId) {

        List<WorkReimbursement> results = new ArrayList<WorkReimbursement>();
        List<Task> tasks = new ArrayList<Task>();
        TaskQuery todoTaskQuery = taskService.createTaskQuery().processDefinitionKey(ActUtils.PD_REIMBURSEMENT[0]).taskAssignee(userId).active().orderByTaskPriority().desc().orderByTaskCreateTime().desc();
        // 设置查询条件
        if (StringUtils.isNotBlank(act.getProcDefKey())){
            todoTaskQuery.processDefinitionKey(act.getProcDefKey());
        }
        if (act.getBeginDate() != null){
            todoTaskQuery.taskCreatedAfter(act.getBeginDate());
        }
        if (act.getEndDate() != null){
            todoTaskQuery.taskCreatedBefore(act.getEndDate());
        }
        // 根据当前人的ID查询
        List<Task> todoList = todoTaskQuery.list();

        // 根据当前人未签收的任务
        List<Task> unsignedTasks = taskService.createTaskQuery().processDefinitionKey(ActUtils.PD_REIMBURSEMENT[0]).taskCandidateUser(userId).active().orderByTaskPriority().desc().orderByTaskCreateTime().desc().list();
        // 合并
        tasks.addAll(todoList);
        tasks.addAll(unsignedTasks);
        // 根据流程的业务ID查询实体并关联
        for (Task task : tasks) {
            String processInstanceId = task.getProcessInstanceId();
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).active().singleResult();
            String businessKey = processInstance.getBusinessKey();
            WorkReimbursement workReimbursement = workReimbursementDao.get(businessKey);
            workReimbursement.setTask(task);
            workReimbursement.setProcessInstance(processInstance);
            workReimbursement.setProcessDefinition(repositoryService.createProcessDefinitionQuery().processDefinitionId((processInstance.getProcessDefinitionId())).singleResult());
            results.add(workReimbursement);
        }
        return results;
    }

    /**
     * 获取已办任务
     * @return
     */
    public List<WorkReimbursement> historicList(Act act){
        String userId = UserUtils.getUser().getId();//ObjectUtils.toString(UserUtils.getUser().getId());
//        HistoricTaskInstanceQuery histTaskQuery = historyService.createHistoricTaskInstanceQuery().taskAssignee(userId).finished()
//                .includeProcessVariables().orderByHistoricTaskInstanceEndTime().desc();
        HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery().finished().taskAssignee(userId);
        // 设置查询条件
        if (StringUtils.isNotBlank(act.getProcDefKey())){
            query.processDefinitionKey(act.getProcDefKey());
        }
        if (act.getBeginDate() != null){
            query.taskCompletedAfter(act.getBeginDate());
        }
        if (act.getEndDate() != null){
            query.taskCompletedBefore(act.getEndDate());
        }
        // 查询总数
//        page.setCount(histTaskQuery.count());
//        page.initialize();
        // 查询列表
//        List<HistoricTaskInstance> histList = histTaskQuery.listPage(page.getFirstResult(), page.getMaxResults());
        List<HistoricTaskInstance> list = query.list();
        List<WorkReimbursement> list1 = new ArrayList<>();
        Office office = UserUtils.getSelectCompany();
        String companyId = office==null?"":office.getId();
        for (HistoricTaskInstance histTask : list) {
            WorkReimbursement workReimbursement = this.getByProcessInstanceId(histTask.getProcessInstanceId());
            if (workReimbursement != null && workReimbursement.getCompanyId().equals(companyId)) {
                workReimbursement.setCreateBy(UserUtils.get(workReimbursement.getCreateBy().getId()));
                historyService.getHistoricIdentityLinksForProcessInstance(histTask.getProcessInstanceId());
                act.setHistTask(histTask);
                act.setVars(histTask.getProcessVariables());
                act.setStatus("finish");
                act.setProcDef(ProcessDefCache.get(histTask.getProcessDefinitionId()));
                workReimbursement.setAct(act);
                list1.add(workReimbursement);
            }
        }
//        workReimbursement.setPage(page);
        return list1;
    }
    /**
     * 获取流程详细信息
     * @param processInstanceId
     */
    @SuppressWarnings("unchecked")
    public WorkReimbursement getByProcessInstanceId(String processInstanceId) {
        WorkReimbursement workReimbursement = workReimbursementDao.getByProcessInstanceId(processInstanceId);
        return workReimbursement;
    }

    /**
     * 读取流程信息
     * @param page
     * @param workReimbursement
     * @return
     */
    public Page<WorkReimbursement> find(Page<WorkReimbursement> page, WorkReimbursement workReimbursement) {
        workReimbursement.getSqlMap().put("dsf", dataScopeFilter(workReimbursement.getCurrentUser(), "o", "u","", MenuStatusEnum.WORK_REIMBURSEMENT.getValue()));
        workReimbursement.setPage(page);
        page.setList(workReimbursementDao.findList(workReimbursement));

        for(WorkReimbursement item : page.getList()) {
            String processInstanceId = item.getProcessInstanceId();
            Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).active().singleResult();
            //item.setTask(task);
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            if(historicProcessInstance!=null) {
                item.setHistoricProcessInstance(historicProcessInstance);
                item.setProcessDefinition(repositoryService.createProcessDefinitionQuery().processDefinitionId(historicProcessInstance.getProcessDefinitionId()).singleResult());
            } else {
                ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).active().singleResult();
                if (processInstance != null){
                    item.setProcessDefinition(repositoryService.createProcessDefinitionQuery().processDefinitionId(processInstance.getProcessDefinitionId()).singleResult());
                    item.setProcessInstance(processInstance);
                }
            }
            ProcessInstance processInstance = actTaskService.getProcIns(item.getProcessInstanceId());
            if (processInstance!=null) {
                Task taskInfok = actTaskService.getCurrentTaskInfo(processInstance);
                if (StringUtils.isNotBlank(taskInfok.getAssignee()) && taskInfok.getAssignee().equals(UserUtils.getUser().getId())) {
                    item.setTask(taskInfok);
                }
            }
        }
        return page;
    }

    /**
     * 获取一条报销单信息
     * @param workReimbursement
     * @return
     */
    public WorkReimbursement findOne(WorkReimbursement workReimbursement) {
        String processInstanceId = workReimbursement.getProcessInstanceId();
//		Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).active().singleResult();
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        if(historicProcessInstance!=null) {
            workReimbursement.setHistoricProcessInstance(historicProcessInstance);
            workReimbursement.setProcessDefinition(repositoryService.createProcessDefinitionQuery().processDefinitionId(historicProcessInstance.getProcessDefinitionId()).singleResult());
        } else {
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).active().singleResult();
            if (processInstance != null){
                workReimbursement.setProcessInstance(processInstance);
                workReimbursement.setProcessDefinition(repositoryService.createProcessDefinitionQuery().processDefinitionId(processInstance.getProcessDefinitionId()).singleResult());
            }
        }
        ProcessInstance processInstance = actTaskService.getProcIns(workReimbursement.getProcessInstanceId());
        if (processInstance!=null) {
            Task taskInfok = actTaskService.getCurrentTaskInfo(processInstance);
            if (StringUtils.isNotBlank(taskInfok.getAssignee()) && taskInfok.getAssignee().equals(UserUtils.getUser().getId())) {
                workReimbursement.setTask(taskInfok);
            }
        }
        return workReimbursement;
    }

    /**
     * 报销作废：强制撤销
     * @param workReimbursement
     */
    @Transactional(readOnly = false)
    public void cancelInvalidate(WorkReimbursement workReimbursement) {
        String invalidateProcessInstanceId = workReimbursement.getProcessInstanceId();
        try {
            //将流程图中尚未走到的task的流程追踪信息逻辑删除，添加一条"撤销"流程追踪信息
            WorkActivityProcess process = new WorkActivityProcess();
            process.setProcessInstanceId(workReimbursement.getProcessInstanceId());
            process.setIsApproval("0");
            //List<WorkActivityProcess> processList1 = workActivityProcessService.findByProcInsId(process);
            WorkActivityProcess workActivityProcess = new WorkActivityProcess();
            workActivityProcess.setProcessInstanceId(workReimbursement.getProcessInstanceId());
            List<WorkActivityProcess> processList = workActivityProcessService.findList(workActivityProcess);
            WorkProjectNotify notify = new WorkProjectNotify();
            notify.setNotifyId(workReimbursement.getId());
            List<User> userList = workProjectNotifyService.readByNotifyId(notify);
            if (userList!=null && userList.size()!=0) {
                for (User u : userList) {
                    User user = UserUtils.get(u.getId());
                    UserUtils.pushMeIm(user.getId());
                }
            }
            if(processList!=null && processList.size()>0){
                for (int i =0;i<processList.size();i++) {
                    WorkActivityProcess p = processList.get(i);
                    if(StringUtils.isNotBlank(p.getIsApproval()) && "0".equals(p.getIsApproval())){
                        p.setDelFlag("1");
                        p.setIsApproval("-1");
                        workActivityProcessDao.updateDelFlagAndIsApproval(p);
                    }
                }
                WorkActivityProcess pro = new WorkActivityProcess();
                pro.setId("");
                pro.setDelFlag("0");
                pro.preInsert();
                pro.setRemarks("[强制撤销]");
                pro.setProcessKey(processList.get(0).getProcessKey());
                pro.setIsApproval("1");
                pro.setProcessInstanceId(processList.get(0).getProcessInstanceId());
                pro.setCount(0);
                workActivityProcessDao.insert(pro);
            }

            //结束该流程,设为"撤销"状态
            actTaskService.endProcessInstance(invalidateProcessInstanceId,"报销-强制撤销");
            workReimbursement.setStatus("3");
            workReimbursement.preUpdate();
            workReimbursementDao.update(workReimbursement);
        }catch (ActivitiObjectNotFoundException e){
            System.err.println("撤销报销作废异常，因为这个流程已不存在!");
            e.printStackTrace();
        }
        catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 查询待办任务
     *
     * @param userId
     *           必须依据用户编号查询
     * @return
     */
//    @Transactional(readOnly = true)
//    public List<WorkReimbursementCount> findTodoTasks(String userId) {
//        List<WorkReimbursementCount> results = new ArrayList<WorkReimbursementCount>();
//        // 根据当前人的ID查询
//        TaskQuery taskQuery = taskService.createTaskQuery().taskCandidateOrAssigned(userId);
//        List<Task> tasks = taskQuery.list();
//        // 根据流程的业务ID查询实体并关联
//        for (Task task : tasks) {
//            String processInstanceId = task.getProcessInstanceId();
//            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
//                    .processInstanceId(processInstanceId).active().singleResult();
//            String businessKey = processInstance.getBusinessKey();
//            if (businessKey == null) {
//                continue;
//            }
//            WorkReimbursementCount workReimbursement = workReimbursementDao.get(businessKey);
//            workReimbursement.setTask(task);
//            workReimbursement.setProcessInstance(processInstance);
//            workReimbursement.setProcessDefinition(workReimbursement.getProcessDefinition());
//            results.add(workReimbursement);
//        }
//        return results;
//    }


    /*-----------------======  新版本=====--------------------------*/

}