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

import com.uas.platform.b2b.core.util.ContextUtils;
import com.uas.platform.b2b.core.util.ThreadTask;
import com.uas.platform.b2b.dao.*;
import com.uas.platform.b2b.event.PurchaseOrderEndReleaseEvent;
import com.uas.platform.b2b.event.PurchaseOrderReplyReleaseEvent;
import com.uas.platform.b2b.event.PurchaseOrderSaveReleaseEvent;
import com.uas.platform.b2b.model.*;
import com.uas.platform.b2b.ps.service.PersonalProductService;
import com.uas.platform.b2b.service.PurchaseOrderService;
import com.uas.platform.b2b.support.SystemSession;
import com.uas.platform.b2b.support.XingePusher;
import com.uas.platform.core.exception.IllegalOperatorException;
import com.uas.platform.core.exception.NotFoundException;
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.platform.core.util.NumberUtil;
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.util.CollectionUtils;

import javax.persistence.criteria.*;
import java.util.*;

@Service
@Transactional
public class PurchaseOrderServiceImpl implements PurchaseOrderService {

	@Autowired
	private PurchaseOrderDao purchaseOrderDao;

	@Autowired
	private PurchaseOrderAllDao purchaseOrderAllDao;

	@Autowired
	private PurchaseOrderTodoDao purchaseOrderTodoDao;

	@Autowired
	private PurchaseOrderDoneDao purchaseOrderDoneDao;

	@Autowired
	private PurchaseOrderEndDao purchaseOrderEndDao;

	@Autowired
	private PurchaseOrderReplyDao purchaseOrderReplyDao;

	@Autowired
	private PurchaseOrderWaitingDao purchaseOrderWaitingDao;

	@Autowired
	private PurchaseOrderReceivedDao purchaseOrderReceivedDao;

	@Autowired
	private PurchaseOrderItemDao purchaseOrderItemDao;

	@Autowired
	private EnterpriseDao enterpriseDao;

	@Autowired
	private UserBaseInfoDao userBaseInfoDao;

	@Autowired
	private UserOrderDao userOrderDao;

	@Autowired
	private PrintLogDao printLogDao;

	@Autowired
	private PurcOrderInfoItemDao purcOrderInfoItemDao;

	@Autowired
	private UserDao userDao;

	@Autowired
	private RoleDao roleDao;

	@Autowired
	private VendorDao vendorDao;

	@Autowired
	private DistributeDao distributeDao;

	@Autowired
    private PersonalProductService personalProductService;

	@Override
	public void save(List<PurcOrderInfoItem> orderItems) {
	 	orderItems = purcOrderInfoItemDao.save(orderItems);
		List<PurchaseOrderInfo> orderAlls = PurcOrderInfoItem.distinct(orderItems);
		List<PurchaseOrderInfo> newOrderAlls = new ArrayList<>();
		for (PurchaseOrderInfo orderAll : orderAlls) {
			if (orderAll.getUser() == null) {
				User user = userDao.findOne(orderAll.getUserUU());
				if (user == null) {
					Enterprise enterprise = enterpriseDao.findOne(orderAll.getEnUU());
					user = userDao.findOne(enterprise.getEnAdminuu());
				}
				orderAll.setUser(user);
			}
			// 为空设置成企业管理员
			if (orderAll.getVendUserUU() == null) {
                Enterprise vendor = enterpriseDao.findOne(orderAll.getVendUU());
                orderAll.setVendUserUU(vendor.getEnAdminuu());
            }
            // 更新我的产品库
            if (!CollectionUtils.isEmpty(orderAll.getOrderItems())) {
			    for (PurcOrderInfoItem item : orderAll.getOrderItems()) {
					personalProductService.covertPersonalProduct(item.getProductId(), "erp上传采购单");
                }
            }
            newOrderAlls.add(orderAll);
		}
		saveUserOrders(orderAlls);
		ContextUtils.publishEvent(new PurchaseOrderSaveReleaseEvent(orderAlls));
	}

	/**
	 * 保存至用户单据表
	 *
	 * @param orders 采购订单
	 * @return
	 */
	private void saveUserOrders(final List<PurchaseOrderInfo> orders){
		ThreadTask.getInstance().execute(new Runnable() {
			@Override
			public void run() {
				/* 添加供应商的阅读记录*/
				Set<Long> userUUs = new HashSet<>();
				List<UserOrders> list = new ArrayList<>();
				for (PurchaseOrderInfo order : orders) {
					// 添加管理员
					List<Role> roles = roleDao.findByEnUUAndIssys(order.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(order.getEnUU(), order.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;
					for (Long userUU : userUUs) {
						if (userUU == null) {
							continue;
						}
						userOrders = new UserOrders(userUU, order.getVendUU(), order.getId(), "sale", "purc$orders");
						list.add(userOrders);
					}
					/* 添加采购员的阅读记录*/
					if (order.getUserUU() != null) {
                        userOrders = new UserOrders(order.getUserUU(), order.getEnUU(), order.getId(), "purc", "purc$orders");
					    userOrders.setReadStatus((short) Status.READ.value());
                        list.add(userOrders);
                    }
				}
				userOrderDao.save(list);
			}
		});
	}

	@Override
	public Page<PurchaseOrder> findAllByPageInfo(final PageInfo pageInfo, final SearchFilter filter) {
		if (filter != null) {
			if (!CollectionUtils.isEmpty(filter.getDistribute())) {
                pageInfo.expression(PredicateUtils.in("enUU", filter.getDistribute(), false));
            }
		}
		return purchaseOrderDao.findAll(new Specification<PurchaseOrder>() {
			@Override
			public Predicate toPredicate(Root<PurchaseOrder> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
				query.where(pageInfo.getPredicates(root, query, builder));
				return null;
			}
		}, pageInfo);
	}

	@Override
	public Page<PurchaseOrderAll> findAllDetailByPageInfo(final PageInfo pageInfo, final SearchFilter filter) {
		if (filter != null) {
			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 (!CollectionUtils.isEmpty(filter.getDistribute())) {
                pageInfo.expression(PredicateUtils.in("enUU", filter.getDistribute(), false));
            }
		}
		Page<PurchaseOrderAll> pageOrders = purchaseOrderAllDao.findAll(new Specification<PurchaseOrderAll>() {
			@Override
			public Predicate toPredicate(Root<PurchaseOrderAll> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
				Predicate[] predicates = pageInfo.getPredicates(root, query, builder);
				if (filter != null && filter.getFromDelivery() != null) {
					predicates = Arrays.copyOf(predicates, predicates.length + 1);
					SetJoin<PurchaseOrderAll, PurchaseOrderAllItem> join = root
							.join(root.getModel().getSet("orderItems", PurchaseOrderAllItem.class), JoinType.INNER);
					Predicate p = builder.greaterThanOrEqualTo(join.get("delivery").as(Date.class),
							new Date(filter.getFromDelivery()));
					predicates[predicates.length - 1] = p;
				}
				return query.where(predicates).getRestriction();
			}
		}, pageInfo);
		List<PurchaseOrderAll> orders = pageOrders.getContent();
		for (PurchaseOrderAll order : orders) {
			Enterprise enter = enterpriseDao.findEnterpriseByUu(order.getVendUU());
			if (enter != null) {
				order.setEnName(enter.getEnName());
			}
			if (!CollectionUtils.isEmpty(order.getOrderItems())) {
			    for (PurchaseOrderAllItem item : order.getOrderItems()) {
			        item.setLatestReplyQty(findLastReplyQty(item.getId()));
                }
            }
		}
		return pageOrders;
	}

	@Override
	@Transactional
	public PurchaseOrderReply reply(PurchaseOrderReply reply) {
		PurchaseOrderReply purchaseOrderReply = reply(reply, true);
		// 单条回复产生消息
		List<PurchaseOrderItem> newOrderItems = new ArrayList<>();
		newOrderItems.add(reply.getOrderItem());
		ContextUtils.publishEvent(new PurchaseOrderReplyReleaseEvent(PurchaseOrderItem.distinct(newOrderItems)));
		return purchaseOrderReply;
	}

	/**
	 * @param reply
	 * @param isB2b
	 *            是否b2b新增
	 */
	private PurchaseOrderReply reply(PurchaseOrderReply reply, boolean isB2b) {
		if (isB2b) {
			reply.setDate(new Date());
			// 作为B2B->买家ERP数据是否已传输的标志--为传输
			reply.setStatus((short) Status.NOT_UPLOAD.value());
			// 作为B2B->卖家ERP数据是否已传输的标志--为传输
			reply.setSendStatus((short) Status.NOT_UPLOAD.value());
			reply.setRecorder(SystemSession.getUser().getUserName());
			reply.setType("供应商平台回复");
		}
		PurchaseOrderItem item = purchaseOrderItemDao.findOne(reply.getOrderItem().getId());
		Double replyQty = item.getReplyQty();
		replyQty = replyQty == null ? 0 : replyQty;
		item.setReplyQty(replyQty + reply.getQty());
		if (item.getReplyQty() < 0) {
			throw new IllegalOperatorException("回复的数量合计不能为负数");
		}
		reply.setOrderItem(item);
		reply = purchaseOrderReplyDao.save(reply);
		if (item.getReplyQty() >= item.getQty()) {
			item.setStatus((short) Status.REPLIED.value());
		} else {
			item.setStatus((short) Status.NOT_REPLY.value());
		}
		purchaseOrderItemDao.updateByReply(reply.getDelivery(), reply.getRemark(), item.getId(), item.getStatus());
		PurchaseOrder order = item.getOrder();
		// 订单主记录状态
		order = updateOrderStatus(order.getId());
		// 将回复信息推送给采购企业采购员（或管理员）
		if (order.getUserUU() != null) {
			Enterprise vendor = enterpriseDao.findOne(order.getVendUU());
			if (vendor != null) {
				UserBaseInfo user = userBaseInfoDao.findOne(order.getUserUU());
				XingePusher.pushByUser(user, "新增采购单回复", "单号:" + order.getCode() + ",供应商:" + vendor.getEnName(), "", "");
			}
		}
		return reply;
	}

	/**
	 * 修改客户采购单的状态
	 */
	private PurchaseOrder updateOrderStatus(long orderId) {
		int notReply = purchaseOrderItemDao.getCountByStatus(orderId, (short) Status.NOT_REPLY.value());
		PurchaseOrder order = purchaseOrderDao.findOne(orderId);
		if (order.getDisplay() == 1) {
			// 设置查看状态为已查看
            order.setDisplay(Constant.NO);
        }
		order.setStatus((short) (notReply > 0 ? Status.NOT_REPLY.value() : Status.REPLIED.value()));
		if (purchaseOrderItemDao.getCountByReply(orderId) > 0) {
            order.setReply(Constant.YES);
        } else {
            order.setReply(Constant.NO);
        }
		if (purchaseOrderItemDao.getCountByEnd(orderId, Constant.YES) > 0) {
            order.setEnd(Constant.YES);
        } else {
            // 反结案之后
            order.setEnd(Constant.NO);
        }
		order = purchaseOrderDao.save(order);
		return order;
	}

	@Override
	public PurchaseOrderAll findById(Long id) {
		PurchaseOrderAll purchaseOrderAll = purchaseOrderAllDao.findOne(id);
		if (purchaseOrderAll == null) {
			throw new NotFoundException();
		}
		if (!CollectionUtils.isEmpty(purchaseOrderAll.getOrderItems())) {
			for (PurchaseOrderAllItem item : purchaseOrderAll.getOrderItems()) {
				item.setLatestReplyQty(findLastReplyQty(item.getId()));
			}
		}
		return purchaseOrderAll;
	}

	@Override
	public List<PurchaseOrderReply> reply(String[] orderItemIdString, Long date) {
		List<PurchaseOrderReply> replies = new ArrayList<PurchaseOrderReply>();
		List<PurchaseOrderItem> itemList = new ArrayList<>();
		for (String orderItemId : orderItemIdString) {
			PurchaseOrderItem orderItem = purchaseOrderItemDao.findOne(Long.parseLong(orderItemId));
			itemList.add(orderItem);
			PurchaseOrderReply reply = new PurchaseOrderReply();
			reply.setOrderItem(orderItem);
			// 指定交货日期
			if (date != null) {
				reply.setDelivery(new Date(date));
			} else { // 默认交货日期
				reply.setDelivery(orderItem.getDelivery());
			}
			reply.setRemark("批量回复");
			if (orderItem.getReplyQty() == null) {
				orderItem.setReplyQty((double) 0);
			}
			reply.setQty(orderItem.getQty() - orderItem.getReplyQty());
			reply = reply(reply, true);
			if (reply != null) {
				replies.add(reply);
			}
		}
		// 触发回复事件  批量回复只产生一条消息
		ContextUtils.publishEvent(new PurchaseOrderReplyReleaseEvent(PurchaseOrderItem.distinct(itemList)));
		return replies;
	}

	@Override
	public List<PurchaseOrderReply> findReplyByOrderItem(long orderItemId) {
		return purchaseOrderReplyDao.findByOrderItemId(orderItemId);
	}

	@Override
	public List<PurchaseOrderReply> findNotUploadReply() {
		return purchaseOrderReplyDao.findByEnUUAndStatus(SystemSession.getUser().getEnterprise().getUu(),
				(short) Status.NOT_UPLOAD.value());
	}

	@Override
	public List<PurchaseOrderReply> findNotSendReply() {
		return purchaseOrderReplyDao.findByVendUUAndSendStatus(SystemSession.getUser().getEnterprise().getUu(),
				(short) Status.NOT_UPLOAD.value());
	}

	@Override
	public void onReplyUploadSuccess(String[] idArray) {
		for (String id : idArray) {
			PurchaseOrderReply reply = purchaseOrderReplyDao.findOne(Long.parseLong(id));
			if (reply != null) {
				reply.setStatus((short) Status.DOWNLOADED.value());
				purchaseOrderReplyDao.save(reply);
			}
		}
	}

	@Override
	public void onReplyDownSuccess(String[] idArray) {
		for (String id : idArray) {
			PurchaseOrderReply reply = purchaseOrderReplyDao.findOne(Long.parseLong(id));
			if (reply != null) {
				reply.setSendStatus((short) Status.DOWNLOADED.value());
				purchaseOrderReplyDao.save(reply);
			}
		}
	}

	@Override
	public void reply(List<PurchaseOrderReply> replies) {
		for (PurchaseOrderReply reply : replies) {
            reply(reply, false);
        }
	}

	@Override
	public List<PurchaseOrderAll> findNotUploadOrder() {
		return purchaseOrderAllDao.findByVendUUAndSendStatus(SystemSession.getUser().getEnterprise().getUu(),
				(short) Status.NOT_UPLOAD.value());
	}

	@Override
	public void onSaleDownSuccess(String[] idArray) {
		for (String id : idArray) {
			PurchaseOrder order = purchaseOrderDao.findOne(Long.parseLong(id));
			if (order != null) {
				order.setSendStatus((short) Status.DOWNLOADED.value());
				purchaseOrderDao.save(order);
			}
		}
	}

	@Override
	public List<PurchaseOrderItem> findNotSendEnd() {
		return purchaseOrderItemDao.findByVendUUAndEndStatus(SystemSession.getUser().getEnterprise().getUu(),
				(short) Status.NOT_UPLOAD.value());
	}

	@Override
	public void onEndDownSuccess(String[] idArray) {
		for (String id : idArray) {
			PurchaseOrderItem orderItem = purchaseOrderItemDao.findOne(Long.parseLong(id));
			if (orderItem != null) {
				orderItem.setEndStatus((short) Status.DOWNLOADED.value());
				purchaseOrderItemDao.save(orderItem);
			}
		}
	}

	@Override
	public void saveItems(List<PurchaseOrderItem> items) {
		purchaseOrderItemDao.save(items);
		List<PurchaseOrderItem> eventItems = new ArrayList<>();
		for (PurchaseOrderItem item : items) {
			if (NumberUtil.nvl(item.getAcceptQty(), 0).doubleValue() < item.getQty() + NumberUtil.nvl(item.getReturnQty(), 0).doubleValue()) {
				eventItems.add(item);
			}
		}
		ContextUtils.publishEvent(new PurchaseOrderEndReleaseEvent(PurchaseOrderItem.distinctItem(eventItems)));
		for (PurchaseOrderItem item : items)
			// 明细结案情况下，明细状态为已回复（即不再处理），此时同时修改主记录状态
        {
            updateOrderStatus(item.getOrder().getId());
        }
	}

	@Override
	public Page<PurchaseOrderTodo> findTodoByPageInfo(final PageInfo pageInfo, SearchFilter filter) {
		if (filter != null) {
			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 (!CollectionUtils.isEmpty(filter.getDistribute())) {
				pageInfo.expression(PredicateUtils.in("enUU", filter.getDistribute(), false));
			}
			pageInfo.expression(PredicateUtils.eq("status", Status.NOT_REPLY.value(), false));
		}
		Page<PurchaseOrderTodo> pageOrders = purchaseOrderTodoDao.findAll(new Specification<PurchaseOrderTodo>() {
			@Override
			public Predicate toPredicate(Root<PurchaseOrderTodo> root, CriteriaQuery<?> query,
					CriteriaBuilder builder) {
				return query.where(pageInfo.getPredicates(root, query, builder)).getRestriction();
			}
		}, pageInfo);
		for (PurchaseOrderTodo order : pageOrders.getContent()) {
			Enterprise enter = enterpriseDao.findEnterpriseByUu(order.getVendUU());
			if (enter != null) {
				order.setEnName(enter.getEnName());
			}
			if (!CollectionUtils.isEmpty(order.getOrderItems())) {
			    for (PurchaseOrderTodoItem item : order.getOrderItems()) {
			        item.setLatestReplyQty(findLastReplyQty(item.getId()));
                }
            }
		}
		return pageOrders;
	}

	@Override
	public Page<PurchaseOrderDone> findDoneByPageInfo(final PageInfo pageInfo, SearchFilter filter) {
		if (filter != null) {
			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 (!CollectionUtils.isEmpty(filter.getDistribute())) {
                pageInfo.expression(PredicateUtils.in("enUU", filter.getDistribute(), false));
            }
		}
		Page<PurchaseOrderDone> pageOrders = purchaseOrderDoneDao.findAll(new Specification<PurchaseOrderDone>() {
			@Override
			public Predicate toPredicate(Root<PurchaseOrderDone> root, CriteriaQuery<?> query,
					CriteriaBuilder builder) {
				return query.where(pageInfo.getPredicates(root, query, builder)).getRestriction();
			}
		}, pageInfo);
		for (PurchaseOrderDone order : pageOrders.getContent()) {
			Enterprise enter = enterpriseDao.findEnterpriseByUu(order.getVendUU());
			if (enter != null) {
				order.setEnName(enter.getEnName());
			}
            if (!CollectionUtils.isEmpty(order.getOrderItems())) {
                for (PurchaseOrderDoneItem item : order.getOrderItems()) {
                    item.setLatestReplyQty(findLastReplyQty(item.getId()));
                }
            }
		}
		return pageOrders;
	}

	@Override
	public Page<PurchaseOrderReceived> findReceivedByPageInfo(final PageInfo pageInfo, SearchFilter filter) {
		if (filter != null) {
			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 (!CollectionUtils.isEmpty(filter.getDistribute())) {
                pageInfo.expression(PredicateUtils.in("enUU", filter.getDistribute(), false));
            }
		}
		Page<PurchaseOrderReceived> pageOrders = purchaseOrderReceivedDao
				.findAll(new Specification<PurchaseOrderReceived>() {
					@Override
					public Predicate toPredicate(Root<PurchaseOrderReceived> root, CriteriaQuery<?> query,
							CriteriaBuilder builder) {
						return query.where(pageInfo.getPredicates(root, query, builder)).getRestriction();
					}
				}, pageInfo);
		List<PurchaseOrderReceived> orders = pageOrders.getContent();
		for (PurchaseOrderReceived order : orders) {
			Enterprise enter = enterpriseDao.findEnterpriseByUu(order.getVendUU());
			if (enter != null) {
				order.setEnName(enter.getEnName());
			}
            if (!CollectionUtils.isEmpty(order.getOrderItems())) {
                for (PurchaseOrderReceivedItem item : order.getOrderItems()) {
                    item.setLatestReplyQty(findLastReplyQty(item.getId()));
                }
            }
		}
		return pageOrders;
	}

	@Override
	public Page<PurchaseOrderWaiting> findWaitingByPageInfo(final PageInfo pageInfo, SearchFilter filter) {
		if (filter != null) {
			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 (!CollectionUtils.isEmpty(filter.getDistribute())) {
                pageInfo.expression(PredicateUtils.in("enUU", filter.getDistribute(), false));
            }
		}
		Page<PurchaseOrderWaiting> pageOrders = purchaseOrderWaitingDao
				.findAll(new Specification<PurchaseOrderWaiting>() {
					@Override
					public Predicate toPredicate(Root<PurchaseOrderWaiting> root, CriteriaQuery<?> query,
							CriteriaBuilder builder) {
						return query.where(pageInfo.getPredicates(root, query, builder)).getRestriction();
					}
				}, pageInfo);
		List<PurchaseOrderWaiting> orders = pageOrders.getContent();
		for (PurchaseOrderWaiting order : orders) {
			Enterprise enter = enterpriseDao.findEnterpriseByUu(order.getVendUU());
			if (enter != null) {
				order.setEnName(enter.getEnName());
			}
            if (!CollectionUtils.isEmpty(order.getOrderItems())) {
                for (PurchaseOrderWaitingItem item : order.getOrderItems()) {
                    item.setLatestReplyQty(findLastReplyQty(item.getId()));
                }
            }
		}
		return pageOrders;
	}

	@Override
	public void setDisplay(String[] idArray, Short status) {
		for (String id : idArray) {
			PurchaseOrder order = purchaseOrderDao.findOne(Long.parseLong(id));
			if (order != null) {
				order.setDisplay(status);
				purchaseOrderDao.save(order);
			}
		}
	}

	@Override
	public void print(Long id) {
		PurchaseOrderAll order = purchaseOrderAllDao.findOne(id);
		if (order != null) {
			order.setPrint((short) ((order.getPrint() == null ? 0 : order.getPrint()) + 1));
			PrintLog printLog = new PrintLog(new Date(), SystemSession.getUser().getUserName(), SystemSession.getUser().getUserUU(), order.getEnUU(), "平台客户打印采购单", order.getId(), "purc$orders", order.getCode(), order.getErpId(), Constant.NO);
			printLogDao.save(printLog);
		}
		purchaseOrderAllDao.save(order);
	}

	@Override
	public Long getAllCount() {
		return purchaseOrderAllDao.countByVendUU(SystemSession.getUser().getEnterprise().getUu());
	}

	@Override
	public List<PrintLog> findPrintNotUploadReply() {
		return printLogDao.findByEnUUAndStatusAndTable(SystemSession.getUser().getEnterprise().getUu(), Constant.NO,"purc$orders");
	}

	@Override
	public void onPrintSendSuccess(String[] codeArray) {
		for (String code : codeArray) {
			List<PrintLog> printLogs = printLogDao.findByStatusAndCode(Constant.NO, code);
			for (PrintLog printLog : printLogs) {
				if (printLog != null) {
					printLog.setStatus(Constant.YES);
					printLogDao.save(printLog);
				}
			}
		}
	}

	@Override
	public Page<PurchaseOrderAll> findAllOrdersDetailByPageInfo(final PageInfo pageInfo, final SearchFilter filter) {
		if (filter != null) {
			pageInfo.expression(PredicateUtils.ne("status", Status.UNAUDIT.value(), 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 (!CollectionUtils.isEmpty(filter.getDistribute())) {
                pageInfo.expression(PredicateUtils.in("enUU", filter.getDistribute(), false));
            }
		}
		Page<PurchaseOrderAll> pageOrders = purchaseOrderAllDao.findAll(new Specification<PurchaseOrderAll>() {
			@Override
			public Predicate toPredicate(Root<PurchaseOrderAll> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
				Predicate[] predicates = pageInfo.getPredicates(root, query, builder);
				if (filter != null && filter.getFromDelivery() != null) {
					predicates = Arrays.copyOf(predicates, predicates.length + 1);
					SetJoin<PurchaseOrderAll, PurchaseOrderAllItem> join = root
							.join(root.getModel().getSet("orderItems", PurchaseOrderAllItem.class), JoinType.INNER);
					Predicate p = builder.greaterThanOrEqualTo(join.get("delivery").as(Date.class),
							new Date(filter.getFromDelivery()));
					predicates[predicates.length - 1] = p;
				}
				return query.where(predicates).getRestriction();
			}
		}, pageInfo);
		List<PurchaseOrderAll> orders = pageOrders.getContent();
		for (PurchaseOrderAll order : orders) {
			Enterprise enter = enterpriseDao.findEnterpriseByUu(order.getVendUU());
			if (enter != null) {
				order.setEnName(enter.getEnName());
			}
		}
		return pageOrders;
	}

	@Override
	public Page<PurchaseOrderEnd> findEndOrdersByPageInfo(final PageInfo pageInfo, final SearchFilter filter) {
		if (filter != null) {
			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 (!CollectionUtils.isEmpty(filter.getDistribute())) {
                pageInfo.expression(PredicateUtils.in("enUU", filter.getDistribute(), false));
            }
		}
		Page<PurchaseOrderEnd> pageOrders = purchaseOrderEndDao.findAll(new Specification<PurchaseOrderEnd>() {
			@Override
			public Predicate toPredicate(Root<PurchaseOrderEnd> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
				return query.where(pageInfo.getPredicates(root, query, builder)).getRestriction();
			}
		}, pageInfo);
		List<PurchaseOrderEnd> orders = pageOrders.getContent();
		for (PurchaseOrderEnd order : orders) {
			Enterprise enter = enterpriseDao.findEnterpriseByUu(order.getVendUU());
			if (enter != null) {
				order.setEnName(enter.getEnName());
			}
		}
		return pageOrders;
	}

    /**
     * 获取明细最后一次回复数量
     *
     * @param orderItemId 订单明细ID
     * @return
     */
    @Override
    public Double findLastReplyQty(long orderItemId) {
        List<PurchaseOrderReply> replies = findReplyByOrderItem(orderItemId);
        return CollectionUtils.isEmpty(replies) ? 0 : replies.get(0).getQty();
    }
}
