/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.youchain.businessdata.rest;


import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.youchain.DuplicateSubmission.DuplicateSubmission;
import com.youchain.annotation.AnonymousAccess;
import com.youchain.annotation.Log;
import com.youchain.basicdata.domain.*;
import com.youchain.basicdata.repository.*;
import com.youchain.basicdata.service.AreaService;
import com.youchain.basicdata.service.dto.AreaDto;
import com.youchain.basicdata.service.dto.BomAccountPointDto;
import com.youchain.businessdata.domain.*;
import com.youchain.businessdata.inputJson.ZzjlPickConfirm;
import com.youchain.businessdata.repository.*;
import com.youchain.businessdata.returnJson.*;
import com.youchain.businessdata.inputJson.IPPickDetail;
import com.youchain.businessdata.inputJson.IScanPut;
import com.youchain.businessdata.service.*;
import com.youchain.businessdata.service.dto.*;
import com.youchain.businessdata.service.dto.jsonDto.CxjlDto;
import com.youchain.exception.BadRequestException;
import com.youchain.exception.OperBadRequestException;
import com.youchain.exception.handler.ApiResult;
import com.youchain.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;

import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import javax.servlet.http.HttpServletResponse;

import static org.springframework.http.HttpStatus.BAD_REQUEST;

/**
 * @author huojin
 * @website https://eladmin.vip
 * @date 2023-08-16
 **/
@RestController
@Slf4j
@RequiredArgsConstructor
@Api(tags = "pickDetail管理")
@RequestMapping("/api/pickDetail")
public class PickDetailController {

    private final PickDetailService pickDetailService;
    private final TaskService taskService;
    private final PickDetailRepository pickDetailRepository;
    private final PickTicketService pickTicketService;
    private final InventoryService inventoryService;
    private final InventoryLogService inventoryLogService;
    private final XppRecordService xppRecordService;
    private final BillTypeRepository billTypeRepository;
    private final InventoryRepository inventoryRepository;
    private final TaskRepository taskRepository;
    private final AreaRepository areaRepository;
    private final ItemRepository itemRepository;
    private final ItemKeyService itemKeyService;
    private final PointRepository pointRepository;
    private final XppRecordRepository xppRecordRepository;
    private final AutomaticPlanningRepository automaticPlanningRepository;
    private final BomAccountRepository bomAccountRepository;
    private final PickTicketRepository pickTicketRepository;
    private  final AreaService areaService;

    @PostMapping("/getIdData")
    @Log("根据主表id查询pickDetail的数据")
    @ApiOperation("根据主表id查询pickDetail的数据")
    @AnonymousAccess
    public ResponseEntity<Object> getIdData(@RequestBody Long ids) {
        return new ResponseEntity<>(pickDetailRepository.queryByPickTicketId(ids), HttpStatus.OK);
    }

    @Log("导出数据")
    @ApiOperation("导出数据")
    @GetMapping(value = "/queryPickDetailZsc/download")
    @AnonymousAccess
    public void exportPickDetail(HttpServletResponse response, PickDetailQueryCriteria criteria) throws Exception {
        pickDetailService.download(pickDetailService.queryZscAll(criteria), response);
    }

    @GetMapping
    @Log("查询pickDetail")
    @ApiOperation("查询pickDetail")
    @AnonymousAccess
    public ResponseEntity<Object> queryPickDetail(PickDetailQueryCriteria criteria, Pageable pageable) {
        return new ResponseEntity<>(pickDetailService.queryAll(criteria, pageable), HttpStatus.OK);
    }

    @GetMapping(value = "/queryPickDetailZzjl")
    @Log("查询制造叫料数据")
    @ApiOperation("查询制造叫料数据")
    @AnonymousAccess
    public ResponseEntity<Object> queryPickDetailZzjl(PickDetailQueryCriteria criteria, Pageable pageable) {
        criteria.setType(BaseStatus.ZZJL);
        return new ResponseEntity<>(pickDetailService.queryAll(criteria, pageable), HttpStatus.OK);
    }

    @GetMapping(value = "/queryPickDetailZsc")
    @Log("查询指示残")
    @ApiOperation("查询指示残")
    @AnonymousAccess
    public ResponseEntity<Object> queryPickDetailZsc(PickDetailQueryCriteria criteria, Pageable pageable) {
        criteria.setPageType("ZSC");
        return new ResponseEntity<>(pickDetailService.queryPickDetailAll(criteria, pageable), HttpStatus.OK);
    }

    @GetMapping(value = "/queryPickDetailAll")
    @Log("查询pickDetail所有")
    @ApiOperation("查询pickDetail所有")
    @AnonymousAccess
    public ResponseEntity<Object> queryPickDetailAll(PickDetailQueryCriteria criteria, Pageable pageable) {
        criteria.setPageType("ALL");
        return new ResponseEntity<>(pickDetailService.queryPickDetailAll(criteria, pageable), HttpStatus.OK);
    }

    @PostMapping
    @Log("新增pickDetail")
    @ApiOperation("新增pickDetail")
    @AnonymousAccess
    @Transactional
    public ResponseEntity<Object> createPickDetail(@Validated @RequestBody PickDetail resources) throws Exception {
        //判断库存数量有没有这么多
        InventoryQueryCriteria inventoryQueryCriteria = new InventoryQueryCriteria();
        double quantityNum = 0;
        if (resources.getPoint() != null) {
           double qty=inventoryService.getInvQty(resources.getItem().getId(),resources.getPickTicket().getArea().getId(),
                    resources.getPoint().getId());
           if(qty<resources.getOrderQty()){
               throw new BadRequestException(HttpStatus.NOT_FOUND, "库存不足，库存"+qty);
           }
        } else {
//            inventoryQueryCriteria.setAreaName(resources.getPickTicket().getArea().getName());
//            inventoryQueryCriteria.setItemCodeOne(resources.getItem().getCode());
//            List<InventoryDto> inventoryDtos = inventoryService.queryAll(inventoryQueryCriteria);
//            for (InventoryDto inv : inventoryDtos) {
//                quantityNum += (inv.getQuantity()-inv.getQueuedQty());
//            }
        }
            //新增加订单数量
            PickTicket pickTicket = resources.getPickTicket();
            pickTicket.setOrderQuantity(pickTicket.getOrderQuantity() + resources.getOrderQty());
            pickTicketService.update(pickTicket);
            resources.setStatus(BizStatus.OPEN);
            PickDetailDto pickDetailDto = pickDetailService.create(resources);
        return new ResponseEntity<>("操作成功", HttpStatus.CREATED);
    }

    @PutMapping
    @Log("修改pickDetail")
    @ApiOperation("修改pickDetail")
    @PreAuthorize("@el.check('super:man')")
    @Transactional
    public ResponseEntity<Object> updatePickDetail(@Validated @RequestBody PickDetail resources) {
        if(resources.getAllocatedQty()>0){
            throw new BadRequestException("已出单，不能修改");
        }
        pickDetailService.update(resources);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @DeleteMapping
    @Log("删除pickDetail")
    @ApiOperation("删除pickDetail")
    @PreAuthorize("@el.check('super:man')")
    @Transactional
    public ResponseEntity<Object> deletePickDetail(@RequestBody Long[] ids) {
        //删除时需判断是否有分配
        for(Long id:ids){
            PickDetail pickDetail=pickDetailRepository.getById(id);
            if(pickDetail.getAllocatedQty()+pickDetail.getBcQty()>0){
                return new ResponseEntity<>(pickDetail.getItem().getCode()+"已出单，不允许删除",BAD_REQUEST);
            }else{
//                pickDetailRepository.deleteById(id);
            }
        }
        pickDetailService.deleteAll(ids);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @PostMapping("/zzjlApp")
    @Log("制造叫料App")
    @ApiOperation("制造叫料App")
    @PreAuthorize("@el.check('super:man')")
    @AnonymousAccess
    @Transactional
    @DuplicateSubmission(5)
    public ResponseEntity<Object> zzjlApp(@RequestBody CxjlDto cxjldto) throws Exception {
        String ewm=cxjldto.getEwm();
        String type=cxjldto.getType();
        if(type.equals("cxjl_001")){
            //解析二维码内容
            String[] str=ewm.split("]");
            if(str.length>=3){//固定库位标签
                String pointCode=str[3];
                String bomItemCode=str[0];
                String bonded=str[2];
                Point point=pointRepository.findByCode(pointCode);
                Item item=itemRepository.findByCode(bomItemCode);
                if(point==null||!point.getType().equals("ZZKW")){
                    throw  new BadRequestException("制造库位错误");
                }
                List<BomAccount> bomAccounts=bomAccountRepository.queryEwmJx(item.getId(),point.getId(),bonded);
                //查询BOM，寻找收容数
                cxjldto.setRk_id(point.getArea().getId());
                cxjldto.setItem_id(item.getId());
                cxjldto.setZzkw_id(point.getId());
                cxjldto.setBonded(bonded);
                cxjldto.setArea_name(point.getArea().getName());
                cxjldto.setPoint_code(point.getCode());
                cxjldto.setItem_name(item.getName());
                cxjldto.setItem_code(item.getCode());
                cxjldto.setOrder_qty(item.getExtendD3().intValue());
                if(bomAccounts.size()>0){
                    cxjldto.setOrder_qty(bomAccounts.get(0).getSrs());
                }
                return new ResponseEntity<>(cxjldto,HttpStatus.OK);
            }else{
                throw  new BadRequestException("扫描错误");
            }

        }else  if(type.equals("cxjl_002")){//制造叫料APP

            PickDetail pickDetail = pickDetailService.cxjlCreate(cxjldto);
            //自动分配
            pickDetailService.allocate(pickDetail.getId(), pickDetail.getOrderQty() - pickDetail.getAllocatedQty(), pickDetail.getPo(), BaseStatus.ZZJL);
            int qh_qty=pickDetail.getOrderQty().intValue()-pickDetail.getAllocatedQty().intValue();
            if(qh_qty>0){
                throw  new BadRequestException(pickDetail.getItem().getCode()+"库存缺货,仅有"+pickDetail.getAllocatedQty().intValue()+"，请汇报上级");
            }
        }else  if(type.equals("cxjl_003")){//制造入库APP
            //解析二维码内容
            String[] str=ewm.split("]");
            if(str.length>=3) {
                String pointCode = str[3];
                String bomItemCode = str[0];
                String bonded = str[2];
                Point point = pointRepository.findByCode(pointCode);
                if (point == null || !point.getType().equals("ZZKW")) {
                    throw new BadRequestException("制造库位错误");
                }
                Item item = itemRepository.findByCode(bomItemCode);
                ItemKey itemKey = itemKeyService.getItemKey(item, null, bonded);
                Inventory inventory = inventoryService.getInventory(itemKey, point.getArea(), point, point, point.getDept(), BizStatus.ZZKW_TL, null);
                double srcQty = inventory.getQuantity();
                inventory.setQuantity(inventory.getQuantity() + cxjldto.getOrder_qty());
                inventoryService.update(inventory);
                InventoryLog inventoryLog = inventoryLogService.storeInventoryLog(BizStatus.ZZKW_RK, BizStatus.ADD, "制造入库APP", point.getArea(), itemKey, inventory.getPoint(), inventory.getPoint(), null, null, srcQty, cxjldto.getOrder_qty() + 0d, null, null,
                        BizStatus.ZZKW_TL, null, inventory.getId(), "制造入库APP");
//                inventoryLog.setZzkw(point);
                inventoryLogService.update(inventoryLog);
            }else {
                throw  new BadRequestException("扫描错误");
            }
        }
        return new ResponseEntity<>("操作成功", HttpStatus.OK);
    }

    @PostMapping("/zzjl")
    @Log("制造叫料")
    @ApiOperation("制造叫料")
    @PreAuthorize("@el.check('super:man')")
    @AnonymousAccess
    @Transactional
    @DuplicateSubmission(5)
    public ResponseEntity<Object> zzjl(@RequestBody CxjlDto cxjldto) throws Exception {
        PickDetail pickDetail=pickDetailService.cxjlCreate(cxjldto);
        BomAccount bomAccount=bomAccountRepository.getById(cxjldto.getBom_account_id());
        cxjldto.setBonded(bomAccount.getBonded());
        //自动分配
        pickDetailService.allocate(pickDetail.getId(), pickDetail.getOrderQty() - pickDetail.getAllocatedQty(),pickDetail.getPo(),BaseStatus.ZZJL);
        int qh_qty=pickDetail.getOrderQty().intValue()-pickDetail.getAllocatedQty().intValue();
        if(qh_qty>0){
            throw  new BadRequestException(pickDetail.getItem().getCode()+"库存缺货,仅有"+pickDetail.getAllocatedQty().intValue()+"，请汇报上级");
        }
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @PostMapping("/zzjlCountList")
    @Log("制造叫料拣货列表汇总")
    @ApiOperation("制造叫料拣货列表汇总")
    @AnonymousAccess
    public ResponseEntity<Object> zzjlCountList(@RequestBody HashMap map) throws Exception {
        List<PickDetail> ds=pickDetailRepository.notPickList();
        for(PickDetail pickDetail:ds) {
            //无库存数据分配
            if (pickDetail.getAllocatedQty() < pickDetail.getOrderQty()) {
                pickDetailService.allocate(pickDetail.getId(), pickDetail.getOrderQty() - pickDetail.getAllocatedQty(), pickDetail.getPo(), BaseStatus.ZZJL);
            }
        }
        //查询叫料返回数据
        List<ZzjlPickCountList> list=pickDetailService.queryZzjlPickCountList();
        return new ResponseEntity<>(list,HttpStatus.OK);
    }

    @PostMapping("/zzjlList")
    @Log("制造叫料拣货列表")
    @ApiOperation("制造叫料拣货列表")
    @AnonymousAccess
    public ResponseEntity<Object> zzjlList(@RequestBody HashMap map) throws Exception {
        String itemCode=map.get("itemCode")==null?null:map.get("itemCode").toString();
        String areaName=map.get("area_name")==null?null:map.get("area_name").toString();
       //查询叫料返回数据
        List<ZzjlPickList> list=pickDetailService.queryZzjlPickList(itemCode,areaName);
        return new ResponseEntity<>(list,HttpStatus.OK);
    }

    @PostMapping("/zzjlPickApp")
    @Log("制造叫料拣货确认")
    @ApiOperation("制造叫料拣货确认")
    @AnonymousAccess
    @PreAuthorize("@el.check('super:man')")
    @DuplicateSubmission(5)
    public ResponseEntity<Object> zzjlPickApp(@RequestBody ZzjlPickConfirm zzjlPick) throws Exception {
        String type= zzjlPick.getType();
        if(type.equals("zzjl_pick_001")){
            PickDetail pickDetail=pickDetailRepository.getById(zzjlPick.getDetail_id());
            if(pickDetail.getPickedQty()>=pickDetail.getOrderQty()){
                return new ResponseEntity<>("拣货完成，返回列表",HttpStatus.OK);
            }
            if(pickDetail.getAllocatedQty()<pickDetail.getOrderQty()) {
                pickDetailService.allocate(pickDetail.getId(), pickDetail.getOrderQty() - pickDetail.getAllocatedQty(), pickDetail.getPo(), BaseStatus.ZZJL);
            }
            JSONArray array=new JSONArray();
            //查询是否有Task或者库存
            List<Task> tasks=taskRepository.getPickNotAllTask(pickDetail.getId());
            String view_type="01";
            String view_des="无库存";
            String view_name="箱单号";
            ZzjlPickHead head=new ZzjlPickHead();
            List<ZzjlPickDetail> detail_list=new ArrayList<>();
            if(tasks.size()>=0){
               for(Task t:tasks){
                   ZzjlPickDetail detail=new ZzjlPickDetail();
                   detail.setStock_code(t.getDstStockCode()==null?"":t.getDstStockCode());
                   detail.setPoint_code(t.getSrcPoint().getCode());
                   detail.setPch(t.getItemKey().getPropC1());
                   detail.setItem_code(t.getItemKey().getItem().getCode());
                   detail.setItem_name(t.getItemKey().getItem().getName());
                   detail.setBonded(pickDetail.getPropC2());
                   detail.setQty(t.getPlanQty()+"");
                   detail_list.add(detail);
                   if(t.getDstStockCode()!=null){
                       view_type="03";
                       view_name="箱单号";
                   }else {
                       view_type = "02";
                       view_name = "现品票";
                   }
               }
            }
//            if(tasks.size()==0){
//                List<XdInventory> invs= inventoryService.queryInvForPickDetail(pickDetail.getId());
//                for(XdInventory inv:invs) {
//                    ZzjlPickDetail detail=new ZzjlPickDetail();
//                    detail.setStock_code(inv.getStockCode());
//                    detail.setPoint_code(inv.getPointCode());
//                    detail.setPch(inv.getPropC1());
//                    detail.setItem_code(inv.getItemCode());
//                    detail.setItem_name(inv.getItemName());
//                    detail.setBonded(inv.getBonded());
//                    detail.setQty(inv.getInvQty());
//                    detail_list.add(detail);
//                    view_type="03";
//                }
//            }
            if(pickDetail.getBeXdPf()){
                view_name="箱单(品番)";
                view_type="04";
            }
            if(view_type.equals("01")){
                throw new BadRequestException( "无库存");
            }
            head.setView_des(view_des);
            head.setView_type(view_type);
            head.setView_list(detail_list);
            head.setView_name(view_name);
            return new ResponseEntity<>(head,HttpStatus.OK);
        }else if(type.equals("zzjl_pick_002")){//扫描现品票或者箱单号
            String xppQRCode= null;
            String stock_code=null;
            if(zzjlPick.getView_type().equals("02")){
                xppQRCode=zzjlPick.getScan_code();
            }else if(zzjlPick.getView_type().equals("03")||zzjlPick.getView_type().equals("04")){
                stock_code=zzjlPick.getScan_code();
                if(stock_code.indexOf("84")==0){
                    stock_code=stock_code.substring(2);
                }
            }
            PickDetail pickDetail=pickDetailRepository.getById(zzjlPick.getDetail_id());
            if(stock_code!=null&&(zzjlPick.getView_type().equals("03")||zzjlPick.getView_type().equals("04"))){
                if(!pickDetail.getBeXdPf()){//箱单出库,按照锁定箱单出库
                    //先把符合数据的箱单全部拣货完成，剩余的再挂靠拣货
                    List<Task> ts=taskRepository.getStockTasks(stock_code);
                    boolean no_exits=true;
                    for(Task task:ts) {
                        if (task.getPickDetail().getId().equals(pickDetail.getId())) {
                            no_exits = false;
                        }
                    }
                    if(no_exits){
                        throw new OperBadRequestException( stock_code+"扫描箱单号不正确");
                    }
                    for(Task task:ts){
                        pickTicketService.pickForTask(task.getId(), task.getSrcStockCode(), task.getPlanQty()-task.getMoveQty(), null, SecurityUtils.getCurrentUsername());
                    }

                    List<Inventory> invs = inventoryRepository.queryInvStockCode(stock_code);
                    for (Inventory inv : invs) {
                        double ky_qty=inv.getQuantity()-inv.getQueuedQty();
                        //生成Task，生成出库扣减库存
                        Task task = taskService.storeTask(null,pickDetail,inv.getArea(),inv.getItemKey(),inv.getPoint(),null,ky_qty,inv.getStockCode());
                        task.setBillCode(pickDetail.getItem().getCode()+"关联箱单出库"+pickDetail.getId());
                        task.setTaskType(BizStatus.XD_PICK);
                        taskRepository.save(task);
                        pickTicketService.pickForTask(task.getId(), task.getSrcStockCode(), task.getPlanQty()-task.getMoveQty(), null, SecurityUtils.getCurrentUsername());
                    }
                }else{//箱单品番出库
                    //扫描箱单内现品票即可
                    String xpp=zzjlPick.getXpp();
                    if(xpp==null){
                        throw new OperBadRequestException( "请扫描现品票");
                    }
                    RRkXpp rRkXpp=xppRecordService.xppAnalysis(xpp,null);
                    //查询是否能找到对应的库存
                    List<Inventory> invs = inventoryRepository.queryInvStockItemCode(stock_code,rRkXpp.getItemCode());
                    Inventory inv=invs.get(0);
                    if(inv.getQuantity()<rRkXpp.getNrs()){
                        throw new OperBadRequestException( "箱单"+stock_code+"品番"+rRkXpp.getItemCode()+"库存数量不足纳入数");
                    }
                    Task task = taskService.storeTask(null,pickDetail,inv.getArea(),inv.getItemKey(),
                            inv.getPoint(),null,rRkXpp.getNrs(),inv.getStockCode());
                    task.setTaskType(BizStatus.XD_PF_PICK);
                    taskRepository.save(task);
                    pickTicketService.pickForTask(task.getId(), task.getSrcStockCode(), task.getPlanQty()-task.getMoveQty(), null, SecurityUtils.getCurrentUsername());
                }

            } else if (xppQRCode!=null&&zzjlPick.getView_type().equals("02")) {//现品票拣货确认
                XppRecord xpp = xppRecordRepository.findByEwmType(xppQRCode, BillParmType.XPP_1001);
                if (Objects.isNull(xpp)){
                    throw new OperBadRequestException(HttpStatus.NOT_FOUND, "未找到对应的现品票二维码");
                }
                ItemKey ik=xpp.getItemKey();
                if(xpp.getCkTaskLog()!=null){
                    throw new OperBadRequestException(HttpStatus.NOT_FOUND, xpp.getItemCode()+"现品票已出库");
                }
                //取现品票上的库位进行拣货
                Long srcPointId=null;
                if(xpp.getInvPoint()!=null){
                    srcPointId=xpp.getInvPoint().getId();
                }
                List<Task> ts=taskService.queryTask(null,pickDetail.getId(),ik.getId(),null,srcPointId);
                Task t=null;
                for(Task task:ts){
                    if(task.getMoveQty()<task.getPlanQty()){
                        t=task;
                    }
                }
                if(ts.size()<=0){
                    throw new OperBadRequestException(HttpStatus.NOT_FOUND, ik.getItem().getCode()+"批次"+ik.getPropC1()+"已全部备货");
                }
                if(t==null){
                    throw new OperBadRequestException(HttpStatus.NOT_FOUND, ik.getItem().getCode()+"批次"+ik.getPropC1()+"找不到待拣货任务");
                }
                pickTicketService.pickForTask(t.getId(),pickDetail.getPo(),xpp.getNrs(),xpp,SecurityUtils.getCurrentUsername());
            }
            return new ResponseEntity<>("操作成功",HttpStatus.OK);
        }else {
            throw  new BadRequestException("请选择记录");
        }
    }

    @PostMapping("/allocatePickDetail")
    @Log("制造叫料分配审核")
    @ApiOperation("制造叫料分配审核")
    @AnonymousAccess
    @Transactional
    public synchronized ResponseEntity<Object> allocatePickDetail(@RequestBody Long[] ids) throws Exception {
        List<Long> pickDetailIds = Arrays.asList(ids);
        Collections.sort(pickDetailIds);//升序排序
        if (pickDetailIds.size() > 0) {
            for (Long pickDetailId : pickDetailIds) {
                PickDetail pickDetail=pickDetailRepository.getById(pickDetailId);
                pickDetailService.allocate(pickDetail.getId(), pickDetail.getOrderQty() - pickDetail.getAllocatedQty(),pickDetail.getPo(),BaseStatus.ZZJL);
            }
        } else {
            throw  new BadRequestException("请选择记录");
        }
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @PostMapping("/cancelAllocatePickDetail")
    @Log("制造叫料取消分配")
    @ApiOperation("制造叫料取消分配")
    @AnonymousAccess
    @Transactional
    public synchronized ResponseEntity<Object> cancelAllocatePickDetail(@RequestBody Long[] ids) throws Exception {
        List<Long> pickDetailIds = Arrays.asList(ids);
        Collections.sort(pickDetailIds);//升序排序
        if (pickDetailIds.size() > 0) {
            for (Long pickDetailId : pickDetailIds) {
                PickDetail pickDetail=pickDetailRepository.getById(pickDetailId);
                if(pickDetail.getAllocatedQty()>0&&pickDetail.getPickedQty()<=0) {
                    //取消分配
                    pickDetailService.cancelAllocate(pickDetail.getId());
                }
            }
        } else {
            throw  new BadRequestException("请选择记录");
        }
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @PostMapping("/sbPickdetail")
    @Log("设变")
    @ApiOperation("设变")
    @AnonymousAccess
    @Transactional
    public ResponseEntity<Object> sbPickdetail(@RequestBody HashMap<String,Object> map) {
        Long pdId=Long.parseLong(map.get("pdId").toString());
        Double sbQty=Double.parseDouble(map.get("sbQty").toString());
        if(map.get("sbItemCode")==null){
            throw new BadRequestException("无关联设变");
        }
        String sbItemCode=map.get("sbItemCode").toString();
        Item sbIt=itemRepository.findByCode(sbItemCode);
        PickDetail oldD=pickDetailRepository.getById(pdId);
        double unSb=oldD.getOrderQty()-oldD.getAllocatedQty()-oldD.getBcQty();
        if(sbIt==null){
            throw new BadRequestException(sbItemCode+"物料不存在");
        }
        if(unSb<sbQty){
            throw new BadRequestException("需求不足数小于"+sbQty);
        }
        oldD.setRemark("设变"+oldD.getOrderQty());
        //查询库存是否足够
        Double invQty=inventoryService.getInvQty(sbIt.getId(),oldD.getPickTicket().getArea().getId(),null);
        if(invQty.intValue()<sbQty.intValue()){
            throw new BadRequestException("库存不足"+invQty.intValue());
        }
        //查找对应的BOM
        PickTicket pt=oldD.getPickTicket();
        if(pt.getPickedQuantity()>0){
            throw new BadRequestException(pt.getCode()+"已备货，不能设变");
        }
        Area shArea=pt.getShArea();
        List<BomAccount> bomList=bomAccountRepository.getItemBomList(sbIt.getId());
        if(bomList.size()<=0){
            throw new BadRequestException(sbIt.getCode()+"找不到对应的Bom工位清单"+sbQty);
        }
        BomAccount bomAccount=bomList.get(0);
        PickDetail newD= pickDetailService.createPickDetail(pt,sbIt,oldD.getPo(),sbQty,oldD.getSupplier(),BaseStatus.ZCCK);
        newD.setRemark("设变");
        newD.setSourceId(oldD.getId());
        newD.setBomId(bomAccount.getId());
        newD.setAc(bomAccount.getAc());
        newD.setSupplier(bomAccount.getSupplier());
        newD.setPoint(bomAccount.getZPoint());
        pickDetailService.allocate(newD.getId(), newD.getOrderQty() - newD.getAllocatedQty(),oldD.getPo(),BaseStatus.ZCCK);
        oldD.setOrderQty(oldD.getOrderQty()-sbQty);
        oldD.setSourceId(newD.getId());
        pickDetailService.update(oldD);
        return new ResponseEntity<>(HttpStatus.OK);
    }


    @PostMapping("/queryTaskApp")
    @Log("查询拣货列表")
    @ApiOperation("查询拣货列表")
    @PreAuthorize("@el.check('super:man')")
    @AnonymousAccess
    public ResponseEntity<Object> queryTaskApp(@RequestBody IScanPut s) {
        List<RPTaskList> t = taskService.queryTaskApp(null);
        return new ResponseEntity<>(t, HttpStatus.OK);
    }

    @PostMapping("/pickingApp")
    @Log("APP拣货确认")
    @ApiOperation("APP拣货确认")
    @PreAuthorize("@el.check('super:man')")
    @AnonymousAccess
    public ResponseEntity<Object> pickingApp(@RequestBody IPPickDetail d) throws Exception {
        return pick_in(d.getPickDetailId());
    }

    @PostMapping("/picking")
    @Log("拣货")
    @ApiOperation("拣货确认")
    @AnonymousAccess
    public synchronized ResponseEntity<Object> picking(@RequestBody Long pickDetailId) throws Exception {
        return pick_in(pickDetailId);
    }

    public ResponseEntity<Object> pick_in(Long pickDetailId) {
//        List<Task> ts=taskRepository.getNotPickTask(resources.getPickTicketId());
//        if(ts.size()<=0){
//            throw new BadRequestException("没有需要拣货的明细");
//        }
//        for(Task t:ts) {
//            pickTicketService.pickForTask(t.getId(), t.getSrcStockCode(), t.getPlanQty()-t.getMoveQty(), null, bhr);
//        }
        //查询未完成的拣货任务
        List<Task> ts = taskService.getPickNotAllTask(pickDetailId);
        if (ts.size() > 0) {

//         for (Task task : ts) {
//              log.error("正在拣货-----");
//              taskService.pickConfirm(task.getId(), task.getPlanQty());
//          }
            for(Task t:ts) {
                pickTicketService.pickForTask(t.getId(), t.getSrcStockCode(), t.getPlanQty()-t.getMoveQty(), null, SecurityUtils.getCurrentUsername());
            }

        } else {
            throw new BadRequestException("没有需要拣货的明细");
        }
        log.error("完成拣货-----");
        return new ResponseEntity(ApiResult.fail(HttpStatus.OK.value(), "已拣货完成，请勿重复操作！", ""), HttpStatus.OK);

    }


    @PostMapping("/pickBarBack")
    @Log("退拣")
    @ApiOperation("退拣")
    @AnonymousAccess
    @Transactional
    public synchronized ResponseEntity<Object> pickBarBack(@RequestBody Long pickDetailId) throws Exception {
        //查询已完成的拣货任务
        List<Task> Tasks = taskService.getPickAllTask(pickDetailId);
        if (Tasks.size() > 0) {
            try {
                for (Task task : Tasks) {
                    taskService.pickBarBack(task.getId(), task.getMoveQty());
                }
            } catch (Exception e) {
                return new ResponseEntity(ApiResult.fail(BAD_REQUEST.value(), e.getMessage(), ""), HttpStatus.BAD_REQUEST);
            }
        } else {
            return new ResponseEntity(ApiResult.fail(BAD_REQUEST.value(), "已退拣完成，请勿重复操作！", ""), HttpStatus.BAD_REQUEST);
        }
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @PostMapping("/autoBcbl")
    @Log("指示残-波次补料")
    @ApiOperation("指示残-波次补料")
    @PreAuthorize("@el.check('super:man')")
    @AnonymousAccess
    @Transactional
    public ResponseEntity<Object> autoBcbl(@RequestBody HashMap<String,Object> map) {
        BillType bt=billTypeRepository.findByName(BaseStatus.BT_BCBL);
        if(bt==null){
            return new ResponseEntity<>("维护波次补料类型", BAD_REQUEST);
        }
        if(map.get("bh_date")==null){
            return new ResponseEntity<>("输入日期", BAD_REQUEST);
        }
        Date blDate=DateUtil.ymd_date(map.get("bh_date").toString());
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        Date date2=DateUtil.ymd_date((LocalDate.now()).format(formatter));
        int comparison=DateUtil.dateComparison(blDate,date2);
        if(comparison<0){
            return new ResponseEntity<>("补货日期不能小于当前日期", BAD_REQUEST);
        }
//        List<AutomaticPlanning>  plans=automaticPlanningRepository.getAll();
//        if(plans.size()>0){
//            AutomaticPlanning plan=plans.get(0);
//            Date blDate=plan.getJhDate();
//            Date blDate=new Date();
//        for(AutomaticPlanning plan:plans){
            //得到出库单的出库库区
            List<Object[]> outAreaGcs=pickTicketRepository.queryBhCkAreas(DateUtil.dateYmd(blDate));
            for(Object[] outAreaGc:outAreaGcs) {
                Long outAreaId=Long.parseLong(outAreaGc[0].toString());
                String gc=outAreaGc[1].toString();
                Area outArea = areaRepository.getById(outAreaId);
                log.info(outArea.getName()+"=="+gc);
                List<Object[]> objs = pickDetailService.getQueryBcbl(blDate,outAreaId,gc);
                if (objs.size() > 0) {
                    PickTicket pickTicket = pickTicketService.storePick(bt, null, outArea, "大", "波次补料");
                    for (Object[] obj : objs) {
                        PickDetail oldDetail = pickDetailRepository.getById(Long.parseLong(obj[0].toString()));
                        double orderQty = oldDetail.getOrderQty() - oldDetail.getAllocatedQty() - oldDetail.getBcQty();
                        PickDetail pickDetail = pickDetailService.createPickDetail(pickTicket, oldDetail.getItem(), null, orderQty, oldDetail.getSupplier(),BaseStatus.ZCCK);
                        pickDetail.setPoint(oldDetail.getPoint());
                        pickDetail.setPo(oldDetail.getPo());
                        pickDetail.setPropC3(oldDetail.getPropC3());
                        pickDetail.setAc(oldDetail.getAc());
                        pickDetail.setContents(oldDetail.getContents());
                        pickDetail.setBomId(oldDetail.getBomId());
                        pickDetail.setSourceId(oldDetail.getId());
                        pickDetail.setSourceName(oldDetail.getPickTicket().getCode());
                        pickDetail.setArea(oldDetail.getArea());
                        pickDetail.setShArea(oldDetail.getShArea());
                        pickDetailService.update(pickDetail);
                        pickDetailService.allocate(pickDetail.getId(), pickDetail.getOrderQty(),pickDetail.getPo(),BaseStatus.ZCCK);
                        double bcQty = pickDetail.getAllocatedQty();
                        //将出单数写入到订单数
                        pickDetail.setOrderQty(bcQty);
                        pickDetailService.update(pickDetail);
                        //本次出单数量
                        pickTicket.setOrderQuantity(pickTicket.getOrderQuantity() + bcQty);
                        pickTicket.setGcCode(oldDetail.getPickTicket().getGcCode());
                        pickTicketService.update(pickTicket);
                        //回写,刷新补货数量
                        oldDetail.setBcQty(pickDetailRepository.getBcQty(oldDetail.getId()));
                        pickDetailService.update(oldDetail);
                    }
                }
            }
//        }
        return new ResponseEntity<>("补料成功",HttpStatus.OK);
    }

}
