package com.uas.platform.b2b.service.impl;

import com.uas.message.mail.service.MailService;
import com.uas.platform.b2b.core.util.*;
import com.uas.platform.b2b.dao.*;
import com.uas.platform.b2b.erp.model.Inquiry;
import com.uas.platform.b2b.erp.model.QuotationDown;
import com.uas.platform.b2b.erp.model.QuotationDownDetail;
import com.uas.platform.b2b.event.PurchaseInquiryItemDecideReleaseEvent;
import com.uas.platform.b2b.event.PurchaseInquiryItemInvalidReleaseEvent;
import com.uas.platform.b2b.event.PurchaseInquiryItemReplyReleaseEvent;
import com.uas.platform.b2b.event.PurchaseInquiryItemSaveReleaseEvent;
import com.uas.platform.b2b.model.*;
import com.uas.platform.b2b.ps.service.PersonalProductService;
import com.uas.platform.b2b.search.SearchService;
import com.uas.platform.b2b.service.PurchaseInquiryService;
import com.uas.platform.b2b.support.MessageConf;
import com.uas.platform.b2b.support.SPageUtils;
import com.uas.platform.b2b.support.SystemSession;
import com.uas.platform.b2b.support.XingePusher;
import com.uas.platform.b2b.temporary.model.UserInfo;
import com.uas.platform.core.concurrent.IRunnable;
import com.uas.platform.core.exception.IllegalOperatorException;
import com.uas.platform.core.exception.IllegalStatusException;
import com.uas.platform.core.model.Constant;
import com.uas.platform.core.model.PageInfo;
import com.uas.platform.core.model.Status;
import com.uas.platform.core.persistence.criteria.PredicateUtils;
import com.uas.search.b2b.model.PageParams;
import com.uas.search.b2b.model.SPage;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;
import java.util.regex.Pattern;


@Service
public class PurchaseInquiryServiceImpl implements PurchaseInquiryService {

	@Autowired
	private PurchaseInquiryReplyDao purchaseInquiryReplyDao;

	@Autowired
	private PurchaseInquiryItemDao purchaseInquiryItemDao;

	@Autowired
	private PurchaseInquiryDao purchaseInquiryDao;

	@Autowired
	private AttachDao attachDao;

	@Autowired
	private UserBaseInfoDao userBaseInfoDao;

	@Autowired
	private SearchService searchService;

	@Autowired
	private CommonDao commonDao;

	@Autowired
	private ProductDao productDao;

	@Autowired
	private UserOrderDao userOrderDao;

	@Autowired
	private UserDao userDao;

	@Autowired
	private RoleDao roleDao;

	@Autowired
	private VendorDao vendorDao;

	@Autowired
	private DistributeDao distributeDao;

	@Autowired
	private MailService mailService;

	@Autowired
	private EnterpriseDao enterpriseDao;

	@Autowired
	private MessageConf messageConf;

	@Autowired
    private PurchaseInquiryItemTempDao tempDao;

	@Autowired
	private PurchaseInquiryTempDao inquiryTempDao;

	@Autowired
    private PersonalProductService personalProductService;

    static final String EMAIL_REGEXP = "\\w[-\\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\\.)+[A-Za-z]{2,14}";

    @Override
    public void saveList(List<PurchaseInquiryItemTemp> purchaseInquiryItemTemps) {
		try {
			for (PurchaseInquiryItemTemp itemTemp : purchaseInquiryItemTemps) {
				PurchaseInquiryTemp inquiryTemp = inquiryTempDao.findByCodeAndEnUU(itemTemp.getInquiry().getCode(), itemTemp.getInquiry().getEnUU());
				if (inquiryTemp == null) {
					PurchaseInquiryTemp temp = inquiryTempDao.save(itemTemp.getInquiry());
					itemTemp.setInId(temp.getId());
				} else {
					itemTemp.setInId(inquiryTemp.getId());
				}
			}
			purchaseInquiryItemTemps = tempDao.save(purchaseInquiryItemTemps);
		} catch (Exception e) {
			for (PurchaseInquiryItemTemp temp : purchaseInquiryItemTemps) {
				if (inquiryTempDao.exists(temp.getInId())) {
					inquiryTempDao.delete(temp.getInId());
				}
				throw new IllegalOperatorException("保存失败");
			}
		}
		List<PurchaseInquiryItem> inquiryItems = new ArrayList<PurchaseInquiryItem>();
		if (!CollectionUtils.isEmpty(purchaseInquiryItemTemps)) {
			for (PurchaseInquiryItemTemp temp : purchaseInquiryItemTemps) {
				PurchaseInquiryItem item = new PurchaseInquiryItem();
				BeanUtils.copyProperties(temp, item, PurchaseInquiryItem.class);
				item.setInquiry(purchaseInquiryDao.findOne(temp.getInId()));
				item.setProduct(productDao.findOne(temp.getProductId()));
			}
			saveUserOrders(inquiryItems);
			Long userUU = SystemSession.getUser().getUserUU();
			Long enUU = SystemSession.getUser().getEnterprise().getUu();
			String userIp = SystemSession.getUser().getIp();
			String userName = SystemSession.getUser().getUserName();
			sendRemind(PurchaseInquiryItem.distinct(inquiryItems), userUU, userName, userIp, enUU);
			// 产生消息
			List<PurchaseInquiry> inquiries = PurchaseInquiryItem.distinct(inquiryItems);
			List<PurchaseInquiryItem> items = new ArrayList<>();
			for (PurchaseInquiry inquiry : inquiries) {
				Set<Long> enUUs = new HashSet<>();
				for (PurchaseInquiryItem inquiryItem : inquiry.getInquiryItems()) {
					if (!enUUs.contains(inquiryItem.getVendUU())) {
						items.add(inquiryItem);
						enUUs.add(inquiryItem.getVendUU());
					}
				}
			}
			ContextUtils.publishEvent(new PurchaseInquiryItemSaveReleaseEvent(items));
		}
    }

	/**
	 * 保存至用户单据表
	 *
	 * @param purcitems 采购询价单
	 * @return
	 */
	private void saveUserOrders(final List<PurchaseInquiryItem> purcitems){
		ThreadTask.getInstance().execute(new Runnable() {
			@Override
			public void run() {
				/* 添加供应商的阅读记录*/
				for(PurchaseInquiryItem item : purcitems) {
					Set<Long> userUUs = new HashSet<>();
					// 添加管理员
					List<Role> roles = roleDao.findByEnUUAndIssys(item.getVendUU(), Constant.YES);
					if (!CollectionUtils.isEmpty(roles)) {
						List<User> admins = userDao.findByRole(roles.get(0).getId());
						for (User admin : admins) {
							if (!userUUs.contains(admin.getUserUU())) {
								userUUs.add(admin.getUserUU());
							}
						}
					}
					List<Vendor> vendors = vendorDao.findByMyEnUUAndVendUU(item.getInquiry().getEnUU(), item.getVendUU());
					// 查找有权限的用户
					if (!CollectionUtils.isEmpty(vendors)) {
						Long vendorId = vendors.get(0).getId();
						List<Distribute> distributes = distributeDao.findByVendorId(vendorId);
						if (!CollectionUtils.isEmpty(distributes)) {
							for (Distribute distribute : distributes) {
								if (!userUUs.contains(distribute.getUserUU())) {
									userUUs.add(distribute.getUserUU());
								}
							}
						}
					}
					UserOrders userOrders;
					List<UserOrders> list = new ArrayList<>();
					for (Long userUU : userUUs) {
						if (userUU == null) {
							continue;
						}
						userOrders = new UserOrders(userUU, item.getVendUU(), item.getId(), "sale", "v$purc$inquiryitems");
						list.add(userOrders);
					}

					/* 添加采购员的阅读记录*/
					if (item.getInquiry().getRecorderUU() != null) {
                        userOrders = new UserOrders(item.getInquiry().getRecorderUU(), item.getInquiry().getEnUU(), item.getId(), "purc", "v$purc$inquiryitems");
                        userOrders.setReadStatus((short) Status.READ.value());
                        list.add(userOrders);
                    }
					userOrderDao.save(list);
				}
			}
		});
	}

	/**
	 * 发送通知
	 *
	 * @param inquiries 采购询价单主表
	 * @param userUU
	 *@param userName
	 * @param userIp
	 * @param enUU @return
	 */
	private void sendRemind(final List<PurchaseInquiry> inquiries, final Long userUU, final String userName, final String userIp, final Long enUU){
		ThreadTask.getInstance().execute(new Runnable() {
			@Override
			public void run() {
				for (PurchaseInquiry inquiry : inquiries) {
					// 一个询价单，给一个企业只发一封邮件
					Set<Long> enUUs = new HashSet<>();
					for (PurchaseInquiryItem inquiryItem : inquiry.getInquiryItems()) {
						if (null != inquiryItem.getVendUU() && !enUUs.contains(inquiryItem.getVendUU())) {
							// 查找业务员邮箱
							String userEmailSql = "select distinct us.user_email ememail from sec$users us " +
									" left join sec$userrole ur on us.user_uu = ur.user_uu left join sec$roles sr " +
									" on ur.role_id = sr.role_id where sr.role_desc = '业务员' and us.user_email is not null " +
									" and sr.role_enuu = " + inquiryItem.getVendUU() + " and us.user_uu in (" +
									"select pd_useruu from purc$distribute where pd_vdid = (" +
									"select ve_id from purc$vendors where ve_myenuu = " + inquiry.getEnUU() + " and ve_vendenuu = " + inquiryItem.getVendUU() + "))";
							List<UserInfo> userEmails = commonDao.query(userEmailSql, UserInfo.class);
							String userTelSql = "select distinct us.user_tel emphone from sec$users us " +
									" left join sec$userrole ur on us.user_uu = ur.user_uu left join sec$roles sr " +
									" on ur.role_id = sr.role_id where sr.role_desc = '业务员' and us.user_tel is not null " +
									" and sr.role_enuu = " + inquiryItem.getVendUU() + " and us.user_uu in (" +
									"select pd_useruu from purc$distribute where pd_vdid = (" +
									"select ve_id from purc$vendors where ve_myenuu = " + inquiry.getEnUU() + " and ve_vendenuu = " + inquiryItem.getVendUU() + "))";
							List<UserInfo> userTels = commonDao.query(userTelSql, UserInfo.class);
							// 发邮件
							Map<String, Object> model = new HashMap<String, Object>();
							Enterprise vendor = enterpriseDao.findOne(inquiryItem.getVendUU());
							if (null != vendor) {
								model.put("vendorname", vendor.getEnName());
							} else {
								model.put("vendorname", "供应商");
							}
							model.put("custname", inquiry.getEnterprise().getEnName());
							model.put("code", inquiry.getCode());
							model.put("date", DateFormatUtils.DATE_FORMAT.format(new Date()));
							// 不存在被分配客户的业务员则添加系统管理员
							if (CollectionUtils.isEmpty(userEmails) && CollectionUtils.isEmpty(userTels)) {
								Enterprise enterprise = enterpriseDao.findOne(inquiryItem.getVendUU());
								if (null != enterprise) {
									User admin = userDao.findOne(enterprise.getEnAdminuu());
									if (null != admin) {
										UserInfo adminInfo = new UserInfo(admin);
										userEmails.add(adminInfo);
										userTels.add(adminInfo);
									}
								}
							}
							for (UserInfo userEmail : userEmails) {
								if (Pattern.matches(EMAIL_REGEXP, userEmail.getEmemail())) {
									try {
										// 调用自动询价消息模版id
										mailService.send(messageConf.getTplAutoInquiryForB2B(), userEmail.getEmemail(), model);
									} catch (Exception e) {
										e.printStackTrace();
									}
								}
							}
							enUUs.add(inquiryItem.getVendUU());
						}
					}
				}
			}
		});
	}

	@Override
	public List<PurchaseInquiryItem> findNotUploadReply() {
        List<PurchaseInquiryItem> items =  purchaseInquiryItemDao.findByEnUUAndBackStatus(SystemSession.getUser().getEnterprise().getUu(),
                (short) Status.NOT_UPLOAD.value());
        if(!CollectionUtils.isEmpty(items)) {
            purchaseInquiryItemDao.updateStatus(SystemSession.getUser().getEnterprise().getUu(), Constant.NO);
        }
		return items;
	}

	@Override
	public void onReplyUploadSuccess(String[] idArray) {
		for (String id : idArray) {
			PurchaseInquiryItem item = purchaseInquiryItemDao.findOne(Long.parseLong(id));
			if (item != null) {
				item.setBackStatus((short) Status.DOWNLOADED.value());
				item.setErpstatus(Constant.YES);
				purchaseInquiryItemDao.save(item);
			}
		}
	}

	@Override
	public void onReplyDecide(List<PurchaseInquiryItem> inquiryItems) {
		for (PurchaseInquiryItem inquiryItem : inquiryItems) {
            purchaseInquiryItemDao.updateDecideStatusByID(inquiryItem.getAgreed(), inquiryItem.getDecideStatus(), inquiryItem.getId());
        }
		ContextUtils.publishEvent(new PurchaseInquiryItemDecideReleaseEvent(inquiryItems));
	}

	@Override
	public List<PurchaseInquiryItem> findNotUploadInquiry() {
		return purchaseInquiryItemDao.findByVendUUAndSendStatus(SystemSession.getUser().getEnterprise().getUu(),
				(short) Status.NOT_UPLOAD.value());
	}

	@Override
	public void onQuotationDownSuccess(String[] idArray) {
		for (String id : idArray) {
			PurchaseInquiryItem item = purchaseInquiryItemDao.findOne(Long.parseLong(id));
			if (item != null) {
				item.setSendStatus((short) Status.DOWNLOADED.value());
				purchaseInquiryItemDao.save(item);
			}
		}
	}

	@Override
	@Transactional
	public void reply(List<QuotationDown> downs) {
		for (QuotationDown down : downs) {
			PurchaseInquiryItem item = purchaseInquiryItemDao.findOne(down.getB2b_id_id());
			if (item != null) {
				item.setMinOrderQty(down.getQu_minbuyqty());
				item.setMinPackQty(down.getQu_minqty());
				item.setVendFromDate(down.getQu_fromdate());
				item.setVendToDate(down.getQu_todate());
				item.setStatus((short) Status.REPLIED.value());
				item.setBackStatus((short) Status.NOT_UPLOAD.value());
				item.setReplySendStatus((short) Status.DOWNLOADED.value());
				item.setRemark(String.valueOf(System.currentTimeMillis()));
				item.setBrand(down.getQu_brand());// 供应商物料品牌
				item.setVendorprodcode(down.getQu_prodcode());// 供应商物料编号
				item.setLeadtime(down.getQu_leadtime());// 交货日期
				if (!CollectionUtils.isEmpty(down.getDetails())) {
					purchaseInquiryReplyDao.delete(item.getReplies());
					Set<PurchaseInquiryReply> replies = new HashSet<PurchaseInquiryReply>();
					for (QuotationDownDetail detail : down.getDetails()) {
						replies.add(detail.convert());
					}
					item.setReplies(replies);
				}
				Long userUU = item.getUserUU();
				if (userUU == null) {
					userUU = item.getInquiry().getRecorderUU();
				}
				if (userUU != null && userUU != 0) {
					// 消息推送
					UserBaseInfo user = userBaseInfoDao.findOne(userUU);
					XingePusher.pushByUser(user, "询价单回复", "单号:" + item.getInquiry().getCode() + ",第" + item.getNumber() + "行", "", "");
				}
				purchaseInquiryItemDao.save(item);
			}
		}
	}

	@Override
	public List<PurchaseInquiryItem> findNotUploadInquiryReply() {
		return purchaseInquiryItemDao.findByVendUUAndReplySendStatus(SystemSession.getUser().getEnterprise().getUu(),
				(short) Status.NOT_REPLY.value());
	}

	@Override
	public void onReplyDownSuccess(String[] idArray) {
		for (String id : idArray) {
			PurchaseInquiryItem item = purchaseInquiryItemDao.findOne(Long.parseLong(id));
			if (item != null) {
				item.setReplySendStatus((short) Status.DOWNLOADED.value());
				purchaseInquiryItemDao.save(item);
			}
		}
	}

	@Override
	public List<PurchaseInquiryItem> findNotUploadInquiryReplyDecide() {
		return purchaseInquiryItemDao.findByVendUUAndDecideStatus(SystemSession.getUser().getEnterprise().getUu(),
				(short) Status.NOT_UPLOAD.value());
	}

	@Override
	public void onReplyDecideDownSuccess(String[] idArray) {
		for (String id : idArray) {
			PurchaseInquiryItem item = purchaseInquiryItemDao.findOne(Long.parseLong(id));
			if (item != null) {
				item.setDecideStatus((short) Status.DOWNLOADED.value());
				purchaseInquiryItemDao.save(item);
			}
		}
	}

    @Override
	public void onReplyInvalidDownSuccess(String[] idArray) {
		for (String id : idArray) {
			PurchaseInquiryItem item = purchaseInquiryItemDao.findOne(Long.parseLong(id));
			if (item != null) {
				item.setInvalidStatus((short) Status.DOWNLOADED.value());
				purchaseInquiryItemDao.save(item);
			}
		}
	}

	/**
	 * 不使用关键词搜索时，从数据库直接获取已失效询价单列表
	 *
	 * @param pageInfo 页面参数
	 * @param keyword  关键词
	 * @param filter   搜索过滤条件
	 * @return
	 */
	@Override
	public SPage<PurchaseInquiryItem> findInvalidByPageInfo(PageInfo pageInfo, String keyword, SearchFilter filter) {
		Date date = new Date();
		Calendar now = Calendar.getInstance();
		now.setTime(date);
		// 判断时间设置为23：59：59 ，截止报价日期当天也可报价
		now.set(Calendar.HOUR_OF_DAY, 23);
		now.set(Calendar.MINUTE, 59);
		now.set(Calendar.SECOND, 59);
		// 增加已失效过滤条件
		pageInfo.expression(PredicateUtils.or(
				// 状态为314 已作废
				PredicateUtils.eq("status", Status.DISABLED.value(), false),
				// invalid 为1，已过客户报价有效截止日期
				PredicateUtils.eq("invalid", Constant.YES, true),
				// 未回复且客户系统已提交(this.status == 200 && null != this.getInquiry().getCheck() && this.getInquiry().getCheck() == 1)
				PredicateUtils.and(PredicateUtils.eq("status", Status.NOT_REPLY.value(), false),
						PredicateUtils.eq("inquiry.check", Constant.YES, false)),
				// 未回复但是已过报价截止日期
				PredicateUtils.and(PredicateUtils.eq("status", Status.NOT_REPLY.value(), false),
						PredicateUtils.lte("inquiry.endDate", now.getTime(), false))

		));
		return findByPageInfo(pageInfo, keyword, filter);
	}

    /**
     * 不使用关键词搜索时，从数据库直接获取待报价询价单列表
     *
     * @param pageInfo 页面参数
     * @param keyword  关键词
     * @param filter   搜索过滤条件
     * @return
     */
    @Override
    public SPage<PurchaseInquiryItem> findTodoByPageInfo(PageInfo pageInfo, String keyword, SearchFilter filter) {
        // 提交状态不为1
        pageInfo.expression(PredicateUtils.or(PredicateUtils.isNull("inquiry.check"), PredicateUtils.eq("inquiry.check", Constant.NO, false)));
        return findByPageInfo(pageInfo, keyword, filter);
    }

    @Override
	public SPage<PurchaseInquiryItem> findByPageInfo(final PageInfo pageInfo, final String keyword,
			final SearchFilter filter) {
		Page<PurchaseInquiryItem> inquiryitems = purchaseInquiryItemDao
				.findAll(new Specification<PurchaseInquiryItem>() {
			@Override
            public Predicate toPredicate(Root<PurchaseInquiryItem> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
				if (filter != null) {
					if (!CollectionUtils.isEmpty(filter.getDistribute())) {
                        pageInfo.expression(PredicateUtils.in("inquiry.enUU", filter.getDistribute(), false));
                    }
					if (filter.getFromDate() != null) {
                        pageInfo.expression(PredicateUtils.gte("inquiry.date", new Date(filter.getFromDate()), false));
                    }
					if (filter.getEndDate() != null) {
                        pageInfo.expression(PredicateUtils.lte("inquiry.date", new Date(filter.getEndDate()), false));
                    }
				}
				if (StringUtils.hasText(keyword)) {
					List<Object> lists = new ArrayList<>();
					PageParams pageParams = new PageParams();
					ModelMap map = new ModelMap();
					map.put("id_venduu", SystemSession.getUser().getEnterprise().getUu());
					pageParams.setFilters(map);
					for (PurchaseInquiryItem list : searchService.searchPurchaseInquiryItemIds(keyword, pageParams).getContent()) {
						lists.add(list.getId());
					}
					pageInfo.expression(PredicateUtils.in("id", lists, false));
				}
				return query.where(pageInfo.getPredicates(root, query, builder)).getRestriction();
			}
		}, pageInfo);
		return SPageUtils.covertSPage(inquiryitems);
	}

	@Override
	public Page<PurchaseInquiryItem> findAllByPageInfo(final PageInfo pageInfo, final String keyword,
			final SearchFilter filter) {
		return purchaseInquiryItemDao.findAll(new Specification<PurchaseInquiryItem>() {
			@Override
            public Predicate toPredicate(Root<PurchaseInquiryItem> root, CriteriaQuery<?> query,
                                         CriteriaBuilder builder) {
				if (filter != null) {
					if (!CollectionUtils.isEmpty(filter.getDistribute())) {
                        pageInfo.expression(PredicateUtils.in("inquiry.enUU", filter.getDistribute(), false));
                    }
					if (filter.getFromDate() != null) {
                        pageInfo.expression(PredicateUtils.gte("date", new Date(filter.getFromDate()), false));
                    }
					if (filter.getEndDate() != null) {
                        pageInfo.expression(PredicateUtils.lte("date", new Date(filter.getEndDate()), false));
                    }
				}
				if (!StringUtils.isEmpty(keyword)) {
					PageParams pageParams = new PageParams();
					ModelMap map = new ModelMap();
					List<Long> lists = new ArrayList<>();
					map.put("id_venduu", SystemSession.getUser().getEnterprise().getUu());
					pageParams.setFilters(map);
					for (PurchaseInquiryItem list : searchService.searchPurchaseInquiryItemIds(keyword, pageParams)
							.getContent()) {
						lists.add(list.getId());
					}
					pageInfo.expression(PredicateUtils.in("id", lists, false));
				}
				return query.where(pageInfo.getPredicates(root, query, builder)).getRestriction();
			}
		}, pageInfo);
	}

	@Override
	public List<PurchaseInquiryItem> findById(Long id) {
		return purchaseInquiryItemDao.findByVendUUAndInquiry(SystemSession.getUser().getEnterprise().getUu(), id);
	}

	@Override
	public PurchaseInquiryItem findItemByItemId(Long itemId) {
		return purchaseInquiryItemDao.findOne(itemId);
	}

	@Override
	public PurchaseInquiryItem save(PurchaseInquiryItem inquiryItem) {
		return purchaseInquiryItemDao.save(inquiryItem);
	}

	/**
	 * 校验询价单回复记录
	 *
	 * @param current
	 * @param origin
	 */
	private void checkInquiryItemReplies(PurchaseInquiryItem current, PurchaseInquiryItem origin) {
		if (null != current.getReplies()) {
			for (PurchaseInquiryReply reply : current.getReplies()) {
				if (null == reply.getLapQty()) {
					reply.setLapQty(0D);
				}
				if (null != origin.getReplies()) {
					for (PurchaseInquiryReply originReply : origin.getReplies()) {
						// 分段数量一致的情况下，通过PurchaseInquiryReply.id防重复
						if (null != originReply.getLapQty() && Objects.equals(originReply.getLapQty(), reply.getLapQty())) {
							reply.setId(originReply.getId());
							break;
						}
					}
				}
			}
		}
	}

	@SuppressWarnings("deprecation")
	@Override
	public void saveAttach(List<Attach> attachs) {
		List<Attach> validAttachs = new ArrayList<Attach>();
		if (!CollectionUtils.isEmpty(attachs)) {
			long enUU = SystemSession.getUser().getEnterprise().getUu();
			for (Attach attach : attachs) {
				List<PurchaseInquiry> inquiries = purchaseInquiryDao.findByEnUUAndSourceId(enUU, Long.parseLong(attach.getSourceId()));
				if (!CollectionUtils.isEmpty(inquiries)) {
					PurchaseInquiry inquiry = inquiries.get(0);
					attach.setRelativeTable("purc$inquiry");
					attach.setRelativeKey(inquiry.getId());
					validAttachs.add(attach);
				}
			}
		}
		if (!CollectionUtils.isEmpty(validAttachs)) {
			attachDao.save(validAttachs);
		}
	}

	@Override
	public void check(Long[] sourceIds) {
		// UAS报价单提交时，需要更新采购询价单明细触发器中的监听字段，触发索引更新，来让待报价但已提交的单据进入已失效列表
		List<PurchaseInquiryItem> saveItems = new ArrayList<>();
		for (Long sourceId : sourceIds) {
			List<PurchaseInquiry> inquiries = purchaseInquiryDao.findByEnUUAndSourceId(SystemSession.getUser().getEnterprise().getUu(), sourceId);
			if (!CollectionUtils.isEmpty(inquiries)) {
				for (PurchaseInquiryItem inquiryItem : inquiries.get(0).getInquiryItems()) {
					inquiryItem.setErpstatus(Constant.NO);  // 修改此字段触发索引
					saveItems.add(inquiryItem);
				}
			}
		}
		purchaseInquiryItemDao.save(saveItems);
		purchaseInquiryDao.updateByCheck(Constant.YES, SystemSession.getUser().getEnterprise().getUu(), sourceIds);
	}

	@Override
	public void reCheck(Long[] sourceIds) {
		// UAS报价单反提交时，需要更新采购询价单明细触发器中的监听字段，触发索引更新，来让待报价被反提交的单据从已失效回到待报价列表
		List<PurchaseInquiryItem> saveItems = new ArrayList<>();
		List<PurchaseInquiry> saveInquiries = new ArrayList<>();
		for (Long sourceId : sourceIds) {
			List<PurchaseInquiry> inquiries = purchaseInquiryDao.findByEnUUAndSourceId(SystemSession.getUser().getEnterprise().getUu(), sourceId);
			if (!CollectionUtils.isEmpty(inquiries)) {
				PurchaseInquiry inquiry = inquiries.get(0);
				inquiry.setCheck(Constant.NO);  // 反提交
				saveInquiries.add(inquiry);
				for (PurchaseInquiryItem inquiryItem : inquiry.getInquiryItems()) {
					inquiryItem.setErpstatus(Constant.YES);  // 修改此字段触发索引
					saveItems.add(inquiryItem);
				}
			}
		}
		purchaseInquiryDao.save(saveInquiries);
		purchaseInquiryItemDao.save(saveItems);
	}

	@Override
	public void onReplyInvalid(List<Inquiry> inquiries) {
		final Long enuu = SystemSession.getUser().getEnterprise().getUu();
		final List<PurchaseInquiryItem> newInquiryItems = new ArrayList<>();
		ThreadUtils.tasks(new IRunnable<Inquiry>() {

			@Override
			public void run(Inquiry inquiry) {
				List<PurchaseInquiry> purchaseInquiries = purchaseInquiryDao.findByEnUUAndSourceId(enuu, inquiry.getIn_id());
				if (!CollectionUtils.isEmpty(purchaseInquiries)) {
					PurchaseInquiry purchaseInquiry = purchaseInquiries.get(0);
					for (PurchaseInquiryItem item : purchaseInquiry.getInquiryItems()) {
						item.setStatus((short) Status.DISABLED.value());
						item.setInvalidStatus((short) Status.NOT_UPLOAD.value()); // 获取作废信息时，更新作废上传状态为 待上传
						synchronized (newInquiryItems) {
							newInquiryItems.add(item);
						}
					}
				}
			}

		}, inquiries).run();
		List<PurchaseInquiryItem> savedInquiryItems = purchaseInquiryItemDao.save(newInquiryItems);
		// 触发消息事件
		ContextUtils.publishEvent(new PurchaseInquiryItemInvalidReleaseEvent(savedInquiryItems));
	}

    /**
     * 根据询价单明细id返回询价单明细
     *
     * @param itemId 询价单明细id
     * @return
     */
    @Override
    public PurchaseInquiryItem getInquiryItemByItemId(Long itemId) {
        return purchaseInquiryItemDao.findOne(itemId);
    }

	/**
	 * 查找所有待上传到卖家ERP的报价信息的作废决定
	 *
	 * @return
	 */
	@Override
	public List<PurchaseInquiryItem> findNotUploadInquiryReplyInvalid() {
		return purchaseInquiryItemDao.findByVendUUAndInvalidStatus(SystemSession.getUser().getEnterprise().getUu(),
				(short) Status.NOT_UPLOAD.value());
	}

    @Override
    @Transactional
    public PurchaseInquiryItem reply(PurchaseInquiryItem inquiryItem) {
        PurchaseInquiryItem item = purchaseInquiryItemDao.findOne(inquiryItem.getId());
        if (!item.isReplyable()) {
            throw new IllegalStatusException("该询价单已经报价，不允许再次报价");
        }
        if ((item.getInquiry().getCheck() != null && item.getInquiry().getCheck() == Constant.YES) || (item.getAgreed() != null)) {
            throw new IllegalOperatorException("报价失败，客户系统已经提交了该询价单");
        }
        // 判断是回复报价还是修改报价
        Short status = inquiryItem.getStatus();
        inquiryItem.setStatus((short) Status.REPLIED.value());
        inquiryItem.setBackStatus((short) Status.NOT_UPLOAD.value());
        inquiryItem.setReplySendStatus((short) Status.NOT_UPLOAD.value());
        // 将采纳状态设置成申请状态，方便过滤
        inquiryItem.setDecideStatus((short) Status.UNAUDIT.value());
        // 防回复记录重复
        checkInquiryItemReplies(inquiryItem, item);
        Long userUU = inquiryItem.getUserUU();
        if (userUU == null) {
            userUU = item.getInquiry().getRecorderUU();
        }
        if (userUU != null && userUU != 0) {
            // 消息推送
            XingePusher.pushByUserUU(userUU, "询价单回复", "单号:" + item.getInquiry().getCode() + ",第" + item.getNumber() + "行", "", "");
        }
        PurchaseInquiryItem purchaseInquiryItem = purchaseInquiryItemDao.save(inquiryItem);
        // 产生消息
        if ("B2B".equals(purchaseInquiryItem.getSourceApp())) { // b2b的询价单才产生消息，erp的询价单会在erp产生消息
            List<PurchaseInquiryItem> inquiryItems = new ArrayList<>();
            // 判断是回复报价还是修改报价
            inquiryItem.setStatus(status);
            inquiryItems.add(purchaseInquiryItem);
            ContextUtils.publishEvent(new PurchaseInquiryItemReplyReleaseEvent(inquiryItems));
        }
        // 更新个人物料库信息
        personalProductService.covertPersonalProduct(purchaseInquiryItem.getProductId(), "客户询价单报价");
        return purchaseInquiryItem;
    }

}
