/**
 * Copyright &copy; 2012-2014 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.cku.oa.dog.service;

import java.lang.reflect.InvocationTargetException;
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.Set;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Validator;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;

import com.cku.core.RESTResponse;
import com.cku.core.ZAErrorCode;
import com.cku.core.ZAException;
import com.cku.oa.dog.dao.DogActivationDao;
import com.cku.oa.dog.dao.DogBirthCertificateDao;
import com.cku.oa.dog.dao.DogChipChangeDao;
import com.cku.oa.dog.dao.DogChipDao;
import com.cku.oa.dog.dao.DogDnaParentsCompareDao;
import com.cku.oa.dog.dao.DogNewbornDao;
import com.cku.oa.dog.dao.DogStickerDao;
import com.cku.oa.dog.dao.DogVideoAppraisalDao;
import com.cku.oa.dog.entity.Dog;
import com.cku.oa.dog.entity.DogActivation;
import com.cku.oa.dog.entity.DogBirthCertificate;
import com.cku.oa.dog.entity.DogBirthCertificateApply;
import com.cku.oa.dog.entity.DogBirthCertificateTransfer;
import com.cku.oa.dog.entity.DogChip;
import com.cku.oa.dog.entity.DogChipChange;
import com.cku.oa.dog.entity.DogColorMark;
import com.cku.oa.dog.entity.DogName;
import com.cku.oa.dog.entity.DogNewborn;
import com.cku.oa.dog.entity.DogSticker;
import com.cku.oa.dog.entity.DogType;
import com.cku.oa.dog.entity.DogVideoAppraisal;
import com.cku.oa.finance.entity.PaymentChargingItem;
import com.cku.oa.finance.entity.PaymentOrder;
import com.cku.oa.finance.entity.PaymentOrderDetail;
import com.cku.oa.finance.service.PaymentChargingItemService;
import com.cku.oa.finance.service.PaymentOrderService;
import com.cku.oa.kennel.entity.Kennel;
import com.cku.oa.kennel.service.KennelService;
import com.cku.oa.sys.code.SysCodeUtil;
import com.cku.oa.sys.dao.ExpressSendDao;
import com.cku.oa.sys.entity.user.CardTypeEnum;
import com.cku.oa.sys.entity.user.Member;
import com.cku.oa.sys.service.ExpressQueueService;
import com.cku.oa.sys.service.LoginServerService;
import com.cku.oa.sys.service.RemindService;
import com.cku.oa.sys.service.user.MemberService;
import com.cku.oa.sys.util.MemberUtil;
import com.cku.oa.sys.zalog.SysContext;
import com.cku.util.DateUtils;
import com.cku.util.Debugger;
import com.thinkgem.jeesite.common.beanvalidator.BeanValidators;
import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.service.CrudService;
import com.thinkgem.jeesite.modules.sys.entity.Office;
import com.thinkgem.jeesite.modules.sys.entity.User;
import com.thinkgem.jeesite.modules.sys.service.OfficeService;
import com.thinkgem.jeesite.modules.sys.utils.DataPermissionUtil;
import com.thinkgem.jeesite.modules.sys.utils.DictUtils;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import okhttp3.OkHttpClient;
import okhttp3.Request;

/**
 * 出生证明Service
 *
 * @author lgl
 * @version 2016-08-04
 */
@Service
@Transactional(readOnly = true)
public class DogBirthCertificateService extends CrudService<DogBirthCertificateDao, DogBirthCertificate> {
	private static final String BUSINESS_NAME = "出生证明";
	private static final String DOG_CHIP_FEE = "dog_chip_change@chipFee";
	private static final String SECOND_BREEDER_FEE = "second_breeder@all";
	private static final String DOG_BIRTH_CERTIFICATE_FEE = "dog_birth_certificate@New";
	private static final String DOG_BIRTH_COUPON = "sys_coupon@birth";
	public static Long newBusinessTimeMillis = null;
	public static Long DOG_ACTIVATION_MILLIS = null;
	public static Long DOG_LEVELPRINT_MILLIS = null;
	public static Long KENNEL_UNACTIVATION_MILLIS = null;
	public static Long ACTICATION_OFF_MILLS = null;
	public static Long CANCEL_PASSPORT_MILLS = null;

	static {
		try {
			newBusinessTimeMillis = new SimpleDateFormat("yyyy-MM-dd").parse("2017-06-01").getTime();
			DOG_ACTIVATION_MILLIS = new SimpleDateFormat("yyyy-MM-dd").parse("2018-09-01").getTime();
			DOG_LEVELPRINT_MILLIS = new SimpleDateFormat("yyyy-MM-dd").parse("2018-11-11").getTime();
			KENNEL_UNACTIVATION_MILLIS = new SimpleDateFormat("yyyy-MM-dd").parse("2019-04-01").getTime();
			ACTICATION_OFF_MILLS = new SimpleDateFormat("yyyy-MM-dd").parse("2020-04-29").getTime();
			CANCEL_PASSPORT_MILLS = new SimpleDateFormat("yyyy-MM-dd").parse("2023-03-09").getTime();
		} catch (ParseException e) {
			System.out.println("出生纸判断新旧业务记录格式化时间出错");
		}
	}

	private static final String KENNEL_START_URL = Global.getConfig("petpricingUrl") + "/kennelStar/getByCode?code=";
	/**
	 * 验证Bean实例对象
	 */
	@Autowired
	protected Validator validator;

	@Autowired
	public DogService dogService;
	@Autowired
	public DogChipChangeService dogChipChangeService;
	@Autowired
	public MemberService memberService;
	@Autowired
	public PaymentChargingItemService paymentChargingItemService;
	@Autowired
	public DogNewbornDao dogNewbornDao;
	@Autowired
	public KennelService kennelService;
	@Autowired
	public RemindService remindService;
	@Autowired
	public DogTypeService dogTypeService;
	@Autowired
	public DogColorMarkService dogColorMarkService;
	@Autowired
	public OfficeService officeService;
	@Autowired
	public ExpressQueueService expressQueueService;
	@Autowired
	public PaymentOrderService paymentOrderService;
	@Autowired
	public DogDnaParentsCompareDao dogDnaParentsCompareDao;
	@Autowired
	public DogChipDao dogChipDao;
	@Autowired
	public BusinessBanService businessBanService;
	@Autowired
	public ExpressSendDao expressSendDao;
	@Autowired
	public DogChipChangeDao dogChipChangeDao;
	@Autowired
	public LoginServerService loginServerService;
	@Autowired
	private DogActivationDao dogActivationDao;
	@Autowired
	private DogStickerDao dogStickerDao;
//	@Autowired
//	private DogVideoAppraisalService dogVideoAppraisalService;
	@Autowired
	private DogVideoAppraisalDao dogVideoAppraisalDao;
	@Autowired
	private DogSecondBreederService dogSecondBreederService;

	@Autowired
	private DogBirthCertificateTransferService transferService;

	public DogBirthCertificate get(String id) {
		return super.get(id);
	}

	/**
	 * @description: 出生证明打印
	 * @author: laiguanglong
	 * @date: 2016年8月30日 下午2:29:36
	 */
	@Transactional(readOnly = false)
	public String print(String id, Model model) throws ZAException {
		DogBirthCertificate one = super.get(id);
		// 检查打印的数据权限
		checkBirthCertPermission(one);
		// 准备打印数据，只打印审核通过的
		DogBirthCertificate example = new DogBirthCertificate();
		example.setFmdogBreedCertifiedCode(one.getFmdogBreedCertifiedCode());
		example.setReviewState("1");
		List<DogBirthCertificate> list = findList(example);
		for (DogBirthCertificate dogBirthCertificate : list) {
			dogBirthCertificate.setColorFlagEn(dogBirthCertificate.getColorFlag());
			// 新出生纸打印校验整窝犬只芯片号都必须有值
			if (dogBirthCertificate.getCreateDate().getTime() > newBusinessTimeMillis
					&& StringUtils.isBlank(dogBirthCertificate.getIdentificationFlag())) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "同窝登记卡存在未填写的芯片号，无法打印");
			}
			if (dogBirthCertificate.getCreateDate().getTime() > DOG_ACTIVATION_MILLIS
					&& StringUtils.isBlank(dogBirthCertificate.getCabPassport())) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "同窝登记卡存在未填写的宠爱护照号，无法打印");
			}
			// 毛色新的打印中文，旧的打印英文
			if (dogBirthCertificate.getCreateDate().getTime() > DogBirthCertificateService.newBusinessTimeMillis) {
				// 打印毛色只显示中文
				DogColorMark dogColorMark = dogColorMarkService
						.getByDogColorMarkCode(dogBirthCertificate.getColorFlag());
				if (dogColorMark != null) {
					String colorFlag = dogColorMark.getDogColorMarkCn();
					if (colorFlag != null) {
						dogBirthCertificate.setColorFlag(colorFlag.substring(colorFlag.indexOf("-") + 1));
					}
				}
			}
			expressQueueService.push(one.getMemberCode(), one.getRunningNumber(), "新生犬登记卡",
					dogBirthCertificate.getBirthCerRegCode(), "dog_birth_certificate",
					dogBirthCertificate.getFmdogBreedCertifiedCode(), null); // GYH2 TODO
			if (StringUtils.isNotBlank(dogBirthCertificate.getDogBreed())) {
				DogType dogType = dogTypeService.getByDogBreedCode(dogBirthCertificate.getDogBreed());
				if (dogType != null) {
					dogBirthCertificate.setBreedCnName(dogType.getBreedCnName());
				} else {
					throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "出生纸" + dogBirthCertificate.getBirthCerRegCode()
							+ "的犬种" + dogBirthCertificate.getDogBreed() + ",在犬种表无法找到对应的记录，请检查是否有该犬种");
				}
			}
		}
		// 修改打印状态为9(已打印，可重置)
		one.setPrintType("9");
		dao.updatePrintType(one);
		// 通过状态机记录日志
		SysContext sysContext = new SysContext(null, null, null);
		sysContext.noStateExecute(sysContext, BUSINESS_NAME + "打印", one.getMemberCode(), "dog_birth_certificate",
				one.getId(), one.getRunningNumber(), (str) -> {
				});
		model.addAttribute("dogBirthCertificateList", list);
		model.addAttribute("kinBreedPrintFlag", getKinBreedPrintFlag(one));

		List<DogType> dogTypeList = dogTypeService.findList(new DogType());
		// TODO fci-print update by zjw 保留之前逻辑，过滤出 11组犬只
		List<String> group11List = dogTypeList.stream().filter(dt -> "11".equals(dt.getTypeGroup()))
				.map(DogType::getDogBreedCode).collect(Collectors.toList());
		// add by zjw 新加国家级犬种判断
//		List<String> countryList = dogTypeList.stream()
//				.filter(dt -> DogBreedClassEnum.COUNTRY.code().equals(dt.getBreedClass())|| DogBreedClassEnum.TEMP.code().equals(dt.getBreedClass())).map(DogType::getDogBreedCode)
//				.collect(Collectors.toList());
//		if (countryList.contains(one.getDogBreed())) {
//			return "oa/dog/birthcertificate/dogBirthCountryPrint";
//		} else 
		if (group11List.contains(one.getDogBreed())) {
			return "oa/dog/birthcertificate/dogBirthInfoFciPrint";
		} else {
			if (one.getPaymentTime().getTime() >= CANCEL_PASSPORT_MILLS) {
				return "oa/dog/birthcertificate/dogBirthInfoCancelPassportPrint";
			} else if (one.getCreateDate().getTime() >= ACTICATION_OFF_MILLS) {
				return "oa/dog/birthcertificate/dogBirthInfoNewPrint";
			} else if (one.getCreateDate().getTime() >= DOG_LEVELPRINT_MILLIS) {
				return "oa/dog/birthcertificate/dogBirthInfoPrint";
			} else if (one.getPaymentTime() != null && one.getPaymentTime().getTime() > DOG_ACTIVATION_MILLIS) {
				return "oa/dog/birthcertificate/dogBirthNewPrint";
			} else if (one.getCreateDate().getTime() <= newBusinessTimeMillis) {
				return "oa/dog/birthcertificate/dogBirthCertificatePrint";
			} else {
				return "oa/dog/birthcertificate/dogBirthCertificateNewPrint";
			}
		}
	}

	@Transactional(readOnly = false)
	public String classPrint(String id, Model model) throws ZAException {
		DogBirthCertificate one = super.get(id);
		// 检查打印的数据权限
		checkBirthCertPermission(one);
		// 准备打印数据，只打印审核通过的
		DogBirthCertificate example = new DogBirthCertificate();
		example.setFmdogBreedCertifiedCode(one.getFmdogBreedCertifiedCode());
		example.setReviewState("1");
		List<DogBirthCertificate> list = findList(example);
		for (DogBirthCertificate dogBirthCertificate : list) {
			// 新出生纸打印校验整窝犬只芯片号都必须有值
			if (dogBirthCertificate.getCreateDate().getTime() > newBusinessTimeMillis
					&& StringUtils.isBlank(dogBirthCertificate.getIdentificationFlag())) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "同窝登记卡存在未填写的芯片号，无法打印");
			}
			if (dogBirthCertificate.getCreateDate().getTime() > DOG_ACTIVATION_MILLIS
					&& StringUtils.isBlank(dogBirthCertificate.getCabPassport())) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "同窝登记卡存在未填写的宠爱护照号，无法打印");
			}
			// 毛色新的打印中文，旧的打印英文
			if (dogBirthCertificate.getCreateDate().getTime() > DogBirthCertificateService.newBusinessTimeMillis) {
				// 打印毛色只显示中文
				DogColorMark dogColorMark = dogColorMarkService
						.getByDogColorMarkCode(dogBirthCertificate.getColorFlag());
				if (dogColorMark != null) {
					String colorFlag = dogColorMark.getDogColorMarkCn();
					if (colorFlag != null) {
						dogBirthCertificate.setColorFlag(colorFlag.substring(colorFlag.indexOf("-") + 1));
					}
				}
			}
			if (StringUtils.isNotBlank(dogBirthCertificate.getDogBreed())) {
				DogType dogType = dogTypeService.getByDogBreedCode(dogBirthCertificate.getDogBreed());
				if (dogType != null) {
					dogBirthCertificate.setBreedCnName(dogType.getBreedCnName());
				} else {
					throw new ZAException(ZAErrorCode.ZA_VALID_FAILED,
							"优宠级（E）贴纸" + dogBirthCertificate.getBirthCerRegCode() + "的犬种"
									+ dogBirthCertificate.getDogBreed() + ",在犬种表无法找到对应的记录，请检查是否有该犬种");
				}
			}
			// 贴纸编号
			String stickerNo = dogBirthCertificate.getCabPassport().replace("N", "E");
			dogBirthCertificate.setStickerNo(stickerNo);
			expressQueueService.push(one.getMemberCode(), one.getRunningNumber(), "优宠级（E）贴纸", stickerNo, "dog_sticker",
					dogBirthCertificate.getId(), null);
			// 保存在贴纸表
			saveDogSticker(dogBirthCertificate);
		}
		// 修改打印状态为9(已打印，可重置)
		one.setClassPrintStatus("9");
		dao.updateClassPrintStatus(one);
		// 通过状态机记录日志
		SysContext sysContext = new SysContext(null, null, null);
		sysContext.noStateExecute(sysContext, BUSINESS_NAME + "打印", one.getMemberCode(), "dog_sticker", one.getId(),
				one.getRunningNumber(), (str) -> {
				});
		model.addAttribute("dogBirthCertificateList", list);

		if (one.getCreateDate().getTime() >= DateUtils.strToDateLong("2019-02-01 00:00:00").getTime()) {
			return "oa/dog/birthcertificate/dogBirthLevelNewPrint";
		} else if (one.getCreateDate().getTime() >= DOG_LEVELPRINT_MILLIS) {
			return "oa/dog/birthcertificate/dogBirthLevelPrint";
		} else {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "请在宠爱王国APP或者会员中心申请等级贴纸");
		}
	}

	@Transactional(readOnly = false)
	private void saveDogSticker(DogBirthCertificate dogBirthCertificate) {
		DogSticker dogsticker = dogStickerDao
				.getByIdentificationFlagAndClass(dogBirthCertificate.getIdentificationFlag(), "1");
		if (dogsticker == null) {
			dogsticker = new DogSticker();
			dogsticker.setIdentificationFlag(dogBirthCertificate.getIdentificationFlag());
			dogsticker.setStickerNo(dogBirthCertificate.getCabPassport().replace("N", "E"));
			dogsticker.setStickerClass("1");
			dogsticker.preInsert();
			dogStickerDao.insert(dogsticker);
		}
	}

	/**
	 * @description: 根据母犬血统证书号获取近亲配种次数 如果超过两次，除第一次配种证明申请的出生纸没有这个标记位，其余都有
	 * @author: laiguanglong
	 * @date: 2017/5/26 14:14
	 */
	private String getKinBreedPrintFlag(DogBirthCertificate dogBirthCertificate) {
		String kinBreedPrintFlag = "false";
		DogNewborn dogNewborn = dogNewbornDao.getByBreedCertifiedCode(dogBirthCertificate.getFmdogBreedCertifiedCode());
		List<String> breedCertifiedCodeList = dogNewbornDao
				.getKinBreedByFemalePedigreeCertified(dogNewborn.getFemalePedigreeCertified());
		if (breedCertifiedCodeList.size() >= 2
				&& breedCertifiedCodeList.contains(dogBirthCertificate.getFmdogBreedCertifiedCode())
				&& !breedCertifiedCodeList.get(0).equals(dogBirthCertificate.getFmdogBreedCertifiedCode())) {
			kinBreedPrintFlag = "true";
		}
		return kinBreedPrintFlag;
	}

	/**
	 * @description: 检查打印的数据权限
	 * @author: laiguanglong
	 * @date: 2016年8月31日 下午5:21:47
	 */
	private void checkBirthCertPermission(DogBirthCertificate dogBirthCertificate) throws ZAException {
		if (DataPermissionUtil.isBirthCertDataLimited()) {
			Member member = memberService.getByMemberCode(dogBirthCertificate.getMemberCode());
			if (member == null) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "无法根据犬主人会员号找到相应的会员记录");
			} else {
				if (StringUtils.isBlank(member.getProvince())) {
					throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "该犬主人省份为空，只能总部打印");
				} else {
					// 获取当前用户有权限访问的省份
					String[] provinces = DataPermissionUtil.getBirthCertPermission();
					boolean flag = false;
					for (String province : provinces) {
						if (member.getProvince().equals(province)) {
							// 通过
							flag = true;
							break;
						}
					}
					if (!flag) {
						throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "无法打印该犬主所在省份的出生证明");
					}
				}
			}
		}
	}

	public List<DogBirthCertificate> findList(DogBirthCertificate dogBirthCertificate) {
		return super.findList(dogBirthCertificate);
	}

	public Page<DogBirthCertificate> findPage(Page<DogBirthCertificate> page, DogBirthCertificate dogBirthCertificate) {
		dogBirthCertificate.setPage(page);
		// 在sql中加入对organizer字段进行筛选
		dogBirthCertificate.getSqlMap().put("province", dataScopeFilter(dogBirthCertificate));
		if (org.apache.commons.lang.StringUtils.isBlank(dogBirthCertificate.getDogBreed())) {
			// 根据当前登录端查询犬种
			dogBirthCertificate.getSqlMap().put("dogBreedMap", loginServerService.dataScopeFilter());
		} else {
			dogBirthCertificate.getSqlMap().put("dogBreedMap", " ='" + dogBirthCertificate.getDogBreed() + "'");
		}
		String printStatus = dogBirthCertificate.getPrintStatus();
		if (StringUtils.isNotBlank(printStatus)) {
			dogBirthCertificate.getSqlMap().put("printStatus", printStatus);
		}
		page.setIbatisPagePluginEnable(false);
		int count = dao.listCount(dogBirthCertificate);
		int pageNo = page.getPageNo();
		int pageSize = page.getPageSize();
		page.setCount(count);
		if ((pageNo - 1) * pageSize >= count) {
			page.setList(new ArrayList<DogBirthCertificate>(0));
			return page;
		}
		List<DogBirthCertificate> list = dao.findList(dogBirthCertificate);
		// 优化查询SQL 另外查询kinGetDna、newbornPrintType 字段
		Set<String> fmdogBreedCertifiedCodeSet = list.stream().map(a -> a.getFmdogBreedCertifiedCode())
				.collect(Collectors.toSet());
		List<DogNewborn> dogNewbornList = dogNewbornDao.findAllListByBreedCertifiedCodes(fmdogBreedCertifiedCodeSet);
		Map<String, DogNewborn> map = dogNewbornList.stream()
				.collect(Collectors.toMap(DogNewborn::getBreedCertifiedCode, DogNewborn -> DogNewborn));
		list.forEach(a -> {
			if (map.get(a.getFmdogBreedCertifiedCode()) != null) {
				a.setKinGetDna(map.get(a.getFmdogBreedCertifiedCode()).getKinGetDna());
				a.setNewbornPrintType(map.get(a.getFmdogBreedCertifiedCode()).getPrintType());
			}
		});

		page.setList(list);
		return super.findPage(page, dogBirthCertificate);
	}

	public Page<DogBirthCertificate> findClubPage(Page<DogBirthCertificate> page,
			DogBirthCertificate dogBirthCertificate) {
		dogBirthCertificate.setPage(page);
		// 从dog表里查询打印状态 封装到出生证明表里
		List<DogBirthCertificate> clubList = dao.findClubList(dogBirthCertificate);
		for (DogBirthCertificate birth : clubList) {
			String pedigreeCertified = birth.getPedigreeCertified();
			if (StringUtils.isNotBlank(pedigreeCertified)) {
				Dog dog = dogService.getByPedigreeCertifiedCode(pedigreeCertified);
				if (dog != null) {
					String printState = dog.getPrintState();
					birth.setPrintType(printState);
				}
			}
		}
		page.setList(clubList);
		return page;
	}

	public Page<DogBirthCertificate> dogAllNestList(Page<DogBirthCertificate> page,
			DogBirthCertificate dogBirthCertificate) {
		dogBirthCertificate.setPage(page);
		// 从dog表里查询打印状态 封装到出生证明表里
		List<DogBirthCertificate> clubList = dao.dogAllNestList(dogBirthCertificate);
		for (DogBirthCertificate birth : clubList) {
			String pedigreeCertified = birth.getPedigreeCertified();
			if (StringUtils.isNotBlank(pedigreeCertified)) {
				Dog dog = dogService.getByPedigreeCertifiedCode(pedigreeCertified);
				if (dog != null) {
					String printState = dog.getPrintState();
					birth.setPrintType(printState);
				}
			}
		}
		page.setList(clubList);
		return page;
	}

	public Page<DogBirthCertificate> findClubOldPage(Page<DogBirthCertificate> page,
			DogBirthCertificate dogBirthCertificate) {
		dogBirthCertificate.setPage(page);
		// 从dog表里查询打印状态 封装到出生证明表里
		List<DogBirthCertificate> clubList = dao.findOldClubList(dogBirthCertificate);
		page.setList(clubList);
		return page;
	}

	@Transactional(readOnly = false)
	public void save(DogBirthCertificate dogBirthCertificate) {
		// 出生纸犬英文名不允许包含中文
		if (isContainChinese(dogBirthCertificate.getDogEnName())) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "犬只英文名不能包含中文，请修改后提交");
		}
		super.save(dogBirthCertificate);
	}

	/**
	 * @description: 是否包含中文字符，true表示包含
	 * @author: laiguanglong
	 * @date: 2016年11月3日 下午12:09:13
	 */
	private boolean isContainChinese(String str) {
		String regEx = "[\\u4e00-\\u9fa5]+";
		Pattern p = Pattern.compile(regEx);
		Matcher m = p.matcher(str);
		if (m.find())
			return true;
		else
			return false;
	}

	/**
	 * @description: 编辑出生证明
	 * @author: laiguanglong
	 * @date: 2016年9月2日 上午10:05:30
	 */
	@Transactional(readOnly = false)
	public void update(DogBirthCertificate update) {
		Date createDate = update.getCreateDate();
		Date date11 = DateUtils.strToDateLong("2018-11-11 00:00:00");
		boolean dateFlag = createDate.getTime() - date11.getTime() > 0 ? true : false;

		DogBirthCertificate dogBirthCertificate = get(update.getId());
		// 已审核
		if ("1".equals(dogBirthCertificate.getReviewState())) {
			// 修改了毛色
			if (!dogBirthCertificate.getColorFlag().equals(update.getColorFlag())) {
				// 毛色还为原来的毛色，修改毛色走另外的方法
				update.setColorFlag(dogBirthCertificate.getColorFlag());
			}
		}
//		修改犬种
		String dogBreed1 = update.getDogBreed();
		String dogBreed2 = dogBirthCertificate.getDogBreed();
		if (!dogBreed1.equals(dogBreed2)) {
			if (!dogBreed1.substring(0, 3).equals(dogBreed2.substring(0, 3))) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "修改后的犬种有误");
			}
			if (dogBreed1.startsWith("172")) {
				if (!dogBreed1.contains("A") && !dogBreed1.contains("B") && !dogBreed1.contains("C")
						&& !dogBreed1.contains("D")) {
					throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "修改后的犬种有误");
				}
			}
			if (dogBreed1.startsWith("148")) {
				if (!dogBreed1.contains("A") && !dogBreed1.contains("B") && !dogBreed1.contains("C")) {
					throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "修改后的犬种有误");
				}
			}
		}
		// 只有在新生犬登记为已缴费未处理的情况下可以修改出生纸的临时会员信息
		DogChip dogChip = dogChipDao.getByBirthCode(dogBirthCertificate.getBirthCerRegCode());
		if (dogChip != null && "2".equals(dogChip.getPaymentState()) && "0".equals(dogChip.getProcessState())
				&& !"3".equals(dogChip.getReviewState())) {
			// 应校验新犬主姓名与会员号：1、是否存在、2是否匹配、3会员必须是有效的
			Member member = memberService.getByMemberCode(update.getTempMemberCode());
			Member breeder = memberService.getByMemberCode(dogBirthCertificate.getMemberCode());
			if (member == null) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "新犬主会员号有误");
			}
			if (!member.getName().equals(update.getTempUserName())) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "新犬主会员姓名有误");
			}
//			if (!MemberUtil.isActiveProfessionalMember(member)) {
//				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "新犬主不是有效专业会员");
//			}
			// CKU宠爱银卡及以上会员才可以办理！
			if (CardTypeEnum.DEFAULT_CARD.code() == UserUtils.getMemberCardType(member)) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "CKU宠爱银卡及以上会员才可以办理！");
			}
			// 判断新犬主与申请人为同一站点会员
			if (!((StringUtils.isBlank(member.getMemberSite()) && StringUtils.isBlank(breeder.getMemberSite()))
					|| member.getMemberSite().equals(breeder.getMemberSite()))) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "新犬主与申请人会员站点不同，不能进行新生犬登记");
			}
		} else {
			update.setTempMemberCode(dogBirthCertificate.getTempMemberCode());
			update.setTempUserName(dogBirthCertificate.getTempUserName());
		}
		if (StringUtils.isNotBlank(update.getIdentificationFlag())
				&& isCanInputIdentificationFlag(dogBirthCertificate)) {
			// 写入芯片号，并且添加芯片变更记录
			insertDogChipChange(dogBirthCertificate, update.getIdentificationFlag());
			// 不管电子纸质证书，录入芯片之后都生成一个“芯片待邮寄”
			// if ("1".equals(dogBirthCertificate.getEcertFlag())) {
			expressQueueService.push(dogBirthCertificate.getMemberCode(), dogBirthCertificate.getRunningNumber(),
					"新生犬登记卡芯片", dogBirthCertificate.getBirthCerRegCode(),
					"1".equals(dogBirthCertificate.getEcertFlag()) ? "dog_birth_certificate" : null,
					dogBirthCertificate.getFmdogBreedCertifiedCode(), null);
			// }
			// 11月11日之前护照号前面带C
			if (!dateFlag) {
				// 护照号前面带C
				if (StringUtils.isNotBlank(update.getCabPassport()) && !update.getCabPassport().startsWith("C")) {
					update.setCabPassport("C" + update.getCabPassport());
				}
			}

			validateIdentificationFlagAndCabPassport(update);
		} else if (StringUtils.isNotBlank(update.getIdentificationFlag())
				&& StringUtils.isNotBlank(dogBirthCertificate.getIdentificationFlag())
				&& !"9".equals(dogBirthCertificate.getPrintType())) {
			// 修改芯片号，并修改芯片变更表芯片号
			updateDogChipChange(dogBirthCertificate, update.getIdentificationFlag());
			if (!dateFlag) {
				// 护照号前面带C
				if (StringUtils.isNotBlank(update.getCabPassport()) && !update.getCabPassport().startsWith("C")) {
					update.setCabPassport("C" + update.getCabPassport());
				}
			}
			validateIdentificationFlagAndCabPassport(update);
		} else {
			update.setIdentificationFlag(dogBirthCertificate.getIdentificationFlag());
			update.setCabPassport(dogBirthCertificate.getCabPassport());
			update.setCabRegisterCode(dogBirthCertificate.getCabRegisterCode());
		}
		super.save(update);
	}

	/**
	 * @description: 芯片号和宠爱护照号唯一性校验
	 * @author: laiguanglong
	 * @date: 2018/8/1 14:06
	 */
	public void validateIdentificationFlagAndCabPassport(DogBirthCertificate update) {
		validateIdentificationFlag(update);
		// 护照号查重
		if (StringUtils.isNotBlank(update.getCabPassport())) {
			DogBirthCertificate dogBirthCertificate = new DogBirthCertificate();
			dogBirthCertificate.setCabPassport(update.getCabPassport());
			List<DogBirthCertificate> dogBirthCertificateList = dao.findList(dogBirthCertificate);
			if (dogBirthCertificateList.size() > 0) {
				if (!update.getId().equals(dogBirthCertificateList.get(0).getId())) {
					throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "护照号" + update.getCabPassport() + "已被其他登记卡使用");
				}
			}
		}
	}

	public void validateIdentificationFlag(DogBirthCertificate update) {
		// 芯片号查重
		if (StringUtils.isNotBlank(update.getIdentificationFlag())) {
			DogBirthCertificate dogBirthCertificate = new DogBirthCertificate();
			dogBirthCertificate.setIdentificationFlag(update.getIdentificationFlag());
			List<DogBirthCertificate> dogBirthCertificateList = dao.findList(dogBirthCertificate);
			if (dogBirthCertificateList.size() > 0) {
				if (!update.getId().equals(dogBirthCertificateList.get(0).getId())) {
					throw new ZAException(ZAErrorCode.ZA_VALID_FAILED,
							"芯片号" + update.getIdentificationFlag() + "已被其他登记卡使用");
				}
			}
		}
	}

	@Transactional(readOnly = false)
	public void delete(DogBirthCertificate dogBirthCertificate) {
		super.delete(dogBirthCertificate);
	}

	/**
	 * @description: 出生证明根据举办单位进行过滤
	 * @author: laiguanglong
	 * @date: 2016年8月29日 下午8:17:35
	 */
	private String dataScopeFilter(DogBirthCertificate dogBirthCertificate) {
		StringBuilder sb = new StringBuilder();
		if (StringUtils.isNotBlank(dogBirthCertificate.getAgency())) {
			if ("other".equals(dogBirthCertificate.getAgency())) {
				sb.append("NOT IN (");
				Office office1 = officeService.get("8c9825c10d714397b464ec796435748a");
				Office office2 = officeService.get("c2ce7357a6a945008a5cd3d264b384f1");
				Office office3 = officeService.get("d709ba143756439a81e96effa08b2a82");
				JSONObject object1 = JSONObject.fromObject(office1.getDataPermission());
				JSONArray array1 = object1.getJSONArray("dog_breed_certified");
				for (int i = 0; i < array1.size(); i++) {
					sb.append("'" + array1.getString(i) + "',");
				}
				JSONObject object2 = JSONObject.fromObject(office2.getDataPermission());
				JSONArray array2 = object2.getJSONArray("dog_breed_certified");
				for (int i = 0; i < array2.size(); i++) {
					sb.append("'" + array2.getString(i) + "',");
				}
				JSONObject object3 = JSONObject.fromObject(office3.getDataPermission());
				JSONArray array3 = object3.getJSONArray("dog_breed_certified");
				for (int i = 0; i < array3.size(); i++) {
					sb.append("'" + array3.getString(i) + "',");
				}
				sb.deleteCharAt(sb.length() - 1);
				sb.append(")");
			} else {
				Office office = officeService.get(dogBirthCertificate.getAgency());
				String stringPermissions = office.getDataPermission();
				if (StringUtils.isNotBlank(stringPermissions)) {
					JSONObject object = JSONObject.fromObject(stringPermissions);
					JSONArray array = object.getJSONArray("dog_breed_certified");
					sb.append("IN (");
					for (int i = 0; i < array.size(); i++) {
						sb.append("'" + array.getString(i) + "',");
					}
					sb.deleteCharAt(sb.length() - 1);
					sb.append(")");
				}
			}
		}
		return sb.toString();
	}

	/**
	 * @description: 重置打印，修改打印类型为协会打印
	 * @author: laiguanglong
	 * @date: 2016年8月16日 下午3:42:25
	 */
	@Transactional(readOnly = false)
	public void resetPrint(DogBirthCertificate reset) {
		DogBirthCertificate dogBirthCertificate = get(reset.getId());
		dogBirthCertificate.setPrintType("1");
		dao.updatePrintType(dogBirthCertificate);
	}

	/**
	 * 重置等级贴纸打印，修改打印类型为协会打印
	 *
	 * @param reset
	 */
	@Transactional(readOnly = false)
	public void resetClassPrint(DogBirthCertificate reset) {
		DogBirthCertificate dogBirthCertificate = get(reset.getId());
		dogBirthCertificate.setClassPrintStatus("1");
		dao.updateClassPrintStatus(dogBirthCertificate);
	}

	/**
	 * @description: 出生证明审核，如果是3(锁定)，则只改当前记录。否则要同步当前批次所有审核状态
	 * @author: laiguanglong
	 * @date: 2016年8月12日 下午5:02:40
	 */
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void audit(DogBirthCertificate review) throws ZAException {
		try {
			DogBirthCertificate dogBirthCertificate = get(review.getId());
			// 未通过的数据可直接变更为除为审核外的任何状态，此处将未通过的数据当做待审核处理 zhuoHeng
			// 审核通过的数据也可以修改审核状态
			if ("1".equals(dogBirthCertificate.getReviewState()) || "2".equals(dogBirthCertificate.getReviewState())) {
				dogBirthCertificate.setReviewState("0");
			}
			// 由于没有处理状态不能使用状态机，故把状态始终设为0，未处理
			SysContext sysContext = new SysContext(dogBirthCertificate.getPaymentState(),
					dogBirthCertificate.getReviewState(), "0");
			dogBirthCertificate.setReviewRemarks(review.getReviewRemarks());
			dogBirthCertificate.setReviewTime(new Date());
			dogBirthCertificate.setReviewState(review.getReviewState());
			if ("3".equals(review.getReviewState())) {
				// 注销
				SysContext sy = new SysContext(dogBirthCertificate.getPaymentState(),
						dogBirthCertificate.getReviewState(), "2");
				sy.noStateExecute(sy, BUSINESS_NAME, dogBirthCertificate.getMemberCode(), "dog_birth_certificate",
						dogBirthCertificate.getId(), dogBirthCertificate.getRunningNumber(), (str) -> {
						});
				super.save(dogBirthCertificate);
			} else {
				if ("1".equals(review.getReviewState())) {
					// 通过
					sysContext.confirmSuccess(sysContext, BUSINESS_NAME, dogBirthCertificate.getMemberCode(),
							"dog_birth_certificate", dogBirthCertificate.getId(),
							dogBirthCertificate.getRunningNumber(), (str) -> {
							});
					// 修改配种证明记录的出生日期、本胎数量和登记数量
					DogNewborn dogNewborn = dogNewbornDao
							.getByBreedCertifiedCode(dogBirthCertificate.getFmdogBreedCertifiedCode());
					dogNewborn.setBirthday(dogBirthCertificate.getDogBirthday());
					String sameBatchNum = dogBirthCertificate.getSameBatchNum().replace(" ", "");
					dogNewborn.setDogRegisterNum(sameBatchNum.substring(0, 1) + "," + sameBatchNum.substring(2, 3));// CKU登记数
					dogNewborn.setPuppyBirthNum(dogBirthCertificate.getSameBatchNum());// 出生数（几公几母）
					dogNewborn.setPuppyRegisterNum(dogBirthCertificate.getSameBatchNum());// 登记数（几公几母）
					// dogNewborn.setImplantedNum(implantedNum);// 已植数量
					if (UserUtils.getUser().getId() != null) {
						dogNewborn.preUpdate();
					} else {
						// 定时任务无法获取当前登录用户，需要手动设置
						User updateBy = new User();
						updateBy.setId("1");
						updateBy.setUpdateDate(new Date());
						dogNewborn.setUpdateBy(updateBy);
					}

					dogNewbornDao.update(dogNewborn);
					// 该配种证明都通过
					dao.review(dogBirthCertificate);
				} else if ("2".equals(review.getReviewState())) {
					// 不通过
					sysContext.confirmFail(sysContext, BUSINESS_NAME, review.getReviewRemarks(),
							dogBirthCertificate.getMemberCode(), "dog_birth_certificate", dogBirthCertificate.getId(),
							dogBirthCertificate.getRunningNumber(), (str) -> {
							});
					// 该配种证明都不通过
					dao.review(dogBirthCertificate);
				}
				// 给用户发送消息
				sendMsg(dogBirthCertificate);
			}
		} catch (Exception e) {
			throw e;
		}
	}

	// /**
	// *
	// * @description: 生成犬只信息
	// * @author: laiguanglong
	// * @date: 2016年8月12日 下午5:49:28
	// */
	// private String insertDog(DogBirthCertificate dogBirthCertificate){
	// Dog dog = new Dog();
	// dog.setBirthCertificateLevelCode(dogBirthCertificate.getBirthCerRegCode());
	// dog.setPedigreeCertifiedCode(dogBirthCertificate.getPedigreeCertified());
	// dog.setDogOwner(dogBirthCertificate.getDogOwenr());
	// dog.setMemberCode(dogBirthCertificate.getMemberCode());
	// dog.setSecondDogOwner(dogBirthCertificate.getSecondDogOwner());
	// dog.setSecondOwnerMemberNum(dogBirthCertificate.getSecondOwnerMemberCode());
	// dog.setNameEn(dogBirthCertificate.getDogEnName());
	// dog.setBreeder(dogBirthCertificate.getBreeder());
	// dog.setGender(dogBirthCertificate.getDogGender());
	// dog.setDogBreed(dogBirthCertificate.getDogBreed());
	// dog.setColorFlag(dogBirthCertificate.getColorFlag());
	// dog.setBirthdate(dogBirthCertificate.getDogBirthday());
	// dog.setFdogPedigreeCertified(dogBirthCertificate.getFdogPedigreeCertified());
	// dog.setMdogPedigreeCertified(dogBirthCertificate.getMdogPedigreeCertified());
	// dog.setFmdogBreedCertifiedCode(dogBirthCertificate.getFmdogBreedCertifiedCode());
	// dog.setPrintState("0");
	// dog.setDnaPayState("0");
	// dog.setBreedPayState("0");
	//// dog.setDogGeneration("0");
	// dogService.save(dog);
	// return dog.getId();
	// }

	/**
	 * @description: 生成芯片登记记录
	 * @author: laiguanglong
	 * @date: 2016年8月12日 下午6:00:04
	 */
	public void insertDogChipChange(DogBirthCertificate dogBirthCertificate, String identificationFlag) {
		// 根据流水号获取订单
		PaymentOrder paymentOrder = paymentOrderService.getByOrderCode(dogBirthCertificate.getRunningNumber());
		DogChipChange dogChipChange = new DogChipChange();
		dogChipChange.setBirthCode(dogBirthCertificate.getBirthCerRegCode());
		dogChipChange.setPaymentMemberCode(dogBirthCertificate.getMemberCode());
		dogChipChange.setChipCodeNew(identificationFlag);
		dogChipChange.setPaymentState("2");
		dogChipChange.setPaymentTime(paymentOrder.getPaymentTime());
		dogChipChange.setRunningNumber(paymentOrder.getOrderCode());
		dogChipChange.setReviewState("0");
		dogChipChange.setProcessState("0");
		dogChipChangeService.save(dogChipChange);
	}

	/**
	 * @description: 更新芯片登记记录
	 * @author: laiguanglong
	 * @date: 2016年8月12日 下午6:00:04
	 */
	public void updateDogChipChange(DogBirthCertificate dogBirthCertificate, String identificationFlag) {
		// 根据流水号和芯片号获取记录
		DogChipChange example = new DogChipChange();
		example.setRunningNumber(dogBirthCertificate.getRunningNumber());
		example.setChipCodeNew(dogBirthCertificate.getIdentificationFlag());
		List<DogChipChange> dogChipChangeList = dogChipChangeService.findList(example);
		if (dogChipChangeList.size() > 0) {
			DogChipChange dogChipChange = dogChipChangeList.get(0);
			dogChipChange.setChipCodeNew(identificationFlag);
			dogChipChangeService.save(dogChipChange);
		}
	}

	public void updateDogChip(DogBirthCertificate dogBirthCertificate, String identificationFlag) {
		if (StringUtils.isNotBlank(dogBirthCertificate.getPedigreeCertified())) {
			Dog dog = dogService.getByPedigreeCertifiedCode(dogBirthCertificate.getPedigreeCertified());
			if (dog != null && !identificationFlag.equals(dog.getIdentificationFlag())) {
				dog.setIdentificationFlag(identificationFlag);
				dogService.save(dog);
			}
		}
	}

	/**
	 * @description: 业务校验
	 * @author: laiguanglong
	 * @date: 2016年8月17日 上午11:53:33
	 */
	private void validate(DogBirthCertificateApply dogBirthCertificateApply, DogNewborn dogNewborn) throws ZAException {
		// 校验母犬主为有效专业会员
		validateMDogOwner(dogNewborn.getFdogOwnerCode());
		// 校验犬只出生日期为配种后50-70天内
		int between_day = getDayBetween(dogBirthCertificateApply.getDogBirthday(), dogNewborn.getBreedDate());
		if (between_day < 50 || between_day > 70) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "犬只出生日期必须为配种后50-70天内");
		}
		// 校验犬只是否重名或为空
		validateDogEnName(dogBirthCertificateApply);
	}

	/**
	 * @description: 获取出生纸费用
	 * @author: laiguanglong
	 * @date: 2016年8月17日 上午10:22:21
	 */
	private String getPrice(DogBirthCertificateApply apply) {
		// 根据支付项查询金额
		PaymentChargingItem paymentChargingItem = paymentChargingItemService.get(apply.getPaymentChargingItemId());
		Double price = Double.valueOf(paymentChargingItem.getPrice());
		// 加急加收30%的费用
		if ("1".equals(apply.getUrgent())) {
			price = price * 1.3;
		}
		return price.toString();
	}

	/**
	 * @description: 计算天数差
	 * @author: laiguanglong
	 * @date: 2016年8月15日 下午5:07:58
	 */
	private int getDayBetween(Date date, Date birthdate) {
		Calendar dateCalendar = Calendar.getInstance();
		Calendar birthdateCalendar = Calendar.getInstance();
		dateCalendar.setTime(date);
		birthdateCalendar.setTime(birthdate);
		long between = dateCalendar.getTimeInMillis() - birthdateCalendar.getTimeInMillis();
		long between_day = between / (1000 * 3600 * 24);
		return (int) between_day;
	}

	/**
	 * @description: 计算月份差
	 * @author: laiguanglong
	 * @date: 2016年8月15日 下午4:58:22
	 */
	private int getMonthAge(Date date, Date birthdate) {
		Calendar dateCalendar = Calendar.getInstance();
		Calendar birthdateCalendar = Calendar.getInstance();
		dateCalendar.setTime(date);
		birthdateCalendar.setTime(birthdate);
		int monthAge = dateCalendar.get(Calendar.MONTH) - birthdateCalendar.get(Calendar.MONTH);
		if (dateCalendar.get(Calendar.YEAR) != birthdateCalendar.get(Calendar.YEAR)) {
			monthAge = (dateCalendar.get(Calendar.YEAR) - birthdateCalendar.get(Calendar.YEAR)) * 12 + monthAge;
		}
		birthdateCalendar.add(Calendar.MONTH, monthAge);
		if (birthdateCalendar.getTime().after(dateCalendar.getTime())) {
			monthAge = monthAge - 1;
		}
		return monthAge;
	}

	/**
	 * @description: 校验母犬主为有效专业会员
	 * @author: laiguanglong
	 * @date: 2016年8月15日 下午4:52:17
	 */
	public void validateMDogOwner(String memberCode) throws ZAException {
		Member member = memberService.getByMemberCode(memberCode);
		if (member == null) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "该会员的登录信息不存在");
		}
		if (!MemberUtil.isActiveProfessionalMember(member)) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "母犬主不是有效专业会员");
		}
		if (!MemberUtil.isProfessionalMember(member)) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "该业务仅限有效专业会员及有效犬舍办理");
		}
	}

	/**
	 * @description: 校验母犬主为有有效犬舍
	 * @author: laiguanglong
	 * @date: 2016年8月15日 下午4:52:17
	 */
	public void validateMDogOwnerKennel(String memberCode) throws ZAException {
		Kennel kennel = kennelService.getKennelByMemberCode(memberCode);
		if (kennel == null) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "母犬主没有关联的犬舍信息，不允许申请新生犬登记卡");
		}
		if (kennel.getEndTime() == null || (kennel.getEndTime().getTime() + 86399000) < System.currentTimeMillis()) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "母犬主的犬舍为无效犬舍，不允许申请新生犬登记卡");
		}
		// 校验犬舍审核状态
		if (!"1".equals(kennel.getReviewState())) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "母犬主的犬舍审核状态为不通过，不允许申请新生犬登记卡");
		}
	}

	// /**
	// *
	// * @description: 会员端提交出生证明申请订单
	// * @author: laiguanglong
	// * @date: 2016年8月16日 下午5:51:09
	// */
	// @Transactional(readOnly = false,rollbackFor=Exception.class)
	// public void addClientSide(DogBirthCertificateApply dogBirthCertificateApply)
	// throws ZAException {
	// //出生证明基础校验
	// DogNewborn dogNewborn = basicValidate(dogBirthCertificateApply);
	// //验证犬舍、获取犬舍名
	// dogBirthCertificateApply.setKennelName(validateKennel(dogNewborn));
	// //业务校验
	// validate(dogBirthCertificateApply,dogNewborn);
	// boolean oaFlag = false;
	// //核心业务
	// save(dogBirthCertificateApply, dogNewborn, oaFlag);
	// }

	/**
	 * @description: OA端提交出生证明申请订单
	 * @author: laiguanglong
	 * @date: 2016年8月24日 下午7:44:41
	 */
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void addOaSide(DogBirthCertificateApply dogBirthCertificateApply) throws ZAException {
		// 出生证明基础校验
		DogNewborn dogNewborn = basicValidate(dogBirthCertificateApply);
		String kennelName = "";
		try {
			kennelName = validateKennel(dogNewborn);
		} catch (Exception e) {
			// 如果发生了异常，不进行处理
		}
		dogBirthCertificateApply.setKennelName(kennelName);
		boolean oaFlag = true;
		// 核心业务
		save(dogBirthCertificateApply, dogNewborn, oaFlag);
	}

	/**
	 * @description: 出生证明基础校验
	 * @author: laiguanglong
	 * @date: 2016年8月24日 下午7:59:58
	 */
	private DogNewborn basicValidate(DogBirthCertificateApply dogBirthCertificateApply) throws ZAException {
		// 参数校验
		try {
			BeanValidators.validateWithException(validator, dogBirthCertificateApply);
			for (DogBirthCertificate dogBirthCertificate : dogBirthCertificateApply.getDogBirthCertificateList()) {
				BeanValidators.validateWithException(validator, dogBirthCertificate);
			}
		} catch (Exception e) {
			logger.info("参数校验出错", e);
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "参数有误");
		}
		// 查询配种证明表
		DogNewborn dogNewborn = dogNewbornDao
				.getByBreedCertifiedCode(dogBirthCertificateApply.getFmdogBreedCertifiedCode());
		if (dogNewborn == null) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "配种证明编号有误");
		}
		// 业务禁止校验
		Dog fatherDog = dogService.getByPedigreeCertifiedCode(dogNewborn.getMalePedigreeCertified());
		Dog motherDog = dogService.getByPedigreeCertifiedCode(dogNewborn.getFemalePedigreeCertified());
		businessBanService.validateBusinessBan(fatherDog, "父（母）犬为禁止繁殖状态");
		businessBanService.validateBusinessBan(motherDog, "父（母）犬为禁止繁殖状态");
		// 获取同胎犬数格式为 x公y母
		dogBirthCertificateApply.setSameBatchNum(getSameBatchNum(dogBirthCertificateApply));
		// 验证出生纸是否已登记
		if (dao.findByFmdogBreedCertifiedCode(dogBirthCertificateApply.getFmdogBreedCertifiedCode()).size() != 0) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "此配犬证明的出生纸信息已登记，请勿重复登记");
		}
		// start-20180202-chaixueteng 校验母犬主有效及犬舍有效
		validateNewBornMother(dogNewborn.getFdogOwnerCode());
		// end
		return dogNewborn;
	}

	/**
	 * 根据配种证明查询一条出生纸信息
	 *
	 * @param fmdogBreedCertifiedCode
	 * @return
	 */
	public DogBirthCertificate getfindByFmdogBreedCertifiedCode(String fmdogBreedCertifiedCode) {
		return dao.getfindByFmdogBreedCertifiedCode(fmdogBreedCertifiedCode);
	}

	/**
	 * 根据配种证明查询出生纸信息
	 *
	 * @param fmdogBreedCertifiedCode
	 * @return
	 */
	public List<DogBirthCertificate> findByFmdogBreedCertifiedCode(String fmdogBreedCertifiedCode) {
		return dao.findByFmdogBreedCertifiedCode(fmdogBreedCertifiedCode);
	}

	public List<DogBirthCertificate> findByFmdogBreedCertifiedCodeAndRunningNumber(String fmdogBreedCertifiedCode,
			String runningNumber) {
		return dao.findByFmdogBreedCertifiedCodeAndRunningNumber(fmdogBreedCertifiedCode, runningNumber);
	}

	/**
	 * @description: 出生证明基础校验
	 * @author: chaixueteng
	 * @date: 2018年2月5日 下午7:59:58
	 */
	public void validateNewBornMother(String motherDogMemberCode) {
		Member motherMember = memberService.getByMemberCode(motherDogMemberCode);
		if (!MemberUtil.isActiveProfessionalMember(motherMember)) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "母犬主不是有效专业会员");
		}
		if (!"professional".equals(motherMember.getMemberType())) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "母犬主不是专业会员");
		}
		Kennel kennel = kennelService.getKennelByMemberCode(motherDogMemberCode);
		if (kennel == null) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "母犬主没有犬舍");
		}

		// 母犬主犬舍是否有效校验
		boolean flag = false;
		if (kennel != null) {
			Date endTime = kennel.getEndTime();
			if (endTime != null) {
				if ((endTime.getTime() + 86399000) > System.currentTimeMillis()) {// 有效
					flag = true;
				}
			}
		}
		if (!flag) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "母犬主犬舍无效");
		}
		if (!"1".equals(kennel.getReviewState())) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "母犬主犬舍必须审核通过才能申请新生犬识别登记卡");
		}
	}

	/**
	 * @description: 保存订单核心业务
	 * @author: laiguanglong
	 * @date: 2016年8月24日 下午7:44:11
	 */
	private void save(DogBirthCertificateApply dogBirthCertificateApply, DogNewborn dogNewborn, boolean oaFlag)
			throws ZAException {
		// //更新配种证明信息
		// updateDogNewBorn(dogNewborn, dogBirthCertificateApply);
		// 添加出生证明信息
		insertDogBirthCertificate(dogBirthCertificateApply, dogNewborn, oaFlag);
		// 给用户发送消息
		DogBirthCertificate dogBirthCertificate = new DogBirthCertificate();
		dogBirthCertificate.setFmdogBreedCertifiedCode(dogNewborn.getBreedCertifiedCode());
		dogBirthCertificate.setMemberCode(dogNewborn.getFdogOwnerCode());
		sendMsg(dogBirthCertificate);
	}

	/**
	 * @description: 验证犬舍、获取犬舍名
	 * @author: laiguanglong
	 * @date: 2016年8月17日 上午11:20:16
	 */
	private String validateKennel(DogNewborn dogNewborn) throws ZAException {
		Kennel kennel = kennelService.getKennelByMemberCode(dogNewborn.getFdogOwnerCode());
		if (kennel == null) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "母犬主所属的犬舍信息不存在");
		}
		// if(!"1".equals(kennel.getPaymentState())){
		// throw new ZAException(ZAErrorCode.ZA_VALID_FAILED,"母犬主所属的犬舍未缴费");
		// }
		if (StringUtils.isBlank(kennel.getNameEn())) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "犬舍英文名错误，请联系CKU会员部");
		}
		String dog_kennelName = kennel.getNameEn().replace("'s", "").replace("’s", "");
		dog_kennelName = dog_kennelName.replace("（FCI）", "").replace("（审核中）", "").replace("（待审核）", "");
		dog_kennelName = dog_kennelName.replace("待审核", "").replace("（不能繁殖）", "").replace("（FCI不能繁殖）", "");
		dog_kennelName = dog_kennelName.replace("（FCI不能作繁殖）", "").replace("Kennel", "");
		return dog_kennelName;
	}

	/**
	 * @description: 校验犬只是否重名或为空
	 * @author: laiguanglong
	 * @date: 2016年8月16日 下午6:11:17
	 */
	private void validateDogEnName(DogBirthCertificateApply dogBirthCertificateApply) throws ZAException {
		List<DogBirthCertificate> dogBirthCertificateList = dogBirthCertificateApply.getDogBirthCertificateList();
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < dogBirthCertificateList.size(); i++) {
			String dogEnName = dogBirthCertificateList.get(i).getDogEnName();
			if (StringUtils.isBlank(dogEnName)) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "犬名不能为空");
			}
			if (i == 0) {
				sb.append(dogEnName);
			} else {
				if (sb.indexOf(dogEnName) != -1) {
					throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "犬名重复");
				}
			}
		}
	}

	/**
	 * @description: 获取同胎犬数格式为 x公y母
	 * @author: laiguanglong
	 * @date: 2016年8月16日 下午6:39:29
	 */
	private String getSameBatchNum(DogBirthCertificateApply dogBirthCertificateApply) throws ZAException {
		if (dogBirthCertificateApply.getDogBirthCertificateList().size() == 0) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "申请出生证明数不能为0");
		}
		int male = 0;
		int female = 0;
		for (DogBirthCertificate dogBirthCertificate : dogBirthCertificateApply.getDogBirthCertificateList()) {
			if ("1".equals(dogBirthCertificate.getDogGender())) {
				male++;
			} else if ("2".equals(dogBirthCertificate.getDogGender())) {
				female++;
			}
		}
		return male + "公" + female + "母";
	}

	/**
	 * @description: 添加出生证明信息
	 * @author: laiguanglong
	 * @date: 2016年8月17日 上午10:54:04
	 */
	private void insertDogBirthCertificate(DogBirthCertificateApply dogBirthCertificateApply, DogNewborn dogNewborn,
			boolean oaFlag) {
		String price = getPrice(dogBirthCertificateApply);
		Date paymentTime = paymentOrderService.getPaymentTimeByOrderCode(dogBirthCertificateApply.getRunningNumber());
		for (DogBirthCertificate temp : dogBirthCertificateApply.getDogBirthCertificateList()) {
			DogBirthCertificate dogBirthCertificate = new DogBirthCertificate();
			dogBirthCertificate.setBirthCerRegCode(SysCodeUtil.getBirthCertificateCode());
			dogBirthCertificate.setDogGender(temp.getDogGender());
			// 设置犬名
			String dogEnName = temp.getDogEnName();
			dogBirthCertificate.setDogEnName(dogBirthCertificateApply.getKennelName() + " "
					+ dogEnName.substring(0, 1).toUpperCase() + dogEnName.substring(1).toLowerCase());
			if (temp.getColorFlag() != null) {
				dogBirthCertificate.setColorFlag(StringEscapeUtils.unescapeHtml4(temp.getColorFlag()));
			}

			dogBirthCertificate.setDogBirthday(dogBirthCertificateApply.getDogBirthday());
			dogBirthCertificate.setFmdogBreedCertifiedCode(dogBirthCertificateApply.getFmdogBreedCertifiedCode());
			dogBirthCertificate.setFdogPedigreeCertified(dogNewborn.getMalePedigreeCertified());
			dogBirthCertificate.setMdogPedigreeCertified(dogNewborn.getFemalePedigreeCertified());
			// 以下都是母犬主人的信息
			dogBirthCertificate.setDogOwenr(dogNewborn.getFemaleDogOwner());
			dogBirthCertificate.setMemberCode(dogNewborn.getFdogOwnerCode());
			dogBirthCertificate.setBreeder(dogNewborn.getFemaleDogOwner());
			dogBirthCertificate.setBreederMemberCode(dogNewborn.getFdogOwnerCode());
			dogBirthCertificate.setTempUserName(dogNewborn.getFemaleDogOwner());
			dogBirthCertificate.setTempMemberCode(dogNewborn.getFdogOwnerCode());

			dogBirthCertificate.setDogBreed(dogNewborn.getDogBreed());
			dogBirthCertificate.setSameBatchNum(dogBirthCertificateApply.getSameBatchNum());
			// 状态
			dogBirthCertificate.setUrgent("1".equals(dogBirthCertificateApply.getUrgent()) ? "1" : "0");
			dogBirthCertificate.setReviewState("0");
			dogBirthCertificate.setPrice(price);
			// 可以打印
			dogBirthCertificate.setPrintType("1");
			dogBirthCertificate.setDelFlag("0");
			// 默认是生成订单状态
			String paymentState = "9";
			// 如果是OA提交则改为已缴费
			if (oaFlag) {
				paymentState = "2";
				dogBirthCertificate.setPaymentTime(paymentTime);
			}
			dogBirthCertificate.setPaymentState(paymentState);
			dogBirthCertificate.setRunningNumber(dogBirthCertificateApply.getRunningNumber());
			// 生成随机6位数字或字母字符串 识别码
			dogBirthCertificate.setSnCode(RandomStringUtils.randomAlphanumeric(6).toUpperCase());
			// 申请日期与出生日期差小于两个月增加可抵扣标记，大于两个月增加不可抵扣标记
			dogBirthCertificate.setDeduction(getDeduction(dogBirthCertificateApply.getDogBirthday()));
			// 白色柴犬禁止繁殖和赛事业务,20180601以后杜高犬禁止繁殖配种 ,允许赛事业务
			dogBirthCertificate.setBusinessBan(businessBanService.getBusinessBan(dogNewborn.getDogBreed(),
					temp.getColorFlag(), dogBirthCertificate.getDogBirthday()));
			dogBirthCertificate.setShowBan(businessBanService.getShowBan(dogNewborn.getDogBreed(), temp.getColorFlag(),
					dogBirthCertificate.getDogBirthday()));
			// 2020-05-01起犬只办理登记卡默认激活
			dogBirthCertificate.setActivitionState("1");
			super.save(dogBirthCertificate);
		}
	}

	/**
	 * @throws ParseException
	 * @description: 获取出生纸是否抵扣标志位
	 * @author: laiguanglong
	 * @date: 2016年11月4日 下午4:15:39
	 */
	public String getDeduction(Date dogBirthday) {
		String deduction = "0";
		Date now = new Date();
		// 申请日期与出生日期差小于两个月增加可抵扣标记
		if (getMonthAge(now, dogBirthday) < 2) {
			deduction = "1";
		} else {
			// 判断是否正好2个月
			Calendar calendar = Calendar.getInstance();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			try {
				calendar.setTime(sdf.parse(sdf.format(dogBirthday)));
			} catch (ParseException e) {
				e.printStackTrace();
			}
			calendar.add(Calendar.MONTH, 2);
			calendar.add(Calendar.DATE, 1);
			if (now.getTime() < calendar.getTimeInMillis()) {
				deduction = "1";
			}
		}
		return deduction;
	}

	/**
	 * @description: 给用户发送消息，根据审核状态来判断发送内容
	 * @author: laiguanglong
	 * @date: 2016年8月19日 上午10:08:33
	 */
	private void sendMsg(DogBirthCertificate dogBirthCertificate) {
		String reviewState = dogBirthCertificate.getReviewState();
		// 只有0，1，2的状态发消息
		if ("0".equals(reviewState) || "1".equals(reviewState) || "2".equals(reviewState)) {
			String content = null;
			if ("0".equals(reviewState)) {
				// 未审核状态，提交未缴费
				SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日HH时mm分");
				String dateString = formatter.format(new Date());
				content = "您于" + dateString + "提交了配种证明编号为“" + dogBirthCertificate.getFmdogBreedCertifiedCode()
						+ "”出生纸申请，请您务必于当日24时前完成缴费，过期订单失效哦。";
			} else if ("1".equals(reviewState)) {
				// 审核通过
				content = "您提交的配种证明编号为“" + dogBirthCertificate.getFmdogBreedCertifiedCode() + "”的出生纸审核通过。";
			} else if ("2".equals(reviewState)) {
				// 审核不通过
				content = "您提交的配种证明编号为“" + dogBirthCertificate.getFmdogBreedCertifiedCode() + "”的出生纸审核未通过，请修改后重新提交。";
			}
			remindService.addRemind(content, dogBirthCertificate.getMemberCode());
		}
	}

	/**
	 * @description: oa财务模块的出生证明申请订单录入根据配种证明号查询父母犬信息
	 * @author: laiguanglong
	 * @date: 2016年9月1日 上午10:16:28
	 */
	public HashMap<String, String> getByFmdogBreedCertifiedCode(String fmdogBreedCertifiedCode) {
		HashMap<String, String> map = new HashMap<String, String>();
		DogNewborn dogNewborn = dogNewbornDao.getByBreedCertifiedCode(fmdogBreedCertifiedCode);
		if (dogNewborn != null) {
			map.put("breedDate", DateUtils.dateToStr(dogNewborn.getBreedDate()));
			map.put("dogBreed", dogNewborn.getDogBreed());
			map.put("maleDogOwner", dogNewborn.getMaleDogOwner());
			map.put("malePedigreeCertified", dogNewborn.getMalePedigreeCertified());
			map.put("femaleDogOwner", dogNewborn.getFemaleDogOwner());
			map.put("femalePedigreeCertified", dogNewborn.getFemalePedigreeCertified());
			DogType dogType = dogTypeService.getByDogBreedCode(dogNewborn.getDogBreed());
			StringBuilder sb = new StringBuilder();
			if (StringUtils.isNotBlank(dogType.getDogColor())) {
				String[] dogColorArray = dogType.getDogColor().split(",");
				for (String dogColorMarkCode : dogColorArray) {
					DogColorMark dogColorMark = dogColorMarkService.getByDogColorMarkCode(dogColorMarkCode);
					if (dogColorMark != null) {
						sb.append(dogColorMark.getDogColorMarkCode() + "=" + dogColorMark.getDogColorMarkCn() + ",");
					}
				}
			} else {
				// 查询出所有颜色
				for (DogColorMark dogColorMark : dogColorMarkService.findAllList()) {
					sb.append(dogColorMark.getDogColorMarkCode() + "=" + dogColorMark.getDogColorMarkCn() + ",");
				}
			}
			sb.deleteCharAt(sb.length() - 1);
			map.put("dogColor", sb.toString());
		}
		return map;
	}

	/**
	 * @description: 生成随机犬名
	 * @author: laiguanglong
	 * @date: 2016年8月25日 上午11:06:39
	 */
	public HashMap<String, String> getDogNames(String maleNum, String femaleNum) {
		HashMap<String, String> map = new HashMap<String, String>();
		List<DogName> list = dao.getDogNames(Integer.valueOf(maleNum), Integer.valueOf(femaleNum));
		StringBuilder sb = new StringBuilder();
		for (DogName dogName : list) {
			sb.append(dogName.getDogName() + ",");
		}
		sb.deleteCharAt(sb.length() - 1);
		map.put("dogNameList", sb.toString());
		return map;
	}

	/**
	 * @description: 根据出生证明编号进行查询
	 * @author: laiguanglong
	 * @date: 2016年9月1日 下午5:47:07
	 */
	public DogBirthCertificate getByBirthCerRegCode(String birthCerRegCode) {
		return dao.getByBirthCerRegCode(birthCerRegCode);
	}

	/**
	 * 护照号
	 *
	 * @param cabPassport
	 * @return
	 */
	public DogBirthCertificate getByCabPassport(String cabPassport) {
		return dao.getByCabPassport(cabPassport);
	}

	/**
	 * @Description：根据出生证明编号进行查询,返回是否存在数据标识
	 * @author: zhuoHeng
	 * @version: 2016年10月14日 下午4:27:21
	 */
	public String getMessageByBirthCerRegCode(String birthCerRegCode) {
		DogBirthCertificate model = dao.getByBirthCerRegCode(birthCerRegCode);
		String flag = "failure";
		if (model != null) {
			flag = "success";
		} else {
			flag = "failure";
		}
		return flag;
	}

	/**
	 * @Description：根据出生纸编号查询出生纸信息
	 * @author: zhuoHeng
	 * @version: 2016年10月24日 下午12:06:42
	 */
	@SuppressWarnings("all")
	public Map<String, String> getBirthCerRegByCode(String birthCerRegCode) {
		DogBirthCertificate birthCertificate = dao.getByBirthCerRegCode(birthCerRegCode);
		Map<String, String> map = new HashMap<String, String>();
		if (birthCertificate != null) {
			DogType dogType = dogTypeService.getByDogBreedCode(birthCertificate.getDogBreed());
			map.put("dogBreedCnName", dogType == null ? "" : dogType.getBreedCnName());// 品种
			map.put("dogGender", DictUtils.getDictLabel(birthCertificate.getDogGender(), "dog_gender", ""));// 性别
			map.put("dogEnName", birthCertificate.getDogEnName());// 犬只姓名
			map.put("identificationFlag", birthCertificate.getIdentificationFlag());
			map.put("result", "success");
		} else {
			map.put("result", "failure");
		}
		return map;
	}

	/**
	 * @description: 获取已付款待审核的出生证明申请记录数
	 * @author: laiguanglong
	 * @date: 2016年8月29日 下午3:46:43
	 */
	public int getAuditCount() {
		DogBirthCertificate dogBirthCertificate = new DogBirthCertificate();
		// 已付款
		dogBirthCertificate.setPaymentState("2");
		// 未审核
		dogBirthCertificate.setReviewState("0");
		return dao.listCount(dogBirthCertificate);
	}

	/**
	 * @description: 证书换发业务校验
	 * @author: laiguanglong
	 * @date: 2016年9月13日 下午6:18:14
	 */
	public void validateBusiness(List<DogBirthCertificate> poList) {
		DogBirthCertificate po = poList.get(0);
		// 重复订单校验
		DogBirthCertificate example = new DogBirthCertificate();
		example.setFmdogBreedCertifiedCode(po.getFmdogBreedCertifiedCode());
		example.setReviewStateExclud("3");
		List<DogBirthCertificate> list = findList(example);
		Member loginMember = UserUtils.getLoginMember();
		if (po.getDogBirthday().after(new Date())) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "出生日期不能大于当前日期！");
		}
		//犬名重复校验
		if(poList.size() != poList.stream()
				.map(DogBirthCertificate::getDogEnName)
				.distinct()
				.count()){
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "犬只英文名同窝内不可重复！");
		}

		// 申请人为母犬主校验
		Debugger.doAssert(po.getMemberCode().equals(loginMember.getMemberCode()), ZAErrorCode.ZA_VALID_FAILED,
				"申请人需为母犬主人");
		// //因为不排除注销的记录，所以注释以下代码
		// //排除注销的记录
		// for(Iterator<DogBirthCertificate> it = list.iterator(); it.hasNext();) {
		// DogBirthCertificate dogBirthCertificate = it.next();
		// if("3".equals(dogBirthCertificate.getReviewState())){
		// //排除已注销的记录
		// it.remove();
		// }
		// }
		if (list.size() > 0) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "已有新生犬登记卡申请订单");
		}
		// 根据犬种判断是否超过一窝最大数
		DogType dogType = dogTypeService.getByDogBreedCode(po.getDogBreed());
		if (Integer.parseInt(dogType.getBatchMaxNum()) < poList.size()) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "您申请的犬只数量超过申请上限，需联系协会线下提交申请");
		}
		if (StringUtils.isNotBlank(po.getSecondBreederMemberCode())) {
			checkSecondBreeder(po.getSecondBreederMemberCode());
		}
		basicValidate(po);
	}

	public void checkSecondBreeder(String secondBreederMemberCode) {
		if (StringUtils.isBlank(secondBreederMemberCode)) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "第二繁殖人会员号为空");
		}
		Member member = memberService.getByMemberCode(secondBreederMemberCode);
		if (member == null) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "会员号码有误，请输入正确会员号");
		}
		if (!MemberUtil.isActiveMember(member)) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "第二繁殖人需为有效爱宠银卡及以上会员办理!");
		}
		if (CardTypeEnum.DEFAULT_CARD.code() == UserUtils.getMemberCardType(secondBreederMemberCode)) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "第二繁殖人需为有效爱宠银卡及以上会员办理！");
		}
		Member loginMember = UserUtils.getLoginMember();
		String memberSite = loginMember.getMemberSite();
		if (!((StringUtils.isBlank(member.getMemberSite()) && StringUtils.isBlank(memberSite))
				|| memberSite.equals(member.getMemberSite()))) {
			memberSite = memberSite == null ? "2" : loginMember.getMemberSite();
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED,
					"第二繁殖人需为" + DictUtils.getDictLabel(memberSite, "member_site", "") + "有效银卡及以上会员办理");
		}
	}

	/**
	 * 根据出生纸编号和识别码 查询
	 *
	 * @Author chaixueteng
	 * @2016年10月12日上午10:43:34
	 */
	public DogBirthCertificate getByBirthCodeAndSnCode(String birthCode, String snCode) {
		return dao.getByBirthCodeAndSnCode(birthCode, snCode);
	}

	/**
	 * 根据出生纸编号和识别码或芯片号查询
	 * 
	 * @param birthCode
	 * @param snCode
	 * @return
	 */
	public DogBirthCertificate findByBirthCodeAndSnCode(String birthCode, String snCode) {
		return dao.findByBirthCodeAndSnCode(birthCode, snCode);
	}

	/**
	 * 根据芯片号查询
	 *
	 * @Author chaixueteng
	 * @2016年10月12日下午3:59:39
	 */
	public DogBirthCertificate getByIdentificationFlag(String identificationFlag) {
		if (StringUtils.isBlank(identificationFlag)) {
			return null;
		}
		return dao.getByIdentificationFlag(identificationFlag);
	}

	/**
	 * 医院新生犬管理
	 *
	 * @Author chaixueteng
	 * @2016年10月13日下午1:55:14
	 */
	public Page<DogBirthCertificate> findHospitalBirthPage(Page<DogBirthCertificate> page,
			DogBirthCertificate dogBirthCertificate) {
		dogBirthCertificate.setPage(page);
		page.setList(dao.findHospitalList(dogBirthCertificate));
		return page;
	}

	/**
	 * 医院新生犬管理
	 *
	 * @Author chaixueteng
	 * @2016年10月13日下午1:55:14
	 */
	public Page<DogBirthCertificate> findOldHospitalBirthPage(Page<DogBirthCertificate> page,
			DogBirthCertificate dogBirthCertificate) {
		dogBirthCertificate.setPage(page);
		page.setList(dao.findOldHospitalList(dogBirthCertificate));
		return page;
	}

	/**
	 * 出生纸修改
	 *
	 * @Author chaixueteng
	 * @2017年1月11日下午2:59:30
	 */
	public void updateByBirth(DogBirthCertificate dogbir) {
		super.save(dogbir);
	}

	/**
	 * @description: 出生纸自动审核
	 * @author: laiguanglong
	 * @date: 2017/2/7 16:28
	 */
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void autoAudit(DogBirthCertificate review) {
		// 默认审核通过
		String reviewState = "1";
		String reviewRemarks = "系统自动审核-通过";
		try {
			basicValidate(review);
		} catch (Exception e) {
			// 审核校验抛异常，审核不通过
			reviewState = "2";
			reviewRemarks = "系统自动审核-不通过：" + e.getMessage();
		}
		// 处理审核结果
		DogBirthCertificate copy = new DogBirthCertificate();
		BeanUtils.copyProperties(review, copy);
		copy.setReviewState(reviewState);
		copy.setReviewRemarks(reviewRemarks);
		// 审核
		audit(copy);
	}

	/**
	 * @description: 基础业务校验，添加业务表和自动审核都会触发
	 * @author: laiguanglong
	 * @date: 2017/2/7 17:05
	 */
	public void basicValidate(DogBirthCertificate po) {
		// 校验母犬主为有效专业会员
		validateMDogOwner(po.getMemberCode());
		// 校验母犬主为有效犬舍
		validateMDogOwnerKennel(po.getMemberCode());
		DogNewborn dogNewborn = dogNewbornDao.getByBreedCertifiedCode(po.getFmdogBreedCertifiedCode());
		// 校验配种证明为审核通过
		if (!"1".equals(dogNewborn.getReviewState())) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "配种证明未通过审核，不允许申请出生证明");
		}
		// 校验犬只出生日期为配种后50-70天内
		// int between_day = getDayBetween(po.getDogBirthday(),
		// dogNewborn.getBreedDate());
		// if(between_day<50||between_day>70){
		// throw new ZAException(ZAErrorCode.ZA_VALID_FAILED,"犬只出生日期必须为配种后50-70天内");
		// }
		if (!checkDogBirthday(po.getDogBirthday(), dogNewborn)) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "犬只出生日期必须为配种后50-70天内");
		}
		// 【犬籍管理-出生纸申请】出生纸申请需在犬只出生四个月内申请，超过四个月申请提示：出生证明需在犬只出生四个月内申请，逾期无法办理
		// if(po.getCreateDate()==null){
		// if(!com.cku.oa.sys.util.DateUtils.isInXMounth(po.getDogBirthday(),4)){
		// throw new ZAException(ZAErrorCode.ZA_VALID_FAILED,"出生证明需在犬只出生四个月内申请，逾期无法办理");
		// }
		// }else{
		// //拿记录创建时间和出生日期判断
		// Calendar dateCalendar = Calendar.getInstance();
		// dateCalendar.setTime(po.getDogBirthday());
		// dateCalendar.add(Calendar.MONTH, 4); //月份加x
		// dateCalendar.add(Calendar.DATE, 1); //日期加x
		// if(po.getCreateDate().getTime()>dateCalendar.getTimeInMillis()){
		// throw new ZAException(ZAErrorCode.ZA_VALID_FAILED,"出生证明需在犬只出生四个月内申请，逾期无法办理");
		// }
		// }
		if (!checkDogBirthday(po.getDogBirthday(), po.getCreateDate() == null ? new Date() : po.getCreateDate())) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "出生证明需在犬只出生四个月内申请，逾期无法办理");
		}
		// 业务禁止校验
		Dog fatherDog = dogService.getByPedigreeCertifiedCode(dogNewborn.getMalePedigreeCertified());
		Dog motherDog = dogService.getByPedigreeCertifiedCode(dogNewborn.getFemalePedigreeCertified());
		if ("1".equals(fatherDog.getBusinessBan())) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "父犬为禁止繁殖状态，无法办理该业务");
		}
		if ("1".equals(motherDog.getBusinessBan())) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "母犬为禁止繁殖状态，无法办理该业务");
		}
		/*
		 * 0此方法涉及包括在定时任务里 1validateMDogOwner(po.getMemberCode());方法是本类方法，抛出异常不会出现marked
		 * as rollback-only 2如果是其他类里抛异常，会被标记为marked as rollback-only 3所以这样要提取出判断逻辑来
		 * businessBanService.validateBusinessBan(fatherDog,"父（母）犬为禁止繁殖状态");
		 * businessBanService.validateBusinessBan(motherDog,"父（母）犬为禁止繁殖状态");
		 */
	}

	/**
	 * @description: 出生纸付款后业务
	 * @author: laiguanglong
	 * @date: 2017/2/8 9:52
	 */
	public void afterPay(String fmdogBreedCertifiedCode) {
		// 根据配种证明编号查询1条出生纸进行审核
		DogBirthCertificate dogBirthCertificate = dao.getOneByFmdogBreedCertifiedCode(fmdogBreedCertifiedCode);
		if (dogBirthCertificate != null)
			// 加急自动审核
			if ("1".equals(dogBirthCertificate.getUrgent())) {
				autoAudit(dogBirthCertificate);
			}
	}

	/**
	 * 获取上架状态
	 *
	 * @param po
	 * @return
	 */
	public String getUpperStates(DogBirthCertificate po) {
		int monthAge = getMonthAge(new Date(), po.getDogBirthday());
		if (monthAge <= 24) {
			DogActivation dogActivation = dogActivationDao.getByBirthCode(po.getBirthCerRegCode());
			if (dogActivation == null && po.getCreateDate().getTime() >= KENNEL_UNACTIVATION_MILLIS
					&& "1".equals(po.getActivitionState())) {
				if (po.getSendDate() != null && System.currentTimeMillis() > po.getSendDate().getTime()) {
					return "未上架";
				} else if (StringUtils.isNotBlank(po.getIsAll()) && "1".equals(po.getIsAll())) {
					return "未上架";
				} else {
					return "";
				}
			} else if (dogActivation == null && po.getCreateDate().getTime() < DOG_ACTIVATION_MILLIS
					&& getBusinessState(po).equals("已寄出")) {
				return "未上架";
			} else if (dogActivation != null && dogActivation.getType().equals("2")) {
				if (StringUtils.isNotBlank(dogActivation.getUpperReview())
						&& "0".equals(dogActivation.getUpperReview())) {
					return "待审核";
				} else if ("1".equals(dogActivation.getUpperReview()) && "1".equals(dogActivation.getState())) {
					return "已上架";
				} else if ("2".equals(dogActivation.getUpperReview()) && "1".equals(dogActivation.getState())) {
					return "审核失败";
				} else if ("1".equals(dogActivation.getUpperReview()) && "0".equals(dogActivation.getState())) {
					return "已下架";
				} else {
					return "";
				}
			} else if (dogActivation != null && dogActivation.getType().equals("1")) {
				if (dogActivation.getState().equals("1") && dogActivation.getReviewState().equals("1")) {
					return "已上架";
				} else if (dogActivation.getState().equals("0") && dogActivation.getReviewState().equals("1")) {
					return "已下架";
				} else {
					return "";
				}
			} else {
				return "";
			}
		} else {
			return "";
		}
	}

	/**
	 * @description: 获取业务状态
	 *               1、业务状态显示按时间划分，登记卡和血统证书列表页的业务状态显示做区分，2017年6月1日0：00分以后的数据显示业务状态；
	 *               2017年5月31日23:59:59秒前的数据不显示业务状态
	 * @author: laiguanglong
	 * @date: 2017/5/17 19:11
	 */
	public String getBusinessState(DogBirthCertificate po) {
		if (po.getCreateDate().getTime() < newBusinessTimeMillis) {
			return "";
		}
		if ("3".equals(po.getReviewState())) {
			return "已注销";
		} else if ("2".equals(po.getReviewState())) {
			return "未通过";
		} else if ("1".equals(po.getReviewState())) {
			DogChip dogChip = dogChipDao.getByBirthCode(po.getBirthCerRegCode());
			if (po.getCreateDate().getTime() > newBusinessTimeMillis
					&& StringUtils.isBlank(po.getIdentificationFlag())) {
				return "已通过";
			} else if (dogChip != null && "1".equals(dogChip.getIsAll())) {
				return "已通过";
			} else {
				if ("0".equals(po.getEcertFlag())) {
					if (!"9".equals(po.getPrintType())) {
						return "待打印";
					} else {
						if (po.getSendDate() != null && System.currentTimeMillis() > po.getSendDate().getTime()) {
							if (StringUtils.isNotBlank(po.getActivitionState())
									&& po.getActivitionState().equals("1")) {
								return "已完成";
							} else if (StringUtils.isNotBlank(po.getActivitionState())
									&& po.getActivitionState().equals("2")) {
								return "激活失败";
							} else if (StringUtils.isNotBlank(po.getActivitionState())
									&& po.getActivitionState().equals("3")) {
								return "超期激活未缴费";
							} else if (StringUtils.isNotBlank(po.getActivitionState())
									&& po.getActivitionState().equals("0")) {
								return "激活中";
							} else if (po.getCreateDate().getTime() > DOG_ACTIVATION_MILLIS) {
								// 犬只激活状态
								DogActivation dogActivation = dogActivationDao.getByBirthCode(po.getBirthCerRegCode());
								if (dogActivation == null) {
									Calendar calendar = Calendar.getInstance();
									calendar.setTime(po.getSendDate());
									calendar.add(Calendar.DATE, DogActivationService.EXPIRE_DAY + 1);
									if (System.currentTimeMillis() > calendar.getTimeInMillis()) {
										return "超期未激活";
									} else {
										return "寄出待激活";
									}
								} else {
									if ("0".equals(dogActivation.getReviewState())) {
										// if (StringUtils.isNotBlank(dogActivation.getRunningNumber()) &&
										// !"2".equals(dogActivation.getPaymentState())) {
										// return "超期未激活";
										// } else {
										// }
										return "激活中";
									} else if ("1".equals(dogActivation.getReviewState())) {
										return "已完成";
									} else if ("2".equals(dogActivation.getReviewState())) {
										return "激活失败";
									}
								}
							} else {
								return "已寄出";
							}
						} else {
							return "待邮寄";
						}
					}
				} else if ("1".equals(po.getEcertFlag())) {
					if (po.getSendDate() != null && System.currentTimeMillis() > po.getSendDate().getTime()) {
						if (StringUtils.isNotBlank(po.getActivitionState()) && po.getActivitionState().equals("1")) {
							return "已完成";
						}
						return "已寄出";
					} else {
						return "待邮寄";
					}
				}
			}
		} else if ("0".equals(po.getReviewState())) {
			if ("1".equals(po.getPaymentState())) {
				return "待支付";
			} else if ("2".equals(po.getPaymentState())) {
				return "待审核";
			}
		}
		return "";
	}

	/**
	 * 四星五星犬舍免激活
	 *
	 * @param
	 * @param memberCode
	 * @return
	 */
	public boolean needActivition(String memberCode) {
		try {
			OkHttpClient client = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS)
					.readTimeout(20, TimeUnit.SECONDS).build();
			Request request = new Request.Builder().url(KENNEL_START_URL + memberCode).build();
			JSONObject jsonObject = null;
			String data = client.newCall(request).execute().body().string();
			if (data != null) {
				jsonObject = JSONObject.fromObject(data);
			}
			Object ob = jsonObject.get("data");
			if (ob == null) {
				return true;
			}
			jsonObject = JSONObject.fromObject(ob);
			String star = (String) jsonObject.get("star");
			if (star.equals("4") || star.equals("5")) {
				return false;
			} else {
				return true;
			}
		} catch (Exception e) {
			System.out.print(e.getMessage());
			throw new ZAException(ZAErrorCode.ZA_ERC_INVALID_STATUS, "犬舍星级获取失败");
		}
	}

	/**
	 * @description: 校验犬只出生日期为配种后50-70天内
	 * @author: laiguanglong
	 * @date: 2017/5/18 10:59
	 */
	public boolean checkDogBirthday(Date dogBirthday, DogNewborn dogNewborn) {
		int between_day = getDayBetween(dogBirthday, dogNewborn.getBreedDate());
		if (between_day < 50 || between_day > 70) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * @description: 出生纸申请需在犬只出生四个月内申请，超过四个月申请提示
	 * @author: laiguanglong
	 * @date: 2017/5/18 10:46
	 */
	public boolean checkDogBirthday(Date dogBirthday, Date createDate) {
		Calendar dogBirthdayCalendar = Calendar.getInstance();
		dogBirthdayCalendar.setTime(dogBirthday);
		dogBirthdayCalendar.add(Calendar.MONTH, 4); // 月份加x
		dogBirthdayCalendar.add(Calendar.DATE, 1); // 日期加1
		if (dogBirthdayCalendar.getTimeInMillis() > createDate.getTime()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @description: 出生纸申请需在犬只出生十四个月内申请，超过十四个月申请提示
	 * @author: laiguanglong
	 * @date: 2019/6/19 17:41
	 */
	public boolean checkDogBirthday1(Date dogBirthday, Date createDate) {
		Calendar dogBirthdayCalendar = Calendar.getInstance();
		dogBirthdayCalendar.setTime(dogBirthday);
		dogBirthdayCalendar.add(Calendar.MONTH, 14); // 月份加x
		dogBirthdayCalendar.add(Calendar.DATE, 2); // 日期加2
		if (dogBirthdayCalendar.getTimeInMillis() > createDate.getTime()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @description: 是否能输入芯片号，返回true表示可以 1审核通过 2芯片号为空 3记录创建时间为2017年6月1日以后
	 * @author: laiguanglong
	 * @date: 2017/5/18 17:59
	 */
	public boolean isCanInputIdentificationFlag(DogBirthCertificate po) {
		boolean flag = false;
		if ("1".equals(po.getReviewState()) && StringUtils.isBlank(po.getIdentificationFlag())
				&& po.getCreateDate().getTime() > newBusinessTimeMillis) {
			flag = true;
		}
		return flag;
	}

	/**
	 * 根据出生纸和芯片号查询
	 *
	 * @param birthCode
	 * @param chipCode
	 * @return
	 */
	public DogBirthCertificate getByBirthCodeAndChipCode(String birthCode, String chipCode) {
		return dao.getByBirthCodeAndChipCode(birthCode, chipCode);
	}

	// private void addDogChipChange(DogBirthCertificate po,String
	// identificationFlag){
	// DogChipChange dogChipChange = new DogChipChange();
	// dogChipChange.setBirthCode(po.getBirthCerRegCode());
	// dogChipChange.setChipCodeNew(identificationFlag);
	// dogChipChange.setPaymentMemberCode(po.getBreederMemberCode());
	// dogChipChange.setReviewState("0");
	// dogChipChange.setPaymentState("2");
	// dogChipChange.setProcessState("0");
	// User user = UserUtils.getLoginUser();
	// StringBuilder sb = new StringBuilder();
	// sb.append(user.getId());
	// sb.append("-");
	// sb.append(user.getName());
	// sb.append(":");
	// sb.append(DateUtils.getStringDate());
	// dogChipChange.setOperator(sb.toString());
	// dogChipChange.setRunningNumber(po.getRunningNumber());
	// PaymentChargingItem dogChipItem =
	// paymentChargingItemService.getByShortName(DOG_CHIP_FEE);
	// dogChipChange.setPrice(dogChipItem.getPrice());
	// dogChipChangeService.save(dogChipChange);
	// }

	@Transactional(readOnly = false)
	public String reGetForm(DogBirthCertificate dogBirthCertificate, Model model) {
		DogColorMark dogColorMark = dogColorMarkService.getByDogColorMarkCode(dogBirthCertificate.getColorFlag());
		if (dogColorMark != null) {
			dogBirthCertificate.setColorFlag(dogColorMark.getDogColorMarkCn());
		}
		model.addAttribute("dogBirthCertificate", dogBirthCertificate);
		Member breeder = memberService.getByMemberCode(dogBirthCertificate.getBreederMemberCode());
		model.addAttribute("breeder", breeder);
		PaymentChargingItem dogBirthCertificatePaymentChargingItem = getDogBirthCertificatePaymentChargingItem();
		model.addAttribute("dogBirthCertificatePaymentChargingItem", dogBirthCertificatePaymentChargingItem);
		PaymentChargingItem dogChipPaymentChargingItem = getDogChipPaymentChargingItem();
		model.addAttribute("dogChipPaymentChargingItem", dogChipPaymentChargingItem);
		Double totalPrice = Double.parseDouble(dogBirthCertificatePaymentChargingItem.getPrice())
				+ Double.parseDouble(dogChipPaymentChargingItem.getPrice());
		model.addAttribute("totalPrice", +totalPrice);
		String birthCerRegCodeNew = "";
		String remarks = dogBirthCertificate.getRemarks();
		if (StringUtils.isNotBlank(remarks) && remarks.contains("新生犬登记卡重领(新生犬登记卡编号:")) {
			int index = remarks.indexOf("新生犬登记卡重领(新生犬登记卡编号:") + 27;
			birthCerRegCodeNew = remarks.substring(index, index + 9);
		} else {
			birthCerRegCodeNew = SysCodeUtil.getBirthCertificateCode();
		}
		model.addAttribute("birthCerRegCodeNew", birthCerRegCodeNew);
		return "oa/dog/birthcertificate/dogBirthCertificateRegetForm";
	}

	/**
	 * @description: 出生纸重领
	 * @author: laiguanglong
	 * @date: 2017/5/18 18:58
	 */
	@Transactional(readOnly = false)
	public void reGet(DogBirthCertificate reget, HttpServletRequest request) {

		String identificationFlag = reget.getIdentificationFlag();
		if (StringUtils.isNotBlank(identificationFlag) && identificationFlag.length() == 15) {
			Map<String, String> resultMap = createCabCodeReGet(reget.getIdentificationFlag(),
					reget.getPedigreeCertified());

			String cabRegisterCode = resultMap.get("cabRegisterCode");
			String cabPassport = resultMap.get("cabPassport");
			reget.setCabPassport(cabPassport);
			reget.setCabRegisterCode(cabRegisterCode);
		}

		DogBirthCertificate po = dao.get(reget.getId());
		if (!"3".equals(po.getReviewState())) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "该记录状态不是已注销，不允许重领");
		}
		if (StringUtils.isNotBlank(po.getRegetNewBirthCode())) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "该记录已经重领新生犬登记卡");
		}
		String birthCerRegCodeNew = request.getParameter("birthCerRegCodeNew");
		DogBirthCertificate newPo = new DogBirthCertificate();
		try {
			org.apache.commons.beanutils.BeanUtils.copyProperties(newPo, reget);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		// 构造出生纸重领订单
		PaymentOrder paymentOrder = buildReGetPaymentOrder(reget);
		// 写入订单信息
		paymentOrderService.save(paymentOrder);
		// 写入业务表信息
		newPo.setBirthCerRegCode(birthCerRegCodeNew);
		newPo.setRegetOldBirthCode(po.getBirthCerRegCode());
		if ("1".equals(reget.getReGetType())) {
			newPo.setIdentificationFlag(null);
			newPo.setCabPassport(null);
			newPo.setCabRegisterCode(null);
		}
		newPo.setUrgent("0");
		newPo.setPrice(paymentOrder.getTotalPrice());
		newPo.setReviewState("0");
		newPo.setClassPrintStatus("1");

		newPo.setReviewTime(null);
		newPo.setRunningNumber(paymentOrder.getOrderCode());
		newPo.setPaymentState("2");
		newPo.setPaymentTime(paymentOrder.getPaymentTime());
		newPo.setPrintType("1");
		newPo.preInsert();
		dao.insert(newPo);
		String remarks = "新生犬登记卡重领(新生犬登记卡编号:" + birthCerRegCodeNew + ")。";
		// 更新旧业务记录备注
		if (StringUtils.isNotBlank(po.getRemarks())) {
			remarks += po.getRemarks();
		}
		if ("2".equals(reget.getReGetType())) {
			remarks = reget.getRemarks();
		}
		po.setRegetNewBirthCode(newPo.getBirthCerRegCode());
		po.setRemarks(remarks);
		dao.update(po);
		// 芯片变更表新增记录
		if ("3".equals(reget.getReGetType())) {
			if (reget.getIdentificationFlag().equals(po.getIdentificationFlag())) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "新芯片号与原芯片号一样，请修改");
			}
			DogChipChange dogChipChange = new DogChipChange();
			dogChipChange.setBirthCode(newPo.getBirthCerRegCode());
			dogChipChange.setPaymentMemberCode(paymentOrder.getOrderCode());
			dogChipChange.setChipCodeNew(reget.getIdentificationFlag());
			dogChipChange.setPaymentState("2");
			dogChipChange.setPaymentTime(paymentOrder.getPaymentTime());
			dogChipChange.setRunningNumber(paymentOrder.getOrderCode());
			dogChipChange.setReviewState("0");
			dogChipChange.setProcessState("0");
			dogChipChangeService.save(dogChipChange);
		}
	}

	/**
	 * @description: 获取出生纸收费项
	 * @author: laiguanglong
	 * @date: 2016/12/30 10:50
	 */
	public PaymentChargingItem getDogBirthCertificatePaymentChargingItem() {
		// 根据支付项查询金额
		PaymentChargingItem paymentChargingItem = paymentChargingItemService.getByShortName(DOG_BIRTH_CERTIFICATE_FEE);
		return paymentChargingItem;
	}

	/**
	 * @description: 获取芯片收费项
	 * @author: laiguanglong
	 * @date: 2016/12/30 10:50
	 */
	public PaymentChargingItem getDogChipPaymentChargingItem() {
		PaymentChargingItem paymentChargingItem = paymentChargingItemService.getByShortName(DOG_CHIP_FEE);
		return paymentChargingItem;
	}

	/**
	 * @description: 获取第二繁殖人收费项
	 * @author:
	 * @date:
	 */
	public PaymentChargingItem getSecondBreederPaymentChargingItem() {
		PaymentChargingItem paymentChargingItem = paymentChargingItemService.getByShortName(SECOND_BREEDER_FEE);
		return paymentChargingItem;
	}

	/**
	 * @description: 获取出生纸优惠劵收费项
	 * @author: chaixueteng
	 * @date: 2018/4/18 10:50
	 */
	public PaymentChargingItem getCouponPaymentChargingItem() {
		PaymentChargingItem paymentChargingItem = paymentChargingItemService.getByShortName(DOG_BIRTH_COUPON);
		return paymentChargingItem;
	}

	/**
	 * @description: 构造出生纸重领订单
	 * @author: laiguanglong
	 * @date: 2017/5/22 14:19
	 */
	private PaymentOrder buildReGetPaymentOrder(DogBirthCertificate po) {
		PaymentChargingItem dogBirthCertificatePaymentChargingItem = getDogBirthCertificatePaymentChargingItem();
		PaymentChargingItem dogChipPaymentChargingItem = getDogChipPaymentChargingItem();
		if ("3".equals(po.getReGetType())) {// 建档服务费(补发登记卡)（0元）”“芯片费（补发芯片）（0元）”
			dogBirthCertificatePaymentChargingItem = paymentChargingItemService
					.getByShortName("dog_birth_certificate@reget3");
			dogChipPaymentChargingItem = paymentChargingItemService.getByShortName("dog_chip_change@reget3");
		}
		Member member = memberService.getByMemberCode(po.getBreederMemberCode());
		PaymentOrder order = new PaymentOrder();
		order.setReceiveProvince(member.getProvince());
		order.setReceiveCity(member.getCity());
		order.setReceiveAddress(member.getAddress());
		order.setReceivePostCode(member.getPostcode());
		order.setReceiveDel(member.getMobile());
		order.setReceiver(member.getName());
		order.setMemberCode(member.getMemberCode());
		order.setMemberName(member.getName());
		String loginType = UserUtils.getLoginUser().getLoginType();
		order.setLocked("0");
		order.setSource(loginType);
		order.setPaymentWay("25");
		order.setPaymentState("2");
		List<PaymentOrderDetail> orderDetailList = new ArrayList<PaymentOrderDetail>();
		PaymentOrderDetail dogBirthCertificatePaymentOrderDetail = new PaymentOrderDetail();
		dogBirthCertificatePaymentOrderDetail.setMemberCode(member.getMemberCode());
		dogBirthCertificatePaymentOrderDetail.setMemberName(member.getName());
		dogBirthCertificatePaymentOrderDetail.setChargingItemId(dogBirthCertificatePaymentChargingItem.getId());
		dogBirthCertificatePaymentOrderDetail.setChargingItemName(dogBirthCertificatePaymentChargingItem.getName());
		dogBirthCertificatePaymentOrderDetail.setPrice(dogBirthCertificatePaymentChargingItem.getPrice());
		dogBirthCertificatePaymentOrderDetail.setNum("1");
		orderDetailList.add(dogBirthCertificatePaymentOrderDetail);
		if (!"2".equals(po.getReGetType())) {// 类型不为2的都收取芯片费
			PaymentOrderDetail dogChipPayPaymentOrderDetail = new PaymentOrderDetail();
			dogChipPayPaymentOrderDetail.setMemberCode(member.getMemberCode());
			dogChipPayPaymentOrderDetail.setMemberName(member.getName());
			dogChipPayPaymentOrderDetail.setChargingItemId(dogChipPaymentChargingItem.getId());
			dogChipPayPaymentOrderDetail.setChargingItemName(dogChipPaymentChargingItem.getName());
			dogChipPayPaymentOrderDetail.setPrice(dogChipPaymentChargingItem.getPrice());
			dogChipPayPaymentOrderDetail.setNum("1");
			orderDetailList.add(dogChipPayPaymentOrderDetail);
		}
		order.setOrderDetailList(orderDetailList);
		return order;
	}

	/**
	 * @description: 根据起止时间查询繁殖人申请的出生纸数量
	 * @author: chaixueteng
	 * @date: 2018/4/13 14:19
	 */
	public int getKennelBirth(Date startDate, Date endDate, String memberCode) {
		int i = dao.getKennelBirth(startDate, endDate, memberCode);
		return i;
	}

	/**
	 * 根据芯片号查询
	 *
	 * @Author cuihuaiyu
	 * @2018年5月12日下午3:59:39
	 */
	public List<DogBirthCertificate> getByIdentificationFlagList(String identificationFlag) {
		if (StringUtils.isBlank(identificationFlag)) {
			return null;
		}
		return dao.getByIdentificationFlagList(identificationFlag);
	}

	/**
	 * 三码合一新增功能 根据芯片号生成宠爱护照号 宠爱登记卡好
	 * <p>
	 * 护照号：9位，首位为字母N（10月15日做的改动） 宠爱登记卡号：9位
	 * 以芯片号后六位为基准，芯片号、护照号、宠爱登记卡号后六位一致，护照号、宠爱登记卡号后八位一致。
	 *
	 * @return
	 */
	public synchronized Map<String, String> createCabCode(String id, String identificationFlag) {

		Map<String, String> result = new HashMap<String, String>();
		if (StringUtils.isBlank(identificationFlag)) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "芯片号不能为空");
		}
		if (identificationFlag.length() != 15) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "芯片号格式不正确");
		}

		if (StringUtils.isNotBlank(identificationFlag)) {
			DogBirthCertificate dogBirthCertificate = new DogBirthCertificate();
			dogBirthCertificate.setIdentificationFlag(identificationFlag);
			List<DogBirthCertificate> dogBirthCertificateList = dao.findList(dogBirthCertificate);
			// 鉴定表
			DogVideoAppraisal dogVideoAppraisal = new DogVideoAppraisal();
			dogVideoAppraisal.setChipNo(identificationFlag);
			List<DogVideoAppraisal> dogVideoAppraisalList = dogVideoAppraisalDao.findList(dogVideoAppraisal);
			if (dogBirthCertificateList.size() > 0) {
				if (!id.equals(dogBirthCertificateList.get(0).getId())) {
					throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "芯片号" + identificationFlag + "已被其他登记卡使用");
				}
			}
			if (dogVideoAppraisalList.size() > 0) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "芯片号" + identificationFlag + "已被其他视频鉴定使用");
			}
		}
		// 芯片号的后六位
		String last6 = identificationFlag.substring(9, identificationFlag.length());

		// 查询出未修改前数据
		DogBirthCertificate oldDogBirthCertificate = dao.get(id);
		String oldIdentificationFlag = "";
		if (oldDogBirthCertificate != null) {
			oldIdentificationFlag = oldDogBirthCertificate.getIdentificationFlag();
		}
		// 如果是修改操作
		if (StringUtils.isNotBlank(oldIdentificationFlag)
				&& last6.equals(oldIdentificationFlag.substring(9, identificationFlag.length()))) {
			result.put("cabRegisterCode", oldDogBirthCertificate.getCabRegisterCode());
			result.put("cabPassport", oldDogBirthCertificate.getCabPassport());
		} else {

			// 如果是添加的操作

			// 护照号第三位为后六位的校验位，计算规则为：
			// （护照号第四位*1+护照号第五位*3+护照号第六位*5+护照号第七位*2+护照号第八位*4+护照号第九位*6）除以9的余数，详细公式参照excel表的公式。
			int position4 = Integer.parseInt(last6.substring(0, 1));
			int position5 = Integer.parseInt(last6.substring(1, 2));
			int position6 = Integer.parseInt(last6.substring(2, 3));
			int position7 = Integer.parseInt(last6.substring(3, 4));
			int position8 = Integer.parseInt(last6.substring(4, 5));
			int position9 = Integer.parseInt(last6.substring(5, 6));
			int count = position4 * 1 + position5 * 3 + position6 * 5 + position7 * 2 + position8 * 4 + position9 * 6;
			int position3 = count % 9;
			// 护照号第二位（下方标红的位数）为后七位的占用校验位，即：
			// 生成该护照号时，如果后七位数字不重复，第二位为0，否则为依次递增
			for (int i = 0; i < 10; i++) {
				String cabPassport = "N" + i + position3 + last6;
				// 宠爱登记卡号与护照号后八位一样，首位为渠道码
				// CKU新生犬为D
				// CKU纯种犬为A
				// CAAC新生猫为B
				// CAAC以往猫只为M
				// 非CKU犬只为W
				// 非CKU猫只为S
				// 其他动物为O
				String cabRegisterCode = "D" + i + position3 + last6;

				DogBirthCertificate dogBirthCertificate = dao.getByCabPassport(cabPassport);
				if (dogBirthCertificate == null) {
					result.put("cabRegisterCode", cabRegisterCode);
					result.put("cabPassport", cabPassport);
					break;
				}
			}

		}

		return result;

	}

	public synchronized Map<String, String> createCabCodeReGet(String identificationFlag, String pedigreeCertified) {
		Map<String, String> result = new HashMap<>();
		// 芯片号的后六位
		String ticket = Pattern.compile("[^(0-9)]").matcher(identificationFlag).replaceAll("").trim();
		String last6;
		if (ticket.length() >= 6) {
			last6 = ticket.substring(ticket.length() - 6);
		} else {
			last6 = pedigreeCertified.substring(0, pedigreeCertified.length() - 3);
			last6 = last6.substring(last6.length() - 6);
		}
		try {
			Integer.parseInt(last6);
		} catch (NumberFormatException e) {
			throw new ZAException(ZAErrorCode.ZA_ERROR, "请联系工作人员线下申请400-660-7000");
		}
		// 护照号第三位为后六位的校验位，计算规则为：
		// （护照号第四位*1+护照号第五位*3+护照号第六位*5+护照号第七位*2+护照号第八位*4+护照号第九位*6）除以9的余数，详细公式参照excel表的公式。
		int position4 = Integer.parseInt(last6.substring(0, 1));
		int position5 = Integer.parseInt(last6.substring(1, 2));
		int position6 = Integer.parseInt(last6.substring(2, 3));
		int position7 = Integer.parseInt(last6.substring(3, 4));
		int position8 = Integer.parseInt(last6.substring(4, 5));
		int position9 = Integer.parseInt(last6.substring(5, 6));
		int count = position4 * 1 + position5 * 3 + position6 * 5 + position7 * 2 + position8 * 4 + position9 * 6;
		int position3 = count % 9;
		// 护照号第二位（下方标红的位数）为后七位的占用校验位，即：
		// 生成该护照号时，如果后七位数字不重复，第二位为0，否则为依次递增
		for (int i = 0; i < 10; i++) {
			String cabPassport = "J" + i + position3 + last6;// "N" + i + position3 + last6;
			String cabRegisterCode = "D" + i + position3 + last6;

			DogBirthCertificate dogBirthCertificate = dao.getByCabPassport(cabPassport);
			if (dogBirthCertificate == null) {
				result.put("cabRegisterCode", cabRegisterCode);
				result.put("cabPassport", cabPassport);
				break;
			}
		}
		return result;
	}

	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void deltelAll(DogBirthCertificate po) throws ZAException {
		try {
			DogBirthCertificate dogBirthCertificate = get(po.getId());
			String remarks = po.getRemarks();
			if (StringUtils.isBlank(remarks)) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "删除原因不能为空");
			}
			// 修改配种证明
			DogNewborn dogNewborn = dogNewbornDao
					.getByBreedCertifiedCode(dogBirthCertificate.getFmdogBreedCertifiedCode());
			dogNewborn.setBirthday(null);
			dogNewborn.setDogRegisterNum("");// CKU登记数
			dogNewborn.setPuppyBirthNum("");// 出生数（几公几母）
			dogNewborn.setPuppyRegisterNum("");// 登记数（几公几母）
			if (UserUtils.getUser().getId() != null) {
				dogNewborn.preUpdate();
			} else {
				// 定时任务无法获取当前登录用户，需要手动设置
				User updateBy = new User();
				updateBy.setId("1");
				updateBy.setUpdateDate(new Date());
				dogNewborn.setUpdateBy(updateBy);
			}
			dogNewbornDao.update(dogNewborn);
			// 修改出生纸

			dao.updateALLByFmdogBreedCertifiedCode(po.getFmdogBreedCertifiedCode(), remarks);
		} catch (Exception e) {
			throw e;
		}
	}

	public boolean isAllNest(String birthCerRegCode) {
		boolean flag = false;
		DogChip dogChip = dogChipDao.getByBirthCode(birthCerRegCode);
		if (dogChip != null && StringUtils.isNotBlank(dogChip.getIsAll()) && "1".equals(dogChip.getIsAll())) {
			flag = true;
		}
		return flag;
	}

	@Value("${DogBirthCertificateTransferLaunchDate}")
	private String DogBirthCertificateTransferLaunchDate;

	public DogBirthCertificate checkTransfer(JSONObject vo) {
		String[] temps = DogBirthCertificateTransferLaunchDate.split("-");
		Integer y = Integer.valueOf(temps[0]);
		Integer m = Integer.valueOf(temps[1]);
		Integer d = Integer.valueOf(temps[2]);
		Date TRANSFER_LAUNCH_DATE = new Date(y - 1900, m - 1, d + 1, 0, 0);

		// 获取参数
		if (vo.get("birthCerRegCode") == null || StringUtils.isBlank(vo.getString("birthCerRegCode")))
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "身份识别登记卡号为空");
		if (vo.get("identificationFlag") == null || StringUtils.isBlank(vo.getString("identificationFlag")))
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "芯片号为空");

		DogBirthCertificate dogBirthCertificate = dao.getByBirthCerRegCode(vo.getString("birthCerRegCode"));
		if (dogBirthCertificate == null)
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "身份识别登记卡号查不到");
		if (StringUtils.isNotBlank(dogBirthCertificate.getPedigreeCertified()))
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "已有血统证书不可转让");
		if (TRANSFER_LAUNCH_DATE.after(dogBirthCertificate.getPaymentTime()))
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "老数据不可转让");
		if (StringUtils.isBlank(dogBirthCertificate.getIdentificationFlag()))
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "登记卡没有录入芯片");
		if (!vo.getString("identificationFlag").equals(dogBirthCertificate.getIdentificationFlag()))
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "识别卡号与芯片号不匹配");
		// if (dogBirthCertificate.getSnCode() != null &&
		// StringUtils.isNotBlank(dogBirthCertificate.getSnCode())
		// && vo.get("snCode") != null) {
		// if (!dogBirthCertificate.getSnCode().equals(vo.getString("snCode")))
		// throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "识别码不匹配");
		// }
		// 增加可转让条件验证 审核通过，有芯片编号,上线那天之前包含当天生成的数据不能转让
		if (!"1".equals(dogBirthCertificate.getReviewState()))
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "登记卡未审核通过");
		if (UserUtils.getLoginMember().getMemberCode().equals(dogBirthCertificate.getMemberCode()))
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "登记卡已经是本人的");
		// 只能转让一次，繁殖人转新犬主
		DogBirthCertificateTransfer t = new DogBirthCertificateTransfer();
		t.setDelFlag("0");
		t.setDogBirthCertificateId(dogBirthCertificate.getId());
		if (transferService.findList(t).size() > 0)
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "登记卡只能转让一次");
		// 杜高、马犬暂不支持转让，点击提示：该犬种暂不支持登记卡转让功能292 阿根廷杜高犬 15C 马犬
		if ("292".equals(dogBirthCertificate.getDogBreed()) || "15C".equals(dogBirthCertificate.getDogBreed()))
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "该犬种暂不支持登记卡转让功能");
		return dogBirthCertificate;
	}

	@Transactional(readOnly = false)
	public RESTResponse transfer(String json) {
		JSONObject vo = JSONObject.fromObject(json);
		if (vo.get("snCode") == null)
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "识别码必填");

		DogBirthCertificate dogBirthCertificate = checkTransfer(vo);
		if (!vo.getString("snCode").toLowerCase().equals(dogBirthCertificate.getSnCode().toLowerCase()))
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "识别码不匹配");
		if ("1".equals(dogBirthCertificate.getDelFlag())
				|| (vo.get("tempMemberCode") != null && StringUtils.isNotBlank(vo.getString("tempMemberCode"))
						&& !vo.getString("tempMemberCode").equals(dogBirthCertificate.getTempMemberCode())))
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "原犬主明下没有查到登记卡");

		// 1 修改tempMemberCode 2 增加转让流水
		DogBirthCertificateTransfer dogBirthCertificateTransfer = new DogBirthCertificateTransfer();
		dogBirthCertificateTransfer.setTransferorMemberCode(dogBirthCertificate.getMemberCode());// 转出犬主会员号
		dogBirthCertificateTransfer.setTransferorMemberName(dogBirthCertificate.getDogOwenr());
		dogBirthCertificateTransfer.setReceiverMemberCode(UserUtils.getLoginMember().getMemberCode());// 新犬主会员号
		dogBirthCertificateTransfer.setReceiverMemberName(UserUtils.getLoginMember().getName());
		dogBirthCertificateTransfer.setDogBirthCertificateId(dogBirthCertificate.getId());
		transferService.save(dogBirthCertificateTransfer);
		dogBirthCertificate.setMemberCode(dogBirthCertificateTransfer.getReceiverMemberCode());
		dogBirthCertificate.setDogOwenr(dogBirthCertificateTransfer.getReceiverMemberName());
		dogBirthCertificate.preUpdate();
		dao.update(dogBirthCertificate);
		return new RESTResponse("data", dogBirthCertificate.getId());
	}

	public RESTResponse getSecondBreeder(HttpServletRequest request) {
		String secondBreederMemberCode = request.getParameter("secondBreederMemberCode");
		if (StringUtils.isBlank(secondBreederMemberCode)) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "第二繁殖人会员号为空");
		}
		Member member = memberService.getByMemberCode(secondBreederMemberCode);
		if (member == null) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "会员号码有误，请输入正确会员号");
		}
		if (!MemberUtil.isActiveMember(member)) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "第二繁殖人需为有效爱宠银卡及以上会员办理!");
		}
		if (CardTypeEnum.DEFAULT_CARD.code() == UserUtils.getMemberCardType(secondBreederMemberCode)) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "第二繁殖人需为有效爱宠银卡及以上会员办理！");
		}
		Member loginMember = UserUtils.getLoginMember();
		String memberSite = loginMember.getMemberSite();
		if (!((StringUtils.isBlank(member.getMemberSite()) && StringUtils.isBlank(memberSite))
				|| memberSite.equals(member.getMemberSite()))) {
			memberSite = memberSite == null ? "2" : loginMember.getMemberSite();
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED,
					"第二繁殖人需为" + DictUtils.getDictLabel(memberSite, "member_site", "") + "有效银卡及以上会员办理");
		}
		JSONObject jo = new JSONObject();
		jo.put("secondBreederMemberCode", member.getMemberCode());
		jo.put("secondBreeder", member.getName());
		return new RESTResponse("data", jo);
	}
	
	
	public DogBirthCertificate getParentsByBirthCerRegCode(String birthCerRegCode) {
		return dao.getParentsByBirthCerRegCode(birthCerRegCode);
	}
}
