package com.sw.mes.fb.turnstore.controller;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sw.mes.base.erp.entity.ReportSapRecord;
import com.sw.mes.base.erp.service.ReportSapRecordService;
import com.sw.mes.base.factory.inspect.dto.ProductRuleValidateDto;
import com.sw.mes.base.factory.material.entity.MaterialModel;
import com.sw.mes.base.factory.material.service.MaterialModelService;
import com.sw.mes.base.global.GlobalSwitch;
import com.sw.mes.base.global.SwitchConfig;
import com.sw.mes.base.system.entity.SysLog;
import com.sw.mes.base.system.service.SysLogService;
import com.sw.mes.core.annotation.TokenNotValidation;
import com.sw.mes.core.api.system.StoreFeignClients;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.dto.PushSapDto;
import com.sw.mes.core.dto.SectionMesToFbReceiveDto;
import com.sw.mes.core.dto.WmsToFbReceiveDto;
import com.sw.mes.core.dto.store.WarehouseOutputBillBo;
import com.sw.mes.core.dto.store.WarehouseOutputBillDetailBo;
import com.sw.mes.core.entity.FbCheckOutData;
import com.sw.mes.core.enums.EnumValues;
import com.sw.mes.core.response.ResponsePage;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultCode;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.core.utils.*;
import com.sw.mes.base.factory.inspect.dto.ProductRuleDto;
import com.sw.mes.base.factory.inspect.entity.ProductAssemblyRule;
import com.sw.mes.base.factory.inspect.service.ProductAssemblyRuleService;
import com.sw.mes.fb.checkout.service.FbCheckOutDataService;
import com.sw.mes.fb.turnstore.dto.*;
import com.sw.mes.fb.turnstore.dto.vo.FbTurnstoreTrayItemVo;
import com.sw.mes.fb.turnstore.entity.FbTurnstoreTray;
import com.sw.mes.fb.turnstore.entity.FbTurnstoreTrayItem;
import com.sw.mes.fb.turnstore.service.FbTurnstoreTrayItemService;
import com.sw.mes.fb.turnstore.service.FbTurnstoreTrayService;
import com.sw.mes.fb.turnstore.service.RawMaterialReceivingService;
import com.sw.mes.base.workinprocess.service.PlanProcessingOrderService;
import com.sw.mes.base.workinprocess.service.WipStorageService;
import com.sw.mes.fls.entity.ProductionBindingTray;
import com.sw.mes.fls.service.ProductionBindingTrayService;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

import static com.sw.mes.base.global.GlobalSwitchNamespace.CODE_SWITCH;
import static com.sw.mes.base.global.GlobalSwitchNamespace.NAMESPACE_FB_CHECK;


/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@RestController
@RequestMapping("/FbTurnstoreTray")
@Slf4j
@Api(description = "方棒组托接口")
public class FbTurnstoreTrayController {
    @Autowired
    ModelMapper modelMapper;

    @Autowired
    private FbTurnstoreTrayService fbTurnstoreTrayService;

    @Autowired
    private FbTurnstoreTrayItemService fbTurnstoreTrayItemService;

    @Autowired
    private RawMaterialReceivingService receivingService;

    @Autowired
    private FbCheckOutDataService checkOutService;

    @Autowired
    private WipStorageService wipStorageService;

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private ProductAssemblyRuleService productAssemblyRuleService;

    @Autowired
    private PlanProcessingOrderService planProcessingOrderService;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private StoreFeignClients storeFeignClients;

    @Autowired
    @Qualifier(value = "fBMesThreadPoolTaskExecutor")
    private ThreadPoolTaskExecutor fbMesThreadPoolExecutor;

    @Autowired
    private MaterialModelService materialModelService;

    @Autowired
    private SysLogService sysLogService;

    @Autowired
    private ReportSapRecordService reportSapRecordService;

    @Autowired
    private ProductionBindingTrayService productionBindingTrayService;

    @ApiOperation(value = "分页查询方棒组托列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rows", value = "行数", dataType = "integer", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "页码", dataType = "integer", paramType = "query"),
            @ApiImplicitParam(name = "search_EQ_trayNo", value = "托号", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "search_EQ_status", value = "打托状态", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "search_EQ_inputType", value = "入库状态", dataType = "integer", paramType = "query"),
            @ApiImplicitParam(name = "search_GTE_time", value = "组托时间", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "search_LTE_time", value = "组托时间", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "search_GTE_confirmTime", value = "确认时间", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "search_LTE_confirmTime", value = "确认时间", dataType = "String", paramType = "query"),
    })
    @GetMapping("/listByPage")
    public Result<ResponsePage<FbTurnstoreTrayDto>> listByPage(ServletRequest request, @ApiIgnore RequestPage requestPage) {
        Specification<FbTurnstoreTray> specification = DynamicSpecifications.bySearchFilter(request, FbTurnstoreTray.class);
        Page<FbTurnstoreTray> page = fbTurnstoreTrayService.findByExample(specification, PageUtil.createPageable(requestPage));
        List<FbTurnstoreTrayDto> dtos = page.getContent().stream()
                .map(this::toLazyDto)
                .collect(Collectors.toList());
        ResponsePage responsePage = new ResponsePage(dtos, page.getTotalElements());
        return ResultGenerator.success(responsePage);
    }

    @ApiOperation(value = "获取所有方棒组托")
    @GetMapping("/listAll")
    public Result<List<FbTurnstoreTrayDto>> listAll(ServletRequest request) {
        Specification<FbTurnstoreTray> specification = DynamicSpecifications.bySearchFilter(request, FbTurnstoreTray.class);
        List<FbTurnstoreTray> fbTurnstoreTrays = fbTurnstoreTrayService.findByExampleSort(specification, null);
        List<FbTurnstoreTrayDto> fbTurnstoreTrayDtos = fbTurnstoreTrays.stream()
                .map(this::toLazyDto)
                .collect(Collectors.toList());
        return ResultGenerator.success(fbTurnstoreTrayDtos);
    }

    @ApiOperation(value = "方棒组托详细信息")
    @GetMapping("/{id}")
    public Result<FbTurnstoreTrayPostDto> get(@PathVariable @ApiParam(value = "方棒组托id") Integer id) {
        FbTurnstoreTray fbTurnstoreTray = fbTurnstoreTrayService.get(id);
        if (null == fbTurnstoreTray) {
            return ResultGenerator.fail("该方棒组托不存在");
        }
        FbTurnstoreTrayPostDto postDto = new FbTurnstoreTrayPostDto();
        postDto.setFbTray(fbTurnstoreTray);
        //查询详情列表
        List<FbTurnstoreTrayItem> fbTurnstoreTrayItemList = fbTurnstoreTrayItemService.getItemsByTrayId(id);
        postDto.setTrayItems(fbTurnstoreTrayItemList);
        //查询组托规则
        if (null != fbTurnstoreTray.getStation()) {
            ProductAssemblyRule ruleByStation = productAssemblyRuleService.findRuleByStation(fbTurnstoreTray.getStation());
            postDto.setProductRule(ruleByStation);
        }
        //更新打印时间
        fbTurnstoreTray.setPrintTime(new Date());
        fbTurnstoreTrayService.saveOrUpdate(fbTurnstoreTray);
        return ResultGenerator.success(postDto);
    }

    @ApiOperation(value = "创建方棒组托接口")
    @PostMapping("/create")
//    public Result create(@RequestBody @Valid @ApiParam(value = "组拖主表对象") FbTurnstoreTrayPostDto postDto, BindingResult bindingResult) {
    public Result create(@RequestBody @Valid @ApiParam(value = "组拖主表对象") FbTurnstoreTrayDto postDto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        if (null == postDto) {
            return ResultGenerator.fail("组拖申请错误");
        }
        if (null == postDto.getTrayItems() || postDto.getTrayItems().isEmpty()) {
            return ResultGenerator.fail("组拖明细错误");
        }
        //FbTurnstoreTray turnstoreTray = postDto.getFbTray();
        FbTurnstoreTray turnstoreTray = fromDto(postDto);
        List<FbTurnstoreTrayItem> items = postDto.getTrayItems();
//        ProductAssemblyRule productRule = postDto.getProductRule();
        ProductAssemblyRule productRule = null;
        if (null != postDto.getRuleId()) {
            productRule = productAssemblyRuleService.get(postDto.getRuleId());
        }
        turnstoreTray.setUser(BaseContextHandler.getUsername());
        fbTurnstoreTrayService.createTray(productRule, turnstoreTray, items);
        return ResultGenerator.success();
    }

    @ApiOperation(value = "更新组拖主表")
    @PostMapping("/update")
    public Result update(@RequestBody @Valid @ApiParam(value = "组拖主表") FbTurnstoreTrayDto postDto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        if (postDto.getId() == null) {
            return ResultGenerator.fail("id不能为空");
        }
        FbTurnstoreTray entity = fbTurnstoreTrayService.get(postDto.getId());
        if (entity == null) {
            return ResultGenerator.fail("原信息不存在");
        }
        //查询托号是否重复
        FbTurnstoreTray fbTurnstoreTray = fbTurnstoreTrayService.findByTrayNo(postDto.getTrayNo());
        if (null != fbTurnstoreTray && !postDto.getId().equals(fbTurnstoreTray.getId())) {
            return ResultGenerator.fail("新提交的托号已存在,请重新编辑");
        }
        if (postDto.getTrayItems() == null || postDto.getTrayItems().isEmpty()) {
            return ResultGenerator.fail("组拖明细错误");
        }

        ProductAssemblyRule productRule = null;
        if (null != postDto.getRuleId()) {
            productRule = productAssemblyRuleService.get(postDto.getRuleId());
        }

        try {
            FbTurnstoreTray turnstoreTray = fromDto(postDto);
            if (!turnstoreTray.getTrayNo().equals(entity.getTrayNo())) {
                turnstoreTray.setOrderNum(Integer.valueOf(turnstoreTray.getTrayNo().substring(11, 14)));
            }
            List<FbTurnstoreTrayItem> items = postDto.getTrayItems();
            turnstoreTray.setUpdateUser(BaseContextHandler.getUsername());
            Integer tornieNum = productRule.getTornieNum();
            if (tornieNum == items.size() && null == turnstoreTray.getReportingTime()) {
                turnstoreTray.setReportingTime(new Date());
            }
            fbTurnstoreTrayService.updateTray(turnstoreTray, items);
            ReportSapRecord byFbSectionNo = reportSapRecordService.findByFbTrayNo(items.get(0).getTrayNo());
            SwitchConfig config1 = GlobalSwitch.switchConfig(CODE_SWITCH, "updateTurnStoreTrayPusgSap", false);
            if (null != byFbSectionNo) {
                List<ReportSapRecord> byFbVersionId = reportSapRecordService.findByFbVersionIdAndTrayNo(byFbSectionNo.getVersionId(), byFbSectionNo.getTrayNo());
                SwitchConfig config = GlobalSwitch.switchConfig(CODE_SWITCH, "updateTurnStoreTray", false);
                if (config.isEnable()) {
                    //冲销操作
                    List<FbTurnstoreTrayItem> fbTurnstoreTrayItems = new ArrayList<>();
                    for (ReportSapRecord reportSapRecord : byFbVersionId) {
                        FbTurnstoreTrayItem fbTurnstoreTrayItem = new FbTurnstoreTrayItem();
                        fbTurnstoreTrayItem.setSectionNo(reportSapRecord.getSectionNo());
                        fbTurnstoreTrayItem.setTrayNo(reportSapRecord.getTrayNo());
                        fbTurnstoreTrayItems.add(fbTurnstoreTrayItem);
                    }
                    if (null != fbTurnstoreTrayItems) {
                        fbTurnstoreTrayService.fbWriteOffAccounts(fbTurnstoreTrayItems);
                    }
                }
            }
            if (config1.isEnable()) {
                //报工操作
                fbTurnstoreTrayService.pushSap(items);
            }
        } catch (Exception e) {
            e.printStackTrace();
            SysLog syslog = new SysLog();
            syslog.setCreateTime(new Date());
            syslog.setType("error");
            syslog.setCreateUserName("SYSTEM");
            syslog.setContent(e.getMessage());
            syslog.setResult(e.getMessage());
            syslog.setName("方棒组托上报SAP");
            syslog.setMethodName("sendSquareRodInfo()");
            syslog.setServerAddr("");
            syslog.setReqType("HTTP");
            syslog.setReqIp(IpUtils.getLocalIP());
            sysLogService.save(syslog);
        }
        return ResultGenerator.success();
    }

    @ApiOperation(value = "方棒组托退库")
    @GetMapping("/cancel/{id}")
    public Result cancel(@PathVariable @ApiParam(value = "方棒组托id") Integer id) {
        FbTurnstoreTrayPostDto fbTurnstoreTrayPostDto = fbTurnstoreTrayItemService.cancelStock(id);
        return ResultGenerator.success("退库成功", fbTurnstoreTrayPostDto);
    }

    @ApiOperation(value = "单包组拖长度校验")
    @PostMapping("/lengthCheck")
    public Result lengthCheck(@RequestBody @Valid @ApiParam(value = "成品组拖规则") ProductRuleDto ruleDto) {
        Result result = fbTurnstoreTrayService.lengthCheck(ruleDto);
        return result;
    }

    @ApiOperation(value = "根据托号查询信息")
    @GetMapping("/getTray")
    public Result<ResponsePage<FbTurnstoreTrayDto>> getFbTray(@ApiParam(value = "托号", type = "query") @RequestParam(value = "trayNo") String trayNo) {
        FbTurnstoreTray result = fbTurnstoreTrayService.getFbTray(trayNo);
        if (null == result) {
            return ResultGenerator.fail("未查询到组拖信息");
        }
        List<FbTurnstoreTrayDto> list = new ArrayList<>();
        list.add(toLazyDto(result));
        ResponsePage responsePage = new ResponsePage(list, 1L);
        return ResultGenerator.success(responsePage);
    }

    @ApiOperation(value = "校验晶段信息是否符合规则")
    @PostMapping("/validateRuleNew")
    public Result validateRuleNew(@RequestBody @Valid @ApiParam(value = "组托规则校验Dto") ProductRuleValidateDto ruleDto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        try {
            //如果这个方棒是一个拼棒，则需要查询拼棒的信息，然后进行每个棒的validate
            //如果是拼棒,则查询获取所有
            String split = ",";
            //查询晶段信息
            FbCheckOutData checkOut = checkOutService.findDataByFbSectionNo(ruleDto.getSectionNo());
            if (null == checkOut || null == checkOut.getYbLevel()) {
                return ResultGenerator.fail("当前晶段信息不存在或晶段暂未评级");
            }
            List<FbTurnstoreTrayItem> fbTurnstoreTrayItemList = new ArrayList<>();
            if (null != checkOut.getSectionCompose() && checkOut.getSectionCompose().contains(split)) {
                String[] sections = checkOut.getSectionCompose().split(split);
                List<String> sectionNoList = Arrays.asList(sections);
                for (int i = 0; i < sectionNoList.size(); i++) {
                    ProductRuleValidateDto ruleRequest = new ProductRuleValidateDto();
                    ruleRequest.setRuleId(ruleDto.getRuleId());
                    ruleRequest.setSectionNo(sections[i]);
                    ruleRequest.setHasGone(ruleDto.getHasGone());
                    Result<List<FbTurnstoreTrayItem>> result = fbTurnstoreTrayService.validateRuleNew(ruleRequest, true);
                    if (result != null && result.getData() != null && result.getCode() == 200 && null != result.getData().get(0)) {
                        //fixme 需要重置对应的sectionNo
                        result.getData().get(0).setSectionNo(ruleRequest.getSectionNo());
                        fbTurnstoreTrayItemList.addAll(result.getData());
                    } else {
                        return result;
                    }
                }
                return ResultGenerator.success(fbTurnstoreTrayItemList);
            }
            return fbTurnstoreTrayService.validateRuleNew(ruleDto, false);
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
    }


    @ApiOperation(value = "批量校验晶段信息是否符合规则")
    @PostMapping("/batchValidateRule")
    public Result batchValidateRule(@RequestBody @Valid @ApiParam(value = "组托规则校验Dto") List<ProductRuleValidateDto> ruleDtoList, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        if (CollectionUtils.isEmpty(ruleDtoList)) {
            return ResultGenerator.fail("传入的晶段编号列表不能为空");
        }
        Set<String> dump = new HashSet<>(ruleDtoList.size());
        List<FbTurnstoreTrayItem> fbTurnstoreTrayItemList = new ArrayList<>();
        for (ProductRuleValidateDto ruleDto : ruleDtoList) {
            if (dump.contains(ruleDto.getSectionNo())) {
                return ResultGenerator.fail("当前晶段【" + ruleDto.getSectionNo() + "】已在列表中，请检查数据！勿重复组托!");
            }
            try {
                dump.add(ruleDto.getSectionNo());
                Result<List<FbTurnstoreTrayItem>> result = fbTurnstoreTrayService.validateRuleNew(ruleDto, true);
                if (result != null && result.getData() != null && result.getCode() == 200 && null != result.getData().get(0)) {
                    fbTurnstoreTrayItemList.addAll(result.getData());
                } else {
                    return result;
                }
            } catch (Exception e) {
                return ResultGenerator.fail(e.getMessage());
            }
        }
        return ResultGenerator.success(fbTurnstoreTrayItemList);
    }

    @ApiOperation(value = "自动组托")
    @PostMapping("/automaticAssemblySupport")
    public Result automaticAssemblySupport(@RequestParam @ApiParam(value = "托盘编号")String trayNo) {
        if (null==trayNo){
            return ResultGenerator.fail("托盘编号不能为空");
        }
        ProductionBindingTray productionBindingTray= productionBindingTrayService.findByTrayNo(trayNo);
        if (null==productionBindingTray||null==productionBindingTray.getCrystalNo()){
            return ResultGenerator.fail("当前托盘"+trayNo+"没有绑定晶棒");
        }
        FbTurnstoreTrayItemVo turnstoreTrayItemVo= fbTurnstoreTrayService.validateRule(productionBindingTray.getCrystalNo(), true);
        if (null == turnstoreTrayItemVo) {
            return ResultGenerator.fail("组拖申请错误");
        }
        if (null == turnstoreTrayItemVo.getTrayItems() || turnstoreTrayItemVo.getTrayItems().isEmpty()) {
            return ResultGenerator.fail("组拖明细错误");
        }
        FbTurnstoreTray turnstoreTray = fromVo(turnstoreTrayItemVo);
        ProductAssemblyRule productRule = null;
        if (null != turnstoreTrayItemVo.getRuleId()) {
            productRule = productAssemblyRuleService.get(turnstoreTrayItemVo.getRuleId());
        }
        turnstoreTray.setUser(BaseContextHandler.getUsername());
        fbTurnstoreTrayService.createTray(productRule, turnstoreTray, turnstoreTrayItemVo.getTrayItems());
//        发起入库
        FbTurnstoreTrayItem fbTurnstoreTrayItemDb = fbTurnstoreTrayItemService.findBySectionNo(productionBindingTray.getCrystalNo());
        if (null==fbTurnstoreTrayItemDb){
            return ResultGenerator.fail("组托明细信息不存在");
        }
        //校验状态
        FbTurnstoreTray entity = fbTurnstoreTrayService.get(fbTurnstoreTrayItemDb.getTrayId());
        if (null == entity) {
            return ResultGenerator.fail("原信息不存在");
        }
        SwitchConfig config = GlobalSwitch.switchConfig(NAMESPACE_FB_CHECK, "turnstore_state_out", false);
        if (config != null && config.isEnable()) {
            String configState = config.getValue();
            if (Integer.parseInt(configState) != entity.getState()) {
                return ResultGenerator.fail("当前不处于待出库状态,不能进行发起入库操作,请刷新后再试");
            }
        } else {
            if (0 != entity.getState()) {
                return ResultGenerator.fail("当前不处于待出库状态,不能进行发起入库操作,请刷新后再试");
            }
        }
        List<FbTurnstoreTrayItem> turnstoreTrayItemList = fbTurnstoreTrayItemService.getItemsByTrayId(entity.getId());
        //获取详情列表
        if (null == turnstoreTrayItemList || turnstoreTrayItemList.isEmpty()) {
            return ResultGenerator.fail("组托详情不能为空");
        }
        if (null == entity.getBorderWidth()) {
            return ResultGenerator.fail("边距不能为空");
        }
        return ResultGenerator.success(fbTurnstoreTrayService.sectionMesInitiateReceipt(entity, turnstoreTrayItemList));
    }

    private FbTurnstoreTray fromVo(FbTurnstoreTrayItemVo turnstoreTrayItemVo) {
        return modelMapper.map(turnstoreTrayItemVo, FbTurnstoreTray.class);
    }

    @ApiOperation(value = "取消入库接口")
    @PostMapping("/cancelWarehousing")
    @TokenNotValidation
    public Result cancelWarehousing(@RequestBody WmsCancelWarehousingDto wmsCancelWarehousingDto) {
        String trayNo = wmsCancelWarehousingDto.getTrayNo();
        Integer flag = wmsCancelWarehousingDto.getFlag();
        FbTurnstoreTray byTrayNo = fbTurnstoreTrayService.findByTrayNo(trayNo);
        if (null == byTrayNo) {
            return ResultGenerator.fail(0, "未查询到此托盘号");
        }
        byTrayNo.setFlag(flag);
        fbTurnstoreTrayService.saveOrUpdate(byTrayNo);
        return ResultGenerator.success(1, "SUCCESS", trayNo);
    }

    @ApiOperation(value = "发起入库")
    @PostMapping("/initiateReceipt")
    public Result initiateReceipt(@RequestBody @Valid @ApiParam(value = "组拖主表对象") FbTurnstoreTray turnstoreTray) {
        //校验状态
        FbTurnstoreTray entity = fbTurnstoreTrayService.get(turnstoreTray.getId());
        if (null == entity) {
            return ResultGenerator.fail("原信息不存在");
        }
        SwitchConfig config = GlobalSwitch.switchConfig(NAMESPACE_FB_CHECK, "turnstore_state_out", false);
        if (config != null && config.isEnable()) {
            // fixme 状态改成待入库
            String configState = config.getValue();
            if (Integer.parseInt(configState) != entity.getState()) {
                return ResultGenerator.fail("当前不处于待出库状态,不能进行发起入库操作,请刷新后再试");
            }
        } else {
            if (0 != entity.getState()) {
                return ResultGenerator.fail("当前不处于待出库状态,不能进行发起入库操作,请刷新后再试");
            }
        }
        List<FbTurnstoreTrayItem> turnstoreTrayItemList = fbTurnstoreTrayItemService.getItemsByTrayId(turnstoreTray.getId());
        //获取详情列表
        if (null == turnstoreTrayItemList || turnstoreTrayItemList.isEmpty()) {
            return ResultGenerator.fail("组托详情不能为空");
        }
        if (null == turnstoreTray.getBorderWidth()) {
            return ResultGenerator.fail("边距不能为空");
        }
        if ("综计WMS".equals(entity.getHasGone())) {
            //综计WMS发起入库
            return fbTurnstoreTrayService.initiateReceipt(turnstoreTray, turnstoreTrayItemList);
        } else if ("切片MES".equals(entity.getHasGone())) {
            //切片MES发起入库
            return fbTurnstoreTrayService.sectionMesInitiateReceipt(turnstoreTray, turnstoreTrayItemList);
        }
        return ResultGenerator.fail("发起入库失败");
    }

    @ApiOperation(value = "方棒组托上报ERP")
    @PostMapping("/reportedErp")
    public Result reportedErp(@RequestBody @Valid @ApiParam(value = "组拖主表对象") FbTurnstoreTray turnstoreTray) {
        //校验状态
        FbTurnstoreTray entity = fbTurnstoreTrayService.get(turnstoreTray.getId());
        if (null == entity) {
            return ResultGenerator.fail("原信息不存在");
        }
        // 已入库  未上报ERP
        if (1 == entity.getState() && EnumValues.ReportedErp.未上报.getKey() == entity.getReportedState()) {
            List<FbTurnstoreTrayItem> turnstoreTrayItemList = fbTurnstoreTrayItemService.getItemsByTrayId(turnstoreTray.getId());
            //获取详情列表
            if (null == turnstoreTrayItemList || turnstoreTrayItemList.isEmpty()) {
                return ResultGenerator.fail("组托详情不能为空");
            }
            for (FbTurnstoreTrayItem fbTurnstoreTrayItem : turnstoreTrayItemList) {
                if (EnumValues.ReportedErp.未上报.getKey() != fbTurnstoreTrayItem.getReportedState()) {
                    return ResultGenerator.fail("组托详情当前不处于未上报状态,不能进行上报ERP操作：" + fbTurnstoreTrayItem.getSectionNo());
                }
            }
            //组托上报ERP
            return fbTurnstoreTrayService.reportedErp(entity, turnstoreTrayItemList);
        } else {
            return ResultGenerator.fail("当前不处于入库或未上报状态,不能进行上报ERP操作,请刷新后再试");
        }
    }

    @ApiOperation(value = "方棒WMS接收接口")
    @PostMapping("/fbWmsReceive")
    public Result fbWmsReceive(@RequestBody List<WmsToFbReceiveDto> receiveDto) {

        for (WmsToFbReceiveDto wmsToFbReceiveDto : receiveDto) {
            //查询组托信息
            FbTurnstoreTray turnstoreTray = fbTurnstoreTrayService.findByTrayNo(wmsToFbReceiveDto.getBoxCode());
            if (null == turnstoreTray) {
                return ResultGenerator.fail("该:" + wmsToFbReceiveDto.getBoxCode() + " 托号信息不存在");
            }
            //拒收时增加组托状态判断---只有待确认的可以拒收
            if ((1 == wmsToFbReceiveDto.getType() || 2 == wmsToFbReceiveDto.getType()) && turnstoreTray.getState() != 2) {
                return ResultGenerator.fail("该:" + wmsToFbReceiveDto.getBoxCode() + " 托号不是待确认状态,不能进行接收拒收操作");
            }
            //冲销时增加组托状态判断---只有已确认的可以冲销
            if (3 == wmsToFbReceiveDto.getType() && turnstoreTray.getState() != 1) {
                return ResultGenerator.fail("该:" + wmsToFbReceiveDto.getBoxCode() + " 托号不是已确认状态,不能冲销");
            }
            //查询组托明细
            List<FbTurnstoreTrayItem> trayItemList = fbTurnstoreTrayItemService.getItemsByTrayId(turnstoreTray.getId());
            if (null == trayItemList || trayItemList.isEmpty()) {
                return ResultGenerator.fail("该:" + wmsToFbReceiveDto.getBoxCode() + " 组拖明细错误");
            }
            //构建FbTurnstoreTray更新信息
            buildEntityProp(wmsToFbReceiveDto, turnstoreTray);
            //更新组托表头信息
            fbTurnstoreTrayService.updateTurnstoreTrayStateById(wmsToFbReceiveDto, turnstoreTray);
            //更新组托明细信息
            fbTurnstoreTrayService.updateTrayItemState(wmsToFbReceiveDto, turnstoreTray, trayItemList);

            SwitchConfig config = GlobalSwitch.switchConfig(NAMESPACE_FB_CHECK, "wmsOutOfStockStore", false);
            if (null != config && config.isEnable()) {
                if (turnstoreTray.getState() == 1) {
                    try {
                        ArrayList<WarehouseOutputBillDetailBo> warehouseOutputBillDetailBoArrayList = new ArrayList<>();
                        WarehouseOutputBillBo warehouseOutputBillBo = new WarehouseOutputBillBo();
                        warehouseOutputBillBo.setType("WMS领用");
                        warehouseOutputBillBo.setCreateUserId(1);
                        warehouseOutputBillBo.setCreateUserName(turnstoreTray.getConfirmUser());
                        warehouseOutputBillBo.setAutoAudit(true);
                        for (FbTurnstoreTrayItem fbTurnstoreTrayItem : trayItemList) {
                            WarehouseOutputBillDetailBo bo = new WarehouseOutputBillDetailBo();
                            MaterialModel materialModel = materialModelService.findByCode(fbTurnstoreTrayItem.getMaterialNumber());
                            bo.setMaterialModelId(materialModel.getId().longValue());
                            bo.setMaterialModelCode(materialModel.getCode());
                            bo.setMaterialModelName(materialModel.getName());
                            bo.setMaterialTypeName(materialModel.getMaterialType().getName());
                            bo.setBatchNo(fbTurnstoreTrayItem.getBatchNo());
                            bo.setSupplier(materialModel.getSupplier());
                            bo.setSpecification(materialModel.getSpecification());
                            bo.setMaterialTh(materialModel.getNumberOfDrawings());
                            bo.setRequireCount(fbTurnstoreTrayItem.getTheoryWeightFb());
                            bo.setUnitName(materialModel.getUnit().getName());
                            bo.setWarehouseCode("P32B");
                            bo.setCreateUserId(1);
                            bo.setCreateUserName(fbTurnstoreTrayItem.getConfirmUser());

                            warehouseOutputBillDetailBoArrayList.add(bo);
                        }
                        warehouseOutputBillBo.setOutputBillDetails(warehouseOutputBillDetailBoArrayList);

                        FbTurnstoreTrayItem trayItem = trayItemList.get(0);
                        log.info("wms开始调用线边仓出库接口,物料号:{},批次号:{}", trayItem.getMaterialNumber(), trayItem.getBatchNo());
                        Result<String> result = storeFeignClients.outputApply(warehouseOutputBillBo);
                        log.info("wms调用线边仓出库接口结束,调用结果:{},物料号:{},批次号:{}", result.getMessage(), trayItem.getMaterialNumber(), trayItem.getBatchNo());
                        if (result.getCode() != ResultCode.SUCCESS.getCode()) {
                            return ResultGenerator.fail("线边仓出库失败：" + result.getMessage());
                        }
//                                线边仓接收成功之后方棒组托明细表状态更新为已入库
                        for (FbTurnstoreTrayItem fbTurnstoreTrayItem : trayItemList) {
                            fbTurnstoreTrayItem.setState(1);
                            fbTurnstoreTrayItemService.saveOrUpdate(fbTurnstoreTrayItem);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error("WMS出库线边仓P32B失败", e);
                    }
                }
            }
        }
        return ResultGenerator.success();
    }

    @ApiOperation(value = "方棒切片mes接收接口")
    @PostMapping("/fbSectionMesReceive")
    public Result fbSectionMesReceive(@RequestBody List<SectionMesToFbReceiveDto> receiveDto) {

        for (SectionMesToFbReceiveDto sectionMesToFbReceiveDto : receiveDto) {
            //查询组托信息
            FbTurnstoreTray turnstoreTray = fbTurnstoreTrayService.findByTrayNo(sectionMesToFbReceiveDto.getTrayId());
            if (null == turnstoreTray) {
                return ResultGenerator.fail("该:" + sectionMesToFbReceiveDto.getTrayId() + " 托号信息不存在");
            }
            //拒收时增加组托状态判断---只有待确认的可以拒收
            if (("S".equals(sectionMesToFbReceiveDto.getState()) || "C".equals(sectionMesToFbReceiveDto.getState())) && turnstoreTray.getState() != 2) {
                return ResultGenerator.fail("该:" + sectionMesToFbReceiveDto.getTrayId() + " 托号不是待确认状态,不能进行接收拒收操作");
            }
            //查询组托明细
            List<FbTurnstoreTrayItem> trayItemList = fbTurnstoreTrayItemService.getItemsByTrayId(turnstoreTray.getId());
            if (null == trayItemList || trayItemList.isEmpty()) {
                return ResultGenerator.fail("该:" + sectionMesToFbReceiveDto.getTrayId() + " 组拖明细错误");
            }
            //构建FbTurnstoreTray更新信息
            buildSectionMesEntityProp(sectionMesToFbReceiveDto, turnstoreTray);
            //更新组托表头信息
            fbTurnstoreTrayService.saveOrUpdate(turnstoreTray);
            //更新组托明细信息
            fbTurnstoreTrayService.updateSectionMesTrayItemState(turnstoreTray, trayItemList);

            SwitchConfig config = GlobalSwitch.switchConfig(NAMESPACE_FB_CHECK, "sectionMesOutOfStockStore", false);
            if (null != config && config.isEnable()) {
                if (turnstoreTray.getState() == 1) {
                    try {
                        ArrayList<WarehouseOutputBillDetailBo> warehouseOutputBillDetailBoArrayList = new ArrayList<>();
                        WarehouseOutputBillBo warehouseOutputBillBo = new WarehouseOutputBillBo();
                        warehouseOutputBillBo.setType("切片MES领用");
                        warehouseOutputBillBo.setCreateUserId(1);
                        warehouseOutputBillBo.setCreateUserName(turnstoreTray.getConfirmUser());
                        warehouseOutputBillBo.setAutoAudit(true);
                        for (FbTurnstoreTrayItem fbTurnstoreTrayItem : trayItemList) {
                            WarehouseOutputBillDetailBo bo = new WarehouseOutputBillDetailBo();
                            MaterialModel materialModel = materialModelService.findByCode(fbTurnstoreTrayItem.getMaterialNumber());
                            bo.setMaterialModelId(materialModel.getId().longValue());
                            bo.setMaterialModelCode(materialModel.getCode());
                            bo.setMaterialModelName(materialModel.getName());
                            bo.setMaterialTypeName(materialModel.getMaterialType().getName());
                            bo.setBatchNo(fbTurnstoreTrayItem.getBatchNo());
                            bo.setSupplier(materialModel.getSupplier());
                            bo.setSpecification(materialModel.getSpecification());
                            bo.setMaterialTh(materialModel.getNumberOfDrawings());
                            bo.setRequireCount(fbTurnstoreTrayItem.getTheoryWeightFb());
                            bo.setUnitName(materialModel.getUnit().getName());
                            bo.setWarehouseCode("P32B");
                            bo.setCreateUserId(1);
                            bo.setCreateUserName(fbTurnstoreTrayItem.getConfirmUser());

                            warehouseOutputBillDetailBoArrayList.add(bo);
                        }
                        warehouseOutputBillBo.setOutputBillDetails(warehouseOutputBillDetailBoArrayList);
                        FbTurnstoreTrayItem trayItem = trayItemList.get(0);
                        log.info("切片mes开始调用线边仓出库接口,物料号:{},批次号:{}", trayItem.getMaterialNumber(), trayItem.getBatchNo());
                        Result<String> result = storeFeignClients.outputApply(warehouseOutputBillBo);
                        log.info("切片mes调用线边仓出库接口结束,调用结果:{},物料号:{},批次号:{}", result.getMessage(), trayItem.getMaterialNumber(), trayItem.getBatchNo());

                        if (result.getCode() != ResultCode.SUCCESS.getCode()) {
                            return ResultGenerator.fail("线边仓出库失败：" + result.getMessage());
                        }
//                                线边仓接收成功之后方棒组托明细表状态更新为已入库
                        for (FbTurnstoreTrayItem fbTurnstoreTrayItem : trayItemList) {
                            fbTurnstoreTrayItem.setState(1);
                            fbTurnstoreTrayItemService.saveOrUpdate(fbTurnstoreTrayItem);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error("切片MES出库线边仓P32B失败", e);
                    }
                }
            }
        }
        return ResultGenerator.success();
    }

    private void buildSectionMesEntityProp(SectionMesToFbReceiveDto sectionMesToFbReceiveDto, FbTurnstoreTray turnstoreTray) {
//        //更新信息
        turnstoreTray.setConfirmUser("切片mes");
        turnstoreTray.setConfirmTime(new Date());
        //根据状态进行操作
        if ("S".equals(sectionMesToFbReceiveDto.getState())) {
            //确认接收
            turnstoreTray.setState(1);
        } else if ("C".equals(sectionMesToFbReceiveDto.getState())) {
            //拒收
            turnstoreTray.setState(3);
        }
    }

    private void buildEntityProp(WmsToFbReceiveDto wmsToFbReceiveDto, FbTurnstoreTray turnstoreTray) {
        //更新信息
        turnstoreTray.setConfirmUser(wmsToFbReceiveDto.getRejectionUser());
        turnstoreTray.setConfirmTime(wmsToFbReceiveDto.getRejectionDate());
        //根据状态进行操作
        if (1 == wmsToFbReceiveDto.getType()) {
            //确认接收
            turnstoreTray.setState(1);
        } else if (2 == wmsToFbReceiveDto.getType()) {
            //拒收
            turnstoreTray.setState(3);
            turnstoreTray.setRemark(wmsToFbReceiveDto.getRejectionReason());
        } else {
            //冲销==取消
            turnstoreTray.setState(4);
            if (null != wmsToFbReceiveDto.getRejectionReason()) {
                turnstoreTray.setRemark(wmsToFbReceiveDto.getRejectionReason());
            } else {
                turnstoreTray.setRemark("冲销");
            }
        }
    }

    @ApiOperation(value = "导出Excel")
    @GetMapping("/exportExcel")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "search_EQ_trayNo", value = "托号", dataType = "String", paramType = "query"),
    })
    public void exportExcel(HttpServletRequest request, HttpServletResponse resp) {
        fbTurnstoreTrayItemService.exportExcel(request, resp);
    }

    @ApiOperation(value = "导出方棒组拖Excel")
    @GetMapping("/exportExcel1")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "search_GTE_time", value = "开始时间", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "search_LT_time", value = "结束时间", dataType = "String", paramType = "query"),
    })
    public void exportExcel1(HttpServletRequest request, HttpServletResponse resp) {
        fbTurnstoreTrayItemService.exportExcel1(request, resp);
    }

    @ApiOperation(value = "删除方棒组托")
    @PostMapping("/delete")
    public Result remove(@ApiParam(value = "id集合,逗号分隔,如2,4", type = "query") @RequestParam Integer[] ids) {
        for (Integer id : ids) {
            //校验状态
            FbTurnstoreTray entity = fbTurnstoreTrayService.get(id);
            if (null == entity) {
                return ResultGenerator.fail("原信息不存在");
            }
            if (0 != entity.getState()) { // fixme 修改出库状态
                return ResultGenerator.fail("当前不处于待出库状态,不能进行删除操作,请刷新后再试");
            }
            String userName = BaseContextHandler.getUsername() == null ? "kong" : BaseContextHandler.getUsername();
            log.error("删除方棒组托.." + userName + " id:" + id);
            //删除详情
            fbTurnstoreTrayItemService.deleteByTrayId(id);
            fbTurnstoreTrayService.delete(id);
        }
        return ResultGenerator.success();
    }


    @ApiOperation(value = "组托前根据方棒编号获取晶棒信息")
    @GetMapping("/getInfoByFbSectionNo")
    public Result<FbInfoDto> getInfoByFbSectionNo(@ApiParam(value = "方棒编号", type = "query") @RequestParam(value = "fbSectionNo") String fbSectionNo) {

        if (null == fbSectionNo || StringUtils.isEmpty(fbSectionNo)) {
            return ResultGenerator.fail("方棒编号不能为空！");
        }
        return fbTurnstoreTrayService.getInfoByFbSectionNo(fbSectionNo);

    }

    @ApiOperation(value = "修改方棒组托状态")
    @PostMapping("/updateStateByTrayNo")
    public Result updateStateByTrayNo(@RequestBody UpdateStateByTrayNoDto dto) {
        try {
            log.info("调用修改方棒组托状态请求参数:{}", objectMapper.writeValueAsString(dto));
            fbTurnstoreTrayService.updateStateByTrayNo(dto);
        } catch (JsonProcessingException e) {
            return ResultGenerator.fail("修改方棒组托状态失败");
        }
        return ResultGenerator.success();
    }

    @ApiOperation(value = "根据托盘id修改方棒组托状态")
    @PostMapping("/updateStateByTrayId")
    public Result updateStateByTrayId(@RequestBody UpdateStateByTrayIdDto dto) {
        try {
            log.info("调用修改方棒组托状态请求参数:{}", objectMapper.writeValueAsString(dto));
            fbTurnstoreTrayService.updateStateByTrayId(dto);
        } catch (JsonProcessingException e) {
            return ResultGenerator.fail("修改方棒组托状态失败");
        }
        return ResultGenerator.success();
    }

    @ApiOperation(value = "方棒组托打印明细")
    @GetMapping("/getPrintInfo")
    public Result<FbTurnstoreTrayPrintDto> getPrintInfo(@ApiParam(value = "方棒组托id") Integer id) {

        try {
            return ResultGenerator.success(fbTurnstoreTrayService.getPrintInfo(id));
        } catch (Exception e) {
            log.error("error..getPrintInfo...", e);
            return ResultGenerator.fail(e.getMessage());
        }
    }


    public FbTurnstoreTrayDto toLazyDto(FbTurnstoreTray entity) {
        return modelMapper.map(entity, FbTurnstoreTrayDto.class);
    }

    public FbTurnstoreTrayDto toEagerDto(FbTurnstoreTray entity) {
        return modelMapper.map(entity, FbTurnstoreTrayDto.class);
    }

    public FbTurnstoreTray fromDto(FbTurnstoreTrayDto dto) {
        return modelMapper.map(dto, FbTurnstoreTray.class);
    }

    /**
     * 判断不同晶棒的方棒等级/入库类型 是否相同
     *
     * @param previousProductLevelFb
     * @param productLevelFb
     * @return
     */
    private boolean judgmentProductLevelFb(String previousProductLevelFb, String productLevelFb) {
        boolean flag = false;
        //判断入库类别
        if (org.apache.commons.lang3.StringUtils.isNotBlank(previousProductLevelFb) && org.apache.commons.lang3.StringUtils.isNotBlank(productLevelFb) && previousProductLevelFb.equals(productLevelFb)) {
            flag = true;
        }

        return flag;
    }

}
