package com.bs.jxc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bs.common.core.domain.AjaxResult;
import com.bs.common.utils.bean.BeanUtils;
import com.bs.jxc.domain.*;
import com.bs.jxc.mapper.CkBillMapper;
import com.bs.jxc.service.*;
import com.github.yulichang.base.MPJBaseServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import java.math.BigDecimal;
import java.util.*;

/**
 * 出入库单据Service业务层处理
 *
 * @author bs
 * @date 2023-07-10
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class CkBillServiceImpl  extends MPJBaseServiceImpl<CkBillMapper, CkBill> implements ICkBillService {


    @Resource
    private ICkBillCargoService ckBillCargoService;
    @Resource
    private ICmCargoService cmCargoService;
    @Resource
    private ICmCustService cmCustService;
    @Resource
    private ICkCargoStockService ckCargoStockService;
    @Resource
    private ICmStockService cmStockService;
    @Resource
    private ICkStockChangeService ckStockChangeService;
    @Resource
    private ICkBillStockService ckBillStockService;

    /**
     * 混配矿操作，生成对应数据
     * @param ckBill
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult mixtureCargo(CkBill ckBill) {
        //原货物
        List<CkBillStock> oldCargos = ckBill.getOldCargos();
        //新货物
        List<CkBillStock> newCargo = ckBill.getNewCargos();
        //创建单据
        ckBill.setBillType("4");
        if (null == ckBill.getBillDate()) {
            ckBill.setBillDate(new Date());
        }
        ckBill.setStatus("1");
        ckBill.setSourceType("3");
        ckBill.setBillStatus("0");
        this.saveOrUpdate(ckBill);
        //根据原货物生成单据明细
        List<Object> billCargoIds = ckBillCargoService.listObjs(new LambdaQueryWrapper<CkBillCargo>().select(CkBillCargo::getId).eq(CkBillCargo::getBillId,ckBill.getId()));
        if(billCargoIds.size()>0){
            ckBillCargoService.removeByIds(billCargoIds);
            ckBillStockService.remove(new LambdaQueryWrapper<CkBillStock>().in(CkBillStock::getBillCargoId,billCargoIds));
        }
        oldCargos.forEach(ele->{
            LambdaQueryWrapper<CkCargoStock> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(CkCargoStock::getCustId,ckBill.getCustId());
            wrapper.eq(CkCargoStock::getCargoId,ele.getCargoId());
            wrapper.eq(CkCargoStock::getStockId,ele.getStockId());
            wrapper.eq(CkCargoStock::getBillNumber,ele.getBillNumber());
            CkCargoStock ckCargoStock = ckCargoStockService.getOne(wrapper);
            //创建单据明细
            CkBillCargo ckBillCargo = new CkBillCargo();
            ckBillCargo.setBillId(ckBill.getId());
            ckBillCargo.setSourceType(ckBill.getSourceType());
            ckBillCargo.setBillStatus(ckBill.getBillStatus());
            ckBillCargo.setBillDate(ckBill.getBillDate());
            ckBillCargo.setBillNumber(ckBill.getBillNumber());
            ckBillCargo.setBillNo(ckBill.getBillNo());
            ckBillCargo.setInoutType("2");
            ckBillCargo.setCargoId(ckCargoStock.getCargoId());
            ckBillCargo.setHsCode(ckCargoStock.getHsCode());
            ckBillCargo.setCargoName(ckCargoStock.getCargoName());
            ckBillCargo.setCargoSpec(ckCargoStock.getCargoSpec());
            ckBillCargo.setVoyageNo("无");
            ckBillCargo.setVesselName("无");
            ckBillCargo.setCustId(ckBill.getCustId());
            CmCust cmCust =cmCustService.getById(ckBill.getCustId());
            ckBillCargo.setCustName(cmCust.getCustName());
            ckBillCargo.setOpType(ckCargoStock.getOpType());
            ckBillCargo.setTradType(ckCargoStock.getTradType());
            ckBillCargo.setCargoNum(ele.getCargoNum());
            ckBillCargo.setCargoWt(ele.getCargoWt());
            ckBillCargo.setCargoVol(ele.getCargoVol());
            ckBillCargo.setOriginCountry(ckCargoStock.getOriginCountry());
            ckBillCargo.setCargoValue(ele.getCargoValue());

            ckBillCargo.setExpiryDate(ckCargoStock.getExpiryDate());
            ckBillCargo.setCargoNumber(ckCargoStock.getCargoNumber());
            ckBillCargo.setItemNumber(ckCargoStock.getItemNumber());
            ckBillCargo.setBookNumber(ckCargoStock.getBookNumber());
            ckBillCargo.setCustomsNo(ckCargoStock.getCustomsNo());
            ckBillCargo.setListNumber(ckCargoStock.getListNumber());
            ckBillCargoService.save(ckBillCargo);
            ele.setBillCargoId(ckBillCargo.getId());
            ele.setInoutType(ckBillCargo.getInoutType());
            ele.setId(null);
            ckBillStockService.save(ele);
            //更新库存
        });
        //创建入库单据，创建入库信息，这里的入库信息无航次信息
        newCargo.forEach(ele->{
            CmCargo cmCargo = cmCargoService.getById(ele.getCargoId());
            //创建单据明细
            CkBillCargo ckBillCargo = new CkBillCargo();
            ckBillCargo.setBillId(ckBill.getId());
            ckBillCargo.setSourceType(ckBill.getSourceType());
            ckBillCargo.setBillStatus(ckBill.getBillStatus());
            ckBillCargo.setBillDate(ckBill.getBillDate());
            ckBillCargo.setBillNumber(ckBill.getBillNumber());
            ckBillCargo.setBillNo(ckBill.getBillNo());
            ckBillCargo.setInoutType("1");
            ckBillCargo.setCargoId(ele.getCargoId());
            ckBillCargo.setHsCode(cmCargo.getHsCode());
            ckBillCargo.setCargoName(cmCargo.getCargoName());
            ckBillCargo.setCargoSpec(cmCargo.getCargoSpec());
            ckBillCargo.setVoyageNo("无");
            ckBillCargo.setVesselName("无");
            ckBillCargo.setCustId(ckBill.getCustId());
            CmCust cmCust =cmCustService.getById(ckBill.getCustId());
            ckBillCargo.setCustName(cmCust.getCustName());
            ckBillCargo.setOpType("1");
            ckBillCargo.setTradType("1");
            ckBillCargo.setCargoNum(ele.getCargoNum());
            ckBillCargo.setCargoWt(ele.getCargoWt());
            ckBillCargo.setCargoVol(ele.getCargoVol());
            ckBillCargo.setCargoValue(ele.getCargoValue());
            ckBillCargo.setOriginCountry(cmCargo.getOriginCountry());
            ckBillCargo.setExpiryDate(ele.getExpiryDate());
            ckBillCargo.setCargoNumber(ele.getCargoNumber());
            ckBillCargo.setItemNumber(ele.getItemNumber());
            ckBillCargo.setBookNumber(ele.getBookNumber());
            ckBillCargo.setCustomsNo(ele.getCustomsNo());
            ckBillCargo.setListNumber(ele.getListNumber());
            ckBillCargoService.save(ckBillCargo);
            ele.setBillCargoId(ckBillCargo.getId());
            ele.setBillNumber(ckBillCargo.getBillNumber());
            ele.setInoutType(ckBillCargo.getInoutType());
            ele.setId(null);
            ckBillStockService.save(ele);
        });
        if(ckBill.getSubmitStatus()){
            return warehouseWork(ckBill,false);
        }
        return AjaxResult.success();
    }


    /**
     * 货物转场，生成对应数据(保存、更新、提交)
     * @param ckBill
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult transferCargo(CkBill ckBill) {
        CkBillStock oldCargo = ckBill.getOldCargo();
        List<CkBillStock> newCargos = ckBill.getNewCargos();
        //创建单据
        ckBill.setBillType("3");
        if (null == ckBill.getBillDate()) {
            ckBill.setBillDate(new Date());
        }
        ckBill.setStatus("1");
        ckBill.setBillStatus("0");
        ckBill.setSourceType("2");
        this.saveOrUpdate(ckBill);
        //查询货物库存信息
        LambdaQueryWrapper<CkCargoStock> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CkCargoStock::getCustId,ckBill.getCustId());
        wrapper.eq(CkCargoStock::getCargoId,oldCargo.getCargoId());
        wrapper.eq(CkCargoStock::getStockId,oldCargo.getStockId());
        wrapper.eq(CkCargoStock::getBillNumber,oldCargo.getBillNumber());
        CkCargoStock ckCargoStock = ckCargoStockService.getOne(wrapper);
        //创建出库单据明细
        //查询单据下是否有出库单据明细，有查询出来替换
        LambdaQueryWrapper<CkBillCargo> outBillWrapper =  new LambdaQueryWrapper();
        outBillWrapper.eq(CkBillCargo::getBillId,ckBill.getId());
        outBillWrapper.eq(CkBillCargo::getInoutType,"2");
        CkBillCargo outBillCargo = ckBillCargoService.getOne(outBillWrapper);
        if(outBillCargo==null){
            outBillCargo = new CkBillCargo();
        }
        outBillCargo.setBillId(ckBill.getId());
        outBillCargo.setBillStatus(ckBill.getBillStatus());
        outBillCargo.setSourceType(ckBill.getSourceType());
        outBillCargo.setBillDate(ckBill.getBillDate());
        outBillCargo.setBillNumber(ckBill.getBillNumber());
        outBillCargo.setBillNo(ckBill.getBillNo());
        outBillCargo.setInoutType("2");
        outBillCargo.setCargoId(ckCargoStock.getCargoId());
        outBillCargo.setHsCode(ckCargoStock.getHsCode());
        outBillCargo.setCargoName(ckCargoStock.getCargoName());
        outBillCargo.setCargoSpec(ckCargoStock.getCargoSpec());
        outBillCargo.setVoyageNo("无");
        outBillCargo.setVesselName("无");
        outBillCargo.setCustId(ckBill.getCustId());
        CmCust cmCust =cmCustService.getById(ckBill.getCustId());
        outBillCargo.setCustName(cmCust.getCustName());
        outBillCargo.setOpType(ckCargoStock.getOpType());
        outBillCargo.setTradType(ckCargoStock.getTradType());
        outBillCargo.setOriginCountry(ckCargoStock.getOriginCountry());
        outBillCargo.setCargoNum(oldCargo.getCargoNum());
        outBillCargo.setCargoWt(oldCargo.getCargoWt());
        outBillCargo.setCargoVol(oldCargo.getCargoVol());
        outBillCargo.setCargoValue(oldCargo.getCargoValue());
        outBillCargo.setExpiryDate(ckCargoStock.getExpiryDate());
        outBillCargo.setCargoNumber(ckCargoStock.getCargoNumber());
        outBillCargo.setItemNumber(ckCargoStock.getItemNumber());
        outBillCargo.setBookNumber(ckCargoStock.getBookNumber());
        outBillCargo.setCustomsNo(ckCargoStock.getCustomsNo());
        outBillCargo.setListNumber(ckCargoStock.getListNumber());
        ckBillCargoService.saveOrUpdate(outBillCargo);
        //出库单据明细仓库信息
        LambdaQueryWrapper<CkBillStock> outStockWrapper =  new LambdaQueryWrapper();
        outStockWrapper.eq(CkBillStock::getBillCargoId,outBillCargo.getId());
        outStockWrapper.eq(CkBillStock::getInoutType,"2");
        CkBillStock outBillStock = ckBillStockService.getOne(outStockWrapper);
        if(outBillStock!=null){
            oldCargo.setId(outBillStock.getId());
        }
        oldCargo.setBillCargoId(outBillCargo.getId());
        oldCargo.setInoutType("2");
        ckBillStockService.saveOrUpdate(oldCargo);
        //入库单据明细
        //查询单据下是否有出库单据明细，有查询出来替换
        LambdaQueryWrapper<CkBillCargo> inBillWrapper =  new LambdaQueryWrapper();
        inBillWrapper.select(CkBillCargo::getId);
        inBillWrapper.eq(CkBillCargo::getBillId,ckBill.getId());
        inBillWrapper.eq(CkBillCargo::getInoutType,"1");
        List<Object> ids = ckBillCargoService.listObjs(inBillWrapper);
        ckBillCargoService.removeByIds(ids);
        //入库单据明细仓库信息
        if(ids.size()>0){
            LambdaQueryWrapper<CkBillStock> inStockWrapper =  new LambdaQueryWrapper();
            inStockWrapper.in(CkBillStock::getBillCargoId,ids);
            inStockWrapper.eq(CkBillStock::getInoutType,"1");
            ckBillStockService.remove(inStockWrapper);
        }
        newCargos.forEach(newCargo->{
            newCargo.setId(null);
            CkBillCargo inBillCargo = new CkBillCargo();
            inBillCargo.setBillId(ckBill.getId());
            inBillCargo.setBillStatus(ckBill.getBillStatus());
            inBillCargo.setSourceType(ckBill.getSourceType());
            inBillCargo.setBillDate(ckBill.getBillDate());
            inBillCargo.setBillNumber(ckBill.getBillNumber());
            inBillCargo.setBillNo(ckBill.getBillNo());
            inBillCargo.setInoutType("1");
            inBillCargo.setCargoId(ckCargoStock.getCargoId());
            inBillCargo.setHsCode(ckCargoStock.getHsCode());
            inBillCargo.setCargoName(ckCargoStock.getCargoName());
            inBillCargo.setCargoSpec(ckCargoStock.getCargoSpec());
            inBillCargo.setVoyageNo("无");
            inBillCargo.setVesselName("无");
            inBillCargo.setCustId(ckBill.getCustId());
            inBillCargo.setCustName(cmCust.getCustName());
            inBillCargo.setOpType(ckCargoStock.getOpType());
            inBillCargo.setTradType(ckCargoStock.getTradType());
            inBillCargo.setOriginCountry(ckCargoStock.getOriginCountry());
            inBillCargo.setCargoNum(oldCargo.getCargoNum());
            inBillCargo.setCargoWt(oldCargo.getCargoWt());
            inBillCargo.setCargoVol(oldCargo.getCargoVol());
            inBillCargo.setCargoValue(oldCargo.getCargoValue());
            inBillCargo.setExpiryDate(newCargo.getExpiryDate());
            inBillCargo.setCargoNumber(ckCargoStock.getCargoNumber());
            inBillCargo.setItemNumber(ckCargoStock.getItemNumber());
            inBillCargo.setBookNumber(newCargo.getBookNumber());
            inBillCargo.setCustomsNo(newCargo.getCustomsNo());
            inBillCargo.setListNumber(newCargo.getListNumber());
            inBillCargo.setCargoFlow(newCargo.getCargoFlow());
            ckBillCargoService.save(inBillCargo);
            newCargo.setBillCargoId(inBillCargo.getId());
            newCargo.setBillNumber(inBillCargo.getBillNumber());
            newCargo.setInoutType("1");
        });
        ckBillStockService.saveBatch(newCargos);
        //更新入库（）
        if(ckBill.getSubmitStatus()){
            return  warehouseWork(ckBill,false);
        }
        return AjaxResult.success();
    }

    /**
     * 货物出库
     * @param ckBill
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult outCargo(CkBill ckBill) {
        List<CkBillCargo> ckBillCargos = ckBill.getCkBillCargos();
        // 判断如果为空，去数据库中寻找相应数据
        if (null == ckBillCargos || ckBillCargos.size() ==0) {
            ckBillCargos = ckBillCargoService.list(new LambdaQueryWrapper<CkBillCargo>().eq(CkBillCargo::getBillId, ckBill.getId()));
        }
        //创建单据
        ckBill.setBillType("2");
        ckBill.setStatus("1");
        ckBill.setBillStatus("0");
        ckBill.setSourceType("1");
        this.saveOrUpdate(ckBill);
        Map<Long,CkBillStock> billStockMap = new HashMap<>();
        ckBillCargos.forEach(ckBillCargo->{
            ckBillCargo.setBillStatus("0");
            //创建单据明细
            LambdaQueryWrapper<CkCargoStock> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(CkCargoStock::getCargoId,ckBillCargo.getCargoId());
            wrapper.eq(CkCargoStock::getStockId,ckBillCargo.getOutStockId());
            wrapper.eq(CkCargoStock::getBillNumber,ckBillCargo.getOutBillNumber());
            CkCargoStock ckCargoStock = ckCargoStockService.getOne(wrapper);
            ckBillCargo.setBillDate(ckBill.getBillDate());
            ckBillCargo.setBillNumber(ckBill.getBillNumber());
            ckBillCargo.setBillNo(ckBill.getBillNo());
            ckBillCargo.setInoutType(ckBill.getBillType());
            ckBillCargo.setSourceType("1");
            ckBillCargo.setCargoId(ckCargoStock.getCargoId());
            ckBillCargo.setHsCode(ckCargoStock.getHsCode());
            ckBillCargo.setCargoName(ckCargoStock.getCargoName());
            ckBillCargo.setCargoSpec(ckCargoStock.getCargoSpec());
            ckBillCargo.setVoyageNo(ckBill.getVoyageNo());
            ckBillCargo.setVesselName(ckBill.getVesselName());
            ckBillCargo.setVesselId(ckBill.getVesselId());
            ckBillCargo.setCustId(ckBillCargo.getCustId());
            CmCust cmCust =cmCustService.getById(ckBillCargo.getCustId());
            ckBillCargo.setCustName(cmCust.getCustName());
            ckBillCargo.setOpType(ckCargoStock.getOpType());
            ckBillCargo.setTradType(ckCargoStock.getTradType());
            ckBillCargo.setOriginCountry(ckCargoStock.getOriginCountry());
            ckBillCargo.setBillId(ckBill.getId());
            CkBillStock ckBillStock;
            if(ckBillCargo.getId()!=null){
                ckBillStock = ckBillStockService.getOne(new LambdaQueryWrapper<CkBillStock>().eq(CkBillStock::getBillCargoId,ckBillCargo.getId()));
            }else{
                ckBillStock = new CkBillStock();
            }
            ckBillCargoService.saveOrUpdate(ckBillCargo);
            ckBillStock.setInoutType("2");
            ckBillStock.setStockId(ckCargoStock.getStockId());
            ckBillStock.setStockName(ckCargoStock.getStockName());
            ckBillStock.setStockCode(ckCargoStock.getStockCode());
            ckBillStock.setBillNumber(ckBillCargo.getOutBillNumber());
            ckBillStock.setCargoNum(ckBillCargo.getCargoNum());
            ckBillStock.setCargoWt(ckBillCargo.getCargoWt());
            ckBillStock.setCargoVol(ckBillCargo.getCargoVol());
            ckBillStock.setCargoValue(ckBillCargo.getCargoValue());
            ckBillStock.setBillCargoId(ckBillCargo.getId());
            ckBillStockService.saveOrUpdate(ckBillStock);
            billStockMap.put(ckBillCargo.getId(),ckBillStock);
        });
        if(ckBill.getSubmitStatus()){
            return warehouseWork(ckBill,false);
        }
        return AjaxResult.success();
    }




    /**
     * 货物入库
     * @param ckBill
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult putCargo(CkBill ckBill) {
        //创建单据
        ckBill.setBillType("1");
        ckBill.setStatus("1");
        ckBill.setBillStatus("0");
        ckBill.setSourceType("1");
        this.saveOrUpdate(ckBill);
        List<CkBillCargo> ckBillCargos = ckBill.getCkBillCargos();
        // 判断如果为空，去数据库中寻找相应数据
        if (null == ckBillCargos || ckBillCargos.size() ==0) {
            ckBillCargos = ckBillCargoService.list(new LambdaQueryWrapper<CkBillCargo>().eq(CkBillCargo::getBillId, ckBill.getId()));
        }
        Map<Long,CkBillStock> billStockMap = new HashMap<>();
        ckBillCargos.forEach(ckBillCargo->{
            ckBillCargo.setBillStatus("0");
            //创建单据明细
            ckBillCargo.setBillDate(ckBill.getBillDate());
            ckBillCargo.setBillNumber(ckBill.getBillNumber());
            ckBillCargo.setBillNo(ckBill.getBillNo());
            ckBillCargo.setSourceType("1");
            ckBillCargo.setInoutType(ckBill.getBillType());
            //ckBillCargo.setVoyageNo("无");
            //ckBillCargo.setVesselName("无");
            CmCust cmCust =cmCustService.getById(ckBillCargo.getCustId());
            ckBillCargo.setCustName(cmCust.getCustName());
            ckBillCargo.setOpType("1");
            ckBillCargo.setTradType("1");
            ckBillCargo.setBillId(ckBill.getId());
            ckBillCargo.setVesselId(ckBill.getVesselId());
            ckBillCargo.setVesselName(ckBill.getVesselName());
            ckBillCargo.setVoyageNo(ckBill.getVoyageNo());
            CmStock cmStock = cmStockService.getById(ckBillCargo.getInStockId());
            CkBillStock ckBillStock;
            if(ckBillCargo.getId()!=null){
                ckBillStock = ckBillStockService.getOne(new LambdaQueryWrapper<CkBillStock>().eq(CkBillStock::getBillCargoId,ckBillCargo.getId()));
            }else{
                ckBillStock = new CkBillStock();
            }
            ckBillCargoService.saveOrUpdate(ckBillCargo);
            ckBillStock.setInoutType("1");
            ckBillStock.setStockId(cmStock.getId());
            ckBillStock.setStockName(cmStock.getStockName());
            ckBillStock.setStockCode(cmStock.getStockCode());
            ckBillStock.setBillNumber(ckBillCargo.getBillNumber());
            ckBillStock.setCargoNum(ckBillCargo.getCargoNum());
            ckBillStock.setCargoWt(ckBillCargo.getCargoWt());
            ckBillStock.setCargoVol(ckBillCargo.getCargoVol());
            ckBillStock.setCargoValue(ckBillCargo.getCargoValue());
            ckBillStock.setBillCargoId(ckBillCargo.getId());
            ckBillStockService.saveOrUpdate(ckBillStock);
            billStockMap.put(ckBillCargo.getId(),ckBillStock);
        });
        //这里需要出入库记录
        if(ckBill.getSubmitStatus()){
            return warehouseWork(ckBill,false);
        }
        return AjaxResult.success();
    }





    /**
     * 货物入库（撤回）
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult recallPutBill(Long id) {
        return warehouseWork(this.getById(id),true);
    }
    /**
     * 货物出库（撤回）
     * @param id
     * @return
     */
    public AjaxResult revocationStock(Long id) {
        CkBill ckBill = new CkBill();
        ckBill.setId(id);
        ckBill.setBillStatus("0");
        //更新单据与明细
        this.updateById(ckBill);
        CkBillCargo updateBillCargo = new CkBillCargo();
        updateBillCargo.setBillStatus("0");
        LambdaQueryWrapper<CkBillCargo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CkBillCargo::getBillId,id);
        ckBillCargoService.update(updateBillCargo,wrapper);
        //删除入库记录
        ckStockChangeService.remove(new LambdaQueryWrapper<CkStockChange>().eq(CkStockChange::getBillId,id));
        //调回出库的库存
        List<CkBillCargo>  ckBillCargos = ckBillCargoService.list(wrapper);
        for (int i = 0; i < ckBillCargos.size(); i++) {
            CkBillCargo ckBillCargo = ckBillCargos.get(i);
            //单据明细下出入库信息
            LambdaQueryWrapper<CkBillStock> stockWapper = new LambdaQueryWrapper<>();
            stockWapper.eq(CkBillStock::getBillCargoId,ckBillCargo.getId());
            List<CkBillStock> ckBillStocks = ckBillStockService.list(stockWapper);
            //入库
            if(ckBillCargo.getInoutType().equals("1")){
                //原入库操作，现直接删除入库记录
                for (int i1 = 0; i1 < ckBillStocks.size(); i1++) {
                    CkBillStock ckBillStock = ckBillStocks.get(i1);
                    LambdaQueryWrapper<CkCargoStock> stockWrapper = new LambdaQueryWrapper<>();
                    stockWrapper.eq(CkCargoStock::getCustId,ckBillCargo.getCustId());
                    stockWrapper.eq(CkCargoStock::getCargoId,ckBillCargo.getCargoId());
                    stockWrapper.eq(CkCargoStock::getStockId,ckBillStock.getStockId());
                    stockWrapper.eq(CkCargoStock::getBillNumber,ckBillStock.getBillNumber());
                    CkCargoStock ckCargoStock = ckCargoStockService.getOne(stockWrapper);
                    if(ckCargoStock.getCargoNum().compareTo(ckBillStock.getCargoNum())==0&&
                            ckCargoStock.getCargoWt().compareTo(ckBillStock.getCargoWt())==0&&
                            ckCargoStock.getCargoVol().compareTo(ckBillStock.getCargoVol())==0){
                            //&&ckCargoStock.getCargoValue().compareTo(ckBillStock.getCargoValue())==0
                        ckCargoStockService.removeById(ckCargoStock);
                    }else{
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手动回滚事务
                        return AjaxResult.error("数据已经被出库，不允许撤回操作");
                    }
                }
            }else{
                //原出库操作，现加库存
                ckBillStocks.forEach(ckBillStock->{
                    LambdaQueryWrapper<CkCargoStock> stockWrapper = new LambdaQueryWrapper<>();
                    stockWrapper.eq(CkCargoStock::getCustId,ckBillCargo.getCustId());
                    stockWrapper.eq(CkCargoStock::getCargoId,ckBillCargo.getCargoId());
                    stockWrapper.eq(CkCargoStock::getStockId,ckBillStock.getStockId());
                    stockWrapper.eq(CkCargoStock::getBillNumber,ckBillStock.getBillNumber());
                    CkCargoStock ckCargoStock = ckCargoStockService.getOne(stockWrapper);
                    ckCargoStock.setCargoNum(ckCargoStock.getCargoNum().add(ckBillStock.getCargoNum()));
                    ckCargoStock.setCargoWt(ckCargoStock.getCargoWt().add(ckBillStock.getCargoWt()));
                    ckCargoStock.setCargoVol(ckCargoStock.getCargoVol().add(ckBillStock.getCargoVol()));
                    ckCargoStock.setCargoValue(ckCargoStock.getCargoValue().add(ckBillStock.getCargoValue()));
                    ckCargoStockService.updateById(ckCargoStock);
                });
            }
        }
        return AjaxResult.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult recallOutBill(Long id) {
        return warehouseWork(this.getById(id),true);
    }
    /**
     * 出入库对操作
     * @param ckBill
     * @return
     * isRevocation 是否撤回操作 true 撤回
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult warehouseWork(CkBill ckBill,Boolean isRevocation){
        if(isRevocation){
            return revocationStock(ckBill.getId());
        }else{
            return setCargoStock(ckBill);
        }
    }

    /**
     *
     * @param ckBill
     */
    public AjaxResult setCargoStock(CkBill ckBill){
        ckBill.setBillStatus("1");
        LambdaQueryWrapper<CkBillCargo> wapper = new LambdaQueryWrapper<>();
        wapper.eq(CkBillCargo::getBillId,ckBill.getId());
        //单据明细
        List<CkBillCargo> ckBillCargos = ckBillCargoService.list(wapper);
        for (int i = 0; i < ckBillCargos.size(); i++) {
            CkBillCargo ckBillCargo = ckBillCargos.get(i);
            ckBillCargo.setBillStatus("1");
            //单据明细下出入库信息
            LambdaQueryWrapper<CkBillStock> stockWapper = new LambdaQueryWrapper<>();
            stockWapper.eq(CkBillStock::getBillCargoId,ckBillCargo.getId());
            List<CkBillStock> ckBillStocks = ckBillStockService.list(stockWapper);
            //入库
            if(ckBillCargo.getInoutType().equals("1")){
                ckBillStocks.forEach(ckBillStock->{
                    CkCargoStock inCargoStock = new CkCargoStock();
                    BeanUtils.copyProperties(ckBillCargo,inCargoStock,"id");
                    inCargoStock.setStockDate(ckBillCargo.getBillDate());
                    CmStock cmStock = cmStockService.getById(ckBillStock.getStockId());
                    inCargoStock.setStockId(cmStock.getId());
                    inCargoStock.setStockCode(cmStock.getStockCode());
                    inCargoStock.setStockName(cmStock.getStockName());
                    inCargoStock.setCargoNum(ckBillStock.getCargoNum());
                    inCargoStock.setCargoWt(ckBillStock.getCargoWt());
                    inCargoStock.setCargoVol(ckBillStock.getCargoVol());
                    inCargoStock.setCargoValue(ckBillStock.getCargoValue());
                    ckCargoStockService.save(inCargoStock);
                    saveChange(ckBillCargo,ckBillStock);
                });
            }else{
                //出库
                for (int j = 0; j < ckBillStocks.size(); j++) {
                    CkBillStock ckBillStock = ckBillStocks.get(j);
                    LambdaQueryWrapper<CkCargoStock> wrapper = new LambdaQueryWrapper<>();
                    wrapper.eq(CkCargoStock::getCustId,ckBillCargo.getCustId());
                    wrapper.eq(CkCargoStock::getCargoId,ckBillCargo.getCargoId());
                    wrapper.eq(CkCargoStock::getStockId,ckBillStock.getStockId());
                    wrapper.eq(CkCargoStock::getBillNumber,ckBillStock.getBillNumber());
                    CkCargoStock ckCargoStock = ckCargoStockService.getOne(wrapper);
                    Boolean flag = false;
                    if(ckCargoStock.getCargoNum().compareTo(ckBillStock.getCargoNum())>=0){
                        flag = true;
                        ckCargoStock.setCargoNum(ckCargoStock.getCargoNum().subtract(ckBillStock.getCargoNum()));
                    }
                    if(ckCargoStock.getCargoWt().compareTo(ckBillStock.getCargoWt())>=0){
                        flag = true;
                        ckCargoStock.setCargoWt(ckCargoStock.getCargoWt().subtract(ckBillStock.getCargoWt()));
                    }
                    if(ckCargoStock.getCargoVol().compareTo(ckBillStock.getCargoVol())>=0){
                        flag = true;
                        ckCargoStock.setCargoVol(ckCargoStock.getCargoVol().subtract(ckBillStock.getCargoVol()));
                    }
                    if(ckCargoStock.getCargoValue().compareTo(ckBillStock.getCargoValue())>=0){
                        ckCargoStock.setCargoValue(ckCargoStock.getCargoValue().subtract(ckBillStock.getCargoValue()));
                    }
                    if(!flag){
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手动回滚事务
                        return AjaxResult.error("库存不足");
                    }
                    ckCargoStockService.updateById(ckCargoStock);
                    saveChange(ckBillCargo,ckBillStock);
                }
            }
        }
        this.updateById(ckBill);
        ckBillCargoService.updateBatchById(ckBillCargos);
        return AjaxResult.success();
    }



    /**
     *
     * @param ckBillCargo
     *  ckBillCargo
     * @param ckBillStock
     */
    @Override
    public void saveChange(CkBillCargo ckBillCargo,CkBillStock ckBillStock){
        //查询这个货主，这个商品，这个仓库下剩余量
        QueryWrapper<CkCargoStock> countWapper = new QueryWrapper<>();
        countWapper.select(" SUM(cargo_num) AS cargo_num,SUM(cargo_wt) AS cargo_wt,SUM(cargo_vol) AS cargo_vol,SUM(cargo_value) AS cargo_value").lambda().
                eq(CkCargoStock::getCustId,ckBillCargo.getCustId()).
                eq(CkCargoStock::getCargoId,ckBillCargo.getCargoId()).
                eq(CkCargoStock::getStockId,ckBillStock.getStockId());
        CkCargoStock countStock = ckCargoStockService.getOne(countWapper);
        //第一次入库的时候会空指针
        if(countStock==null){
            countStock = new CkCargoStock();
            countStock.setCargoNum(new BigDecimal(0));
            countStock.setCargoWt(new BigDecimal(0));
            countStock.setCargoVol(new BigDecimal(0));
            countStock.setCargoValue(new BigDecimal(0));
        }
        CkStockChange ckStockChange = new CkStockChange();
        BeanUtils.copyProperties(ckBillCargo,ckStockChange,"id");
        ckStockChange.setChangeType(ckBillCargo.getInoutType());
        CmStock cmStock = cmStockService.getById(ckBillStock.getStockId());
        ckStockChange.setStockId(cmStock.getId());
        ckStockChange.setStockName(cmStock.getStockName());
        ckStockChange.setBeforeNum(countStock.getCargoNum());
        ckStockChange.setBeforeWt(countStock.getCargoWt());
        ckStockChange.setBeforeVol(countStock.getCargoVol());
        ckStockChange.setBeforeValue(countStock.getCargoValue());
        ckStockChange.setChangeNum(ckBillStock.getCargoNum());
        ckStockChange.setChangeWt(ckBillStock.getCargoWt());
        ckStockChange.setChangeVol(ckBillStock.getCargoVol());
        ckStockChange.setChangeValue(ckBillStock.getCargoValue());
        ckStockChange.setChangeDate(ckBillCargo.getBillDate());
        //出库
        if(ckBillCargo.getInoutType().equals("2")){
            ckStockChange.setAfterNum(ckStockChange.getBeforeNum().subtract(ckBillStock.getCargoNum()));
            ckStockChange.setAfterWt(ckStockChange.getBeforeWt().subtract(ckBillStock.getCargoWt()));
            ckStockChange.setAfterVol(ckStockChange.getBeforeVol().subtract(ckBillStock.getCargoVol()));
            ckStockChange.setAfterValue(ckStockChange.getBeforeValue().subtract(ckBillStock.getCargoValue()));
        }else{
            //入库
            ckStockChange.setAfterNum(ckBillStock.getCargoNum().add(ckStockChange.getBeforeNum()));
            ckStockChange.setAfterWt(ckBillStock.getCargoWt().add(ckStockChange.getBeforeWt()));
            ckStockChange.setAfterVol(ckBillStock.getCargoVol().add(ckStockChange.getBeforeVol()));
            ckStockChange.setAfterValue(ckBillStock.getCargoValue().add(ckStockChange.getBeforeValue()));
        }
       ckStockChangeService.save(ckStockChange);
    }


}
