package com.goafanti.order.service.impl;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.goafanti.common.bo.Error;
import com.goafanti.common.constant.AFTConstants;
import com.goafanti.common.constant.ErrorConstants;
import com.goafanti.common.dao.AdminMapper;
import com.goafanti.common.dao.BusinessProjectMapper;
import com.goafanti.common.dao.ContractTaskLogMapper;
import com.goafanti.common.dao.ContractTaskMapper;
import com.goafanti.common.dao.NoticeMapper;
import com.goafanti.common.dao.OrganizationManagementMapper;
import com.goafanti.common.dao.TOrderBillMapper;
import com.goafanti.common.dao.TOrderChangeMapper;
import com.goafanti.common.dao.TOrderDetailMapper;
import com.goafanti.common.dao.TOrderMapper;
import com.goafanti.common.dao.UserBusinessMapper;
import com.goafanti.common.dao.UserFollowBusinessMapper;
import com.goafanti.common.dao.UserFollowMapper;
import com.goafanti.common.dao.UserLockReleaseMapper;
import com.goafanti.common.dao.UserMapper;
import com.goafanti.common.dao.UserRoleMapper;
import com.goafanti.common.enums.DeleteStatus;
import com.goafanti.common.enums.NoticeReadStatus;
import com.goafanti.common.enums.NoticeStatus;
import com.goafanti.common.enums.OrderFlowState;
import com.goafanti.common.enums.UserLockReleaseStatus;
import com.goafanti.common.error.BusinessException;
import com.goafanti.common.model.Admin;
import com.goafanti.common.model.ContractTask;
import com.goafanti.common.model.ContractTaskLog;
import com.goafanti.common.model.Notice;
import com.goafanti.common.model.OrganizationManagement;
import com.goafanti.common.model.TOrder;
import com.goafanti.common.model.TOrderBill;
import com.goafanti.common.model.TOrderChange;
import com.goafanti.common.model.TOrderDetail;
import com.goafanti.common.model.User;
import com.goafanti.common.model.UserBusiness;
import com.goafanti.common.model.UserFollow;
import com.goafanti.common.model.UserFollowBusiness;
import com.goafanti.common.model.UserLockRelease;
import com.goafanti.common.model.UserRole;
import com.goafanti.common.utils.BeanUtilsExt;
import com.goafanti.common.utils.DateUtils;
import com.goafanti.common.utils.MobileMessageUtils;
import com.goafanti.core.mybatis.BaseMybatisDao;
import com.goafanti.core.mybatis.JDBCIdGenerator;
import com.goafanti.core.mybatis.page.Pagination;
import com.goafanti.core.shiro.token.TokenManager;
import com.goafanti.customer.bo.BusinessListBo;
import com.goafanti.customer.bo.FollowBusinessBo;
import com.goafanti.customer.bo.LockingReleaseBo;
import com.goafanti.order.bo.BillDetailBo;
import com.goafanti.order.bo.BillListBo;
import com.goafanti.order.bo.CommodityDetailBo;
import com.goafanti.order.bo.OperatorActive;
import com.goafanti.order.bo.OrderChangeBo;
import com.goafanti.order.bo.OrderListBo;
import com.goafanti.order.bo.ServiceOrderDetailBo;
import com.goafanti.order.bo.C2BOrderDetailBo;
import com.goafanti.order.bo.C2COrderDetailBo;
import com.goafanti.order.enums.ActiveState;
import com.goafanti.order.enums.ApprovalState;
import com.goafanti.order.enums.AuditState;
import com.goafanti.order.enums.ChangeState;
import com.goafanti.order.enums.CommodityType;
import com.goafanti.order.enums.LiquidationState;
import com.goafanti.order.enums.OrderAction;
import com.goafanti.order.enums.OrderChannel;
import com.goafanti.order.enums.OrderStage;
import com.goafanti.order.enums.OrderState;
import com.goafanti.order.enums.PayChannel;
import com.goafanti.order.enums.ProjectStage;
import com.goafanti.order.enums.TransactionMode;
import com.goafanti.order.enums.TransactionSubject;
import com.goafanti.order.service.OrderService;

@Service
public class OrderServiceImpl extends BaseMybatisDao<TOrderMapper> implements OrderService {
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private TOrderMapper tOrderMapper;
	@Autowired
	private TOrderDetailMapper tOrderDetailMapper;
	@Autowired
	private JDBCIdGenerator	idGenerator;
	@Autowired
	private TOrderBillMapper tOrderBillMapper;
	@Autowired
	private OrganizationManagementMapper organizationManagementMapper;
	@Autowired 
	private ContractTaskMapper contractTaskMapper;
	@Autowired
	private TOrderChangeMapper tOrderChangeMapper;
	@Autowired
	private AdminMapper adminMapper;
	@Autowired
	private NoticeMapper noticeMapper;
	@Autowired
	private ContractTaskLogMapper contractTaskLogMapper;
	@Autowired
	private BusinessProjectMapper businessProjectMapper;
	@Autowired
	private UserLockReleaseMapper userLockReleaseMapper;
	@Autowired
	UserRoleMapper	userRoleMapper;
	@Autowired
	private UserBusinessMapper	userBusinessMapper;
	@Autowired
	private UserFollowMapper	userFollowMapper;
	@Autowired
	private UserFollowBusinessMapper	userFollowBusinessMapper;
	
	@Value(value = "${mobileRemindCodeTemplate}")
	private String					mobileRemindCodeTemplate	= null;
	
	@Value(value = "${accessKey}")
	private String					accessKey			= null;

	@Value(value = "${accessSecret}")
	private String					accessSecret		= null;
	
	private final BigDecimal DEFAULT_FIRST_PAYMENT = new BigDecimal(0);//默认首付价格
	private final BigDecimal DEFAULT_COMMODITY_PRICE = new BigDecimal(0);//默认单价
	private final String DEFAULT_PLATFORM_ID = "0"; //平台默认id
	private final String DEFAULT_ADMIN_ID = "1"; //默认管理员
	private final double DEFAULT_BROKERAGE_PROPORTION = 0; //佣金比例
	private final double DEFAULT_COMMODITY_DISCOUNT = 1; //折扣比例
	private final String DEFAULT_COMMODITY_MODE = "NO_MODE"; //暂无规格
	
	/*
	 * -------------------------------------------------- APP管理端 --------------------------------------------------------
	 */
	@Override
	public C2COrderDetailBo selectCommodityDetail(String commodityId, Integer commodityType) {
		C2COrderDetailBo bo = new C2COrderDetailBo();
		CommodityDetailBo cdb = tOrderMapper.selectCommodityDetail(commodityId,commodityType);
		try {
			BeanUtils.copyProperties(bo, cdb);
			bo.setOrderNo(String.valueOf(idGenerator.generateId()));
			bo.setCreateTime(DateUtils.formatDate(new Date(),AFTConstants.YYYYMMDDHHMMSS));
			bo.setCommodityType(commodityType);
			if(bo.getCommodityPrice().equals("0"))
				bo.setCommodityPrice("面议");
			else
				bo.setCommodityPrice(bo.getCommodityPrice()+" 万");
			if(StringUtils.isBlank(bo.getFirstPayment())) 
				bo.setFirstPayment("面议");
			else 
				bo.setFirstPayment(bo.getFirstPayment()+" 万");
		} catch (IllegalAccessException | InvocationTargetException e) {
			e.printStackTrace();
		}
		return bo;
	}

	/**
	 * 只能购买一份
	 * 后期规则：自营服务订单 、需求订单、其他订单不能同时加入购物车
	 */
	@Override
	public int addIntention(String orderNo, String commodityId, String commodityMode, Integer commodityQuantity,Integer commodityType, 
			String createTime,String remarks) throws ParseException {
		CommodityDetailBo bo =  tOrderMapper.selectCommodityDetail(commodityId,commodityType);
		BigDecimal commodityPrice = StringUtils.isBlank(bo.getCommodityPrice()) ? DEFAULT_COMMODITY_PRICE 
				: new BigDecimal(Double.valueOf(bo.getCommodityPrice()));
		BigDecimal commodityFirstPayment = StringUtils.isBlank(bo.getCommodityFirstPayment()) ? DEFAULT_FIRST_PAYMENT 
				: new BigDecimal(Double.valueOf(bo.getCommodityFirstPayment()));
		BigDecimal discountPrice = commodityPrice.multiply(new BigDecimal(DEFAULT_COMMODITY_DISCOUNT));
		BigDecimal discountFirstPayment = commodityFirstPayment.multiply(new BigDecimal(DEFAULT_COMMODITY_DISCOUNT));
		TOrder tOrder = new TOrder();
		tOrder.setOrderNo(orderNo);	
		tOrder.setCreater(DEFAULT_ADMIN_ID);
		tOrder.setCreateTime(DateUtils.parseDate(createTime, AFTConstants.YYYYMMDDHHMMSS));
		if(commodityType == CommodityType.DEMAND.getTypeCode()){
			tOrder.setBuyerId(StringUtils.isBlank(bo.getSellerId()) ? DEFAULT_PLATFORM_ID : bo.getSellerId());
			tOrder.setSellerId(TokenManager.getUserId());
		}else{
			tOrder.setBuyerId(TokenManager.getUserId());
			tOrder.setSellerId(StringUtils.isBlank(bo.getSellerId()) ? DEFAULT_PLATFORM_ID : bo.getSellerId());
		}
		tOrder.setOrderType(commodityType);
		tOrder.setBrokerageAmount(discountPrice.multiply(new BigDecimal(DEFAULT_BROKERAGE_PROPORTION)));
		tOrder.setOrderAmount(commodityPrice);
		tOrder.setFirstPayment(commodityFirstPayment);
		tOrder.setSignTotalAmount(discountPrice);
		tOrder.setSignFirstPayment(discountFirstPayment);
		tOrder.setSignBrokerageAmount(discountPrice.multiply(new BigDecimal(DEFAULT_BROKERAGE_PROPORTION)));
		tOrder.setSignWithdrawAmount(discountPrice.subtract(discountPrice.multiply(new BigDecimal(DEFAULT_BROKERAGE_PROPORTION))));
		tOrder.setDeleteSign(DeleteStatus.UNDELETE.getCode());
		tOrder.setOrderChannel(OrderChannel.APP.getCode());
		tOrder.setApproval(ApprovalState.NORMAL.getCode());
		tOrder.setChangeStatus(ChangeState.UNCHANGE.getCode());
		tOrder.setSalesmanId(getSalesmanIdByUid(TokenManager.getAdminId()));
		tOrder.setOrderRemarks(remarks);
		tOrder.setContractType(bo.getCommodityClassify());
		setOrderState(OrderAction.ADD_INTENTION, new BigDecimal(0), tOrder, false);
		
		TOrderDetail tOrderDetail = new TOrderDetail();
		tOrderDetail.setId(UUID.randomUUID().toString());
		tOrderDetail.setOrderNo(orderNo);
		tOrderDetail.setCommodityId(commodityId);
		tOrderDetail.setCommodityName(bo.getCommodityName());
		tOrderDetail.setCommodityMode(StringUtils.isBlank(commodityMode)?DEFAULT_COMMODITY_MODE: commodityMode);
		tOrderDetail.setCommodityType(commodityType);
		tOrderDetail.setCommodityQuantity(commodityQuantity);
		tOrderDetail.setCommodityPrice(commodityPrice);
		tOrderDetail.setCommodityFirstPayment(commodityFirstPayment);
		tOrderDetail.setDiscountPrice(discountPrice);
		tOrderDetail.setDiscountFirstPayment(discountFirstPayment);
		tOrderDetail.setCreateTime(DateUtils.parseDate(createTime, AFTConstants.YYYYMMDDHHMMSS));
		tOrderDetailMapper.insert(tOrderDetail);
		tOrderMapper.insert(tOrder);
		return 1;
	}
	
	/**
	 * 订单状态流转
	 * @param orderAction
	 * @param changeAmount
	 * @param tOrder
	 * @param confrim
	 */
	public void setOrderState(OrderAction orderAction,BigDecimal changeAmount,TOrder tOrder,boolean confrim){
		BigDecimal initial = new BigDecimal(0);
		checkOrder(tOrder);
		if(orderAction == OrderAction.ADD_INTENTION){ //添加意向订单
			tOrder.setOrderStatus(OrderState.WAIT_FOR_CONFIRM.getCode());
			tOrder.setLiquidationStatus(LiquidationState.WAIT_PAY_FIRST_BALANCE.getCode());
			tOrder.setOrderStage(OrderStage.INTENTION.getCode());
			tOrder.setProjectStage(ProjectStage.NOT_SATISFY_CONDITION.getCode());
			tOrder.setLiquidationStatus(LiquidationState.WAIT_PAY_FIRST_BALANCE.getCode());
			tOrder.setActuallyFirstPayment(initial);
			tOrder.setActuallyBrokerageAmount(initial);
			tOrder.setActuallyTotalAmount(initial);
			tOrder.setActuallyWithdrawAmount(initial);
		}else if(orderAction == OrderAction.CONFIRM_INTENTION){ //确认意向订单 (用户确认)
			if(tOrder.getOrderStatus() != OrderState.WAIT_FOR_CONFIRM.getCode()){
				throw new BusinessException(new Error(ErrorConstants.NOT_ACCORD_WITH_NEXT,"确认意向订单"));
			}
			if (confrim) {
				tOrder.setOrderStatus(OrderState.WAIT_FOR_SIGN.getCode()); // 卖家同意
				tOrder.setOrderStage(OrderStage.FOLLOWING.getCode());
			} else {
				tOrder.setOrderStatus(OrderState.SELLER_REFUSE_BEFORE_SIGNL.getCode()); // 买家拒绝
			}
		}else if(orderAction == OrderAction.CONFIRM_PAY_FOR_FIRST){ // 支付首付(审核流水)
			if(tOrder.getLiquidationStatus() != LiquidationState.WAIT_PAY_FIRST_BALANCE.getCode()){
				throw new BusinessException(new Error(ErrorConstants.NOT_ACCORD_WITH_NEXT,""));
			}
			int boundary = tOrder.getActuallyFirstPayment().add(changeAmount).compareTo(tOrder.getSignFirstPayment());
			int boundary2 = tOrder.getActuallyTotalAmount().add(changeAmount).compareTo(tOrder.getSignTotalAmount());
			if(boundary2 == 1){
				throw new BusinessException(new Error(ErrorConstants.PAY_BEYOND_SIGN,"支付首付款"));
			}else if(boundary2 == 0){ //全付清
				tOrder.setActuallyTotalAmount(tOrder.getSignTotalAmount());
				tOrder.setActuallyFirstPayment(tOrder.getSignFirstPayment());
				tOrder.setLiquidationStatus(LiquidationState.ALREADY_PAY.getCode());
				if(tOrder.getProjectStage() == ProjectStage.NOT_SATISFY_CONDITION.getCode())
					tOrder.setProjectStage(ProjectStage.WAIT_SET_UP.getCode());
			}else if(boundary == 1){ //超过首付未达尾款
				tOrder.setActuallyTotalAmount(tOrder.getActuallyTotalAmount().add(changeAmount));
				tOrder.setActuallyFirstPayment(tOrder.getSignFirstPayment());
				tOrder.setLiquidationStatus(LiquidationState.WAIT_PAY_LAST_BALANCE.getCode());
				if(tOrder.getProjectStage() == ProjectStage.NOT_SATISFY_CONDITION.getCode())
					tOrder.setProjectStage(ProjectStage.WAIT_SET_UP.getCode());
			}else if(boundary == -1){ //首付待付清
				tOrder.setActuallyTotalAmount(tOrder.getActuallyTotalAmount().add(changeAmount));
				tOrder.setActuallyFirstPayment(tOrder.getActuallyFirstPayment().add(changeAmount));
			}else if(boundary == 0){ //首付已结清
				tOrder.setActuallyTotalAmount(tOrder.getActuallyTotalAmount().add(changeAmount));
				tOrder.setActuallyFirstPayment(tOrder.getSignFirstPayment());
				tOrder.setLiquidationStatus(LiquidationState.WAIT_PAY_LAST_BALANCE.getCode());
				if(tOrder.getProjectStage() == ProjectStage.NOT_SATISFY_CONDITION.getCode())
					tOrder.setProjectStage(ProjectStage.WAIT_SET_UP.getCode());
			}
		}else if(orderAction == OrderAction.CONFIRM_PAY_FOR_LAST){ //支付尾款 (审核流水)
			if(tOrder.getLiquidationStatus() != LiquidationState.WAIT_PAY_LAST_BALANCE.getCode()){
				throw new BusinessException(new Error(ErrorConstants.NOT_ACCORD_WITH_NEXT,"支付尾款"));
			}
			int boundary = tOrder.getActuallyTotalAmount().add(changeAmount).compareTo(tOrder.getSignTotalAmount());
			if(boundary == 1){
				throw new BusinessException(new Error(ErrorConstants.PAY_BEYOND_SIGN,"支付尾款"));
			}else if(boundary == -1){
				tOrder.setActuallyTotalAmount(tOrder.getActuallyTotalAmount().add(changeAmount));
			}else if(boundary == 0){
				tOrder.setActuallyTotalAmount(tOrder.getSignTotalAmount());
				tOrder.setLiquidationStatus(LiquidationState.ALREADY_PAY.getCode());
			}
		}else if(orderAction == OrderAction.APPLY_FOR_WITHDRAW){ //提现申请 
			if(tOrder.getOrderStatus() != OrderState.ALREADY_SIGN.getCode() 
					|| tOrder.getLiquidationStatus() != LiquidationState.ALREADY_PAY.getCode()
					|| tOrder.getActuallyTotalAmount().doubleValue() <= 0){
				throw new BusinessException(new Error(ErrorConstants.NOT_ACCORD_WITH_NEXT,"等待提现"));
			}
			tOrder.setLiquidationStatus(LiquidationState.WAIT_FOR_WITHDRAW.getCode());
		}else if(orderAction == OrderAction.CONFIRM_WITHDRAW){ //提现确认 (审核员先审核流水)
			if(tOrder.getOrderStatus() != OrderState.ALREADY_SIGN.getCode() 
					|| tOrder.getLiquidationStatus() != LiquidationState.WAIT_FOR_WITHDRAW.getCode()
					|| tOrder.getActuallyTotalAmount().doubleValue() <= 0){
				throw new BusinessException(new Error(ErrorConstants.NOT_ACCORD_WITH_NEXT,"确认提现"));
			}
			tOrder.setLiquidationStatus(LiquidationState.ALREADY_WITHDRAW.getCode());
			tOrder.setActuallyWithdrawAmount(tOrder.getActuallyWithdrawAmount().add(changeAmount));
		}else if(orderAction == OrderAction.APPLY_FOR_CANCEL){ //取消订单
			boolean flag = true;
			if(tOrder.getOrderStatus() != OrderState.WAIT_FOR_CONFIRM.getCode()
					&& tOrder.getOrderStatus() != OrderState.WAIT_FOR_SIGN.getCode()){
				flag = false;
			}
			if(tOrder.getLiquidationStatus() != LiquidationState.WAIT_PAY_FIRST_BALANCE.getCode()
					&& tOrder.getLiquidationStatus() != LiquidationState.WAIT_PAY_LAST_BALANCE.getCode()
					&& tOrder.getLiquidationStatus() != LiquidationState.ALREADY_PAY.getCode()){
				flag = false;
			}
			if(!flag) throw new BusinessException(new Error(ErrorConstants.NOT_ACCORD_WITH_NEXT,"取消订单"));
			if(TokenManager.getToken() instanceof Admin){
				if(!tOrder.getSellerId().equals(DEFAULT_PLATFORM_ID)) 
					throw new BusinessException(new Error(ErrorConstants.NOT_ACCORD_WITH_NEXT,"取消订单"));
				if(tOrder.getOrderStatus() == OrderState.WAIT_FOR_CONFIRM.getCode())
					tOrder.setOrderStatus(OrderState.SELLER_REFUSE_BEFORE_SIGNL.getCode());
				if( tOrder.getOrderStatus() == OrderState.WAIT_FOR_SIGN.getCode())
					tOrder.setOrderStatus(OrderState.SELLER_CANCEL_AFTER_SIGN.getCode());
			}else if(TokenManager.getToken() instanceof User){
				if(TokenManager.getUserId().equals(tOrder.getSellerId())){
					if(tOrder.getOrderStatus() == OrderState.WAIT_FOR_CONFIRM.getCode())
						tOrder.setOrderStatus(OrderState.SELLER_REFUSE_BEFORE_SIGNL.getCode());
					if( tOrder.getOrderStatus() == OrderState.ALREADY_SIGN.getCode())
						tOrder.setOrderStatus(OrderState.SELLER_CANCEL_AFTER_SIGN.getCode());
				}else if(TokenManager.getUserId().equals(tOrder.getBuyerId())){
					if(tOrder.getOrderStatus() == OrderState.WAIT_FOR_CONFIRM.getCode())
						tOrder.setOrderStatus(OrderState.BUYER_CANCEL_BEFORE_SIGN.getCode());
					if( tOrder.getOrderStatus() == OrderState.ALREADY_SIGN.getCode())
						tOrder.setOrderStatus(OrderState.BUYER_CANCEL_AFTER_SIGN.getCode());
				}
			}		
		}else if(orderAction == OrderAction.APPLY_FOR_REFUND){ //退款申请
			boolean	flag = true;
			if(tOrder.getOrderStatus() != OrderState.BUYER_CANCEL_BEFORE_SIGN.getCode()
					&& tOrder.getOrderStatus() != OrderState.BUYER_CANCEL_AFTER_SIGN.getCode()
					&& tOrder.getOrderStatus() != OrderState.SELLER_REFUSE_BEFORE_SIGNL.getCode()
					&& tOrder.getOrderStatus() != OrderState.SELLER_CANCEL_AFTER_SIGN.getCode()){
				flag = false;
			}
			if(tOrder.getChangeStatus() == ChangeState.CHANGING.getCode()) flag = true; // Add 2018/4/9 if normal order in changing can refund 
			if(tOrder.getLiquidationStatus() == LiquidationState.WAIT_FOR_REFUND_CONFIRM.getCode()
					|| tOrder.getLiquidationStatus() == LiquidationState.REFUSE_REFUND.getCode()
					|| tOrder.getLiquidationStatus() == LiquidationState.AGREE_REFUND.getCode()
					|| tOrder.getLiquidationStatus() == LiquidationState.COMPLETE_REFUND.getCode()){
				flag = false;
			}
			if(tOrder.getActuallyTotalAmount().doubleValue() <= 0)
				flag = false;
			if(!flag) throw new BusinessException(new Error(ErrorConstants.NOT_ACCORD_WITH_NEXT,"申请退款"));
			tOrder.setLiquidationStatus(LiquidationState.WAIT_FOR_REFUND_CONFIRM.getCode());
		}else if(orderAction == OrderAction.CONFIRM_REFUND){ //退款确认
			boolean flag = true;
			if(tOrder.getOrderStatus() != OrderState.BUYER_CANCEL_BEFORE_SIGN.getCode()
					&& tOrder.getOrderStatus() != OrderState.BUYER_CANCEL_AFTER_SIGN.getCode()
					&& tOrder.getOrderStatus() != OrderState.SELLER_REFUSE_BEFORE_SIGNL.getCode()
					&& tOrder.getOrderStatus() != OrderState.SELLER_CANCEL_AFTER_SIGN.getCode()){
				flag = false;
			}
			if(tOrder.getChangeStatus() == ChangeState.CHANGING.getCode()) flag = true; // Add 2018/4/9 if normal order in changing can refund 
			if(tOrder.getLiquidationStatus() != LiquidationState.WAIT_FOR_REFUND_CONFIRM.getCode())
				flag = false;
			if(tOrder.getActuallyTotalAmount().doubleValue() <= 0)
				flag = false;
			if(confrim) {
				if(!flag) throw new BusinessException(new Error(ErrorConstants.NOT_ACCORD_WITH_NEXT,"同意退款")); 
				tOrder.setLiquidationStatus(LiquidationState.AGREE_REFUND.getCode());
			}else{
				if(!flag) throw new BusinessException(new Error(ErrorConstants.NOT_ACCORD_WITH_NEXT,"拒绝退款"));
				tOrder.setLiquidationStatus(LiquidationState.REFUSE_REFUND.getCode());
			}	
		}else if(orderAction == OrderAction.COMPLETE_REFUND){ //完成退款
			boolean flag = true;
			if(tOrder.getOrderStatus() != OrderState.BUYER_CANCEL_BEFORE_SIGN.getCode()
					&& tOrder.getOrderStatus() != OrderState.BUYER_CANCEL_AFTER_SIGN.getCode()
					&& tOrder.getOrderStatus() != OrderState.SELLER_REFUSE_BEFORE_SIGNL.getCode()
					&& tOrder.getOrderStatus() != OrderState.SELLER_CANCEL_AFTER_SIGN.getCode()){
				flag = false;
			}
			if(tOrder.getChangeStatus() == ChangeState.CHANGING.getCode()) flag = true; // Add 2018/4/9 if normal order in changing can refund 
			if(tOrder.getLiquidationStatus() != LiquidationState.AGREE_REFUND.getCode())
				flag = false;
			if(tOrder.getActuallyTotalAmount().doubleValue() <= 0)
				flag = false;
			if(!flag) throw new BusinessException(new Error(ErrorConstants.NOT_ACCORD_WITH_NEXT,"申请退款"));
			tOrder.setActuallyTotalAmount(tOrder.getActuallyTotalAmount().add(changeAmount));
			int boundary = tOrder.getActuallyTotalAmount().compareTo(tOrder.getSignTotalAmount());
			if(boundary == 0) {
				tOrder.setLiquidationStatus(LiquidationState.COMPLETE_REFUND.getCode()); //完成退款
			}else if(boundary == 1){
				tOrder.setLiquidationStatus(LiquidationState.AGREE_REFUND.getCode()); //需要再退款
			}else if(boundary == -1){
				throw new BusinessException(new Error(ErrorConstants.REFUND_BEYOND_SIGN,"退款")); //超过退款金额
			}
		}
	}
	
	
	/**
	 * 设置按钮状态
	 * @param tOrder
	 * @return
	 */
	private OperatorActive setOperatorActive(TOrder tOrder){
		OperatorActive active = new OperatorActive();
		if(tOrder.getDeleteSign() == ActiveState.ABOLISH.getCode()) 
			return active;
		if(tOrder.getDeleteSign() == ActiveState.LOCKING.getCode()) {
			active.setApplyUnLock(true);
			return active;
		}
		if (TokenManager.getToken() instanceof User) {
			active.setConfirmPayForFirst(false);
			active.setConfirmPayForLast(false);
			active.setConfirmWithdraw(false);
			active.setCompleteRefund(false);
			active.setApplyLock(false);
			active.setApplyUnLock(false);
			active.setApplyRevoke(false);
			active.setApplySign(false);
			if (TokenManager.getUserId().equals(tOrder.getBuyerId())) { // 买方
				active.setApplyForWithdraw(false);
				if (tOrder.getOrderStatus() == OrderState.WAIT_FOR_CONFIRM.getCode()) {
					/** 需求订单 开始 **/
					if (tOrder.getOrderType() == CommodityType.DEMAND.getTypeCode()) {
						active.setConfirmIntention(true); 
						active.setRefuseIntention(true); 
					} else {
						active.setConfirmIntention(false); 
						active.setRefuseIntention(false);
					}
					/** 需求订单 结束 **/
				} else {
					active.setConfirmIntention(false);
					active.setRefuseIntention(false);
				}
				if ((tOrder.getOrderStatus() == OrderState.WAIT_FOR_SIGN.getCode() || tOrder.getOrderStatus() == OrderState.ALREADY_SIGN.getCode())
						&& tOrder.getLiquidationStatus() == LiquidationState.WAIT_PAY_FIRST_BALANCE.getCode()) {
					active.setPayForFirst(true); //支付首付
				} else {
					active.setPayForFirst(false); //支付首付
				}
				if ((tOrder.getOrderStatus() == OrderState.WAIT_FOR_SIGN.getCode() || tOrder.getOrderStatus() == OrderState.ALREADY_SIGN.getCode())
						&& tOrder.getLiquidationStatus() == LiquidationState.WAIT_PAY_LAST_BALANCE.getCode()) {
					active.setPayForLast(true); //支付尾款
				} else {
					active.setPayForLast(false); //支付尾款
				}
				boolean flag = true;
				if(tOrder.getOrderStatus() != OrderState.WAIT_FOR_CONFIRM.getCode()
						&& tOrder.getOrderStatus() != OrderState.WAIT_FOR_SIGN.getCode()){
					flag = false;
				}
				if(tOrder.getLiquidationStatus() != LiquidationState.WAIT_PAY_FIRST_BALANCE.getCode()
						&& tOrder.getLiquidationStatus() != LiquidationState.WAIT_PAY_LAST_BALANCE.getCode()
						&& tOrder.getLiquidationStatus() != LiquidationState.ALREADY_PAY.getCode()){
					flag = false;
				}
				active.setApplyForCancel(flag); //申请取消
				flag = true;
				if(tOrder.getOrderStatus() != OrderState.BUYER_CANCEL_BEFORE_SIGN.getCode()
						&& tOrder.getOrderStatus() != OrderState.BUYER_CANCEL_AFTER_SIGN.getCode()
						&& tOrder.getOrderStatus() != OrderState.SELLER_REFUSE_BEFORE_SIGNL.getCode()
						&& tOrder.getOrderStatus() != OrderState.SELLER_CANCEL_AFTER_SIGN.getCode()){
					flag = false;
				}
				if(tOrder.getLiquidationStatus() == LiquidationState.WAIT_FOR_REFUND_CONFIRM.getCode()
						|| tOrder.getLiquidationStatus() == LiquidationState.REFUSE_REFUND.getCode()
						|| tOrder.getLiquidationStatus() == LiquidationState.AGREE_REFUND.getCode()
						|| tOrder.getLiquidationStatus() == LiquidationState.COMPLETE_REFUND.getCode()){
					flag = false;
				}
				if(tOrder.getActuallyTotalAmount().doubleValue() <= 0)
					flag = false;
				active.setApplyForRefund(flag); //申请退款		
			}else if(TokenManager.getUserId().equals(tOrder.getSellerId())){ //卖方
				active.setPayForFirst(false);
				active.setPayForLast(false);
				active.setApplyForRefund(false);
				if (tOrder.getOrderStatus() == OrderState.WAIT_FOR_CONFIRM.getCode()) {
					/** 需求订单 开始 **/
					if (tOrder.getOrderType() == CommodityType.DEMAND.getTypeCode()) {
						active.setConfirmIntention(false); 
						active.setRefuseIntention(false); 
					} else {
						active.setConfirmIntention(true); 
						active.setRefuseIntention(true); 
					}
					/** 需求订单 结束 **/
				} else {
					active.setConfirmIntention(false); 
					active.setRefuseIntention(false); 
				}
				boolean flag = true;
				if(tOrder.getOrderStatus() != OrderState.WAIT_FOR_SIGN.getCode()){
					flag = false;
				}
				if(tOrder.getLiquidationStatus() != LiquidationState.WAIT_PAY_FIRST_BALANCE.getCode()
						&& tOrder.getLiquidationStatus() != LiquidationState.WAIT_PAY_LAST_BALANCE.getCode()
						&& tOrder.getLiquidationStatus() != LiquidationState.ALREADY_PAY.getCode()){
					flag = false;
				}
				active.setApplyForCancel(flag); //申请取消
				flag = true;
				if(tOrder.getOrderStatus() != OrderState.BUYER_CANCEL_BEFORE_SIGN.getCode()
						&& tOrder.getOrderStatus() != OrderState.BUYER_CANCEL_AFTER_SIGN.getCode()
						&& tOrder.getOrderStatus() != OrderState.SELLER_REFUSE_BEFORE_SIGNL.getCode()
						&& tOrder.getOrderStatus() != OrderState.SELLER_CANCEL_AFTER_SIGN.getCode()){
					flag = false;
				}
				if(tOrder.getLiquidationStatus() != LiquidationState.WAIT_FOR_REFUND_CONFIRM.getCode())
					flag = false;
				if(tOrder.getActuallyTotalAmount().doubleValue() <= 0)
					flag = false;
				active.setAgreeRefund(flag); //同意退款
				active.setRefuseRefund(flag); //拒绝退款
				if (tOrder.getOrderStatus() == OrderState.ALREADY_SIGN.getCode() 
						&& tOrder.getLiquidationStatus() == LiquidationState.ALREADY_PAY.getCode()
						&& tOrder.getActuallyTotalAmount().doubleValue() > 0) {
					active.setApplyForWithdraw(true); //申请提现
				} else {
					active.setApplyForWithdraw(false); //申请提现
				}
			}else{
				active.setPayForFirst(false);
				active.setPayForLast(false);
				active.setConfirmIntention(false);
				active.setRefuseIntention(false);
				active.setApplyForCancel(false);
				active.setApplyForRefund(false);
				active.setAgreeRefund(false);
				active.setRefuseRefund(false);
				active.setApplyForWithdraw(false);
			}
		}
		if (TokenManager.getToken() instanceof Admin) {
			active.setPayForFirst(false);
			active.setPayForLast(false);
			active.setApplyForWithdraw(false);
			active.setApplyForRefund(false);
			if (tOrder.getSellerId().equals(DEFAULT_PLATFORM_ID)) { // 平台作为卖方
				if (tOrder.getOrderStatus() == OrderState.WAIT_FOR_CONFIRM.getCode()) {
					active.setConfirmIntention(true);
					active.setRefuseIntention(true);
				} else {
					active.setConfirmIntention(false);
					active.setRefuseIntention(false);
				}
				boolean flag = true;
				if(tOrder.getOrderStatus() != OrderState.WAIT_FOR_SIGN.getCode()){
					flag = false;
				}			
				if(tOrder.getLiquidationStatus() != LiquidationState.WAIT_PAY_FIRST_BALANCE.getCode()
						&& tOrder.getLiquidationStatus() != LiquidationState.WAIT_PAY_LAST_BALANCE.getCode()
						&& tOrder.getLiquidationStatus() != LiquidationState.ALREADY_PAY.getCode()){
					flag = false;
				}
				active.setApplyForCancel(flag); //申请取消
				flag = true;
				if(tOrder.getOrderStatus() != OrderState.BUYER_CANCEL_BEFORE_SIGN.getCode()
						&& tOrder.getOrderStatus() != OrderState.BUYER_CANCEL_AFTER_SIGN.getCode()
						&& tOrder.getOrderStatus() != OrderState.SELLER_REFUSE_BEFORE_SIGNL.getCode()
						&& tOrder.getOrderStatus() != OrderState.SELLER_CANCEL_AFTER_SIGN.getCode()){
					flag = false;
				}
				if(tOrder.getLiquidationStatus() != LiquidationState.WAIT_FOR_REFUND_CONFIRM.getCode())
					flag = false;
				if(tOrder.getActuallyTotalAmount().doubleValue() <= 0)
					flag = false;
				active.setAgreeRefund(flag); //同意退款
				active.setRefuseRefund(flag); //拒绝退款
			} else {
				active.setConfirmIntention(false); //确认意向
				active.setRefuseIntention(false); //拒绝意向
				active.setApplyForCancel(false); //申请取消
				active.setAgreeRefund(false); //同意退款
				active.setRefuseRefund(false); //拒绝退款
			}	
		}
		//平台方作为中间方 确认首付 - 尾款 - 提现 - 退款
		if(tOrder.getOrderStatus() == OrderState.WAIT_FOR_SIGN.getCode()
				&& tOrder.getLiquidationStatus() == LiquidationState.WAIT_PAY_FIRST_BALANCE.getCode()){
			active.setConfirmPayForFirst(true);
		}else{
			active.setConfirmPayForFirst(false);
		}
		if(tOrder.getOrderStatus() == OrderState.WAIT_FOR_SIGN.getCode()
				&& tOrder.getLiquidationStatus() == LiquidationState.WAIT_PAY_FIRST_BALANCE.getCode()){
			active.setConfirmPayForLast(true);
		}else{
			active.setConfirmPayForLast(false);
		}
		if(tOrder.getOrderStatus() == OrderState.ALREADY_SIGN.getCode()
				&& tOrder.getLiquidationStatus() == LiquidationState.WAIT_FOR_WITHDRAW.getCode()){
			active.setConfirmWithdraw(true);
		}else{
			active.setConfirmWithdraw(false);
		}
		boolean flag = true;
		if(tOrder.getOrderStatus() != OrderState.BUYER_CANCEL_BEFORE_SIGN.getCode()
				&& tOrder.getOrderStatus() != OrderState.BUYER_CANCEL_AFTER_SIGN.getCode()
				&& tOrder.getOrderStatus() != OrderState.SELLER_REFUSE_BEFORE_SIGNL.getCode()
				&& tOrder.getOrderStatus() != OrderState.SELLER_CANCEL_AFTER_SIGN.getCode()){
			flag = false;
		}
		if(flag && tOrder.getActuallyTotalAmount().doubleValue() == 0 
				&& tOrder.getDeleteSign() == DeleteStatus.UNDELETE.getCode()){
			active.setApplyRevoke(true); //作废
		}else{
			active.setApplyRevoke(false); //作废
		}
		if(tOrder.getLiquidationStatus() != LiquidationState.AGREE_REFUND.getCode())
			flag = false;
		if(tOrder.getActuallyTotalAmount().doubleValue() <= 0)
			flag = false;
		active.setCompleteRefund(flag); //完成退款
		flag = true;
		if(tOrder.getOrderStatus() != OrderState.WAIT_FOR_SIGN.getCode())
			flag = false;
		active.setApplySign(flag); //签单
		if(tOrder.getDeleteSign() == DeleteStatus.UNDELETE.getCode()){
			active.setApplyLock(true);
		}else{
			active.setApplyLock(false);
		}
		if(tOrder.getDeleteSign() == DeleteStatus.LOCKING.getCode()){
			active.setApplyUnLock(true);
		}else{
			active.setApplyUnLock(false);
		}
		return active;
	}


	/**
	 * 添加流水记录
	 * @param orderNo 订单编号
	 * @param creater 创建人
	 * @param payeeId 收款人
	 * @param payerId 付款人
	 * @param remarks 附言
	 * @param transactionSubject 交易科目
	 * @param payChannel 支付渠道
	 * @param transactionMode 支付方式
	 * @param FundAudit 流水审核
	 * @return
	 */
	public int addFundRecord(String orderNo,String creater,String payeeId,String payerId,String remarks,TransactionSubject transactionSubject,PayChannel payChannel,
			BigDecimal transactionAmount,TransactionMode transactionMode,AuditState auditState){
		TOrderBill bill = new TOrderBill();
		bill.setBillNo(UUID.randomUUID().toString().replace("-", ""));
		bill.setConfirmSign(auditState.getCode());
		bill.setCreater(creater);
		bill.setDeleteSign(Boolean.FALSE);
		bill.setOrderNo(orderNo);
		bill.setTransactionAmount(transactionAmount);
		bill.setPayeeId(payeeId);
		bill.setPayerId(payerId);
		bill.setRemarks(remarks);
		bill.setTransactionAmount(transactionAmount);
		bill.setTransactionMode(transactionMode.getCode());
		bill.setTransactionSubject(transactionSubject.getCode());
		bill.setTransactionChannel(payChannel.getCode());
		bill.setCreateTime(new Date());
		return tOrderBillMapper.insert(bill);
	}
	
	@Override
	public int updatePayForFirst(String orderNo, BigDecimal fundAmount,String remarks) {
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(orderNo);
		addFundRecord(orderNo, TokenManager.getUserToken().getNickname(), DEFAULT_PLATFORM_ID, TokenManager.getUserId(), remarks, 
				TransactionSubject.SUPPLY_PAY,PayChannel.UNIONPAY, fundAmount, TransactionMode.OFFLINE, AuditState.WAIT_AUDIT);
		tOrder.setUpdateTime(new Date());
		return tOrderMapper.updateByPrimaryKeySelective(tOrder);
	}

	@Override
	public int updatePayForLast(String orderNo, BigDecimal fundAmount, String remarks) {
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(orderNo);
		addFundRecord(orderNo, TokenManager.getUserToken().getNickname(), DEFAULT_PLATFORM_ID, TokenManager.getUserId(), remarks, 
				TransactionSubject.SUPPLY_PAY,PayChannel.UNIONPAY, fundAmount, TransactionMode.OFFLINE, AuditState.WAIT_AUDIT);
		tOrder.setUpdateTime(new Date());
		return tOrderMapper.updateByPrimaryKeySelective(tOrder);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Pagination<C2BOrderDetailBo> selectOrderList(boolean confirm,Integer pageNo,Integer pageSize) {
		Map<String, Object> params = new HashMap<String, Object>();
		Pagination<C2BOrderDetailBo> result = new Pagination<C2BOrderDetailBo>();
		if(!confirm) params.put("orderStatus", OrderState.WAIT_FOR_CONFIRM.getCode()); //购买意向
		params.put("uid", TokenManager.getUserId());
		Pagination<TOrder> data = (Pagination<TOrder>)findPage("selectOrderListByPage", "selectOrderListCount", params, pageNo, pageSize);
		List<TOrder> list = (List<TOrder>)data.getList();
		C2BOrderDetailBo bo = null;
		List<C2BOrderDetailBo> boList = new ArrayList<C2BOrderDetailBo>(); 
		List<CommodityDetailBo> commoditys = null;
		CommodityDetailBo cdb = null;
		if(list.size()>0){
			for(TOrder t:list){
				bo = new C2BOrderDetailBo();
				commoditys = new ArrayList<CommodityDetailBo>();
				bo.setOrderNo(String.valueOf(t.getOrderNo()));
				bo.setOrderRemarks(t.getOrderRemarks());
				bo.setOrderStatus(OrderState.getStatus(t.getOrderStatus()).getDesc());
				bo.setCreateTime(DateUtils.formatDate(t.getCreateTime(),AFTConstants.YYYYMMDDHHMMSS));
				bo.setOrderAmount(String.valueOf(t.getOrderAmount()).equals("0")?"面议":String.valueOf(t.getOrderAmount())+" 万");
				bo.setFirstPayment(String.valueOf(t.getFirstPayment()).equals("0")?"面议":String.valueOf(t.getFirstPayment())+" 万");
				bo.setOperatorActive(setOperatorActive(t));
				List<TOrderDetail> tdList = tOrderMapper.selectOrderCommodity(String.valueOf(t.getOrderNo()));
				for(TOrderDetail tod : tdList ){
					cdb = new CommodityDetailBo();
					cdb.setCommodityPrice(String.valueOf(tod.getCommodityPrice()).equals("0")?"面议":String.valueOf(tod.getCommodityPrice())+" 万");
					cdb.setDiscountPrice(String.valueOf(tod.getDiscountPrice()).equals("0")?"面议":String.valueOf(tod.getDiscountPrice())+" 万");
					cdb.setCommodityId(tod.getCommodityId());
					cdb.setCommodityName(tod.getCommodityName());
					cdb.setCommodityMode(tod.getCommodityMode());
					cdb.setCommodityType(tod.getCommodityType());
					cdb.setCommodityQuantity(tod.getCommodityQuantity());
					commoditys.add(cdb);
				}
				bo.setCommoditys(commoditys);
				boList.add(bo);
			}
		}
		result.setList(boList);
		result.setPageNo(data.getPageNo());
		result.setPageSize(data.getPageSize());
		result.setTotalCount(data.getTotalCount());
		result.setFilterNo(data.getFilterNo());
		return result;
	}

	@Override
	public C2BOrderDetailBo selectOrderDetail(String orderNo) {
		TOrder t = tOrderMapper.selectByPrimaryKey(orderNo);
		C2BOrderDetailBo bo = new C2BOrderDetailBo();
		bo.setOrderNo(String.valueOf(t.getOrderNo()));
		bo.setOrderRemarks(t.getOrderRemarks());
		bo.setOrderStatus(OrderState.getStatus(t.getOrderStatus()).getDesc());
		bo.setCreateTime(DateUtils.formatDate(t.getCreateTime(),AFTConstants.YYYYMMDDHHMMSS));
		bo.setOrderAmount(String.valueOf(t.getOrderAmount()).equals("0")?"面议":String.valueOf(t.getOrderAmount())+" 万");
		bo.setFirstPayment(String.valueOf(t.getFirstPayment()).equals("0")?"面议":String.valueOf(t.getFirstPayment())+" 万");
		bo.setOperatorActive(setOperatorActive(t));
		List<CommodityDetailBo> commoditys = new ArrayList<CommodityDetailBo>();
		CommodityDetailBo cdb = null;
		List<TOrderDetail> tdList = tOrderMapper.selectOrderCommodity(String.valueOf(t.getOrderNo()));
		for(TOrderDetail tod : tdList ){
			cdb = new CommodityDetailBo();
			cdb.setCommodityPrice(String.valueOf(tod.getCommodityPrice()).equals("0")?"面议":String.valueOf(tod.getCommodityPrice())+" 万");
			cdb.setDiscountPrice(String.valueOf(tod.getDiscountPrice()).equals("0")?"面议":String.valueOf(tod.getDiscountPrice())+" 万");
			cdb.setCommodityId(tod.getCommodityId());
			cdb.setCommodityName(tod.getCommodityName());
			cdb.setCommodityMode(tod.getCommodityMode());
			cdb.setCommodityType(tod.getCommodityType());
			cdb.setCommodityQuantity(tod.getCommodityQuantity());
			commoditys.add(cdb);
		}
		bo.setCommoditys(commoditys);
		return bo;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Pagination<BillListBo> selectOrderBillList(String orderNo,Integer pageNo,Integer pageSize) {
		Map<String, Object> params = new HashMap<String, Object>();
		if(orderNo != null) params.put("orderNo", orderNo);
		params.put("uid", TokenManager.getUserId());
		Pagination<BillListBo> data = (Pagination<BillListBo>)findPage("selectOrderBillByPage","selectOrderBillCount", params, pageNo, pageSize);
		List<BillListBo> list = (List<BillListBo>)data.getList();
		if(list.size()>0){
			for(BillListBo bo:list){
				bo.setBusinessDesc(setBusinessDesc(bo.getTransactionSubject(),bo.getTransactionAmount()));
			}
		}
		data.setList(list);
		return data;
	}

	@Override
	@Transactional
	public int updateApplyForWithdraw(String orderNo,String remarks) {
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(orderNo);
		BigDecimal transactionAmount = tOrder.getActuallyTotalAmount().subtract(tOrder.getActuallyBrokerageAmount());
		addFundRecord(orderNo, TokenManager.getUserToken().getNickname(), TokenManager.getUserId(), DEFAULT_PLATFORM_ID, remarks,
				TransactionSubject.SUPPLY_COLLECT, PayChannel.UNIONPAY,transactionAmount,TransactionMode.OFFLINE, AuditState.WAIT_AUDIT);
		setOrderState(OrderAction.APPLY_FOR_WITHDRAW, new BigDecimal(0), tOrder, false);
		tOrder.setUpdateTime(new Date());
		tOrderMapper.updateByPrimaryKeySelective(tOrder);
		return 1;
	}

	@Override
	@Transactional
	public int updateApplyForCancel(String orderNo) {
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(orderNo);
		setOrderState(OrderAction.APPLY_FOR_CANCEL, new BigDecimal(0), tOrder, false);
		tOrder.setUpdateTime(new Date());
		tOrderMapper.updateByPrimaryKeySelective(tOrder);
		return 1;
	}

	/**
	 * 
	 * @param transactionSubject 交易科目
	 * @param transactionAmount 交易金额
	 * @param payeeId 收款人
	 * @param payerId 付款人
	 * @return
	 */
	private String setBusinessDesc(Integer transactionSubject,BigDecimal transactionAmount){
		String result = "";
		if(transactionSubject == TransactionSubject.SUPPLY_COLLECT.getCode() || transactionSubject == TransactionSubject.REFUND.getCode()){
			result =  "收入-"+transactionAmount;
		}else if(transactionSubject == TransactionSubject.SUPPLY_PAY.getCode()){
			result =  "支出-"+transactionAmount;
		}
		return result;
	}

	@Override
	public int updateConfirmIntention(String orderNo, boolean confirm) {
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(orderNo);
		setOrderState(OrderAction.CONFIRM_INTENTION, new BigDecimal(0), tOrder, confirm);
		tOrderMapper.updateByPrimaryKeySelective(tOrder);
		return 1;
	}

	
	
	private Map<String,Object> disposeParams(OrderListBo bo,String startDate,String endDate){
		Map<String,Object> params = new HashMap<>();
		if(StringUtils.isNotBlank(bo.getBuyerName())) params.put("buyerName", bo.getBuyerName());
		if(StringUtils.isNotBlank(bo.getOrderNo())) params.put("orderNo", bo.getOrderNo());
		if(null!=bo.getApproval()) params.put("approval", bo.getApproval());
		if(StringUtils.isNotBlank(bo.getSalesmanName())) params.put("salesmanName", bo.getSalesmanName());
		if(StringUtils.isNotBlank(startDate)) params.put("startDate", startDate +" 00:00:00");
		if(StringUtils.isNotBlank(endDate)) params.put("endDate", endDate + "23:59:59");
		if(bo.getOrderStatus() != null) params.put("orderStatus", bo.getOrderStatus());
		if(bo.getLiquidationStatus() != null) params.put("liquidationStatus", bo.getLiquidationStatus());
		if(bo.getProjectStage() != null) params.put("projectStage", bo.getProjectStage());
		if(bo.getOrderChannel() != null) params.put("orderChannel", bo.getOrderChannel());
		
		return params;
	}

	@Override
	public ServiceOrderDetailBo selectServiceOrderDetail(String orderNo) {
		ServiceOrderDetailBo bo = tOrderMapper.selectServiceOrderDetail(orderNo);
		TOrder tOrder = new TOrder();
		try {
			BeanUtilsExt.copyProperties(tOrder, bo);
			tOrder.setActuallyTotalAmount(bo.getActuallyTotalAmount());
			bo.setActive(setOperatorActive(tOrder));
		} catch (IllegalAccessException | InvocationTargetException e) {
			e.printStackTrace();
		}
		return tOrderMapper.selectServiceOrderDetail(orderNo);
	}


	@Override
	public int updateSignServiceOrder(String orderNo,String contractNo, String signFirstPayment, String signTotalAmount,
			String approval,String orderRemarks,String signTime) {
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(orderNo);
		checkOrder(tOrder); //检查订单状态
		 checkProject(tOrder); //检查是否可签单
		if (tOrder.getOrderStatus() != OrderState.WAIT_FOR_SIGN.getCode()) {
			throw new BusinessException(new Error(ErrorConstants.NOT_ACCORD_WITH_NEXT, orderNo, ""));
		} else {
			tOrder.setSignFirstPayment(new BigDecimal(signFirstPayment));
			tOrder.setSignTotalAmount(new BigDecimal(signTotalAmount));
			tOrder.setOrderStage(OrderStage.SIGNED.getCode());
			tOrder.setOrderStatus(OrderState.ALREADY_SIGN.getCode());
			tOrder.setProjectStage(ProjectStage.NOT_SATISFY_CONDITION.getCode());
			tOrder.setApproval(Integer.valueOf(approval));
			tOrder.setUpdateTime(new Date());
			try {
				tOrder.setSignTime(DateUtils.parseDate(signTime, AFTConstants.YYYYMMDD));
			} catch (ParseException e) {
				e.printStackTrace();
			}
			tOrder.setOrderRemarks(orderRemarks);
			tOrder.setContractNo(contractNo);
			tOrderMapper.updateByPrimaryKeySelective(tOrder);
			//releaseProject(releaseList);//释放原锁定业务
			//lockProject(tOrder);//锁定客户业务
		}
		return 1;
	}

	@Override
	public int updateRevokeOrder(String orderNo) {
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(orderNo);
		boolean flag = true;
		if(tOrder.getOrderStatus() != OrderState.BUYER_CANCEL_BEFORE_SIGN.getCode()
				&& tOrder.getOrderStatus() != OrderState.BUYER_CANCEL_AFTER_SIGN.getCode()
				&& tOrder.getOrderStatus() != OrderState.SELLER_REFUSE_BEFORE_SIGNL.getCode()
				&& tOrder.getOrderStatus() != OrderState.SELLER_CANCEL_AFTER_SIGN.getCode()){
			flag = false;
		}
		if(flag && tOrder.getActuallyTotalAmount().doubleValue() == 0){
			tOrder.setDeleteSign(ActiveState.ABOLISH.getCode());
		}else{
			throw new BusinessException(new Error(ErrorConstants.NOT_ACCORD_WITH_NEXT,"作废"));
		}
		tOrder.setUpdateTime(new Date());
		tOrderMapper.updateByPrimaryKeySelective(tOrder);
		return 1;
	}
	
	public void checkOrder(TOrder tOrder){
		if(tOrder == null) 
			 throw new BusinessException(new Error(ErrorConstants.ORDER_NOT_EXIST, "" ,""));
		if(tOrder.getDeleteSign() == ActiveState.ABOLISH.getCode())
			 throw new BusinessException(new Error(ErrorConstants.ORDER_ALREADY_FREEZE, tOrder.getOrderNo(),""));
		if(tOrder.getDeleteSign() == ActiveState.LOCKING.getCode())
			 throw new BusinessException(new Error(ErrorConstants.ORDER_ALREADY_REVOKE, tOrder.getOrderNo(),""));
	}

	public List<LockingReleaseBo> checkProject(TOrder tOrder){
		List<TOrderDetail> list = tOrderMapper.selectOrderCommodity(tOrder.getOrderNo());
		//检查客户锁定情况
		boolean isUserOwner = false;
		List<LockingReleaseBo> userLockedList = userMapper.selectLockedProject(tOrder.getBuyerId(), TokenManager.getAdminId(),null, 0, UserLockReleaseStatus.LOCKED.getCode());
		if(userLockedList.size() > 0){
			isUserOwner = true;
		}
		//检查业务锁定情况
		List<LockingReleaseBo> lockedList = null;
		List<LockingReleaseBo> releaseList = new ArrayList<LockingReleaseBo>();
		boolean isBusinessOwner = false;
		String businessName = "";
		for(TOrderDetail td : list){
			//业务锁定
			lockedList = userMapper.selectLockedProject(tOrder.getBuyerId(), null,td.getCommodityId(), 1, UserLockReleaseStatus.LOCKED.getCode());
			businessName = businessProjectMapper.selectByPrimaryKey(td.getCommodityId()).getBname();
			if(lockedList.size() > 0){
				for(LockingReleaseBo bo : lockedList){
					if(bo.getAid().equals(TokenManager.getAdminId())){
						isBusinessOwner = true;
						releaseList.add(bo);
					} 
				}
				if(!isBusinessOwner) throw new BusinessException(new Error(ErrorConstants.BUSINESS_ALREADY_LOCKED,businessName,""));
			}else{
				if(!isUserOwner) throw new BusinessException(new Error(ErrorConstants.CUSTOMER_ALREADY_LOCKED,businessName,""));
			}
		}
		return releaseList;
	}
	
	private void lockProject(BusinessListBo ub) {
		UserLockRelease ulr= new UserLockRelease();
			ulr.setId(UUID.randomUUID().toString());
			ulr.setType(1);
			ulr.setAid(TokenManager.getAdminId());
			ulr.setBusinessProjectId(ub.getBusinessProjectId());
			SimpleDateFormat sdf =   new SimpleDateFormat( " yyyy-MM-dd HH:mm:ss " ); 
			try {
				if (null==ub.getCreateTime()) {
					ulr.setLockTime(new Date());
				}else {
					ulr.setLockTime(sdf.parse(ub.getCreateTime()));
				}
			} catch (ParseException e) {
				e.printStackTrace();
			}
			ulr.setStatus(UserLockReleaseStatus.LOCKED.getCode());
			ulr.setUid(ub.getUid());
			userLockReleaseMapper.insert(ulr);
		}
	
	@SuppressWarnings("unused")
	private void releaseProject(List<LockingReleaseBo> releaseList){
		if(releaseList != null && releaseList.size()>0){
			UserLockRelease ulr = null;
			for(LockingReleaseBo bo : releaseList){
				ulr = new UserLockRelease();
				ulr.setId(bo.getId());
				ulr.setStatus(UserLockReleaseStatus.RELEASE.getCode());
				userLockReleaseMapper.updateByPrimaryKeySelective(ulr);
			}
			
		}
	}
	
	@Override
	@Transactional
	public int addOrderCommodity(String orderNo, String commodityId,String commodityName, String commodityMode, Integer commodityQuantity,Integer commodityType,
			String commodityPrice, String discountPrice,String commodityFirstPayment,String discountFirstPayment, String remarks) {
			TOrder tOrder = tOrderMapper.selectByPrimaryKey(orderNo);
			checkOrder(tOrder);
			if(tOrder.getOrderStatus() != OrderState.WAIT_FOR_SIGN.getCode() 
					&& tOrder.getChangeStatus() != ChangeState.CHANGING.getCode()){
				 throw new BusinessException(new Error(ErrorConstants.NOT_ACCORD_WITH_NEXT, orderNo,""));
			}else{
				TOrderDetail detail = new TOrderDetail();
				detail.setId(UUID.randomUUID().toString());
				detail.setOrderNo(orderNo);
				detail.setCommodityId(commodityId);
				detail.setCommodityName(commodityName);
				detail.setCommodityQuantity(commodityQuantity);
				detail.setCommodityType(commodityType);
				detail.setCommodityMode(StringUtils.isBlank(commodityMode)?DEFAULT_COMMODITY_MODE:commodityMode);
				detail.setCommodityPrice(new BigDecimal(commodityPrice));
				detail.setDiscountPrice(new BigDecimal(discountPrice));
				detail.setCommodityFirstPayment(new BigDecimal(commodityFirstPayment));
				detail.setDiscountFirstPayment(new BigDecimal(discountFirstPayment));
				detail.setRemarks(remarks);	
				detail.setCreateTime(new Date());
				tOrderDetailMapper.insert(detail);
				//订单市场价总额
				BigDecimal totalAmountChange = new BigDecimal(commodityPrice).multiply(new BigDecimal(commodityQuantity));
				//订单市场价首付金额
				BigDecimal firstPaymentChange = new BigDecimal(commodityFirstPayment).multiply(new BigDecimal(commodityQuantity));
				//订单签单总额
				BigDecimal signTotalAmountChange = new BigDecimal(discountPrice).multiply(new BigDecimal(commodityQuantity));
				//订单签单首付金额
				BigDecimal signFirstPaymentChange = new BigDecimal(discountFirstPayment).multiply(new BigDecimal(commodityQuantity));
				tOrder.setOrderAmount(tOrder.getOrderAmount().add(totalAmountChange));
				tOrder.setFirstPayment(tOrder.getFirstPayment().add(firstPaymentChange));
				tOrder.setSignTotalAmount(tOrder.getSignTotalAmount().add(signTotalAmountChange));
				tOrder.setSignFirstPayment(tOrder.getSignFirstPayment().add(signFirstPaymentChange));
				tOrderMapper.updateByPrimaryKeySelective(tOrder);
			}
			if(tOrder.getOrderStatus() == OrderState.ALREADY_SIGN.getCode()){ //已签单的同步锁定
				UserLockRelease ulr = new UserLockRelease();
				ulr.setId(UUID.randomUUID().toString());
				ulr.setType(1);
				ulr.setAid(TokenManager.getAdminId());
				ulr.setBusinessProjectId(commodityId);
				ulr.setLockTime(tOrder.getSignTime());
				ulr.setStatus(UserLockReleaseStatus.LOCKED.getCode());
				ulr.setUid(tOrder.getBuyerId());
				ulr.setOrderNo(tOrder.getOrderNo());
				userLockReleaseMapper.insert(ulr);
			}
		return 1;
	}

	@Override
	@Transactional
	public int updateOrderCommodity(String detailId,String discountPrice,String discountFirstPayment,Integer commodityQuantity,String remarks) {
		TOrderDetail oldDetail = tOrderDetailMapper.selectByPrimaryKey(detailId);
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(oldDetail.getOrderNo());
		checkOrder(tOrder);
		if (tOrder.getOrderStatus() != OrderState.WAIT_FOR_SIGN.getCode()
				&& tOrder.getChangeStatus() != ChangeState.CHANGING.getCode()) {
			throw new BusinessException(new Error(ErrorConstants.NOT_ACCORD_WITH_NEXT, oldDetail.getOrderNo(), ""));
		} else {
			TOrderDetail detail = new TOrderDetail();
			detail.setId(detailId);
			detail.setOrderNo(oldDetail.getOrderNo());
			detail.setCommodityQuantity(commodityQuantity);
			detail.setDiscountPrice(new BigDecimal(discountPrice));
			detail.setDiscountFirstPayment(new BigDecimal(discountFirstPayment));
			detail.setRemarks(remarks);
			tOrderDetailMapper.updateByPrimaryKeySelective(detail);
			// 订单签单总额
			BigDecimal signTotalAmountChange = new BigDecimal(discountPrice).multiply(new BigDecimal(commodityQuantity))
					.subtract(oldDetail.getDiscountPrice().multiply(new BigDecimal(oldDetail.getCommodityQuantity())));
			// 订单签单首付金额
			BigDecimal signFirstPaymentChange = new BigDecimal(discountFirstPayment).multiply(new BigDecimal(commodityQuantity))
					.subtract(oldDetail.getDiscountFirstPayment().multiply(new BigDecimal(oldDetail.getCommodityQuantity())));
			tOrder.setSignTotalAmount(tOrder.getSignTotalAmount().add(signTotalAmountChange));
			tOrder.setSignFirstPayment(tOrder.getSignFirstPayment().add(signFirstPaymentChange));
			tOrder.setUpdateTime(new Date());
			tOrderMapper.updateByPrimaryKeySelective(tOrder);
		}
		return 1;
	}

	@Override
	@Transactional
	public int deleteOrderCommodity(String detailId) {
		TOrderDetail detail = tOrderDetailMapper.selectByPrimaryKey(detailId);
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(detail.getOrderNo());
		checkOrder(tOrder);
		if (tOrder.getOrderStatus() != OrderState.WAIT_FOR_SIGN.getCode()
				&& tOrder.getChangeStatus() != ChangeState.CHANGING.getCode()) {
			throw new BusinessException(new Error(ErrorConstants.NOT_ACCORD_WITH_NEXT, detail.getOrderNo(), ""));
		} else {
			BigDecimal totalAmountChange = detail.getCommodityPrice()
					.multiply(new BigDecimal(detail.getCommodityQuantity()));
			BigDecimal firstPaymentChange = detail.getCommodityFirstPayment()
					.multiply(new BigDecimal(detail.getCommodityQuantity()));
			BigDecimal signTotalAmountChange = detail.getDiscountPrice()
					.multiply(new BigDecimal(detail.getCommodityQuantity()));
			BigDecimal signFirstPaymentChange = detail.getDiscountFirstPayment()
					.multiply(new BigDecimal(detail.getCommodityQuantity()));
			tOrder.setOrderAmount(tOrder.getOrderAmount().subtract(totalAmountChange));
			tOrder.setFirstPayment(tOrder.getFirstPayment().subtract(firstPaymentChange));
			tOrder.setSignTotalAmount(tOrder.getSignTotalAmount().subtract(signTotalAmountChange));
			tOrder.setSignFirstPayment(tOrder.getSignFirstPayment().subtract(signFirstPaymentChange));
			tOrderMapper.updateByPrimaryKeySelective(tOrder);
			tOrderDetailMapper.deleteByPrimaryKey(detailId);
		}
		if(tOrder.getOrderStatus() == OrderState.ALREADY_SIGN.getCode()){ //已签单的同步锁定
			userLockReleaseMapper.deleteLockByOrder(detail.getOrderNo(),detail.getCommodityId());
		}
		return 1;
	}
	
	@Override
	public List<OrganizationManagement> selectMyDeps(){
		if(TokenManager.hasRole(AFTConstants.SUPERADMIN) || TokenManager.hasRole(AFTConstants.APPROVAL_DECISION)) 
			return organizationManagementMapper.selectAllDeps();
		else
			return selectCurrentDep(TokenManager.getAdminId());
	}
	
	private List<OrganizationManagement> selectSubDeps(List<OrganizationManagement> allData,List<OrganizationManagement> superData){
		List<OrganizationManagement> subData = new ArrayList<>();
		String superIds = "";
		for(OrganizationManagement om : superData){
			if(!om.getId().equals(om.getSuperId())){
				superIds += om.getId() + ",";
			}
		}
		if(StringUtils.isNotBlank(superIds)) subData = organizationManagementMapper.selectSubDeps(superIds.substring(0, superIds.length()-1));
		if(subData != null && subData.size()>0) {
			allData.addAll(subData);
			selectSubDeps(allData,subData);
		} 
		return allData;
	} 
	
	private List<OrganizationManagement> selectCurrentDep(String managerId){
		List<OrganizationManagement> allData = new ArrayList<OrganizationManagement>();
		List<OrganizationManagement> superData = organizationManagementMapper.selectCurrentDeps(managerId);
		if(superData != null && superData.size()>0){
			allData.addAll(superData);
		}
		selectSubDeps(allData,superData);
		return allData;
	}



	

	@Override
	public int createServiceOrder(String uid, Integer orderType,String contractType) {
		BigDecimal initial = new BigDecimal(0);
		TOrder tOrder = new TOrder();
		tOrder.setOrderType(orderType);
		tOrder.setOrderNo(idGenerator.generateId().toString());	
		tOrder.setCreater(TokenManager.getAdminId());
		tOrder.setCreateTime(new Date());
		tOrder.setBuyerId(uid);
		tOrder.setSellerId(DEFAULT_PLATFORM_ID);
		tOrder.setSalesmanId(TokenManager.getAdminId());
		tOrder.setBrokerageAmount(initial);
		tOrder.setFirstPayment(initial);
		tOrder.setOrderAmount(initial);
		tOrder.setSignBrokerageAmount(initial);
		tOrder.setSignFirstPayment(initial);
		tOrder.setSignTotalAmount(initial);
		tOrder.setSignWithdrawAmount(initial);
		tOrder.setOrderChannel(OrderChannel.PORTAL.getCode());	
		tOrder.setDeleteSign(ActiveState.NORMAL.getCode());
		tOrder.setApproval(ApprovalState.NORMAL.getCode());
		tOrder.setContractType(contractType);
		tOrder.setChangeStatus(ChangeState.UNCHANGE.getCode());
		setOrderState(OrderAction.ADD_INTENTION, new BigDecimal(0), tOrder, false);
		return tOrderMapper.insert(tOrder);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Pagination<OrderListBo> selectPublicOrder(OrderListBo bo,String startDate,String endDate,Integer pageNo, Integer pageSize) {
		Map<String, Object> params = new HashMap<String,Object>();
		if(StringUtils.isNotBlank(bo.getBuyerName())) params.put("buyerName", bo.getBuyerName());
		if(bo.getOrderType() != null) params.put("orderType", bo.getOrderType());
		if(bo.getOrderChannel() != null) params.put("orderChannel", bo.getOrderChannel());
		if(bo.getOrderStatus() != null) params.put("orderStatus", bo.getOrderStatus());
		if(StringUtils.isNotBlank(startDate)) params.put("startDate", startDate);
		if(StringUtils.isNotBlank(endDate)) params.put("endDate", endDate);
		return (Pagination<OrderListBo>)findPage("selectPublicOrderByPage","selectPublicOrderCount", 
				params, pageNo, pageSize);
	}

	@Override
	public int updateAppointSalesman(String orderNo, String salesmanId) {
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(orderNo);
		checkOrder(tOrder);
		tOrder.setSalesmanId(salesmanId);
		tOrder.setUpdateTime(new Date());
		return tOrderMapper.updateByPrimaryKeySelective(tOrder);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Pagination<OrderListBo> selectSettlementList(String orderNo, String depId,String buyerName,String salesmanName,  
			String financeId,String financeName,Integer orderStatus,Integer liquidationStatus,Integer approval,Integer isDistributionFinance,
			String startDate,String endDate,Integer pageNo, Integer pageSize) {
		Map<String, Object> params = new HashMap<String, Object>();
		if(StringUtils.isNotBlank(orderNo)) params.put("orderNo", orderNo);
		if(StringUtils.isNotBlank(depId)) params.put("depId", depId);
		if(StringUtils.isNotBlank(buyerName)) params.put("buyerName", buyerName);
		if(StringUtils.isNotBlank(salesmanName)) params.put("salesmanName", salesmanName);
		if(StringUtils.isNotBlank(financeId)) params.put("financeId", financeId);
		if(StringUtils.isNotBlank(financeName)) params.put("financeName", financeName);
		if(orderStatus != null) params.put("orderStatus", orderStatus);
		if(liquidationStatus != null) params.put("liquidationStatus", liquidationStatus);
		if(approval != null) params.put("approval", approval);
		if(isDistributionFinance != null) params.put("isDistributionFinance", isDistributionFinance);
		if(StringUtils.isNotBlank(startDate)) params.put("startDate", startDate);
		if(StringUtils.isNotBlank(endDate)) params.put("endDate", endDate);
		return (Pagination<OrderListBo>)findPage("selectSettlementByPage","selectSettlementCount", params, pageNo, pageSize);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Pagination<BillListBo> selectMyBillList(String payeeName, String payerName, String depId,
			String salesmanName,String orderNo, Integer confirmSign,Integer deleteSign, Integer pageNo, Integer pageSize) {
		Map<String, Object> params = new HashMap<String, Object>();
		if(StringUtils.isNotBlank(payeeName)) params.put("payeeName", payeeName);
		if(StringUtils.isNotBlank(payerName)) params.put("payerName", payerName);
		if(StringUtils.isNotBlank(depId)) params.put("depId", depId);
		if(StringUtils.isNotBlank(salesmanName)) params.put("salesmanName", salesmanName);
		if(StringUtils.isNotBlank(orderNo)) params.put("orderNo", orderNo);
		if(confirmSign != null) params.put("confirmSign", confirmSign);
		if(deleteSign != null) params.put("deleteSign", deleteSign);
		/** 特殊处理字段开始 **/
		if(!TokenManager.hasRole(AFTConstants.SUPERADMIN)){
			params.put("isFinance", 1);
		}
		params.put("aid", TokenManager.getAdminId());
		/** 特殊处理字段结束 **/
		return (Pagination<BillListBo>)findPage("selectBillByPage","selectBillCount", params, pageNo, pageSize);
	}
	
	
	@SuppressWarnings("unchecked")
	@Override
	public Pagination<BillListBo> queryMyBillList(String payeeName, String payerName, String depId,
			String salesmanName,String orderNo, Integer confirmSign,Integer deleteSign, Integer pageNo, Integer pageSize) {
		Map<String, Object> params = new HashMap<String, Object>();
		if(StringUtils.isNotBlank(payeeName)) params.put("payeeName", payeeName);
		if(StringUtils.isNotBlank(payerName)) params.put("payerName", payerName);
		if(StringUtils.isNotBlank(depId)) params.put("depId", depId);
		if(StringUtils.isNotBlank(salesmanName)) params.put("salesmanName", salesmanName);
		if(StringUtils.isNotBlank(orderNo)) params.put("orderNo", orderNo);
		if(confirmSign != null) params.put("confirmSign", confirmSign);
		if(deleteSign != null) params.put("deleteSign", deleteSign);
		/** 特殊处理字段开始 **/
		if(!TokenManager.hasRole(AFTConstants.SUPERADMIN)){
			params.put("isFinance", 0);
		}
		params.put("aid", TokenManager.getAdminId());
		/** 特殊处理字段结束 **/
		return (Pagination<BillListBo>)findPage("selectBillByPage","selectBillCount", params, pageNo, pageSize);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public Pagination<BillListBo> queryAllBillList(String payeeName, String payerName, String depId,
			String salesmanName ,String financeName, String orderNo, Integer confirmSign,Integer deleteSign,Integer pageNo, Integer pageSize) {
		Map<String, Object> params = new HashMap<String, Object>();
		if(StringUtils.isNotBlank(payeeName)) params.put("payeeName", payeeName);
		if(StringUtils.isNotBlank(payerName)) params.put("payerName", payerName);
		if(StringUtils.isNotBlank(depId)) params.put("depId", depId);
		if(StringUtils.isNotBlank(salesmanName)) params.put("salesmanName", salesmanName);
		if(StringUtils.isNotBlank(financeName)) params.put("financeName", financeName);
		if(orderNo != null) params.put("orderNo", orderNo);
		if(confirmSign != null) params.put("confirmSign", confirmSign);
		if(deleteSign != null) params.put("deleteSign", deleteSign);
		Pagination<BillListBo> data = (Pagination<BillListBo>)findPage("selectBillByPage","selectBillCount", params, pageNo, pageSize);
		List<BillListBo> list = (List<BillListBo>)data.getList();
		if(list.size()>0){
			for(BillListBo bo:list){
				bo.setBusinessDesc(setBusinessDesc(bo.getTransactionSubject(),bo.getTransactionAmount()));
			}
		}
		data.setList(list);
		return data;
	}

	@Override
	public BillDetailBo selectBillDetail(String billNo) {
		return tOrderMapper.selectBillDetail(billNo);
	}

	

	@Override
	public int updateBill(String billNo,String orderNo, String financialPayNo, String financialPayTime, String remarks) {
		TOrderBill bill = new TOrderBill();
		bill.setBillNo(billNo);
		bill.setOrderNo(orderNo);
		bill.setFinancialPayNo(financialPayNo);
		try {
			bill.setFinancialPayTime(DateUtils.parseDate(financialPayTime, AFTConstants.YYYYMMDDHHMMSS));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		bill.setRemarks(remarks);
		return tOrderBillMapper.updateByPrimaryKeySelective(bill);
	}

	

	public void sendMessage(TOrder tOrder, String mobile, String type) {
		  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String userName=tOrderMapper.selectByUserName(tOrder.getOrderNo());
			//String message=noticeType.getDesc() + ": 订单编号-" + tOrder.getOrderNo() + ",变更内容："+noticeComment+",操作人-" + TokenManager.getAdminToken().getName();
			String paramString = "{\"number\":\"" + tOrder.getOrderNo() 
			+ "\",\"operator\":\"" + TokenManager.getAdminToken().getName()
			+ "\",\"name\":\"" +  userName
			+ "\",\"time\":\"" +   sdf.format(new Date())
			+ "\",\"type\":\"" +  type +
			"\"}";
			MobileMessageUtils.sendMessage(mobileRemindCodeTemplate, paramString, mobile, accessKey, accessSecret);
	}
	

	@SuppressWarnings("unchecked")
	@Override
	public Pagination<OrderListBo> listSetUpServiceOrder(String buyerName,String salesmanName, String financeName,
			String depId,Integer approval, Integer pageNo, Integer pageSize) {
		Map<String,Object> params = new HashMap<String,Object>();
		if(StringUtils.isNotBlank(buyerName))
			params.put("buyerName", buyerName);
		if(StringUtils.isNotBlank(salesmanName))
			params.put("salesmanName", salesmanName);
		if(StringUtils.isNotBlank(financeName))
			params.put("financeName",financeName);
		if(StringUtils.isNotBlank(depId))
			params.put("depId", depId);
		if(approval != null)
			params.put("approval", approval);
		return  (Pagination<OrderListBo>)findPage("selectSetUpServiceOrderByPage","selectSetUpServiceOrderCount", 
				params, pageNo, pageSize);
	}


	@Override
	public List<TOrderDetail> selectOrderCommodity(String orderNo) {
		return tOrderMapper.selectOrderCommodity(orderNo);
	}

	@Override
	public int updatePayForTest(String orderNo, String payAmount) {
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(orderNo);
		if(tOrder.getLiquidationStatus() == LiquidationState.WAIT_PAY_FIRST_BALANCE.getCode()
				|| tOrder.getLiquidationStatus() == LiquidationState.WAIT_PAY_LAST_BALANCE.getCode()){
			addFundRecord(orderNo, "测试用户", DEFAULT_PLATFORM_ID, TokenManager.getUserId(), "", 
					TransactionSubject.SUPPLY_PAY,PayChannel.UNIONPAY, new BigDecimal(payAmount), TransactionMode.OFFLINE, AuditState.WAIT_AUDIT);
			tOrder.setUpdateTime(new Date());
			tOrderMapper.updateByPrimaryKeySelective(tOrder);
		}else{
			throw new BusinessException(new Error(ErrorConstants.ORDER_CAN_NOT_MODIFY, orderNo, ""));
		}
		return 1;
	}

	@Override
	public int updateRefundForTest(String orderNo, String refundAmount) {
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(orderNo);
		if(tOrder.getLiquidationStatus() == LiquidationState.AGREE_REFUND.getCode()){
			addFundRecord(orderNo, "测试用户", DEFAULT_PLATFORM_ID, TokenManager.getUserId(), "", 
					TransactionSubject.REFUND,PayChannel.UNIONPAY, new BigDecimal(refundAmount).multiply(new BigDecimal(-1)), TransactionMode.OFFLINE, AuditState.WAIT_AUDIT);
			tOrder.setUpdateTime(new Date());
			tOrderMapper.updateByPrimaryKeySelective(tOrder);
		}else{
			throw new BusinessException(new Error(ErrorConstants.ORDER_CAN_NOT_MODIFY, orderNo, ""));
		}
		return 1;
	}
	
	@Override
	public int updateDistributionOrder(String orderNo, String financeId) {
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(orderNo);
		checkOrder(tOrder);
		if(StringUtils.isBlank(tOrder.getFinanceId())){
			tOrder.setFinanceId(financeId);
		}
		tOrder.setUpdateTime(new Date());
		return tOrderMapper.updateByPrimaryKeySelective(tOrder);
	}

	@Override
	public int updateLockOrRevokeOrder(String orderNo, Integer operatorType) {
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(orderNo);
		if(tOrder != null){
			if(operatorType == 0){ //锁定
				if(tOrder.getDeleteSign() != DeleteStatus.UNDELETE.getCode())
					throw new BusinessException(new Error(ErrorConstants.ORDER_CAN_NOT_MODIFY, orderNo, ""));
				tOrder.setDeleteSign(DeleteStatus.LOCKING.getCode());
			}else if(operatorType == 1){ //解锁
				if(tOrder.getDeleteSign() != DeleteStatus.LOCKING.getCode())
					throw new BusinessException(new Error(ErrorConstants.ORDER_CAN_NOT_MODIFY, orderNo, ""));
				tOrder.setDeleteSign(DeleteStatus.UNDELETE.getCode());
			}else if(operatorType == 2){ //作废
				if(tOrder.getDeleteSign() != DeleteStatus.UNDELETE.getCode())
					throw new BusinessException(new Error(ErrorConstants.ORDER_CAN_NOT_MODIFY, orderNo, ""));
				if(tOrder.getActuallyTotalAmount().doubleValue() > 0){
					throw new BusinessException(new Error(ErrorConstants.ORDER_CAN_NOT_MODIFY, orderNo, ""));
				}
				if(tOrder.getOrderStatus() != OrderState.BUYER_CANCEL_AFTER_SIGN.getCode()
						&& tOrder.getOrderStatus() != OrderState.BUYER_CANCEL_BEFORE_SIGN.getCode()
						&& tOrder.getOrderStatus() != OrderState.SELLER_CANCEL_AFTER_SIGN.getCode()
						&& tOrder.getOrderStatus() != OrderState.SELLER_REFUSE_BEFORE_SIGNL.getCode())
					throw new BusinessException(new Error(ErrorConstants.ORDER_CAN_NOT_MODIFY, orderNo, ""));
				tOrder.setDeleteSign(DeleteStatus.DELETED.getCode());
			}else if(operatorType == 3){ //签单前取消订单
				boolean flag = true;
				if(tOrder.getOrderStatus() != OrderState.WAIT_FOR_SIGN.getCode()){
					flag = false;
				}			
				if(tOrder.getLiquidationStatus() != LiquidationState.WAIT_PAY_FIRST_BALANCE.getCode()
						&& tOrder.getLiquidationStatus() != LiquidationState.WAIT_PAY_LAST_BALANCE.getCode()
						&& tOrder.getLiquidationStatus() != LiquidationState.ALREADY_PAY.getCode()){
					flag = false;
				}
				if(!flag)
					throw new BusinessException(new Error(ErrorConstants.ORDER_CAN_NOT_MODIFY, orderNo, ""));
				tOrder.setOrderStatus(OrderState.SELLER_REFUSE_BEFORE_SIGNL.getCode());
			}
			tOrderMapper.updateByPrimaryKey(tOrder);
		}
		return 1;
	}
	
	
	private String getSalesmanIdByUid(String uid){
		User u = userMapper.selectByPrimaryKey(uid);
		if(u!=null&&StringUtils.isBlank(u.getAid())){
			return u.getAid();
		}else{
			return DEFAULT_ADMIN_ID;
		}
	}

	@Override
	public List<BillListBo> selectBillByOrderNo(String orderNo) {
		return tOrderMapper.selectBillByOrderNo(orderNo);
	}

	@Override
	public int updateApplyForRefund(String orderNo) {
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(orderNo);
		setOrderState(OrderAction.APPLY_FOR_REFUND, new BigDecimal(0), tOrder, false);
		tOrder.setUpdateTime(new Date());
		return tOrderMapper.updateByPrimaryKey(tOrder);
	}

	@Override
	public int updateConfirmRefund(String orderNo,boolean confirm) {
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(orderNo);
		setOrderState(OrderAction.CONFIRM_REFUND, new BigDecimal(0), tOrder, confirm);
		tOrder.setUpdateTime(new Date());
		if(confirm){ //同意退款生成退款流水
			BigDecimal transactionAmount = tOrder.getActuallyTotalAmount().subtract(tOrder.getActuallyBrokerageAmount()).multiply(new BigDecimal(-1)); 
			addFundRecord(orderNo, "平台方", DEFAULT_PLATFORM_ID,TokenManager.getUserId(), "同意退款系统生成流水",
					TransactionSubject.REFUND, PayChannel.UNIONPAY,transactionAmount,TransactionMode.OFFLINE, AuditState.WAIT_AUDIT);
		}
		return tOrderMapper.updateByPrimaryKey(tOrder);
	}


	
	/**
	 * PC端添加意向
	 * 只能购买一份
	 * 后期规则：自营服务订单 、需求订单、其他订单不能同时加入购物车
	 * @throws ParseException 
	 */
	@Override
	public int addPurpose(String orderNo, String commodityId, String commodityMode, Integer commodityQuantity,Integer commodityType, 
			String createTime,String remarks) throws ParseException {
		CommodityDetailBo bo =  tOrderMapper.selectCommodityDetail(commodityId,commodityType);
		BigDecimal commodityPrice = StringUtils.isBlank(bo.getCommodityPrice()) ? DEFAULT_COMMODITY_PRICE 
				: new BigDecimal(Double.valueOf(bo.getCommodityPrice()));
		BigDecimal commodityFirstPayment = StringUtils.isBlank(bo.getCommodityFirstPayment()) ? DEFAULT_FIRST_PAYMENT 
				: new BigDecimal(Double.valueOf(bo.getCommodityFirstPayment()));
		BigDecimal discountPrice = commodityPrice.multiply(new BigDecimal(DEFAULT_COMMODITY_DISCOUNT));
		BigDecimal discountFirstPayment = commodityFirstPayment.multiply(new BigDecimal(DEFAULT_COMMODITY_DISCOUNT));
		TOrder tOrder = new TOrder();
		tOrder.setOrderNo(orderNo);	
		tOrder.setCreater(DEFAULT_ADMIN_ID);
		tOrder.setCreateTime(DateUtils.parseDate(createTime, AFTConstants.YYYYMMDDHHMMSS));
		if(commodityType == CommodityType.DEMAND.getTypeCode()){
			tOrder.setBuyerId(StringUtils.isBlank(bo.getSellerId()) ? DEFAULT_PLATFORM_ID : bo.getSellerId());
			tOrder.setSellerId(TokenManager.getUserId());
		}else{
			tOrder.setBuyerId(TokenManager.getUserId());
			tOrder.setSellerId(StringUtils.isBlank(bo.getSellerId()) ? DEFAULT_PLATFORM_ID : bo.getSellerId());
		}
		tOrder.setOrderType(commodityType);
		tOrder.setBrokerageAmount(discountPrice.multiply(new BigDecimal(DEFAULT_BROKERAGE_PROPORTION)));
		tOrder.setOrderAmount(commodityPrice);
		tOrder.setFirstPayment(commodityFirstPayment);
		tOrder.setSignTotalAmount(discountPrice);
		tOrder.setSignFirstPayment(discountFirstPayment);
		tOrder.setSignBrokerageAmount(discountPrice.multiply(new BigDecimal(DEFAULT_BROKERAGE_PROPORTION)));
		tOrder.setSignWithdrawAmount(discountPrice.subtract(discountPrice.multiply(new BigDecimal(DEFAULT_BROKERAGE_PROPORTION))));
		tOrder.setDeleteSign(DeleteStatus.UNDELETE.getCode());
		tOrder.setOrderChannel(OrderChannel.PORTAL.getCode());
		tOrder.setApproval(ApprovalState.NORMAL.getCode());
		tOrder.setChangeStatus(ChangeState.UNCHANGE.getCode());
		tOrder.setSalesmanId(getSalesmanIdByUid(TokenManager.getAdminId()));			
		
		tOrder.setOrderRemarks(remarks);
		tOrder.setContractType(bo.getCommodityClassify());
		setOrderState(OrderAction.ADD_INTENTION, new BigDecimal(0), tOrder, false);
		
		TOrderDetail tOrderDetail = new TOrderDetail();
		tOrderDetail.setId(UUID.randomUUID().toString());
		tOrderDetail.setOrderNo(orderNo);
		tOrderDetail.setCommodityId(commodityId);
		tOrderDetail.setCommodityName(bo.getCommodityName());
		tOrderDetail.setCommodityMode(StringUtils.isBlank(commodityMode)?DEFAULT_COMMODITY_MODE: commodityMode);
		tOrderDetail.setCommodityType(commodityType);
		tOrderDetail.setCommodityQuantity(commodityQuantity);
		tOrderDetail.setCommodityPrice(commodityPrice);
		tOrderDetail.setCommodityFirstPayment(commodityFirstPayment);
		tOrderDetail.setDiscountPrice(discountPrice);
		tOrderDetail.setDiscountFirstPayment(discountFirstPayment);
		tOrderDetail.setCreateTime(DateUtils.parseDate(createTime, AFTConstants.YYYYMMDDHHMMSS));
		tOrderDetailMapper.insert(tOrderDetail);
		tOrderMapper.insert(tOrder);
		return 1;
	}

	@Override
	@Transactional
	public int addOrderChange(String orderNo, String changeComment,String taskList,String dunList) {
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(orderNo);
		tOrder.setChangeStatus(ChangeState.CHANGING.getCode());
		TOrderChange change = new TOrderChange();
		change.setCreaterId(TokenManager.getAdminId());
		change.setCreateTime(new Date());
		change.setOrderNo(orderNo);
		String id=UUID.randomUUID().toString();
		change.setId(id);
		change.setChangeComment(changeComment);
		change.setChangeStatus(ChangeState.CHANGING.getCode());
		change.setDeleteSign(DeleteStatus.UNDELETE.getCode());
		tOrderChangeMapper.insert(change);
		tOrderMapper.updateByPrimaryKeySelective(tOrder);
		generatorNoticeData(NoticeStatus.ORDER_CHANGE_ADD,changeComment,tOrder);
		return 1;
	}

	@Override
	public List<OrderChangeBo> selectOrderChange(String orderNo) {
		return tOrderChangeMapper.selectOrderChange(orderNo);
	}

	@Override
	public int deleteOrderChange(String changeId) {
		TOrderChange change = tOrderChangeMapper.selectByPrimaryKey(changeId);
		change.setDeleteSign(DeleteStatus.DELETED.getCode());
		tOrderChangeMapper.updateByPrimaryKeySelective(change);
		return updateOrderSatusByChange(change.getOrderNo());
	}
	
	/**
	 * 更新变更状态
	 * @param changeId
	 * @return
	 */
	private int updateOrderSatusByChange(String orderNo){
		if(StringUtils.isBlank(orderNo)) return 0;
		int resultStatus = ChangeState.UNCHANGE.getCode();
		int onChangeCount = tOrderChangeMapper.selectCountByStatus(ChangeState.CHANGING.getCode(), orderNo);
		if(onChangeCount > 0){
			resultStatus = ChangeState.CHANGING.getCode();
		} else {
			int completeChangeCount = tOrderChangeMapper.selectCountByStatus(ChangeState.CHANGED.getCode(), orderNo);
			if(completeChangeCount>0) resultStatus = ChangeState.CHANGED.getCode();
		}
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(orderNo);
		tOrder.setChangeStatus(resultStatus);
		return tOrderMapper.updateByPrimaryKeySelective(tOrder);
	}

	@Override
	public int updateOrderChange(String changeId, String changeComment, Integer changeStatus) {
		TOrderChange change = tOrderChangeMapper.selectByPrimaryKey(changeId);
		if(StringUtils.isNotBlank(changeComment))change.setChangeComment(changeComment);
		change.setChangeStatus(changeStatus);
		tOrderChangeMapper.updateByPrimaryKeySelective(change);
		TOrder tOrder = tOrderMapper.selectByPrimaryKey(change.getOrderNo());
		generatorNoticeData(NoticeStatus.ORDER_CHANGE_UDPATE,changeComment,tOrder);
		return updateOrderSatusByChange(change.getOrderNo());
	}


	
	private void generatorNoticeData(NoticeStatus noticeType,String noticeComment,TOrder tOrder){
		if(tOrder == null) return;
		Notice notice = null;
		List<Notice> noticeList = new ArrayList<>();
		Calendar now = Calendar.getInstance();
		now.set(Calendar.MILLISECOND, 0);
		List<String> targetIds = new ArrayList<String>();
		if(StringUtils.isNotBlank(tOrder.getSalesmanId()) && !targetIds.contains(tOrder.getSalesmanId()))
			targetIds.add(tOrder.getSalesmanId());
		if(StringUtils.isNotBlank(tOrder.getFinanceId()) && !targetIds.contains(tOrder.getFinanceId()))
			targetIds.add(tOrder.getFinanceId());
		if(StringUtils.isNotBlank(tOrder.getTechnicianId())  && !targetIds.contains(tOrder.getTechnicianId()))
			targetIds.add(tOrder.getTechnicianId());
		Admin admin = adminMapper.selectAdminByRoleId(AFTConstants.TECH_ADMIN);
		if(admin!= null && !targetIds.contains(admin.getId())) targetIds.add(admin.getId());
		if(targetIds.size()>0){
			for(String id: targetIds){
				notice = new Notice();
				notice.setId(UUID.randomUUID().toString());
				notice.setCreateTime(now.getTime());
				notice.setReaded(NoticeReadStatus.UNREAD.getCode());
				notice.setRid(tOrder.getOrderNo());
				notice.setNoticeType(noticeType.getCode());
				notice.setContent(noticeType.getDesc() + ": 订单编号-" + tOrder.getOrderNo() + ",操作人-" + TokenManager.getAdminToken().getName());
				notice.setAid(id);
				noticeList.add(notice);
			}
			MobileNotice( targetIds, tOrder);
			noticeMapper.insertBatch(noticeList);
			//触发短信提醒
			List<UserRole> list=userRoleMapper. selectAdminRole(AFTConstants.CONSULTANT_MANAGER);
				for (UserRole u : list) {
					targetIds.add(u.getUid());
				}
				String regex = "^(1[1-9][0-9])\\d{8}$";
				 Pattern p = Pattern.compile(regex);
				 String mobile="";
				for (String s : targetIds) {
					Admin a=adminMapper.selectByPrimaryKey(s);
					if (null!=a.getContactMobile()) {
						Matcher m = p.matcher(a.getContactMobile());
					if ( m.matches()) {
						mobile+=a.getContactMobile()+",";
						}
					}
				}
				if(mobile.length()>1){
					mobile=mobile.substring(0, mobile.length()-1);
					sendMessage(tOrder,mobile,OrderFlowState.DDBG.getDesc());
				}

		}
	}


	private void MobileNotice(List<String> targetIds, TOrder tOrder) {
		
		
	}

	@Override
	public void addContractTaskLog() {
		List<ContractTask> list=contractTaskMapper.selectlistContractTask();
		Admin aa=adminMapper.selectAdminName(AFTConstants.DEFAULT_INITIATOR);
		Admin ab=adminMapper.selectAdminName(AFTConstants.CONSULTANT_MANAGER);
		for (ContractTask ct : list) {
			ContractTaskLog c=new ContractTaskLog();
			c.setId(UUID.randomUUID().toString());
			c.setContractTaskId(ct.getId());
			c.setTaskReceiver(ab.getId());
			c.setTaskAllocator(aa.getId());
			c.setCreateTime(new Date());
			contractTaskLogMapper.insert(c);
			if (StringUtils.isNotBlank(ct.getTaskReceiver())&&!ct.getTaskReceiver().equals(ab.getId())) {
				 c=new ContractTaskLog();
				c.setId(UUID.randomUUID().toString());
				c.setContractTaskId(ct.getId());
				c.setTaskReceiver(ct.getTaskReceiver());
				c.setTaskAllocator(ab.getId());
				c.setCreateTime(new Date());
				contractTaskLogMapper.insert(c);
			}
				
		}
		
		
	}

	@Override
	public boolean checkCustomerInformation(String uid) {
		int i=userMapper.checkCustomerInformation(uid);
		if (i<1) {
			return true;
		}
		return false;
	}

	@Override
	public int addBusinessProjectId(FollowBusinessBo fbb) {
		//if(fbb.getUserBusinessList().size()<1) throw new BusinessException(new Error(ErrorConstants.AT_LEAST_A_BUSINESS,"",""));
		//更新跟进记录表
		SimpleDateFormat format = new SimpleDateFormat(AFTConstants.YYYYMMDDHHMMSS);
		fbb.setFollowTime(format.format(new Date()));
		UserFollow userFollow = new UserFollow();
		String followId = UUID.randomUUID().toString();
		userFollow.setId(followId);
		userFollow.setAid(TokenManager.getAdminId());
		userFollow.setContactType(Integer.parseInt(fbb.getContactType()));
		userFollow.setEffective(DeleteStatus.UNDELETE.getCode());
		userFollow.setCreateTime(new Date());
		userFollow.setOcbId(fbb.getOcbId());
		userFollow.setResult(fbb.getResult());
		userFollow.setUid(fbb.getUid());
		int followCount = userBusinessMapper.selectFollowCountByUAid(fbb.getUid(), TokenManager.getAdminId()) + 1;
		userFollow.setFollowCount(followCount);
		userFollowMapper.insert(userFollow);
		//检查客户锁定情况
		if(fbb.getUserBusinessList().size()>0){
			String ufbId = "";
			UserBusiness userBusiness = null;
			UserFollowBusiness userFollowBusiness = null;
			for(BusinessListBo ub: fbb.getUserBusinessList()){
				userBusiness = new UserBusiness();
				userFollowBusiness = new UserFollowBusiness();
				ufbId = UUID.randomUUID().toString();
				if (ub.getFollowSituation()==5) {//如果改成已签合同，则锁定业务
						if (StringUtils.isNotBlank(fbb.getUid())) ub.setUid(fbb.getUid());
						userLockReleaseMapper.updateProject(fbb.getUid(), TokenManager.getAdminId(), ub.getBusinessProjectId());
						lockProject(ub);//锁定客户业务
					}
					String ubId = UUID.randomUUID().toString();
					//更新业务表
					userBusiness.setId(ubId);
					userBusiness.setBusinessProjectId(ub.getBusinessProjectId());
					try {
						userBusiness.setCreateTime(format.parse(fbb.getFollowTime()));
						userBusiness.setUpdateTime(format.parse(fbb.getFollowTime()));
					} catch (ParseException e) {
						e.printStackTrace();
					}
					userBusiness.setCustomerStatus(ub.getCustomerStatus());
					userBusiness.setFollowSituation(ub.getFollowSituation());
					userBusiness.setUid(fbb.getUid());
					userBusiness.setAid(TokenManager.getAdminId());
					userBusiness.setRemarks(ub.getRemarks());
					userBusinessMapper.insert(userBusiness);	
					//更新业务中间表
					userFollowBusiness.setBusinessId(ubId);
					userFollowBusiness.setCustomerStatus(ub.getCustomerStatus());
					userFollowBusiness.setFollowSituation(ub.getFollowSituation());
					userFollowBusiness.setId(ufbId);
					userFollowBusiness.setFollowId(followId);
					userFollowBusiness.setRemarks(ub.getRemarks());
					userFollowBusiness.setBusinessProjectId(ub.getBusinessProjectId());
					userFollowBusinessMapper.insert(userFollowBusiness);
				}
				
			}
		
		
		return 1;
	}

	
}
