package com.sw.mes.yb.accessory.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.sw.mes.core.enums.EnumValues;
import com.sw.mes.yb.accessory.dao.EquipmentAccessoryDao;
import com.sw.mes.yb.accessory.dto.*;
import com.sw.mes.yb.accessory.entity.*;
import com.sw.mes.yb.accessory.service.*;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.utils.DateUtil;
import com.sw.mes.base.factory.init.entity.Equipment;
import com.sw.mes.base.factory.init.service.EquipmentService;
import com.sw.mes.yb.accessory.validatedData.ValidateOperate;
import com.sw.mes.yb.production.entity.EquipmentExtendState;
import com.sw.mes.yb.production.service.EquipmentExtendStateService;
import org.apache.commons.lang3.StringUtils;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;


/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class EquipmentAccessoryServiceImpl extends BaseServiceImpl<EquipmentAccessory> implements EquipmentAccessoryService {

    @Autowired
    ModelMapper modelMapper;

    EquipmentAccessoryDao dao;

    @Autowired
    public void setDao(EquipmentAccessoryDao dao) {
        super.setBaseDao(dao);
        this.dao = dao;
    }

    @Autowired
    private AccessoryMaterialService accessoryMaterialService;

    @Autowired
    private AccessoryOrderService accessoryOrderService;

    @Autowired
    private AccessoryApplyService accessoryApplyService;

//    @Autowired
//    private StoreAccessoryInputItemService storeItemService;

    @Autowired
    private EquipmentService equipmentService;

    @Autowired
    private AccessoryReturnService accessoryReturnService;

    @Autowired
    private EquipmentExtendStateService equipmentExtendStateService;

    @Override
    public void saveOrUpdate(@Valid AccessoryChangeDto accessoryChangeDto) throws RuntimeException {

        Long equipmentAccessoryId = accessoryChangeDto.getEquipmentAccessoryId();
        if (equipmentAccessoryId == null || equipmentAccessoryId == 0) {
            throw new RuntimeException("设备热场信息为空！");
        }

        EquipmentAccessory equipmentAccessory = get(equipmentAccessoryId);
        if (equipmentAccessory == null) {
            throw new RuntimeException("设备热场信息不存在！");
        }

        Long materialId = accessoryChangeDto.getMaterialId();
        if (materialId == null) {
            throw new RuntimeException("热场信息为空！");
        }

        AccessoryMaterial accessoryMaterial = accessoryMaterialService.get(materialId);
        if (accessoryMaterial == null) {
            throw new RuntimeException("热场信息不存在！");
        }
        Integer locationId = accessoryChangeDto.getLocationId();
        if (locationId == null) {
            throw new RuntimeException("库位信息为空！");
        }

//        StoreAccessoryDetail detail = storeAccessoryDetailService.findByGoodsCodeAndLocationId(accessoryChangeDto.getGoodsCode(), locationId);
//        if (detail == null || detail.getCount().compareTo(new BigDecimal(accessoryChangeDto.getChangeCount())) < 0) {
//            throw new RuntimeException("库存不足,无法完成出库！");
//        }

        if (accessoryChangeDto.getUseTime() == null || accessoryChangeDto.getUseTime() < 0) {
            accessoryChangeDto.setUseTime(0d);
        }
        if (StringUtils.isBlank(accessoryChangeDto.getGoodsCode())) {
            accessoryChangeDto.setGoodsCode(accessoryChangeDto.getAccessoryTypeValue() + DateUtil.formatDate(new Date(), "yyyyMMddHHmmssSSS"));
        }
        if (accessoryChangeDto.getChangeCount() == null || accessoryChangeDto.getChangeCount() == 0) {
            accessoryChangeDto.setChangeCount(1);
        }

        //更换记录
        AccessoryOrder accessoryOrder = new AccessoryOrder();
        accessoryOrder.setCreateDate(accessoryChangeDto.getCreateDate());
        accessoryOrder.setCreateUser(accessoryChangeDto.getCreateUser());
        accessoryOrder.setCreateUserId(equipmentAccessory.getOperateUserId());
        accessoryOrder.setEquipment(equipmentAccessory.getEquipment());
        accessoryOrder.setOrg(equipmentAccessory.getMaterial());
        accessoryOrder.setTarget(accessoryMaterial);
        accessoryOrder.setUseTime(equipmentAccessory.getUseTime());
        if ("异常损耗".equals(accessoryChangeDto.getRemark())) {
            accessoryOrder.setAnomalousCause(accessoryChangeDto.getAnomalousCause());
        }
        accessoryOrder.setRemark(accessoryChangeDto.getRemark());
        accessoryOrder.setOrgFactory(equipmentAccessory.getFactory());
        accessoryOrder.setTargetFactory(accessoryChangeDto.getFactory());
        accessoryOrder.setOrgGoodsCode(equipmentAccessory.getGoodsCode());
        accessoryOrder.setTargetGoodsCode(accessoryChangeDto.getGoodsCode());

        accessoryOrder.setApplyUser(equipmentAccessory.getApplyUser());
        accessoryOrder.setApplyDate(equipmentAccessory.getApplyDate());
        accessoryOrder.setBrokeUser(accessoryChangeDto.getBrokeUser());

        //更换数量
        accessoryOrder.setChangeCount(accessoryChangeDto.getChangeCount());
        accessoryOrder.setLocationId(locationId);
        accessoryOrder.setLocationName(accessoryChangeDto.getLocationName());

        accessoryOrder.setDeviceNo(equipmentAccessory.getDeviceNo());
        accessoryOrderService.saveOrUpdate(accessoryOrder);

        equipmentAccessory.setMaterial(accessoryMaterial);

        equipmentAccessory.setGoodsCode(accessoryChangeDto.getGoodsCode());
        equipmentAccessory.setFactory(accessoryChangeDto.getFactory());
        equipmentAccessory.setOperateDate(accessoryChangeDto.getCreateDate());
        equipmentAccessory.setOperateUser(accessoryChangeDto.getCreateUser());
        equipmentAccessory.setUseLife(accessoryChangeDto.getUseLife());
        equipmentAccessory.setUseTime(accessoryChangeDto.getUseTime());
        equipmentAccessory.setWarning(accessoryChangeDto.getWarning());
        equipmentAccessory.setWarnTime(accessoryChangeDto.getWarnTime());

        if (accessoryChangeDto.getWarning()) {
            Double time = equipmentAccessory.getUseLife() - equipmentAccessory.getWarnTime() - equipmentAccessory.getUseTime();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(equipmentAccessory.getOperateDate());
            if (accessoryMaterial.getUnit() != null && "hour".equals(accessoryMaterial.getUnit().getCode())) {
                calendar.add(Calendar.HOUR_OF_DAY, time.intValue());
            } else {
                calendar.add(Calendar.DATE, time.intValue());
            }
            equipmentAccessory.setWarningDate(calendar.getTime());
        }

        saveOrUpdate(equipmentAccessory);

        AccessoryApply accessoryApply = accessoryApplyService.findByGoodsCodeAndEquipmentIdAndState(accessoryOrder.getOrgGoodsCode(), equipmentAccessory.getEquipment().getId(),
                EnumValues.PickInfoStatus.WAITTING.getKey());
        if (accessoryApply != null) {
            accessoryApply.setState(EnumValues.PickInfoStatus.ENDDING.getKey());
            accessoryApply.setStateDate(new Date());
            accessoryApplyService.saveOrUpdate(accessoryApply);
        }

    }

    @Override
    public void saveOrUpdate(@Valid EquipmentAccessoryDto equipmentAccessoryDto) throws RuntimeException {

        Long equipmentId = equipmentAccessoryDto.getEquipmentId();
        if (equipmentId == null || equipmentId == 0) {
            throw new RuntimeException("设备信息为空！");
        }

        Equipment equipment = equipmentService.get(equipmentId);
        if (equipment == null) {
            throw new RuntimeException("设备编号不存在！");
        }

        Long materialId = equipmentAccessoryDto.getMaterialId();
        if (materialId == null) {
            throw new RuntimeException("热场信息为空！");
        }

        Integer locationId = equipmentAccessoryDto.getLocationId();
        if (locationId == null) {
            throw new RuntimeException("库位信息为空！");
        }

        AccessoryMaterial accessoryMaterial = accessoryMaterialService.get(materialId);
        if (accessoryMaterial == null) {
            throw new RuntimeException("热场信息不存在！");
        }

        EquipmentAccessory org = getByEquipment_idAndMaterial_id(equipmentId, materialId);
        if (org != null && !org.getId().equals(equipmentAccessoryDto.getId())) {
            throw new RuntimeException("指定设备存在热场[" + accessoryMaterial.getName() + "]使用信息");
        }

//        StoreAccessoryDetail detail = storeAccessoryDetailService.findByGoodsCodeAndLocationId(equipmentAccessoryDto.getGoodsCode(), locationId);
//        if (detail == null || detail.getCount().compareTo(new BigDecimal(1)) <= 0) {
//            throw new RuntimeException("库存不足,无法完成出库！");
//        }

        EquipmentAccessory equipmentAccessory = modelMapper.map(equipmentAccessoryDto, EquipmentAccessory.class);
        equipmentAccessory.setEquipment(equipment);
        equipmentAccessory.setDeviceNo(equipment.getCode());
        equipmentAccessory.setMaterial(accessoryMaterial);
        if (equipmentAccessory.getOperateDate() == null) {
            equipmentAccessory.setOperateDate(new Date());
        }
        equipmentAccessory.setUnitName(accessoryMaterial.getUnit().getName());
        equipmentAccessory.setOperateUser(BaseContextHandler.getUsername());
        equipmentAccessory.setOperateUserId(BaseContextHandler.getUserID());

        saveOrUpdate(equipmentAccessory);

//        try {
//            storeOutput(equipmentAccessory, accessoryMaterial, detail);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }

    }

    @Override
    public EquipmentAccessory getByEquipment_idAndMaterial_id(Long equipmentId, Long materialId) {
        List<EquipmentAccessory> list = dao.findByEquipment_idAndMaterial_id(equipmentId, materialId);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public EquipmentAccessory getChangeInfo(EquipAccessChangeDto dto) {
        EquipmentAccessory entity = get(dto.getId());
        if (entity != null) {
            Equipment equipment = equipmentService.findByCode(dto.getDeviceNo());
            if (equipment != null) {
                EquipmentAccessory target = getByEquipment_idAndMaterial_id(equipment.getId(), entity.getMaterial().getId());
                if (target != null) {
                    return target;
                }
            }
        }
        return null;
    }

    @Override
    public void batchChange(EquipAccessBatchChangeDto dto) {
        Equipment equipment = equipmentService.findByCode(dto.getDeviceNo());
        Equipment equipment1 = equipmentService.findByCode(dto.getDeviceNo1()); //目标设备
        if (equipment == null || equipment1 == null){
            throw new RuntimeException("当前设备信息有误");
        }
        String materialIds = dto.getMaterialIds();
        String[] mids = materialIds.split(",");
        for (String mid : mids) {
            AccessoryMaterial accessoryMaterial = accessoryMaterialService.get(Long.valueOf(mid));
            EquipmentAccessory accessory1 = getByEquipment_idAndMaterial_id(equipment1.getId(), Long.valueOf(mid)); //目标设备监控
            if(accessory1 == null){
                throw new RuntimeException("目标设备"+equipment1.getCode()+"不存在料号:"+accessoryMaterial.getCodes()+" 名称:"+accessoryMaterial.getName());
            }
            if (accessory1.getNum() == 0){
                throw new RuntimeException("目标设备"+equipment1.getCode()+"与料号"+accessoryMaterial.getCodes()+" 名称:"+accessoryMaterial.getName()+"已解绑");
            }
            EquipmentAccessory accessory = getByEquipment_idAndMaterial_id(equipment.getId(), Long.valueOf(mid));
            if(accessory == null){
                throw new RuntimeException("设备"+equipment.getCode()+"不存在料号:"+accessoryMaterial.getCodes()+" 名称:"+accessoryMaterial.getName());
            }
            if (accessory.getNum() == 0){
                throw new RuntimeException("设备"+equipment.getCode()+"与料号"+accessoryMaterial.getCodes()+" 名称:"+accessoryMaterial.getName()+"已解绑");
            }
//            validateOperate.validateInOrOut(accessory1);
//            validateOperate.validateInOrOut(accessory);
            if(accessory1.getButtonStatus() == 0){
                throw new RuntimeException("目标设备"+equipment1.getCode()+"与料号"+accessoryMaterial.getCodes()+"绑定的监控正在退库要料中，无法变动");
            }

            if(accessory.getButtonStatus() == 0){
                throw new RuntimeException("设备"+equipment.getCode()+"与料号"+accessoryMaterial.getCodes()+"绑定的监控正在退库要料中，无法变动");
            }
            EquipmentAccessoryListByPageDto detail = getDetail(accessory.getId());
            EquipmentAccessoryListByPageDto detail1 = getDetail(accessory1.getId());

            AccessoryOrder order = new AccessoryOrder();
            order.setCreateDate(new Date());
            order.setCreateUser(BaseContextHandler.getUsername());
            order.setCreateUserId(BaseContextHandler.getUserID());
            EquipmentExtendState equipmentExtendState = equipmentExtendStateService.getByCode(accessory.getEquipment().getCode());
            if (equipmentExtendState != null){
                order.setUserClassNo(equipmentExtendState.getClassNo());
                order.setUserTeamGroup(equipmentExtendState.getTeamGroup());
            }
            order.setEquipment(accessory.getEquipment());
            order.setOrg(accessory.getMaterial());
            order.setTarget(accessory1.getMaterial());
            order.setUseTime(detail == null ? null : detail.getUseTime());
            order.setTargetUseTime(detail1 == null ? null : detail1.getUseTime());

//            order.setOrgAttritionRate(detail == null ? null : detail.getAttritionRate());

            order.setRemark("对调");
            order.setOrgFactory(accessory.getFactory());
            order.setTargetFactory(accessory1.getFactory());
            order.setOrgGoodsCode(accessory.getGoodsCode());
            order.setTargetGoodsCode(accessory1.getGoodsCode());
            order.setOrgBatchNo(accessory.getBatchNo());
            order.setTargetBatchNo(accessory1.getBatchNo());

            order.setApplyUser("");
            order.setApplyDate(null);

            //更换数量
            order.setChangeCount(1);
            order.setDeviceNo(accessory.getDeviceNo());

            order.setOrgEngraving(accessory.getEngraving());
            order.setTargetEngraving(accessory1.getEngraving());
            order.setOrgCarbonFelt(accessory.getCarbonFelt());
            order.setTargetCarbonFelt(accessory1.getCarbonFelt());
            accessoryOrderService.saveOrUpdate(order);

            AccessoryOrder record = new AccessoryOrder();
            record.setCreateDate(new Date());
            record.setCreateUser(BaseContextHandler.getUsername());
            record.setCreateUserId(BaseContextHandler.getUserID());
            EquipmentExtendState equipmentExtendState1 = equipmentExtendStateService.getByCode(accessory1.getEquipment().getCode());
            if (equipmentExtendState1 != null){
                record.setUserClassNo(equipmentExtendState1.getClassNo());
                record.setUserTeamGroup(equipmentExtendState1.getTeamGroup());
            }
            record.setEquipment(accessory1.getEquipment());
            record.setOrg(accessory1.getMaterial());
            record.setTarget(accessory.getMaterial());
            record.setUseTime(detail1 == null ? null : detail1.getUseTime());
            record.setTargetUseTime(detail == null ? null : detail.getUseTime());

//            record.setOrgAttritionRate(detail1 == null ? null : detail1.getAttritionRate());

            record.setRemark("对调");
            record.setOrgFactory(accessory1.getFactory());
            record.setTargetFactory(accessory.getFactory());
            record.setOrgGoodsCode(accessory1.getGoodsCode());
            record.setTargetGoodsCode(accessory.getGoodsCode());
            record.setOrgBatchNo(accessory1.getBatchNo());
            record.setTargetBatchNo(accessory.getBatchNo());

            record.setApplyUser("");
            record.setApplyDate(null);

            //更换数量
            record.setChangeCount(1);
//        record.setLocationId();
//        record.setLocationName();

            record.setDeviceNo(accessory1.getDeviceNo());

            record.setOrgEngraving(accessory1.getEngraving());
            record.setTargetEngraving(accessory.getEngraving());
            record.setOrgCarbonFelt(accessory1.getCarbonFelt());
            record.setTargetCarbonFelt(accessory.getCarbonFelt());
            accessoryOrderService.saveOrUpdate(record);

            //虽说对调的是辅料，直接对调设备也是一样的效果
            accessory.setEquipment(equipment1);
            accessory.setDeviceNo(equipment1.getCode());
            accessory.setOperateDate(new Date());
            accessory.setUsedTime(detail == null ? null : detail.getUsedTime());

            accessory1.setEquipment(equipment);
            accessory1.setDeviceNo(equipment.getCode());
            accessory1.setOperateDate(new Date());
            accessory1.setUsedTime(detail1 == null ? null : detail1.getUsedTime());

            // 更新初始
            saveOrUpdate(accessory);

            // 更新目标
            saveOrUpdate(accessory1);
        }
    }

    @Override
    public EquipmentAccessory getUseTimeByCode(String code) {
        return dao.getUseTimeByCode(code);
    }

    @Override
    public List<EquipmentAccessory> findByGoodCodes(String uniqueCode) {
        return dao.findByGoodCodes(uniqueCode);
    }

    @Override
    public List<EquipmentAccessory> findByDeviceCode(String deviceNo) {
        return dao.findByDeviceCode(deviceNo);
    }

    @Override
    public Page<Map<String, Object>> newListByPage(EquipmentAccessoryParmDto dto, Pageable pageable) {
        return dao.newListByPage(dto.getArea(),dto.getSeries(),dto.getDeviceNo(),dto.getMcode(),dto.getGoodsCode()
        ,dto.getUseTime(),dto.getFactory(),dto.getStartOperateDate(),dto.getEndOperateDate(), dto.getNum(), dto.getBatchNo(), pageable);
    }

    @Override
    public BigDecimal getUseTime(Long equipmentAccessoryId) {
        BigDecimal useTime = dao.getUseTime(equipmentAccessoryId);
        if (useTime == null){
            return new BigDecimal("0");
        }
        return useTime;
    }

    /**
     * 查询绑定的设备监控
     * @param uniqueCode
     * @return
     */
    @Override
    public List<EquipmentAccessory> findByGoodCodesWithBind(String uniqueCode) {
        return dao.findByGoodCodesWithBind(uniqueCode);
    }

    @Override
    public void collectForExportAndSaveWithAsync(EquipAccessCreateDto dto, List<EquipmentAccessory> copyOnWriteArrayList) {
        if (dto.getUseTime() == null) {
            dto.setUseTime(0);
        }

        Equipment equipment = equipmentService.findByCode(dto.getDeviceNo());
        if (equipment == null) {
            throw new RuntimeException("设备信息不存在！");
        }

        Integer count = dao.countByGoodsCodeAndBindAndDeleted(dto.getGoodsCode(), 1, 0);
        if (count != null && count > 0) {
            throw new RuntimeException("热场条码已使用！");
        }

//        AccessoryMaterialOut accessoryMaterialOut = accessoryMaterialOutService.findByUniqueCode(dto.getGoodsCode());
//        if (accessoryMaterialOut == null){
//            throw new RuntimeException("热场条码不存在！请让辅料线边仓发料！");
//        }
//        EquipmentAccessory accessory = getByEquipment_idAndMaterial_id(equipment.getId(), Long.valueOf(dto.getMaterialId()));
//        if (accessory != null){
//            throw new RuntimeException("该设备已与该物料模型绑定过了");
//        }

        AccessoryMaterial material = accessoryMaterialService.get(dto.getMaterialId().longValue());
        if (material == null){
            throw new RuntimeException("辅料模型不存在");
        }

        EquipmentAccessory equipmentAccessory = new EquipmentAccessory();
        equipmentAccessory.setDeviceNo(dto.getDeviceNo());
        equipmentAccessory.setEquipment(equipment);
        equipmentAccessory.setGoodsCode(dto.getGoodsCode());
        equipmentAccessory.setFactory(material.getSupplier());
        equipmentAccessory.setMaterial(material);
        equipmentAccessory.setOperateDate(StringUtils.isBlank(dto.getUpdateDate()) ? new Date() : parseDate1(dto.getUpdateDate()));
        equipmentAccessory.setOperateUser(BaseContextHandler.getUsername());
        equipmentAccessory.setOperateUserId(BaseContextHandler.getUserID());
        equipmentAccessory.setUnitName(material.getUnit().getName());
        equipmentAccessory.setUseLife(material.getUseLife());
        equipmentAccessory.setUseTime(dto.getUseTime().doubleValue());
        equipmentAccessory.setWarning(material.getWarning());
        equipmentAccessory.setWarnTime(material.getWarnTime());
        equipmentAccessory.setAccessoryMaterialOut(null);
        equipmentAccessory.setBind(1);
        equipmentAccessory.setNum(dto.getNum());
        equipmentAccessory.setButtonStatus(1);
        equipmentAccessory.setApplyButton(0);
        equipmentAccessory.setBatchNo(dto.getBatchNo());
        equipmentAccessory.setAccessoryType(dto.getAccessoryType());
        equipmentAccessory.setCarbonFelt(dto.getCarbonFelt());
        equipmentAccessory.setEngraving(dto.getEngraving());

        if (equipmentAccessory.getWarning()) { //TODO 可能需要改判定方式
            if (equipmentAccessory.getMaterial().getUseLife() == null || equipmentAccessory.getMaterial().getWarnTime() == null) {
                throw new RuntimeException("辅料编号："+material.getCodes()+"--额定寿命或预警寿命为空");
            }
            //
            Integer time = equipmentAccessory.getMaterial().getUseLife().intValue() - equipmentAccessory.getUseTime().intValue() - equipmentAccessory.getMaterial().getWarnTime().intValue();
            Calendar date = Calendar.getInstance();
            date.setTime(equipmentAccessory.getOperateDate());
            date.add(Calendar.HOUR_OF_DAY, time);
            equipmentAccessory.setWarningDate(date.getTime());
        } else {
            equipmentAccessory.setWarningDate(null);
        }

        equipmentAccessory.setApplyDate(null);
        equipmentAccessory.setApplyUser("");
        copyOnWriteArrayList.add(equipmentAccessory);
//        saveOrUpdate(equipmentAccessory);
    }

    private Date parseDate1(String updateDate) {

        LocalDate parse = null;
        try {
            parse = LocalDate.parse(updateDate, DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("时间格式有误，建议：年/月/日");
        }
        Date from = Date.from(parse.atTime(LocalTime.MIDNIGHT).atZone(ZoneId.systemDefault()).toInstant());
        return from;
    }

    @Override
    public EquipmentAccessoryListByPageDto getDetail(Long id) {
        Map<String, Object> detail = dao.getDetail(id);
        if (detail != null) {
            return JSON.parseObject(JSON.toJSONString(detail), new TypeReference<EquipmentAccessoryListByPageDto>() {
            });
        }
        return null;
    }

    @Override
    public Integer countNewListByPage(EquipmentAccessoryParmDto dto) {
        return dao.countNewListByPage(dto.getArea(),dto.getSeries(),dto.getDeviceNo(),dto.getMcode(),dto.getGoodsCode()
                ,dto.getUseTime(),dto.getFactory(),dto.getStartOperateDate(),dto.getEndOperateDate(),dto.getNum(), dto.getBatchNo());
    }

    @Override
    public void newChange(List<EquipAccessNewChangeDto> dtos) {
        for (EquipAccessNewChangeDto dto : dtos) {
            // 初始监控
            EquipmentAccessory entity = get(dto.getId());
            if (entity == null) {
                throw new RuntimeException("当前热场监控信息不存在！");
            }
            if (entity.getNum() == 0){
                throw new RuntimeException("设备"+ Optional.of(entity).map(EquipmentAccessory::getEquipment).map(Equipment::getCode).orElse("")
                        +"料号"+Optional.of(entity).map(EquipmentAccessory::getMaterial).map(AccessoryMaterial::getCodes).orElse("")+"存在没有绑定辅料的监控！");
            }

            if(entity.getButtonStatus() == 0){
                throw new RuntimeException("设备"+ Optional.of(entity).map(EquipmentAccessory::getEquipment).map(Equipment::getCode).orElse("")
                        +"料号"+Optional.of(entity).map(EquipmentAccessory::getMaterial).map(AccessoryMaterial::getCodes).orElse("") +"存在正在退库要料的监控，无法变动");
            }

//        validateOperate.validateInOrOut(entity);


            EquipmentAccessory target = get(dto.getTargetId());

            if (target == null) {
                throw new RuntimeException("对调目标设备热场监控信息不存在！");
            }

            Equipment equipment = target.getEquipment();
            if (equipment == null) {
                throw new RuntimeException("目标设备信息不存在！");
            }

            if (equipment.getId().equals(entity.getEquipment().getId())) {
                throw new RuntimeException("设备信息相同！");
            }

            if (target.getNum() == 0){
                throw new RuntimeException("设备"+ Optional.of(target).map(EquipmentAccessory::getEquipment).map(Equipment::getCode).orElse("")
                        +"料号"+Optional.of(target).map(EquipmentAccessory::getMaterial).map(AccessoryMaterial::getCodes).orElse("") +"存在没有绑定辅料的监控！");
            }

            if(target.getButtonStatus() == 0){
                throw new RuntimeException("设备"+ Optional.of(target).map(EquipmentAccessory::getEquipment).map(Equipment::getCode).orElse("")
                        +"料号"+Optional.of(target).map(EquipmentAccessory::getMaterial).map(AccessoryMaterial::getCodes).orElse("") +"存在正在退库要料的监控，无法变动");
            }
            EquipmentAccessoryListByPageDto detail = getDetail(entity.getId());
            EquipmentAccessoryListByPageDto detail1 = getDetail(target.getId());

            Equipment orgEquip = entity.getEquipment();

            AccessoryOrder order = new AccessoryOrder();
            order.setCreateDate(new Date());
            order.setCreateUser(BaseContextHandler.getUsername());
            order.setCreateUserId(BaseContextHandler.getUserID());
            EquipmentExtendState equipmentExtendState = equipmentExtendStateService.getByCode(entity.getEquipment().getCode());
            if (equipmentExtendState != null){
                order.setUserClassNo(equipmentExtendState.getClassNo());
                order.setUserTeamGroup(equipmentExtendState.getTeamGroup());
            }
            order.setEquipment(entity.getEquipment());
            order.setOrg(entity.getMaterial());
            order.setTarget(target.getMaterial());
            order.setUseTime(detail == null ? null : detail.getUseTime());
            order.setTargetUseTime(detail1 == null ? null : detail1.getUseTime());
            order.setOrgAttritionRate(detail == null ? null : detail.getAttritionRate());

            order.setRemark("对调");
            order.setOrgFactory(entity.getFactory());
            order.setTargetFactory(target.getFactory());
            order.setOrgGoodsCode(entity.getGoodsCode());
            order.setTargetGoodsCode(target.getGoodsCode());

            order.setApplyUser("");
            order.setApplyDate(null);

            order.setOrgBatchNo(entity.getBatchNo());
            order.setTargetBatchNo(target.getBatchNo());

            order.setOrgEngraving(entity.getEngraving());
            order.setTargetEngraving(target.getEngraving());
            order.setOrgCarbonFelt(entity.getCarbonFelt());
            order.setTargetCarbonFelt(target.getCarbonFelt());

            //更换数量
            order.setChangeCount(1);
            order.setDeviceNo(entity.getDeviceNo());
            accessoryOrderService.saveOrUpdate(order);

            AccessoryOrder record = new AccessoryOrder();
            record.setCreateDate(new Date());
            record.setCreateUser(BaseContextHandler.getUsername());
            record.setCreateUserId(BaseContextHandler.getUserID());
            EquipmentExtendState equipmentExtendState1 = equipmentExtendStateService.getByCode(target.getEquipment().getCode());
            if (equipmentExtendState1 != null){
                record.setUserClassNo(equipmentExtendState1.getClassNo());
                record.setUserTeamGroup(equipmentExtendState1.getTeamGroup());
            }
            record.setEquipment(target.getEquipment());
            record.setOrg(target.getMaterial());
            record.setTarget(entity.getMaterial());
            record.setUseTime(detail1 == null ? null : detail1.getUseTime());
            record.setTargetUseTime(detail == null ? null : detail.getUseTime());

            record.setOrgAttritionRate(detail1 == null ? null : detail1.getAttritionRate());

            record.setRemark("对调");
            record.setOrgFactory(target.getFactory());
            record.setTargetFactory(entity.getFactory());
            record.setOrgGoodsCode(target.getGoodsCode());
            record.setTargetGoodsCode(entity.getGoodsCode());

            record.setOrgBatchNo(target.getBatchNo());
            record.setTargetBatchNo(entity.getBatchNo());

            record.setOrgEngraving(target.getEngraving());
            record.setTargetEngraving(entity.getEngraving());
            record.setOrgCarbonFelt(target.getCarbonFelt());
            record.setTargetCarbonFelt(entity.getCarbonFelt());

            record.setApplyUser("");
            record.setApplyDate(null);

            //更换数量
            record.setChangeCount(1);
//        record.setLocationId();
//        record.setLocationName();

            record.setDeviceNo(target.getDeviceNo());
            accessoryOrderService.saveOrUpdate(record);

            entity.setEquipment(equipment);
            entity.setDeviceNo(equipment.getCode());
            entity.setOperateDate(new Date());

            target.setEquipment(orgEquip);
            target.setDeviceNo(orgEquip.getCode());
            target.setOperateDate(new Date());

            // 更新初始
            saveOrUpdate(entity);


            // 更新目标
            saveOrUpdate(target);
        }
    }

    @Override
    public List<EquipmentAccessory> getByEquipment_id(Long equipmentId) {
        return dao.getByEquipment_id(equipmentId);
    }

    @Override
    public void updateUseLife(Long materialId, Double useLife) {
        dao.updateUseLife(materialId, useLife);
    }

    @Override
    public EquipmentAccessory saveOrUpdate(EquipAccessCreateDto dto) throws RuntimeException {
        if (dto.getUseTime() == null) {
            dto.setUseTime(0);
        }

        Equipment equipment = equipmentService.findByCode(dto.getDeviceNo());
        if (equipment == null) {
            throw new RuntimeException("设备信息不存在！");
        }

        Integer count = dao.countByGoodsCodeAndBindAndDeleted(dto.getGoodsCode(), 1, 0);
        if (count != null && count > 0) {
            throw new RuntimeException("唯一码已使用！");
        }

//        AccessoryMaterialOut accessoryMaterialOut = accessoryMaterialOutService.findByUniqueCode(dto.getGoodsCode());
//        if (accessoryMaterialOut == null){
//            throw new RuntimeException("热场条码不存在！请让辅料线边仓发料！");
//        }
//        EquipmentAccessory accessory = getByEquipment_idAndMaterial_id(equipment.getId(), Long.valueOf(dto.getMaterialId()));
//        if (accessory != null){
//            throw new RuntimeException("该设备已与该物料模型绑定过了");
//        }

        AccessoryMaterial material = accessoryMaterialService.get(dto.getMaterialId().longValue());
        if (material == null){
            throw new RuntimeException("辅料模型不存在");
        }

        EquipmentAccessory equipmentAccessory = new EquipmentAccessory();
        equipmentAccessory.setDeviceNo(dto.getDeviceNo());
        equipmentAccessory.setEquipment(equipment);
        equipmentAccessory.setGoodsCode(dto.getGoodsCode());
        equipmentAccessory.setFactory(material.getSupplier());
        equipmentAccessory.setMaterial(material);
        equipmentAccessory.setOperateDate(new Date());
        equipmentAccessory.setOperateUser(BaseContextHandler.getUsername());
        equipmentAccessory.setOperateUserId(BaseContextHandler.getUserID());
        equipmentAccessory.setUnitName(material.getUnit().getName());
        equipmentAccessory.setUseLife(material.getUseLife());
        equipmentAccessory.setUseTime(dto.getUseTime().doubleValue());
        equipmentAccessory.setUsedTime(0d);
        equipmentAccessory.setWarning(material.getWarning());
        equipmentAccessory.setWarnTime(material.getWarnTime());
        equipmentAccessory.setAccessoryMaterialOut(null);
        equipmentAccessory.setBind(1);
        equipmentAccessory.setNum(dto.getNum());
        equipmentAccessory.setButtonStatus(1);
        equipmentAccessory.setApplyButton(0);
        equipmentAccessory.setBatchNo(dto.getBatchNo());
        equipmentAccessory.setEngraving(dto.getEngraving());
        equipmentAccessory.setCarbonFelt(dto.getCarbonFelt());
        equipmentAccessory.setAccessoryType(dto.getAccessoryType());
        equipmentAccessory.setRemark(dto.getRemark());

        if (equipmentAccessory.getWarning()) { //TODO 可能需要改判定方式
            if (equipmentAccessory.getMaterial().getUseLife() == null || equipmentAccessory.getMaterial().getWarnTime() == null) {
                throw new RuntimeException("辅料编号："+equipmentAccessory.getMaterial().getCodes()+"--额定寿命或预警寿命为空");
            }
            Integer time = equipmentAccessory.getMaterial().getUseLife().intValue() - equipmentAccessory.getUseTime().intValue() - equipmentAccessory.getMaterial().getWarnTime().intValue();
            Calendar date = Calendar.getInstance();
            date.setTime(equipmentAccessory.getOperateDate());
            date.add(Calendar.HOUR_OF_DAY, time);
            equipmentAccessory.setWarningDate(date.getTime());
        } else {
            equipmentAccessory.setWarningDate(null);
        }

        equipmentAccessory.setApplyDate(null);
        equipmentAccessory.setApplyUser("");

        saveOrUpdate(equipmentAccessory);
        return equipmentAccessory;
//        accessoryMaterialOutService.saveOrUpdate(accessoryMaterialOut);
    }


    @Override
    public void update(EquipAccessUpdateDto dto) throws RuntimeException {

        String goodsCode = dto.getGoodsCode();
        EquipmentAccessory entity = get(dto.getId());
        if (entity == null) {
            throw new RuntimeException("热场监控信息不存在！");
        }
        if(entity.getNum() == 0){
            throw new RuntimeException("当前监控已解绑！");
        }

        Integer count = dao.countByGoodsCodeAndBindAndDeleted(dto.getGoodsCode(), 1, 0);
        if (count != null && count > 0) {
            throw new RuntimeException("唯一码已使用！");
        }

//        AccessoryMaterialOut accessoryMaterialOutNew = accessoryMaterialOutService.findByUniqueCode(dto.getGoodsCode());
//        if (accessoryMaterialOutNew == null){
//            throw new RuntimeException("热场条码不存在！请让辅料线边仓发料！");
//        }

        if(entity.getButtonStatus() == 0){
            throw new RuntimeException("正在退库要料中，无法变动");
        }
//        validateOperate.validateInOrOut(entity);

        AccessoryMaterial accessoryMaterial = entity.getMaterial();  //要目标模型

        //更换记录
        AccessoryOrder accessoryOrder = new AccessoryOrder();
        accessoryOrder.setCreateDate(new Date());
        accessoryOrder.setCreateUser(BaseContextHandler.getUsername());
        accessoryOrder.setCreateUserId(BaseContextHandler.getUserID());
        EquipmentExtendState equipmentExtendState = equipmentExtendStateService.getByCode(entity.getEquipment().getCode());
        if (equipmentExtendState != null){
            accessoryOrder.setUserClassNo(equipmentExtendState.getClassNo());
            accessoryOrder.setUserTeamGroup(equipmentExtendState.getTeamGroup());
        }
        accessoryOrder.setEquipment(entity.getEquipment());
        accessoryOrder.setOrg(entity.getMaterial());
        accessoryOrder.setTarget(accessoryMaterial); //要目标模型
        accessoryOrder.setRemark(dto.getReason());
        accessoryOrder.setOrgFactory(entity.getFactory());
        accessoryOrder.setTargetFactory(accessoryMaterial.getSupplier());  //要目标模型
        accessoryOrder.setOrgGoodsCode(entity.getGoodsCode());
        accessoryOrder.setTargetGoodsCode(goodsCode);  //要目标模型

        EquipmentAccessoryListByPageDto detail = getDetail(entity.getId());
//        accessoryOrder.setOrgAttritionRate(detail == null ? null : detail.getAttritionRate());

        accessoryOrder.setUseTime(detail == null ? null : detail.getUseTime());
        accessoryOrder.setTargetUseTime(dto.getUseTime());

        accessoryOrder.setApplyUser(entity.getApplyUser());
        accessoryOrder.setApplyDate(entity.getApplyDate());

        //更换数量
        accessoryOrder.setChangeCount(dto.getCount());
//        accessoryOrder.setLocationId(item.getStoreLocation().getId());
//        accessoryOrder.setLocationName(item.getStoreLocation().getName());

        accessoryOrder.setDeviceNo(entity.getDeviceNo());
        accessoryOrder.setOrgBatchNo(entity.getBatchNo());
        accessoryOrder.setTargetBatchNo(dto.getBatchNo());

        accessoryOrder.setOrgEngraving(entity.getEngraving());
        accessoryOrder.setTargetEngraving(dto.getEngraving());
        accessoryOrder.setOrgCarbonFelt(entity.getCarbonFelt());
        accessoryOrder.setTargetCarbonFelt(dto.getCarbonFelt());
        accessoryOrderService.saveOrUpdate(accessoryOrder);

        // 更新辅料监控
        entity.setGoodsCode(goodsCode);
        entity.setFactory(accessoryMaterial.getSupplier());  //要目标模型
        entity.setOperateUserId(BaseContextHandler.getUserID());
        entity.setOperateDate(new Date());
        entity.setMaterial(accessoryMaterial);  //要目标模型
        entity.setUnitName(accessoryMaterial.getUnit().getName());  //要目标模型
        entity.setUseLife(accessoryMaterial.getUseLife());  //要目标模型
        entity.setUseTime(dto.getUseTime());
        entity.setUsedTime(0d);
        entity.setAccessoryMaterialOut(null);
        entity.setWarning(accessoryMaterial.getWarning());  //要目标模型
        entity.setWarnTime(accessoryMaterial.getWarnTime());  //要目标模型
        entity.setNum(dto.getCount());
        entity.setBatchNo(dto.getBatchNo());
        entity.setEngraving(dto.getEngraving());
        entity.setCarbonFelt(dto.getCarbonFelt());
        entity.setAccessoryType(dto.getAccessoryType());
        entity.setRemark(dto.getRemark());
        if (entity.getWarning()) { //TODO 可能会改判定方式
            if (entity.getMaterial().getUseLife() == null || entity.getMaterial().getWarnTime() == null) {
                throw new RuntimeException("辅料编号："+entity.getMaterial().getCodes()+"--额定寿命或预警寿命为空");
            }
            Integer time = entity.getMaterial().getUseLife().intValue() - entity.getUseTime().intValue() - entity.getMaterial().getWarnTime().intValue();
            Calendar date = Calendar.getInstance();
            date.setTime(entity.getOperateDate());
            date.add(Calendar.HOUR_OF_DAY, time);
            entity.setWarningDate(date.getTime());
        } else {
            entity.setWarningDate(null);
        }
        entity.setApplyDate(null);
        entity.setApplyUser("");

        saveOrUpdate(entity);

//        AccessoryApply accessoryApply = accessoryApplyService.findByGoodsCodeAndState(accessoryOrder.getOrgGoodsCode(), EnumValues.PickInfoStatus.WAITTING.getKey());
//        if (accessoryApply != null) {
//            accessoryApply.setState(EnumValues.PickInfoStatus.ENDDING.getKey());
//            accessoryApply.setStateDate(new Date());
//            accessoryApplyService.saveOrUpdate(accessoryApply);
//        }
    }

    @Override
    public void change(EquipAccessChangeDto dto) throws RuntimeException {

        // 初始监控
        EquipmentAccessory entity = get(dto.getId());
        if (entity == null) {
            throw new RuntimeException("热场监控信息不存在！");
        }
        if (entity.getNum() == 0){
            throw new RuntimeException("当前设备没有绑定的辅料！");
        }

        Equipment equipment = equipmentService.findByCode(dto.getDeviceNo());
        if (equipment == null) {
            throw new RuntimeException("目标设备信息不存在！");
        }

        if(entity.getButtonStatus() == 0){
            throw new RuntimeException("对调设备正在退库要料中，无法变动");
        }

//        validateOperate.validateInOrOut(entity);

        if (equipment.getId().equals(entity.getEquipment().getId())) {
            throw new RuntimeException("设备信息相同！");
        }

        EquipmentAccessory target = getByEquipment_idAndMaterial_id(equipment.getId(), entity.getMaterial().getId());
        if (target == null) {
            throw new RuntimeException("对调目标设备热场监控信息不匹配(需相同辅料对调)！");
        }
        if (target.getNum() == 0){
            throw new RuntimeException(equipment.getCode()+"已与对调辅料解绑！");
        }

        if(target.getButtonStatus() == 0){
            throw new RuntimeException("目标对调设备正在退库要料中，无法变动");
        }
        EquipmentAccessoryListByPageDto detail = getDetail(entity.getId());
        EquipmentAccessoryListByPageDto detail1 = getDetail(target.getId());

        Equipment orgEquip = entity.getEquipment();

        AccessoryOrder order = new AccessoryOrder();
        order.setCreateDate(new Date());
        order.setCreateUser(BaseContextHandler.getUsername());
        order.setCreateUserId(BaseContextHandler.getUserID());
        EquipmentExtendState equipmentExtendState = equipmentExtendStateService.getByCode(entity.getEquipment().getCode());
        if (equipmentExtendState != null){
            order.setUserClassNo(equipmentExtendState.getClassNo());
            order.setUserTeamGroup(equipmentExtendState.getTeamGroup());
        }
        order.setEquipment(entity.getEquipment());
        order.setOrg(entity.getMaterial());
        order.setTarget(target.getMaterial());
        order.setUseTime(detail == null ? null : detail.getUseTime());
        order.setTargetUseTime(detail1 == null ? null : detail1.getUseTime());
//        order.setOrgAttritionRate(detail == null ? null : detail.getAttritionRate());

        order.setRemark("对调");
        order.setOrgFactory(entity.getFactory());
        order.setTargetFactory(target.getFactory());
        order.setOrgGoodsCode(entity.getGoodsCode());
        order.setTargetGoodsCode(target.getGoodsCode());
        order.setOrgBatchNo(entity.getBatchNo());
        order.setTargetBatchNo(target.getBatchNo());

        order.setApplyUser("");
        order.setApplyDate(null);

        //更换数量
        order.setChangeCount(1);
        order.setDeviceNo(entity.getDeviceNo());

        order.setOrgEngraving(entity.getEngraving());
        order.setTargetEngraving(target.getEngraving());
        order.setOrgCarbonFelt(entity.getCarbonFelt());
        order.setTargetCarbonFelt(target.getCarbonFelt());

        accessoryOrderService.saveOrUpdate(order);

        AccessoryOrder record = new AccessoryOrder();
        record.setCreateDate(new Date());
        record.setCreateUser(BaseContextHandler.getUsername());
        record.setCreateUserId(BaseContextHandler.getUserID());
        EquipmentExtendState equipmentExtendState1 = equipmentExtendStateService.getByCode(target.getEquipment().getCode());
        if (equipmentExtendState1 != null){
            record.setUserClassNo(equipmentExtendState1.getClassNo());
            record.setUserTeamGroup(equipmentExtendState1.getTeamGroup());
        }
        record.setEquipment(target.getEquipment());
        record.setOrg(target.getMaterial());
        record.setTarget(entity.getMaterial());
        record.setUseTime(detail1 == null ? null : detail1.getUseTime());
        record.setTargetUseTime(detail == null ? null : detail.getUseTime());

//        record.setOrgAttritionRate(detail1 == null ? null : detail1.getAttritionRate());

        record.setRemark("对调");
        record.setOrgFactory(target.getFactory());
        record.setTargetFactory(entity.getFactory());
        record.setOrgGoodsCode(target.getGoodsCode());
        record.setTargetGoodsCode(entity.getGoodsCode());
        record.setOrgBatchNo(target.getBatchNo());
        record.setTargetBatchNo(entity.getBatchNo());

        record.setApplyUser("");
        record.setApplyDate(null);

        //更换数量
        record.setChangeCount(1);
//        record.setLocationId();
//        record.setLocationName();

        record.setDeviceNo(target.getDeviceNo());

        record.setOrgEngraving(target.getEngraving());
        record.setTargetEngraving(entity.getEngraving());
        record.setOrgCarbonFelt(target.getCarbonFelt());
        record.setTargetCarbonFelt(entity.getCarbonFelt());
        accessoryOrderService.saveOrUpdate(record);

        entity.setEquipment(equipment);
        entity.setDeviceNo(dto.getDeviceNo());
        entity.setOperateDate(new Date());
        entity.setUsedTime(detail == null ? null : detail.getUsedTime());

        target.setEquipment(orgEquip);
        target.setDeviceNo(orgEquip.getCode());
        target.setOperateDate(new Date());
        target.setUsedTime(detail1 == null ? null : detail1.getUsedTime());

        // 更新初始
        saveOrUpdate(entity);


        // 更新目标
        saveOrUpdate(target);
    }

}
