/*
 *  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 com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.youchain.DuplicateSubmission.DuplicateSubmission;
import com.youchain.annotation.AnonymousAccess;
import com.youchain.annotation.Log;
import com.youchain.basicdata.domain.Area;
import com.youchain.basicdata.domain.BillType;
import com.youchain.basicdata.domain.Item;
import com.youchain.basicdata.domain.Point;
import com.youchain.basicdata.repository.AreaRepository;
import com.youchain.basicdata.repository.BillTypeRepository;
import com.youchain.basicdata.repository.ItemRepository;
import com.youchain.basicdata.service.AreaService;
import com.youchain.basicdata.service.PointService;
import com.youchain.businessdata.domain.*;
import com.youchain.businessdata.inputJson.IRkPut;
import com.youchain.businessdata.inputJson.IScanPut;
import com.youchain.businessdata.inputJson.XppPut;
import com.youchain.businessdata.inputJson.buttenJson.XppRecordButton;
import com.youchain.businessdata.repository.CountMoveDetailRecordRepository;
import com.youchain.businessdata.repository.XppRecordRepository;
import com.youchain.businessdata.returnJson.RRkXpp;
import com.youchain.businessdata.service.*;
import com.youchain.businessdata.service.dto.XppRecordDto;
import com.youchain.businessdata.service.dto.XppRecordQueryCriteria;
import com.youchain.exception.BadRequestException;
import com.youchain.exception.handler.ApiError;
import com.youchain.exception.handler.ApiResult;
import com.youchain.modules.system.domain.Dept;
import com.youchain.modules.system.domain.Job;
import com.youchain.modules.system.repository.JobRepository;
import com.youchain.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
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.transaction.interceptor.TransactionAspectSupport;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.*;
import javax.servlet.http.HttpServletResponse;

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

/**
 * @author baobinglin
 * @website https://eladmin.vip
 * @date 2024-01-04
 **/
@RestController
@RequiredArgsConstructor
@Api(tags = "xppRecord管理")
@RequestMapping("/api/xppRecord")
@Slf4j
public class XppRecordController {

    private final XppRecordService xppRecordService;
    private final AsnDetailService asnDetailService;
    private final ItemRepository itemRepository;
    private final XppRecordRepository xppRecordRepository;
    private final InventoryLogService inventoryLogService;
    private final InventoryService inventoryService;
    private final PointService pointService;
    private final AreaService areaService;
    private final ItemKeyService itemKeyService;
    private final RedisUtils redisUtils;
    private final PickTicketService pickTicketService;
    private final BillTypeRepository billTypeRepository;
    private final PickDetailService pickDetailService;
    private final TaskLogService taskLogService;
    private final JobRepository jobRepository;
    private final AreaRepository areaRepository;
    private final CodeUtils codeUtils;
    private final CountMoveDetailRecordRepository countMoveDetailRecordRepository;
    private final CountMoveDetailRecordService countMoveDetailRecordService;

    @Log("导出数据XppRecord")
    @ApiOperation("导出数据XppRecord")
    @GetMapping(value = "/download")
    @AnonymousAccess
    public void exportXppRecord(HttpServletResponse response, XppRecordQueryCriteria criteria) throws Exception {
        xppRecordService.download(xppRecordService.queryAll(criteria), response);
    }

    @GetMapping
    @Log("查询xppRecord")
    @ApiOperation("查询xppRecord")
    @AnonymousAccess
    public ResponseEntity<Object> queryXppRecord(XppRecordQueryCriteria criteria, Pageable pageable) {
        criteria.setType("1001");
        return new ResponseEntity<>(xppRecordService.queryAll(criteria, pageable), HttpStatus.OK);
    }

    @GetMapping(value = "/queryXppRecordZztl")
    @Log("查询xppRecord")
    @ApiOperation("查询xppRecord")
    @AnonymousAccess
    public ResponseEntity<Object> queryXppRecordZztl(XppRecordQueryCriteria criteria, Pageable pageable) {
        criteria.setType("2001");
        return new ResponseEntity<>(xppRecordService.queryAll(criteria, pageable), HttpStatus.OK);
    }

    @PostMapping("/changeFz")
    @Log("复制Apros")
    @ApiOperation("复制Apros")
    @AnonymousAccess
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<Object> changeFz( @RequestBody Long[] ids) {
        for (Long id : ids) {
            XppRecord xppRecord = xppRecordRepository.getById(id);
            xppRecord.setBeFz(Boolean.TRUE);
            xppRecordService.update(xppRecord);
        }
        return new ResponseEntity<>("操作成功", HttpStatus.OK);
    }
    @PostMapping("/cancelReceiv")
    @Log("现品票取消收货")
    @ApiOperation("现品票取消收货")
    @PreAuthorize("@el.check('super:man')")
    @Transactional
    public ResponseEntity<Object> cancelReceiv(@RequestBody Long[] ids) {
        Area area=areaService.findByCode(BaseStatus.DEFAULT_AREA);
        for (Long id : ids) {
            //判断现品票是否已收货
            XppRecord xppRecord = xppRecordRepository.getById(id);
            //现品票已收货未上架
            if (!xppRecord.getStatus().equals(BizStatus.RECEIVED)) {
                throw new BadRequestException("收货状态才能取消收货");
            }
            //生成出库记录
            inventoryLogService.storeInventoryLog(BizStatus.RECEIVING_CANCEL, BizStatus.REDUCE, "现品票取消收货", area, xppRecord.getItemKey(), null, null, null,
                    0d, xppRecord.getNrs() + 0d,  xppRecord.getEwm(), BizStatus.RECEIVING_CANCEL, xppRecord.getId(), null, "现品票取消收货");
            xppRecordRepository.delete(xppRecord);
        }
        return new ResponseEntity<>("操作成功", HttpStatus.OK);
    }
    @PostMapping("/xppLyOut")
    @Log("现品票留样出库")
    @ApiOperation("现品票留样出库")
    @PreAuthorize("@el.check('super:man')")
    @Transactional
    @DuplicateSubmission
    public ResponseEntity<Object> xppLyOut(@RequestBody Long[] ids) {
       Area area=areaService.findByCode(BaseStatus.DEFAULT_AREA);
        //生成备货操作
        BillType bt=billTypeRepository.findByName(BaseStatus.BT_LYCK);
        if(bt==null){
            throw  new BadRequestException("维护留样出库类型");
        }
        Long user_id=SecurityUtils.getCurrentUserId();
        List<Job> jobs=jobRepository.jobAreaCodes(user_id);
        if(jobs.size()>0){
            String areaCode= jobs.get(0).getAreaCode();
            area=areaRepository.getByCode(areaCode);
            if(area==null){
                throw new BadRequestException("维护用户岗位对应的库区");
            }
        }
        Point zzkw=pointService.getPoint(BaseStatus.ZZKW,null,null,null);
        if(zzkw==null){
            return new ResponseEntity<>(BaseStatus.ZZKW + "默认制造库位不存在", BAD_REQUEST);
        }
        PickTicket pt=pickTicketService.storePick(bt,null,area,"大","系统留样出库");
        for (Long id : ids) {
            XppRecord xppRecord = xppRecordRepository.getById(id);
            if(xppRecord.getStatus().equals(BizStatus.PUTAWAY)){
                //上架现品票走出库流程
                xppRecordService.xppShipOut(id,area,xppRecord.getInvPoint(),zzkw,BizStatus.RETENTION_OUT,pt.getCode(),"现品票留样（已上架）");
            }else {
                //现品票已收货未上架
                if (!xppRecord.getStatus().equals(BizStatus.RECEIVED)) {
                    throw new BadRequestException("收货状态才能留样出库");
                }
                //生成出库记录
                inventoryLogService.storeInventoryLog(BizStatus.RETENTION_OUT, BizStatus.REDUCE, "现品票留样", area, xppRecord.getItemKey(), null, null, null, null,
                        0d, xppRecord.getNrs() + 0d, null, xppRecord.getEwm(), BizStatus.RETENTION_OUT, xppRecord.getId(), null, "现品票留样");

                PickDetail detail = pickDetailService.createPickDetail(pt, xppRecord.getItem(), xppRecord.getDdbh(), xppRecord.getNrs() + 0d, xppRecord.getRelaSupplier(),BaseStatus.LYCK);
                detail.setRemark(xppRecord.getEwm());
                pickDetailService.update(detail);
                pt.setOrderQuantity(pt.getOrderQuantity() + detail.getOrderQty());
            }
            //生成出库记录
            xppRecord.setStatus(BizStatus.RETENTION_OUT);
            xppRecord.setLyData(new Timestamp(new Date().getTime()));
            xppRecord.setTfLy(true);
            xppRecord.setLyCode(pt.getCode());
            xppRecordService.update(xppRecord);
        }
        pt.setStatus(BizStatus.SHIP_ALL);
        pt.setShipDate(new Timestamp(new Date().getTime()));
        pickTicketService.update(pt);
        return new ResponseEntity<>("操作成功", HttpStatus.OK);
    }



    @PostMapping("/xpphybf")
    @Log("现品票还样部分")
    @ApiOperation("现品票还样部分")
    @PreAuthorize("@el.check('super:man')")
    @Transactional
    public ResponseEntity<Object> xpphybf(@RequestBody XppRecordButton xppRecordButton) {
        xppRecordService.xpphybf(xppRecordButton);
        return new ResponseEntity<>("操作成功", HttpStatus.OK);
    }

    @PostMapping("/xppHyIn")
    @Log("现品票还样整票")
    @ApiOperation("现品票还样整票")
    @PreAuthorize("@el.check('super:man')")
    @Transactional
    public ResponseEntity<Object> xppHyIn(@RequestBody Long[] ids) {
        for (Long id :ids) {
            XppRecord xppRecord = xppRecordRepository.getById(id);
            Area area=xppRecord.getArea();
            if(area==null){
                Long user_id=SecurityUtils.getCurrentUserId();
                List<Job> jobs=jobRepository.jobAreaCodes(user_id);
                if(jobs.size()>0){
                    String areaCode= jobs.get(0).getAreaCode();
                     area=areaRepository.getByCode(areaCode);
                    if(area==null){
                        throw new BadRequestException("维护岗位对应的库区");
                    }
                    xppRecord.setArea(area);
                }
            }
            if (!xppRecord.getStatus().equals(BizStatus.RETENTION_OUT)) {
                throw new BadRequestException("留样出库状态才能还样");
            }
            xppRecord.setStatus(BizStatus.RETENTION_IN);
            xppRecord.setHyData(new Timestamp(new Date().getTime()));
            //生成出库记录
            inventoryLogService.storeInventoryLog(BizStatus.RETENTION_IN, BizStatus.ADD, "现品票还样", area, xppRecord.getItemKey(), null, null, null,
                    0d, xppRecord.getNrs() + 0d, xppRecord.getEwm(), BizStatus.RETENTION_IN, xppRecord.getId(), null, "现品票还样");
           xppRecordService.update(xppRecord);
        }
        return new ResponseEntity<>("操作成功", HttpStatus.OK);
    }

    @PostMapping("/xppBacKIn")
    @Log("现品票退库接收")
    @ApiOperation("现品票退库接收")
    @PreAuthorize("@el.check('super:man')")
    @Transactional
    @DuplicateSubmission
    public ResponseEntity<Object> xppBacKIn(@RequestBody Long[] ids) {
        Area area=areaService.findByCode(BaseStatus.DEFAULT_AREA);
        String username=SecurityUtils.getCurrentUsername();
        Point srcPoint = pointService.getPoint(null, null, BaseStatus.SHZC, null);
        for (Long id :ids) {
            XppRecord xppRecord = xppRecordRepository.getById(id);
            if (!xppRecord.getStatus().equals(BizStatus.SHIP_ALL)&&!xppRecord.getStatus().equals(BizStatus.SL_ALL)) {
                throw new BadRequestException("未出库不能退库");
            }
            AsnDetail d=xppRecord.getAsnDetailId();
            String billCode="现品票退库接收";
            if(d!=null){
                d.setReceivedQty(0d);
                d.setStatus(BizStatus.RECEIVED);
                asnDetailService.update(d);
                TaskLog tl=xppRecord.getCkTaskLog();
                tl.setTkjsQty(tl.getShipQty());
                tl.setTkjsBy(username);
                taskLogService.update(tl);
                Task task=tl.getTask();
                billCode=task.getBillCode();
                if(tl.getSlQty()>0){
                    //扣减线边库存
                    PickDetail pickDetail=task.getPickDetail();
                    List<Inventory> inventorys=inventoryService.getXbHyInv(pickDetail.getItem(),pickDetail.getShArea(),pickDetail.getPoint(),"退库接收",null);
                    if(inventorys.size()>0){
                        Inventory inv= inventorys.get(0);
                        double srcQty=inv.getQuantity();
                        inv.setQuantity(inv.getQuantity()-tl.getSlQty());
                        inventoryService.update(inv);
                        InventoryLog log= inventoryLogService.storeInventoryLog(BizStatus.TK_JS,BizStatus.REDUCE,billCode,pickDetail.getShArea(),inv.getItemKey(),
                                inv.getPoint(),inv.getPoint(),null,null,srcQty,tl.getSlQty(),null,null,task.getBillCode(),
                                tl.getId(),inv.getId(),"退库接收");
                        log.setZzkw(pickDetail.getPoint());
                        inventoryLogService.update(log);
                    }
                }
                xppRecord.setCkTaskLog(null);
                xppRecord.setBhr(null);
                xppRecord.setBhDate(null);
                xppRecord.setFhr(null);
                xppRecord.setFhDate(null);

            }
            xppRecord.setStatus(BizStatus.RECEIVED);
            xppRecord.setTkData(new Timestamp(new Date().getTime()));
            //生成出库记录
            inventoryLogService.storeInventoryLog(BizStatus.TK_JS, BizStatus.ADD, billCode, area, xppRecord.getItemKey(), srcPoint, srcPoint, null,
                    0d, xppRecord.getNrs() + 0d,  xppRecord.getEwm(), BizStatus.BACK_IN, xppRecord.getId(), null, "现品票退库接收");
            xppRecordService.update(xppRecord);
        }
        return new ResponseEntity<>("操作成功", HttpStatus.OK);
    }

    @PostMapping("/xppXbTl")
    @Log("现品票投料")
    @ApiOperation("现品票投料")
    @PreAuthorize("@el.check('super:man')")
    @Transactional
    public ResponseEntity<Object> xppXbTl(@RequestBody IScanPut iPut) {
        String username=SecurityUtils.getCurrentUsername();
//        String pointCode = iPut.getPointCode();
//        if (pointCode == null||pointCode.equals("")) {
//            return new ResponseEntity<>( "库位不能为空", BAD_REQUEST);
//        }
//        Point dstPoint = pointService.findByCode(pointCode, null, null, null, null);
//        if (dstPoint == null) {
//            return new ResponseEntity<>(pointCode + "库位不存在", BAD_REQUEST);
//        }
        for(Long id:iPut.getIds()){
            XppRecord xppRecord=xppRecordRepository.getById(id);
            TaskLog taskLog=xppRecord.getCkTaskLog();
            if (taskLog==null||taskLog.getSlQty()<=0) {
                throw new BadRequestException(xppRecord.getDdbh()+"现品票状态不正确");
            }
            if(xppRecord.getZzkw()!=null){
                throw new BadRequestException(xppRecord.getDdbh()+"现品票状态不正确");
            }
            Task task=taskLog.getTask();
            PickDetail pickDetail=task.getPickDetail();
            PickTicket pickTicket=pickDetail.getPickTicket();
            Point dstPoint=pickDetail.getPoint();
            Point zzkw=pickDetail.getPoint();
            xppRecord.setZzkw(zzkw);
            xppRecord.setZztlDate(new Timestamp(new Date().getTime()));
            xppRecord.setZztlr(username);
            xppRecord.setStatus(BizStatus.ZZKW_TL);
            xppRecordService.update(xppRecord);
            //查找库存
            //扣除线边暂存库位库存，增加线边制造库位库存
            Area shArea=pickTicket.getShArea();
//            Point srcPoint=shArea.getPoint();
            Point srcPoint=pointService.findEntityById(shArea.getPointId());
            List<Inventory> inventorys=inventoryService.getInventoryXbTl(pickDetail.getItem(),shArea,srcPoint,zzkw);
            if(inventorys.size()<=0){
                return new ResponseEntity<>(pickDetail.getItem().getCode()+"暂存区无库存", HttpStatus.BAD_REQUEST);
            }
            double occurQty=taskLog.getSlQty();
            Inventory srcInv=inventorys.get(0);
            double srcQty1=srcInv.getQuantity();
            srcInv.reduce(occurQty);
            inventoryService.update(srcInv);
            taskLog.setTlBy(username);
            taskLog.setTlQty(occurQty);
            taskLogService.update(taskLog);
            inventoryLogService.storeInventoryLog(BizStatus.ZZKW_TL, BizStatus.REDUCE, "制造库位投料", shArea, srcInv.getItemKey(), srcPoint, dstPoint,
                    zzkw,srcQty1, occurQty, xppRecord.getEwm(), BizStatus.ZZKW_TL, xppRecord.getId(), srcInv.getId(), "制造库位投料");
            //制造库位增加库存
            Inventory dstInv=inventoryService.getInventory(srcInv.getItemKey(),shArea,dstPoint,zzkw,srcInv.getDept(),BizStatus.ZZKW_TL,null);
            double srcQty2=dstInv.getQuantity();
            dstInv.addQty(occurQty);
            inventoryService.update(dstInv);
            inventoryLogService.storeInventoryLog(BizStatus.ZZKW_TL, BizStatus.ADD, "制造库位投料", shArea, srcInv.getItemKey(), srcPoint, dstPoint,
                    zzkw,srcQty2, occurQty, xppRecord.getEwm(), BizStatus.ZZKW_TL, xppRecord.getId(), srcInv.getId(), "制造库位投料");
            xppRecordService.update(xppRecord);
        }
        return new ResponseEntity<>("操作成功", HttpStatus.OK);
    }


//    @PostMapping("/collectFromPass")
//    @Log("现品票采集表")
//    @ApiOperation("现品票采集表")
//    @AnonymousAccess
//    @Transactional(rollbackFor = Exception.class)
//    public ResponseEntity<Object> collectFromPass(@RequestBody IScanPut iPut ) {
//        XppRecord xppRecord = xppRecordService.collectFromPass(iPut.getScanCode());
//       // AsnDetail asnDetail = xppRecordService.addAsnDetail(xppRecord);
//        return new ResponseEntity<>("操作成功", HttpStatus.OK);
//    }
//
//    @PostMapping("/xppCollectApp")
//    @Log("APP现品票采集表")
//    @ApiOperation("APP现品票采集表")
//    @AnonymousAccess
//    @Transactional(rollbackFor = Exception.class)
//    public ResponseEntity<Object> xppCollectApp(@RequestBody String resources) {
//        JSONObject jsonObject = JSONObject.parseObject(resources);
//        String ewm=jsonObject.getString("ewm");
//        if (ewm.length()<85){
//            throw new BadRequestException("二维码格式错误");
//        }
//        int i=0;
//        String gc=ewm.substring(i, i+=2);
//        String pq=ewm.substring(i, i+=1);
//        String pf=ewm.substring(i, i+=10);
//        String ac=ewm.substring(i, i+=3);
//        String jgnr=ewm.substring(i, i+=3);
//        String zf=ewm.substring(i, i+=10);
//        String ddbh=ewm.substring(i, i+=8);
//        String nrzsr=ewm.substring(i, i+=8);
//        String nrs=ewm.substring(i, i+=7);
//        String gys=ewm.substring(i, i+=12);
//        String nrcs=ewm.substring(i, i+=6);
//        String zzkw=ewm.substring(i, i+=6);
//        String cgkw=ewm.substring(i, i+=6);
//        String fzh=ewm.substring(i, i+=3);
//        Item item = itemRepository.findByCode(pf);
//        if (item==null){
//            throw new BadRequestException("部品品番不存在");
//        }
//        XppRecord xppRecord = xppRecordRepository.findByCode(ewm);
//        if (xppRecord==null){
//            xppRecord=new XppRecord();
//            xppRecord.setEwm(ewm);
//        }else{
//            throw new BadRequestException("二维码已采集");
//        }
//        RRkXpp xpp = new RRkXpp();
//        xpp.setItemCode(item.getCode());
//        xpp.setItemName(item.getName());
//        xpp.setAc(ac);
//        xpp.setDdbh(ddbh);
//        xpp.setNrs(Integer.valueOf(nrs));
//        xpp.setNrzsr(nrzsr);
//        xpp.setFzh(fzh);
//        xpp.setGys(gys);
//        xpp.setCjsj(new Date());
//        return new ResponseEntity<>(xpp, HttpStatus.OK);
//    }
    @PostMapping("/confirmCollectApp")
    @Log("APP现品票采集表")
    @ApiOperation("APP现品票采集表")
    @PreAuthorize("@el.check('app:list')")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<Object> confirmCollectApp(@RequestBody IScanPut iPut) {
        Set<String> ewms=iPut.getEwms();
        int type=iPut.getType();
        for(String ewm:ewms){
            XppRecord xppRecord = xppRecordService.collectFromPass(ewm);
            Point srcPoint = pointService.getPoint(null, null, BaseStatus.SHZC, null);
            Area area=xppRecord.getArea();
            if(area==null) {
                Long user_id=SecurityUtils.getCurrentUserId();
                List<Job> jobs=jobRepository.jobAreaCodes(user_id);
                if(jobs.size()>0){
                    String areaCode= jobs.get(0).getAreaCode();
                    area=areaRepository.getByCode(areaCode);
                    if(area==null){
                        throw new BadRequestException("维护用户岗位对应的库区");
                    }
                    xppRecord.setArea(area);
                }
            }
            String pc1=DateUtil.dateYmd(new Date());
            ItemKey ik = itemKeyService.getItemKey(xppRecord.getItem(), DateUtil.dateYmdz(),BaseStatus.KS);
            xppRecord.setItemKey(ik);
            if(type==1) {
                inventoryLogService.storeInventoryLog(BizStatus.RECEIVING, BizStatus.ADD, "现品票采集", area, ik, srcPoint, srcPoint, null, 0d, xppRecord.getNrs() + 0d, ewm,
                        BizStatus.ASN, xppRecord.getId(), null, "现品票采集");
            } else if (type==2) {
                inventoryLogService.storeInventoryLog(BizStatus.RETENTION_IN, BizStatus.ADD, "现品票部分还样入库", area, ik, srcPoint, srcPoint, null, 0d, xppRecord.getNrs() + 0d, ewm,
                        BizStatus.RETENTION_IN, xppRecord.getId(), null, "现品票部分还样入库");
                xppRecord.setStatus(BizStatus.RETENTION_IN);
                xppRecord.setHyData(new Timestamp(new Date().getTime()));
                xppRecord.setHctlr(SecurityUtils.getCurrentUsername());
            }
            xppRecordService.update(xppRecord);
        }
        return new ResponseEntity<>("操作成功", HttpStatus.OK);
    }
    @PostMapping("/xppAnalysisApp")
    @Log("APP现品票解析")
    @ApiOperation("APP现品票解析")
    @PreAuthorize("@el.check('super:man')")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<Object> xppAnalysisApp(@RequestBody String resources) {
        JSONObject jsonObject = JSONObject.parseObject(resources);
        String ewm=jsonObject.getString("ewm");
        String type=jsonObject.getString("type");
        XppRecord xppRecord=null;
        if(type.equals("7")){//现品票二维码解析
            RRkXpp xpp = xppRecordService.xppAnalysis(ewm,null);
            return new ResponseEntity<>(xpp, HttpStatus.OK);
        }else{
            String gw="";
            List<XppRecord> xppRecords = xppRecordRepository.findByEwmTypes(ewm,BillParmType.XPP_1001);
            if (xppRecords.size()<=0){
                throw new BadRequestException("现品票未采集");
            }else {
                xppRecord=xppRecords.get(0);
                if (type.equals("1")) {//留样出库
                    if (!xppRecord.getStatus().equals(BizStatus.RECEIVED) && !xppRecord.getStatus().equals(BizStatus.PUTAWAY)) {
                        throw new BadRequestException("现品票状态不正确");
                    }
                } else if (type.equals("2")) {//还样入库
                    if (!xppRecord.getStatus().equals(BizStatus.RETENTION_OUT)) {
                        throw new BadRequestException("现品票状态不正确");
                    }
                } else if (type.equals("3")) {//现品票出库
                    if (!xppRecord.getStatus().equals(BizStatus.PUTAWAY)) {
                        throw new BadRequestException("现品票状态不正确");
                    }
                } else if (type.equals("4")) {//现品票退库接收
                    if (!xppRecord.getStatus().equals(BizStatus.SHIP_ALL) && !xppRecord.getStatus().equals(BizStatus.SL_ALL)) {
                        throw new BadRequestException("现品票状态不正确");
                    }
                } else if (type.equals("5")) {//现品票投料
                    if (xppRecord.getCkTaskLog() == null) {
                        throw new BadRequestException("现品票未出库");
                    }
                    if (xppRecord.getCkTaskLog().getSlQty() <= 0) {
                        throw new BadRequestException("现品票未接收");
                    }

                    Task t = xppRecord.getCkTaskLog().getTask();
                    PickDetail pd = t.getPickDetail();
                    if (pd.getShArea() != null) {
                        gw = pd.getShArea().getWorkingStation();
                    }
                } else if (type.equals("6")) {//现品票移位
                    if (xppRecord.getCkTaskLog() != null) {
                        throw new BadRequestException("现品票已备货");
                    }
                }
            }
            RRkXpp xpp = xppRecordService.xppAnalysis(xppRecord);
            xpp.setGw(gw);
            return new ResponseEntity<>(xpp, HttpStatus.OK);
        }

    }
    @PostMapping("/xppLyOutApp")
    @Log("APP现品票留样出库")
    @ApiOperation("APP现品票留样出库")
    @PreAuthorize("@el.check('super:man')")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<Object> xppLyOutApp(@RequestBody IScanPut iPut) {

        Area area=areaService.findByCode(BaseStatus.DEFAULT_AREA);
        //生成备货操作
        BillType bt=billTypeRepository.findByName(BaseStatus.BT_LYCK);
        if(bt==null){
            throw  new BadRequestException("维护留样出库类型");
        }
        Long user_id=SecurityUtils.getCurrentUserId();
        List<Job> jobs=jobRepository.jobAreaCodes(user_id);
        if(jobs.size()>0){
            String areaCode= jobs.get(0).getAreaCode();
            area=areaRepository.getByCode(areaCode);
            if(area==null){
                throw new BadRequestException("维护用户岗位对应的库区");
            }
        }
        Point zzkw=pointService.getPoint(BaseStatus.ZZKW,null,null,null);
        if(zzkw==null){
            return new ResponseEntity<>(BaseStatus.ZZKW + "默认制造库位不存在", BAD_REQUEST);
        }
        PickTicket pt=pickTicketService.storePick(bt,null,area,"大",iPut.getCph());
        for (Long id : iPut.getIds()) {
            XppRecord xppRecord = xppRecordRepository.getById(id);
            if(xppRecord.getStatus().equals(BizStatus.PUTAWAY)){
                //上架现品票走出库流程
                xppRecordService.xppShipOut(id,area,xppRecord.getInvPoint(),zzkw,BizStatus.RETENTION_OUT,pt.getCode(),"现品票留样（已上架）");
            }else {
                //现品票已收货未上架
                if (!xppRecord.getStatus().equals(BizStatus.RECEIVED)) {
                    throw new BadRequestException("收货状态才能留样出库");
                }
                //生成出库记录
                inventoryLogService.storeInventoryLog(BizStatus.RETENTION_OUT, BizStatus.REDUCE, "现品票留样", area, xppRecord.getItemKey(), null, null, null, null,
                        0d, xppRecord.getNrs() + 0d, null, xppRecord.getEwm(), BizStatus.RETENTION_OUT, xppRecord.getId(), null, "现品票留样");
            }
            PickDetail detail = pickDetailService.createPickDetail(pt, xppRecord.getItem(), xppRecord.getDdbh(), xppRecord.getNrs() + 0d, xppRecord.getRelaSupplier(),BaseStatus.LYCK);
            detail.setRemark(xppRecord.getEwm());
            pickDetailService.update(detail);
            pt.setOrderQuantity(pt.getOrderQuantity() + detail.getOrderQty());
            //生成出库记录
            xppRecord.setStatus(BizStatus.RETENTION_OUT);
            xppRecord.setLyData(new Timestamp(new Date().getTime()));
            xppRecord.setTfLy(true);
            xppRecord.setLyCode(pt.getCode());
            xppRecordService.update(xppRecord);
        }
        pt.setStatus(BizStatus.SHIP_ALL);
        pt.setShipDate(new Timestamp(new Date().getTime()));
        pickTicketService.update(pt);
        return new ResponseEntity<>("操作成功", HttpStatus.OK);

    }

    @PostMapping("/xppShipOutApp")
    @Log("APP现品票出库")
    @ApiOperation("APP现品票出库")
    @PreAuthorize("@el.check('super:man')")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<Object> xppShipOutApp(@RequestBody IScanPut iPut) {
        Set<Long> ids=iPut.getIds();
        String pointCode=iPut.getPointCode();
        if(pointCode==null||pointCode.equals("")){
            return new ResponseEntity<>("出库库位必填", BAD_REQUEST);
        }
        Point srcPoint=pointService.getPoint(pointCode,null,null,null);
        if(srcPoint==null){
            return new ResponseEntity<>(srcPoint + "库位不存在", BAD_REQUEST);
        }
        Area area=srcPoint.getArea();
//        Point zzkw=pointService.getPoint(BaseStatus.ZZKW,null,null,null);
//        if(zzkw==null){
//            return new ResponseEntity<>(BaseStatus.ZZKW + "默认制造库位不存在", BAD_REQUEST);
//        }
        for(Long id:ids){
            XppRecord xppRecord = xppRecordRepository.getById(id);
            if(!srcPoint.getId().equals(xppRecord.getInvPoint().getId())){
                return new ResponseEntity<>(srcPoint + "库位和现品票对应不匹配"+xppRecord.getInvPoint().getCode(), BAD_REQUEST);
            }
            xppRecordService.xppShipOut(id,area,srcPoint,null,BizStatus.SHIPPING,"现品票直接出库","现品票直接出库");
        }
        return new ResponseEntity<>("操作成功", HttpStatus.OK);
    }

    @PostMapping("/queryAreaCode")
    @Log("APP现品票移库库区校验")
    @ApiOperation("APP现品票移库库区校验")
    @PreAuthorize("@el.check('super:man')")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<Object> queryAreaCode(@RequestBody String resources) {
        JSONObject jsonObject = JSONObject.parseObject(resources);
        String areaCode=jsonObject.getString("areaCode");
        if (areaCode == null || areaCode.equals("")) {
            return new ResponseEntity<>("库区不存在", BAD_REQUEST);
        }
        Area area=areaRepository.getJsKq(areaCode);
        if(area==null){
            return new ResponseEntity<>(areaCode + "库区不存在", BAD_REQUEST);
        }
        return new ResponseEntity<>("操作成功", HttpStatus.OK);
    }
    @PostMapping("/xppMoveOutApp")
    @Log("APP现品票移库")
    @ApiOperation("APP现品票移库")
    @PreAuthorize("@el.check('super:man')")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<Object> xppMoveOutApp(@RequestBody IScanPut iPut) {
        Set<Long> ids=iPut.getIds();
        String pointCode=iPut.getPointCode();
        if(pointCode==null||pointCode.equals("")){
            return new ResponseEntity<>("出库库位必填", BAD_REQUEST);
        }
        Point jskw=pointService.getPoint(pointCode,null,null,null);
        if(jskw==null){
            return new ResponseEntity<>(pointCode + "库位不存在", BAD_REQUEST);
        }
        String areaCode=iPut.getAreaCode();
        if (areaCode == null || areaCode.equals("")) {
            return new ResponseEntity<>("库区不存在", BAD_REQUEST);
        }
        Area shArea=areaRepository.getJsKq(areaCode);
        if(shArea==null){
            return new ResponseEntity<>(areaCode + "库区不存在", BAD_REQUEST);
        }
        Point zzkw=null;
//        Point hcwk=null;
        if(jskw.getType().equals(BaseStatus.ZZKW)){
            zzkw=jskw;
//            hcwk=pointService.findEntityById(shArea.getPointId());
        }else{
//            hcwk=jskw;
            //取默认制造库位
            zzkw=pointService.getPoint(BaseStatus.ZZKW,null,null,null);
            if(zzkw==null){
                return new ResponseEntity<>(BaseStatus.ZZKW + "默认制造库位不存在", BAD_REQUEST);
            }
        }
        Dept dept= UserUtils.getDept();
        for(Long id:ids){
            XppRecord xppRecord = xppRecordRepository.getById(id);
            ItemKey ik=xppRecord.getItemKey();
            //扣除库存
            xppRecordService.xppShipOut(id,xppRecord.getInvPoint().getArea(),xppRecord.getInvPoint(),zzkw,BizStatus.YK_OUT,"现品票直接移库接收","现品票直接移库接收");
            //增加库存,线边接收不需要管理到批次，重新生成itemKey
            ItemKey itemKey=itemKeyService.getItemKey(ik.getItem(),null,ik.getPropC2());
            Inventory inventory=inventoryService.getInventory(itemKey,shArea,jskw,zzkw,dept,BizStatus.YK_JS,null);
            double srcQty=inventory.getQuantity();
            inventory.setQuantity(inventory.getQuantity()+xppRecord.getNrs());
            inventoryService.update(inventory);
            InventoryLog inventoryLog=inventoryLogService.storeInventoryLog(BizStatus.YK_JS, BizStatus.ADD, "现品票直接移库接收", shArea, itemKey, inventory.getPoint(), inventory.getPoint(), null,null, srcQty, xppRecord.getNrs()+0d,null,xppRecord.getEwm(),
                    BizStatus.YK_JS, xppRecord.getId(), inventory.getId(), "现品票直接移库接收");
            inventoryLog.setZzkw(zzkw);
            if(shArea.getPointId()!=null) {
                inventoryLog.setZckw(pointService.findEntityById(shArea.getPointId()));
            }
            inventoryLogService.update(inventoryLog);
            xppRecord.setJsDate(new Timestamp(new Date().getTime()));
            xppRecord.setFhr(SecurityUtils.getCurrentUsername());
            xppRecord.setJskw(jskw);
            xppRecord.setStatus(BizStatus.YK_JS);
            xppRecordService.update(xppRecord);
        }
        return new ResponseEntity<>("操作成功", HttpStatus.OK);
    }

    @PostMapping("/xppInvMoveApp")
    @Log("APP现品票移位")
    @ApiOperation("APP现品票移位")
    @PreAuthorize("@el.check('super:man')")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<Object> xppInvMoveApp(@RequestBody IScanPut iPut) {
        Set<Long> ids=iPut.getIds();
        String pointCode=iPut.getPointCode();
        if(pointCode==null||pointCode.equals("")){
            throw  new BadRequestException("移位库位必填");
        }
        String[] str=pointCode.split("]");
        String gdItemCode=null;
        if(str.length>=3) {//固定库位标签
            pointCode = str[3];
            gdItemCode= str[0];
        }
        Point dstPoint=pointService.getPoint(pointCode,null,null,null);
        if(dstPoint==null){
            throw  new BadRequestException(pointCode + "库位不存在");
        }
        if(gdItemCode==null){
            gdItemCode=dstPoint.getItemCode();
        }
        Area dstArea=dstPoint.getArea();
        Point zzkw=null;
//        Point zzkw=pointService.getPoint(BaseStatus.ZZKW,null,null,null);
//        if(zzkw==null){
//            return new ResponseEntity<>(BaseStatus.ZZKW + "默认制造库位不存在", BAD_REQUEST);
//        }
        for(Long id:ids){
            XppRecord xppRecord = xppRecordRepository.getById(id);
            String itemCode=xppRecord.getItem().getCode();
            if(!xppRecord.getStatus().equals(BizStatus.PUTAWAY)){
                throw new BadRequestException(itemCode+"现品票状态不正确");
            }
            if(gdItemCode!=null&&!gdItemCode.equals("")&&!itemCode.equals(gdItemCode)){
                throw new BadRequestException("品番"+itemCode+"和库位固定品番"+gdItemCode+"不匹配");
            }
            ItemKey ik = xppRecord.getItemKey();
            Point srcPoint=xppRecord.getInvPoint();
            Area srcArea=srcPoint.getArea();
            Inventory inventory=inventoryService.getInventory(ik,srcArea,srcPoint,zzkw,srcArea.getDept(),BizStatus.MOVE,null);
            if(inventory==null){
                throw new BadRequestException(itemCode+"该库位无该批次库存");
            }
            int invQty=(int)(inventory.getQuantity()- inventory.getQueuedQty());
            if(invQty<xppRecord.getNrs()){
                throw new BadRequestException(itemCode+"库存可用不足");
            }
            double srcQty=inventory.getQuantity();
            inventory.reduce(xppRecord.getNrs());
            inventoryService.update(inventory);
            inventoryLogService.storeInventoryLog(BizStatus.MOVE, BizStatus.REDUCE, "现品票移位", srcArea, ik, srcPoint, dstPoint, null,  srcQty, xppRecord.getNrs()+0d,xppRecord.getEwm(),
                    BizStatus.MOVE, xppRecord.getId(), inventory.getId(), "现品票移位");
            //目标库位增加
            Inventory dstInv=inventoryService.getInventory(ik,dstArea,dstPoint,zzkw,dstArea.getDept(),BizStatus.MOVE,null);
            inventoryLogService.storeInventoryLog(BizStatus.MOVE, BizStatus.ADD, "现品票移位", dstArea, ik, srcPoint, dstPoint, null,  dstInv.getQuantity(), xppRecord.getNrs()+0d,xppRecord.getEwm(),
                    BizStatus.MOVE, xppRecord.getId(), dstInv.getId(), "现品票移位");
            dstInv.addQty(xppRecord.getNrs());
            inventoryService.update(dstInv);
            xppRecord.setInvPoint(dstPoint);
            xppRecord.setArea(dstArea);
            if(xppRecord.getCountCode()!=null){
                //查找对应明细，将目标库位写入
                List<CountMoveDetailRecord> rs= countMoveDetailRecordRepository.queryDetails(xppRecord.getCountCode(),xppRecord.getId());
                for(CountMoveDetailRecord r:rs){
                    r.setDstPoint(dstPoint);
                    countMoveDetailRecordService.update(r);
                }
                xppRecord.setCountCode(null);
            }
            xppRecordService.update(xppRecord);
        }
        return new ResponseEntity<>("操作成功", HttpStatus.OK);
    }

    @PostMapping("/xppRecordQX")
    @Log("现品票取消")
    @ApiOperation("现品票取消")
    @PreAuthorize("@el.check('super:man')")
    public ResponseEntity<Object> xppRecordQX(@RequestBody Long id) {
        xppRecordService.xppRecordQX(id);
        return new ResponseEntity<>("取消成功", HttpStatus.OK);
    }


    @PostMapping
    @Log("新增xppRecord")
    @ApiOperation("新增xppRecord")
    @PreAuthorize("@el.check('super:man')")
    public ResponseEntity<Object> createXppRecord(@Validated @RequestBody XppRecord resources) {
        return new ResponseEntity<>(xppRecordService.create(resources), HttpStatus.CREATED);
    }

    @PutMapping
    @Log("修改xppRecord")
    @ApiOperation("修改xppRecord")
    @PreAuthorize("@el.check('super:man')")
    public ResponseEntity<Object> updateXppRecord(@Validated @RequestBody XppRecord resources) {
        xppRecordService.update(resources);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @DeleteMapping
    @Log("删除xppRecord")
    @ApiOperation("删除xppRecord")
    @PreAuthorize("@el.check('super:man')")
    @Transactional
    public ResponseEntity<Object> deleteXppRecord(@RequestBody Long[] ids) {
        for (Long id : ids) {
            //查找对应的入库明细是否收货
            XppRecordDto xpp = xppRecordService.findById(id);
            AsnDetail d = asnDetailService.getEntity(xpp.getAsnDetailId().getId());
            if (d.getReceivedQty() == 0) {
                asnDetailService.delete(xpp.getAsnDetailId().getId());
            } else {
                return new ResponseEntity(xpp.getItemCode() + "已收货,不能删除", HttpStatus.BAD_REQUEST);
            }
        }
        xppRecordService.deleteAll(ids);
        return new ResponseEntity<>(HttpStatus.OK);
    }



    @PostMapping("/xppBd")
    @Log("现品票补打")
    @ApiOperation("现品票补打")
    @PreAuthorize("@el.check('super:man')")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<Object> xppBd( @RequestBody HashMap map) {
        Long id=Long.parseLong(map.get("id").toString());
        String fzh=map.get("fzh").toString();
        String nrs=map.get("nrs").toString();
        XppRecord xpp=xppRecordRepository.getById(id);
        xpp.setBdNrs(Integer.parseInt(nrs));
        xpp.setBdFzh(fzh);
        if(fzh.length()!=3){
            throw  new BadRequestException("分支号必须三位数");
        }
        String ewm=xpp.getEwm();
        //替换后三位
        if(ewm.length()==85) {
            ewm = ewm.substring(0, ewm.length() - 3) + fzh;
        }else{
            ewm = ewm+ fzh;
        }
        //替换数量
        String formatted = String.format("%0" + 7 + "d", xpp.getBdNrs());
        String bd_ewm=ewm.substring(0,45)+formatted+ewm.substring(52,ewm.length());
        xpp.setBdEwm(bd_ewm);
        log.info(bd_ewm);
        xppRecordService.update(xpp);
//        inventoryLogService.storeInventoryLog(BizStatus.ADJUST, BizStatus.INVARIANT, "现品票拆分", xpp.getInvPoint().getArea(), xpp.getItemKey(), xpp.getInvPoint(), xpp.getInvPoint(), null,  srcQty, xppRecord.getNrs()+0d,xppRecord.getEwm(),
//                BizStatus.MOVE, xppRecord.getId(), inventory.getId(), "现品票移位");
        return new ResponseEntity<>("操作成功", HttpStatus.OK);
    }

    @PostMapping("/xppSplit")
    @Log("现品票拆分")
    @ApiOperation("现品票拆分")
    @PreAuthorize("@el.check('super:man')")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<Object> xppSplit( @RequestBody HashMap map) {
        Long id=Long.parseLong(map.get("id").toString());
        Integer splitCount = Integer.valueOf(map.get("cfs").toString());
        String fzh=map.get("fzh").toString();
        if(fzh.length()!=3){
            throw  new BadRequestException("分支号必须三位数");
        }
        XppRecord old_xpp=xppRecordRepository.getById(id);
        String ewm=old_xpp.getEwm();
        //替换后三位
        if(ewm.length()>=85) {
            if(ewm.length()>85) {
                ewm = ewm.substring(0, ewm.length() - 3) + fzh+ewm.substring(85);
            }else {
                ewm = ewm.substring(0, ewm.length() - 3) + fzh;
            }
        }else{
            ewm = ewm+ fzh;
        }
        //替换数量
        String formatted = String.format("%0" + 7 + "d", splitCount);
        String new_ewm=ewm.substring(0,45)+formatted+ewm.substring(52,ewm.length());
        //查询二维码是否重复，重复则换个分支号即可
        XppRecord be_cf=xppRecordRepository.findByEwmType(new_ewm, old_xpp.getType());
        if(be_cf!=null){
            throw  new BadRequestException("现品票重复，更换分支号");
        }
        if(!old_xpp.getStatus().equals(BizStatus.PUTAWAY)){
            throw new BadRequestException("现品票状态不正确");
        }
        if (splitCount <= 0) {
            throw new BadRequestException("拆分数量必须大于0");
        }
        if (old_xpp.getNrs() < splitCount) {
            throw new BadRequestException("拆分数量不能大于原数量");
        }
        XppRecord new_xpp = new XppRecord();
        BeanUtils.copyProperties(old_xpp,new_xpp,"id","nrs");
        new_xpp.setNrs(splitCount);
        new_xpp.setFzh(fzh);
        new_xpp.setEwm(new_ewm);
        new_xpp.setDescription(old_xpp.getId()+"现品票拆分");
        //拆分来源数据
        xppRecordRepository.save(new_xpp);
        old_xpp.setNrs(old_xpp.getNrs()-splitCount);
        xppRecordRepository.save(old_xpp);
        return new ResponseEntity<>("操作成功", HttpStatus.OK);
    }
    @PostMapping("/createReceipt")
    @Log("现品票-生成收货清单")
    @ApiOperation("现品票-生成收货清单")
    @PreAuthorize("@el.check('super:man')")
    @Transactional
    @AnonymousAccess
    public ResponseEntity<Object> createReceipt(@RequestBody Long[] ids) {
        String shqdh=codeUtils.getCode_yyMMdd("SH", 3);
        for (Long id : ids) {
            XppRecord xppRecord = xppRecordRepository.getById(id);
            if (xppRecord.getReceiptCode()!=null) {
                throw new BadRequestException("现品票已生成收货清单");
            }else{
                xppRecord.setReceiptCode(shqdh);
            }
            xppRecordService.update(xppRecord);
        }
        return new ResponseEntity<>(ApiResult.success("操作成功",shqdh), HttpStatus.OK);
    }

    @PostMapping("/cancelReceipt")
    @Log("现品票-取消收货清单")
    @ApiOperation("现品票-取消收货清单")
    @PreAuthorize("@el.check('super:man')")
    @Transactional
    @AnonymousAccess
    public ResponseEntity<Object> cancelReceipt(@RequestBody Long[] ids) {
        for (Long id : ids) {
            XppRecord xppRecord = xppRecordRepository.getById(id);
            xppRecord.setReceiptCode(null);
            xppRecordService.update(xppRecord);
        }
        return new ResponseEntity<>("操作成功", HttpStatus.OK);
    }

    @PostMapping("/adjustOut")
    @Log("现品票-现品票调整出库")
    @ApiOperation("现品票-现品票调整出库")
    @PreAuthorize("@el.check('super:man')")
    @Transactional
    @AnonymousAccess
    public ResponseEntity<Object> adjustOut(@RequestBody Long[] ids) {
        for (Long id : ids) {
            XppRecord xppRecord = xppRecordRepository.getById(id);
            xppRecordService.xppShipOut(id,xppRecord.getInvPoint().getArea(),xppRecord.getInvPoint(),null,BizStatus.ADJUST_OUT,"现品票调整出库","现品票调整出库");
        }
        return new ResponseEntity<>("操作成功", HttpStatus.OK);
    }
}