package com.dk.mdm.service.ivt.inventory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.dk.common.exception.BaseBusinessException;
import com.dk.common.infrastructure.annotaiton.Pagination;
import com.dk.common.infrastructure.constant.Constant;
import com.dk.common.infrastructure.enums.ErrorCodeEnum;
import com.dk.common.mapper.BaseMapper;
import com.dk.common.model.pojo.PageList;
import com.dk.common.response.ResponseCodeEnum;
import com.dk.common.response.ResponseResultUtil;
import com.dk.common.response.ResponseResultVO;
import com.dk.common.service.BaseService;
import com.dk.mdm.infrastructure.convert.ivt.InOutRecordConvert;
import com.dk.mdm.infrastructure.convert.ivt.InventoryConvert;
import com.dk.mdm.mapper.common.CommonMapper;
import com.dk.mdm.mapper.ivt.*;
import com.dk.mdm.model.pojo.ivt.*;
import com.dk.mdm.model.query.ivt.*;
import com.dk.mdm.model.response.ivt.*;
import com.dk.mdm.model.vo.ivt.InOutRecordVO;
import com.dk.mdm.model.vo.ivt.InventoryBatchVO;
import com.dk.mdm.model.vo.ivt.InventoryVO;
import com.dk.mdm.service.common.CommonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author : 寇珊珊
 * @desc : 库存明细
 * @date : 2024/3/20 13:41
 */
@Service
@Transactional
public class InventoryService extends BaseService<Inventory> {

    @Override
    public BaseMapper<Inventory> getRepository() {
        return inventoryMapper;
    }

    @Autowired
    private InventoryMapper inventoryMapper;

    @Autowired
    private InventoryConvert inventoryConvert;

    @Autowired
    private InOutRecordMapper inOutRecordMapper;

    @Autowired
    private InOutRecordConvert inOutRecordConvert;

    @Autowired
    private InventoryBatchMapper inventoryBatchMapper;

    @Autowired
    private OutboundItemCostMapper outboundItemCostMapper;

    @Autowired
    private OutboundMapper outboundMapper;

    @Autowired
    private OutboundItemMapper outboundItemMapper;

    @Autowired
    private InboundMapper inboundMapper;

    @Autowired
    private InboundItemMapper inboundItemMapper;

    @Autowired
    private CommonService commonService;

    @Autowired
    private CommonMapper commonMapper;


    /**
     * @desc : 条件查询
     * @author : 姜永辉
     * @date : 2024/3/8 10:58
     */
    @Pagination
    public ResponseResultVO<PageList<InventoryResponse>> selectByCond(InventoryQuery inboundQuery) {
        return super.mergeListWithCount(inboundQuery, inventoryMapper.selectByCond(inboundQuery), inventoryMapper.countByCond(inboundQuery));
    }


    /**
     * @desc : 入库----赋值并校验库存流水数据
     * @date : 2024/3/21 16:04
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public List<InOutRecordVO> setInOutRecordMessageByInto(List<InOutRecordVO> inOutRecordVOList) {
        //赋值
        for (InOutRecordVO inOutRecordVO : inOutRecordVOList) {
            //业务单据
            inOutRecordVO.setBiznisType(Constant.InventoryDocCode.INTOBOUND.getTableName());
            //业务单ID
            inOutRecordVO.setBiznisId(inOutRecordVO.getIntoId());
            //业务单明细ID
            inOutRecordVO.setBiznisItemId(inOutRecordVO.getItemId());
            //入库价
            inOutRecordVO.setPriceInto(inOutRecordVO.getPriceInto());
            //入库日期
            inOutRecordVO.setAccDate(LocalDate.now());
            //可以输入负数标识  入库没有限制 所以这里给true 为了下面的校验库存
            inOutRecordVO.setCanNegativeFlag(true);
        }
        //region 校验是否传库存需要的数据
        this.checkInventory(inOutRecordVOList);
        //endregion

        return inOutRecordVOList;
    }

    /**
     * @desc : 出库----赋值并校验库存流水数据
     * @date : 2024/3/21 16:06
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public List<InOutRecordVO> setInOutRecordMessageByOut(List<InOutRecordVO> inOutRecordVOList) {
        //region  查询当前公司的系统参数  自动办理信息  并赋值
        Map<String, Object> map = new HashMap<>();
        map.put("cpId", inOutRecordVOList.get(0).getCpId());
        map.put("code",Constant.SystemConstant.IVT_002.getValue());
        //负数标识1
        String flgHandleSetting = commonMapper.getSettingValue(map);
        //endregion
        //赋值
        for (InOutRecordVO inOutRecordVO : inOutRecordVOList) {
            //负数标识1 可以
            if (Constant.FlgAutoHandleStringType.ONE.getValue().equals(flgHandleSetting)) {
                inOutRecordVO.setCanNegativeFlag(true);
            }
            //不可以
            else{
                inOutRecordVO.setCanNegativeFlag(false);
            }
            //业务单据
            inOutRecordVO.setBiznisType(Constant.InventoryDocCode.OUTBOUND.getTableName());
            //业务单ID
            inOutRecordVO.setBiznisId(inOutRecordVO.getOutId());
            //业务单明细ID
            inOutRecordVO.setBiznisItemId(inOutRecordVO.getItemId());
            //region 是负库存逻辑
            if (inOutRecordVO.getCanNegativeFlag() && !Constant.InventoryType.INBOUND.getName().equals(inOutRecordVO.getInventoryType())) {
                //入库数量
                inOutRecordVO.setIntoQty(inOutRecordVO.getOutQty());
                //入库价
                inOutRecordVO.setPriceInto(BigDecimal.ZERO);
                //入库金额
                inOutRecordVO.setIntoAmt(BigDecimal.ZERO);
            }
            //endregion
            //region 不是负库存逻辑
            else {
                //入库数量
                inOutRecordVO.setIntoQty(inOutRecordVO.getOutQty());
                //入库价
                inOutRecordVO.setPriceInto(inOutRecordVO.getPriceOut());
                //入库金额
                inOutRecordVO.setIntoAmt(inOutRecordVO.getOutAmt());
            }
            //endregion
            //入库日期
            inOutRecordVO.setAccDate(LocalDate.now());
        }

        //region 校验是否传库存需要的数据
        this.checkInventory(inOutRecordVOList);
        //endregion

        return inOutRecordVOList;
    }

    /**
     * @desc : 校验是否传入库存需要的数据
     * @date : 2024/3/20 15:32
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public void checkInventory(List<InOutRecordVO> inOutRecordVOList) {
        //校验明细中是否存在为空数据
        if (inOutRecordVOList.size() == 0) {
            throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.DETAIL_LIST_IS_NUL.getMessage());
        }
        for (InOutRecordVO inventoryBatchVO : inOutRecordVOList) {
            //商品ID
            if (inventoryBatchVO.getSkuId() == null || "".equals(inventoryBatchVO.getSkuId())) {
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.SKU_IS_NULL.getMessage());
            }
            //仓库ID
            if (!inventoryBatchVO.getCanNegativeFlag() && (inventoryBatchVO.getWhId() == null || "".equals(inventoryBatchVO.getWhId()))) {
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.WAREHOUSE_IS_NULL.getMessage());
            }
//			//单价不可为空
//			if(inventoryBatchVO.getCostPrice()==null || inventoryBatchVO.getCostPrice().compareTo(BigDecimal.ZERO)==0 ){
//				throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.COST_PRICE_IS_NULL.getMessage());
//			}
            //总单id不可为空
            if (inventoryBatchVO.getBiznisId() == null || "".equals(inventoryBatchVO.getBiznisId())) {
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.FROM_ID_IS_NULL.getMessage());
            }
            //明细id不可为空
            if (inventoryBatchVO.getBiznisItemId() == null || "".equals(inventoryBatchVO.getBiznisItemId())) {
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.FROM_ITEM_ID_IS_NULL.getMessage());
            }
            //入库价不为空
            if (inventoryBatchVO.getPriceInto() == null) {
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.COST_PRICE_IS_NULL.getMessage());
            }
            //数量不为空 并且 >0
            if (inventoryBatchVO.getIntoQty() == null && inventoryBatchVO.getIntoQty().compareTo(BigDecimal.ZERO) > 0) {
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.QTY_IS_NULL.getMessage());
            }
            //金额不为空
            if (inventoryBatchVO.getIntoAmt() == null) {
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.AMT_IS_NULL.getMessage());
            }
        }
        //endregion
    }

    /**
     * @desc : 新建
     * @date : 2024/3/20 13:46
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<?> operatingInventoryInformation(Map<String, Object> map) {

        //region  todo 这里可能会用到 返回的map
        List<InOutRecordVO> intoReturnList = new ArrayList<>();
        List<InOutRecordVO> deleteIntoList = new ArrayList<>();
        List<InOutRecordVO> outReturnList = new ArrayList<>();
        List<InOutRecordVO> deleteOutList = new ArrayList<>();
        //endregion

        // region 库存接收类型对应  和  新建还是删除标识
        String inventoryDocCode = null;
        Boolean addOrEditFlag = true;
        //endregion

        //region map转json  ---用来存储传过来的数据
        JSONArray intoDetail = new JSONArray();
        JSONArray delIntoDetail = new JSONArray();
        JSONArray outDetail = new JSONArray();
        JSONArray delOutDetail = new JSONArray();
        //endregion

        //region json转实体  ----用来存储传过来的数据转完jsonArray后再转成对应实体List
        //入库集合
        List<InOutRecordVO> intoList = new ArrayList<>();
        //入库新建集合
        List<InOutRecordVO> intoAddList = new ArrayList<>();
        //入库编辑集合
        List<InOutRecordVO> intoEditList = new ArrayList<>();
        //入库删除集合
        List<InOutRecordVO> delIntoList = new ArrayList<>();

        //出库集合
        List<InOutRecordVO> outList = new ArrayList<>();
        //出库新建集合
        List<InOutRecordVO> outAddList = new ArrayList<>();
        //出库编辑集合
        List<InOutRecordVO> outEditList = new ArrayList<>();
        //负出库新建集合
        List<InOutRecordVO> outNegAddList = new ArrayList<>();
        //负出库编辑集合
        List<InOutRecordVO> outNegEditList = new ArrayList<>();
        //出库删除集合
        List<InOutRecordVO> delOutList = new ArrayList<>();
        //endregion

        //region map转json 提取数据
        //入库
        if (map.get("intoDetail") != null) {
            intoDetail = (JSONArray) JSON.toJSON(map.get("intoDetail"));
            JSONObject obj = (JSONObject) intoDetail.get(0);
            inventoryDocCode = obj.get("inventoryDocCode").toString();
            addOrEditFlag = obj.getBoolean("addOrEditFlag");
        }
        //入库删除
        if (map.get("delIntoDetail") != null ) {
            delIntoDetail = (JSONArray) JSON.toJSON(map.get("delIntoDetail"));
            if(delIntoDetail.size()>0){
                JSONObject obj = (JSONObject) delIntoDetail.get(0);
                inventoryDocCode = obj.get("inventoryDocCode").toString();
            }
        }
        //出库
        if (map.get("outDetail") != null) {
            outDetail = (JSONArray) JSON.toJSON(map.get("outDetail"));
            JSONObject obj = (JSONObject) outDetail.get(0);
            inventoryDocCode = obj.get("inventoryDocCode").toString();
            addOrEditFlag = obj.getBoolean("addOrEditFlag");
        }
        //出库删除
        if (map.get("delOutDetail") != null) {
            delOutDetail = (JSONArray) JSON.toJSON(map.get("delOutDetail"));
            if(delOutDetail.size()>0){
                JSONObject obj = (JSONObject) delOutDetail.get(0);
                inventoryDocCode = obj.get("inventoryDocCode").toString();
            }
        }
        //endregion

        //region  判断是库位调整还是其他类型操作库存然后走对应的逻辑
        //库位移动
        if (Constant.InventoryDocCode.MOVE.getValue().equals(inventoryDocCode)) {
            //region 新建
            if (addOrEditFlag) {
                //先出
                if (outDetail.size() > 0 ) {
                    outList = outDetail.toJavaList(InOutRecordVO.class);
                    //赋值并校验库存流水数据
                    outList = this.setInOutRecordMessageByOut(outList);
                    //出库
                    outList = this.warehouseAdjustmentOut(outList);
                    //反写出库单金额等信息
                    this.updateOutbound(outList);
                } else if (outDetail.size() == 0 && intoDetail.size() == 0 ) {
                    throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.NO_DATA_MOVED_OUT.getMessage());
                }
                //后入
                if (intoDetail.size() > 0) {
                    intoList = intoDetail.toJavaList(InOutRecordVO.class);
                    //赋值并校验库存流水数据
                    intoList = this.setInOutRecordMessageByInto(intoList);
                    //根据来源id明细查询移动的出库单的单价、成本单价、金额等信息 赋值给需要已入的入库单
                    intoList = this.selectOutbound(intoList);
                    //入库
                    intoList = this.warehouseAdjustmentInto(intoList);
                    //修改入库单单价、金额、成本等信息
                    this.updateIntobound(intoList);
                } else if (outDetail.size() == 0 && intoDetail.size() == 0 ) {
                    throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.NO_DATA_MOVED_IN.getMessage());
                }
            }
            //endregion

            //region 删除
            else {
                //入库
                if (delIntoList.size() > 0) {
                    delIntoList = delIntoDetail.toJavaList(InOutRecordVO.class);
                    //赋值并校验库存流水数据
                    delIntoList = this.setInOutRecordMessageByInto(delIntoList);
                    //入库相关删除
                    this.warehouseAdjustmentDelInto(delIntoList);
                } else {
                    throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.NO_DATA_MOVED_OUT_DEL.getMessage());
                }

                //出库
                if (delOutList.size() > 0) {
                    delOutList = delOutDetail.toJavaList(InOutRecordVO.class);
                    //赋值并校验库存流水数据
                    delOutList = this.setInOutRecordMessageByInto(delOutList);
                    //库存相关反写
                    this.warehouseAdjustmentDelOut(delOutList);
                } else {
                    throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.NO_DATA_MOVED_IN_DEL.getMessage());
                }
            }
            //endregion
        }
        //其他库存操作
        else {
            //region 入库删除库存
            if (delIntoDetail.size() > 0) {
                delIntoList = delIntoDetail.toJavaList(InOutRecordVO.class);
                //赋值并校验库存流水数据
                delIntoList = this.setInOutRecordMessageByInto(delIntoList);
                //删除库存、库存批次，库存流水，出库成本
                this.deleteInventory(delIntoList);
            }
            //endregion

            //region  出库删除库存
            if (delOutDetail.size() > 0) {
                delOutList = delOutDetail.toJavaList(InOutRecordVO.class);
                //赋值并校验库存流水数据
                delOutList = this.setInOutRecordMessageByInto(delOutList);
                //是负库存逻辑
                if (delOutList.get(0).getCanNegativeFlag()) {
                    //操作负库存--删除（作废）
                    this.operatingNegativeInventoryDelete(delOutList);
                }
                //不是负库存逻辑
                else {
                    //删除库存、库存批次，库存流水，出库成本
                    this.deleteInventory(delOutList);
                }
            }
            //endregion

            //region 入库操作库存
            if (intoDetail.size() > 0 && outDetail.size() == 0) {
                intoList = intoDetail.toJavaList(InOutRecordVO.class);
                //赋值并校验库存流水数据
                intoList = this.setInOutRecordMessageByInto(intoList);
                //入库新建
                intoAddList = intoList.stream().filter(it->it.getAddOrEditFlag()).collect(Collectors.toList());
                //入库编辑
                intoEditList = intoList.stream().filter(it->!it.getAddOrEditFlag()).collect(Collectors.toList());
                //新建
                if (intoAddList.size() > 0) {
                    //正常逻辑 新建库存
                    this.operatingInsertInventory(intoAddList);
                }
                //编辑
                if (intoEditList.size() > 0) {
                    //正常逻辑 编辑库存
                    this.operatingUpdateInventory(intoEditList);
                }
            }
            //endregion

            //region 出库操作库存
            else if (outDetail.size() > 0 && intoDetail.size() == 0) {
                outList = outDetail.toJavaList(InOutRecordVO.class);
                //赋值并校验库存流水数据
                outList = this.setInOutRecordMessageByOut(outList);
                //出库新建
                outAddList = outList.stream().filter(it->it.getAddOrEditFlag() && !it.getCanNegativeFlag() ).collect(Collectors.toList());
                //出库编辑
                outEditList = outList.stream().filter(it->!it.getAddOrEditFlag() && !it.getCanNegativeFlag() ).collect(Collectors.toList());
                //负出库新建
                outNegAddList = outList.stream().filter(it->it.getAddOrEditFlag() && it.getCanNegativeFlag() ).collect(Collectors.toList());
                //负出库编辑
                outNegEditList = outList.stream().filter(it->!it.getAddOrEditFlag() && it.getCanNegativeFlag() ).collect(Collectors.toList());
                //走负库存逻辑 -- 新建
                if (outNegAddList.size()>0) {
                    //新建入库单
                    outNegAddList = this.insertOrUpdateInbound(outNegAddList);
                    //操作负库存
                    this.operatingNegativeInventory(outNegAddList);
                }
                //走负库存逻辑 -- 编辑
                if (outNegEditList.size() > 0) {
                    //编辑入库单
                    outNegEditList = this.insertOrUpdateInbound(outNegEditList);
                    //操作负库存
                    this.operatingNegativeInventory(outNegEditList);
                }
                //正常库存逻辑 -- 新建
                if (outAddList.size()>0) {
                    //正常逻辑 新建库存
                    this.operatingInsertInventory(outAddList);
                }
                //正常库存逻辑 -- 编辑
                if (outEditList.size() > 0) {
                    //正常逻辑 编辑库存
                    this.operatingUpdateInventory(outEditList);
                }
            }
            //endregion

        }
        //endregion

        return ResponseResultUtil.success();
    }

    /**
     * @desc : 校验库存是否存在
     * @date : 2024/4/10 14:39
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public InventoryResponse checkInventoryNumber(InOutRecordVO inOutRecordVO) {
        //存在标识
        //根据sku，仓库，非标号查询
        InventoryResponse inventoryResponse = inventoryMapper.selectByOther(new InventoryQuery()
                .setSkuId(inOutRecordVO.getSkuId())
                .setWhId(inOutRecordVO.getWhId())
                .setNonStdCode(inOutRecordVO.getNonStdCode()));
        return inventoryResponse;
    }

    /**
     * @desc : 新建
     * @date : 2024/4/10 8:58
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public void operatingInsertInventory(List<InOutRecordVO> inOutRecordVOList) {
        for (InOutRecordVO inOutRecordVO : inOutRecordVOList) {
            //校验库存是否存在
            InventoryResponse inventoryResponse = this.checkInventoryNumber(inOutRecordVO);
            //入库
            if (Constant.InventoryType.INBOUND.getName().equals(inOutRecordVO.getInventoryType())) {
                //region  库存不存在  再判断采退入库和其他类型入库
                if (inventoryResponse == null) {
                    //采购退货入库
                    if (Constant.InventoryDocCode.PURCHASE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode())) {
                        throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.SKU_IS_NOT_IN_INVENTORY.getMessage());
                    }
                    //其他类型入库
                    else {
                        //region  新建库存
                        inOutRecordVO = this.insertInventory(inOutRecordVO);
                        //endregion

                        //region 库存批次
                        this.insertInventoryBatch(inOutRecordVO);
                        //endregion

                        //region 库存流水
                        this.insertInboundRecord(inOutRecordVO);
                        //endregion
                    }
                }
                //endregion

                //region  库存存在
                else {
                    inOutRecordVO.setInvId(inventoryResponse.getInvId());

                    //region 库存批次
                    //采购退货入库库存批次扣减
                    if (Constant.InventoryDocCode.PURCHASE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode())) {
                        this.updateInventoryBatch(inOutRecordVO);
                    }
                    //其他类型入库新建库存批次
                    else {
                        this.insertInventoryBatch(inOutRecordVO);
                    }
                    //endregion

                    //region  修改库存数量，可用量，金额等信息
                    this.updateInventoryMessageAdd(inventoryResponse, inOutRecordVO);
                    //endregion

                    //region 库存流水
                    this.insertInboundRecord(inOutRecordVO);
                    //endregion

                    //region 采购退货 出库成本 正数
                    if (Constant.InventoryDocCode.PURCHASE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode())) {
                        this.insertOutboundItemCost(inOutRecordVO);
                    }
                    //endregion
                }
                //endregion
            }
            //出库
            else if (Constant.InventoryType.OUTBOUND.getName().equals(inOutRecordVO.getInventoryType())) {
                //region  库存不存在  再判断销售退货出库和其他类型出库
                if (inventoryResponse == null) {
                    //region  根据源出库单明细Id存在  去出库成本里去查价格
                    if (inOutRecordVO.getSOutItemId() != null) {
                        List<OutboundItemCostResponse> outboundItemCostResponses = outboundItemCostMapper.selectByCond(new OutboundItemCostQuery().setOutItemId(inOutRecordVO.getSOutItemId()));
                        if (outboundItemCostResponses.size() > 0) {
                            //出库单价
                            inOutRecordVO.setPriceInto(outboundItemCostResponses.get(0).getCostPrice());
                            //金额
                            inOutRecordVO.setIntoAmt(outboundItemCostResponses.get(0).getCostPrice().multiply(inOutRecordVO.getIntoQty()).abs());
                        } else {
                            //当前销售退货单无法获取源出库单数据
                            throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.UNABLE_TO_OBTAIN_SOURCE_DATA.getMessage());
                        }
                    }
                    //endregion

                    //region 销售退货出库  (负向出库相当于入库)
                    if (Constant.InventoryDocCode.SALE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode())) {
                        //region  新建库存
                        inOutRecordVO = this.insertInventory(inOutRecordVO);
                        //endregion

                        //region 库存批次
                        this.insertInventoryBatch(inOutRecordVO);
                        //endregion

                        //region 库存流水
                        this.insertInboundRecord(inOutRecordVO);
                        //endregion

                    }
                    //endregion

                    //region 其他类型出库  没有库存不允许进行出库
                    else {
                        throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.SKU_IS_NOT_IN_INVENTORY.getMessage());
                    }
                    //endregion
                }
                //region  库存存在
                else {
                    //region  根据源出库单明细Id 去出库成本里去查价格
                    if (inOutRecordVO.getSOutItemId() != null) {
                        List<OutboundItemCostResponse> outboundItemCostResponses = outboundItemCostMapper.selectByCond(new OutboundItemCostQuery().setOutItemId(inOutRecordVO.getSOutItemId()));
                        if (outboundItemCostResponses.size() > 0) {
                            //出库单价
                            inOutRecordVO.setPriceInto(outboundItemCostResponses.get(0).getCostPrice());
                            //金额
                            inOutRecordVO.setIntoAmt(outboundItemCostResponses.get(0).getCostPrice().multiply(inOutRecordVO.getIntoQty()).abs());
                            //反写出库单成本单价、成本金额

                        } else {
                            //当前销售退货单无法获取源出库单数据
                            throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.UNABLE_TO_OBTAIN_SOURCE_DATA.getMessage());
                        }
                    }
                    //endregion

                    inOutRecordVO.setInvId(inventoryResponse.getInvId());

                    //region 库存批次 编辑
                    this.updateInventoryBatch(inOutRecordVO);
                    //endregion

                    //region  修改/新建   库存数量，可用量，金额等信息
                    //销售退货出库  新建库存批次
                    if (Constant.InventoryDocCode.SALE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode())) {
                        this.insertInventoryBatch(inOutRecordVO);
                    }
                    //其他类型出库   修改库存数量，可用量，金额等信息
                    else {
                        this.updateInventoryMessageAdd(inventoryResponse, inOutRecordVO);
                    }
                    //endregion

                    //region 库存流水
                    this.insertInboundRecord(inOutRecordVO);
                    //endregion

                    //region  出库成本
                    //除了销售退货出库  其他类型出库要新建出库成本
                    if (!Constant.InventoryDocCode.SALE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode())) {
                        this.insertOutboundItemCost(inOutRecordVO);
                    }
                    //endregion
                }
                //endregion

            }
        }
    }

    /**
     * @desc : 编辑
     * @date : 2024/4/11 15:22
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public void operatingUpdateInventory(List<InOutRecordVO> inOutRecordVOList) {
        //先删后加
        this.deleteInventory(inOutRecordVOList);
        //新建
        this.operatingInsertInventory(inOutRecordVOList);
        //修改源出库信息
        this.updateOutboundPri(inOutRecordVOList);
    }

    /**
     * @desc : 新建库存批次明细
     * @date : 2024/3/21 14:47
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public InOutRecordVO insertInventoryBatch(InOutRecordVO inOutRecordVO) {
        InventoryBatch inventoryBatch = new InventoryBatch();
        //库存Id
        inventoryBatch.setInvId(inOutRecordVO.getInvId());
        //仓库Id
        inventoryBatch.setWhId(inOutRecordVO.getWhId());
        //商品Id
        inventoryBatch.setSkuId(inOutRecordVO.getSkuId());
        //非标号
        inventoryBatch.setNonStdCode(inOutRecordVO.getNonStdCode());
        //是负库存逻辑
        if (inOutRecordVO.getCanNegativeFlag() && !Constant.InventoryType.INBOUND.getName().equals(inOutRecordVO.getInventoryType())) {
            //来源Id
            inventoryBatch.setFromId(inOutRecordVO.getIntoId());
            //来源明细Id
            inventoryBatch.setFromItemId(inOutRecordVO.getIntoItemId());
            //库存数量
            inventoryBatch.setInvQty(inOutRecordVO.getIntoQty().abs());
        }
        //不是负库存逻辑
        else {
            //来源Id
            inventoryBatch.setFromId(inOutRecordVO.getBiznisId());
            //来源明细Id
            inventoryBatch.setFromItemId(inOutRecordVO.getBiznisItemId());
            //销售退货出库也是新建 但是数量要取反 因为传过来的时候负数
            if (Constant.InventoryDocCode.SALE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode())) {
                //库存数量
                inventoryBatch.setInvQty(inOutRecordVO.getIntoQty().abs());
                //库存单价
                inventoryBatch.setCostPrice(inOutRecordVO.getPriceInto().abs());
                //货物资产
                inventoryBatch.setCostAmt(inOutRecordVO.getIntoAmt().abs());
            } else {
                //库存数量
                inventoryBatch.setInvQty(inOutRecordVO.getIntoQty());
                //库存单价
                inventoryBatch.setCostPrice(inOutRecordVO.getPriceInto());
                //货物资产
                inventoryBatch.setCostAmt(inOutRecordVO.getIntoAmt());
            }
        }
        //账务日期
        inventoryBatch.setAccDate(LocalDate.now());
        //新建
        inventoryBatchMapper.insert(inventoryBatch);
        return inOutRecordVO;
    }

    /**
     * @desc : 新建用-----修改库存数量，可用量，金额等信息
     * @date : 2024/4/10 15:05
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public void updateInventoryMessageAdd(InventoryResponse inventoryResponse, InOutRecordVO inOutRecordVO) {
        //region  根据库存id查询库存批次明细 汇总金额
        List<InventoryBatchResponse> inventoryBatchResponseList = inventoryBatchMapper.selectAmountAndQuantity(new InventoryBatchQuery().setInvId(inventoryResponse.getInvId()));
        //库存资产汇总  ---库存需要
        BigDecimal costAmt = BigDecimal.ZERO;
        if (inventoryBatchResponseList.size() > 0) {
            costAmt = inventoryBatchResponseList.stream().map(InventoryBatchResponse::getCostAmt).reduce(BigDecimal.ZERO, BigDecimal::add)
                    .setScale(6, BigDecimal.ROUND_HALF_UP);
        }
        //endregion

        //region 库存数量重算   库存数量-删除数量
        Inventory inventory = new Inventory();
        //库存id
        inventory.setInvId(inventoryResponse.getInvId());
        //入库
        if (Constant.InventoryType.INBOUND.getName().equals(inOutRecordVO.getInventoryType())) {
            //库存数量 入库+
            inventory.setInvQty(inventoryResponse.getInvQty().add(inOutRecordVO.getIntoQty()));
        }
        //出库
        else if (Constant.InventoryType.OUTBOUND.getName().equals(inOutRecordVO.getInventoryType())) {
            //库存数量 出库   -
            inventory.setInvQty(inventoryResponse.getInvQty().subtract(inOutRecordVO.getIntoQty()));
        }
        //可用量  库存数量-出库中数量-冻结数量
        inventory.setUsableQty(inventory.getInvQty().subtract(inventoryResponse.getFreezeQty()).subtract(inventoryResponse.getOutingQty()));
        //存货资产
        inventory.setCostAmt(costAmt);
        //存货单价
        inventory.setCostPrice(costAmt.compareTo(BigDecimal.ZERO) > 0 ?
               costAmt.divide(inventory.getInvQty(),BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO);
        inventoryMapper.updateAmtAndQty(inventory);
        //endregion
    }

    /**
     * @desc : 新建库存流水
     * @date : 2024/3/21 14:47
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public void insertInboundRecord(InOutRecordVO inOutRecordVO) {
        //是负库存逻辑  这里要新建2次 一正一负
        if (inOutRecordVO.getCanNegativeFlag() && !Constant.InventoryType.INBOUND.getName().equals(inOutRecordVO.getInventoryType())) {
            //新建负数库存流水
            inOutRecordVO.setIntoQty(inOutRecordVO.getIntoQty());
            //实体转换
            InOutRecord inOutRecordNeg = inOutRecordConvert.convertToPo(inOutRecordVO);
            //新建
            inOutRecordMapper.insert(inOutRecordNeg);

            //新建正数流水
            inOutRecordVO.setIntoQty(inOutRecordVO.getIntoQty().abs());
            //实体转换
            InOutRecord inOutRecord = inOutRecordConvert.convertToPo(inOutRecordVO);
            //业务单据  入库
            inOutRecord.setBiznisType(Constant.InventoryDocCode.INTOBOUND.getTableName());
            //业务单Id
            inOutRecord.setBiznisId(inOutRecordVO.getIntoId());
            //业务单明细Id
            inOutRecord.setBiznisItemId(inOutRecordVO.getIntoItemId());
            //新建
            inOutRecordMapper.insert(inOutRecord);

        }
        //不是负库存逻辑
        else {
            //销售退货出库  数量转换一下
            if (Constant.InventoryDocCode.SALE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode())) {
                //入库价
                inOutRecordVO.setPriceInto(inOutRecordVO.getPriceInto().abs());
                //入库数量
                inOutRecordVO.setIntoQty(inOutRecordVO.getIntoQty().abs());
                //入库金额
                inOutRecordVO.setIntoAmt(inOutRecordVO.getIntoAmt().abs());
            }
            //实体转换
            InOutRecord inOutRecord = inOutRecordConvert.convertToPo(inOutRecordVO);
            //新建
            inOutRecordMapper.insert(inOutRecord);
        }
    }

    /**
     * @desc : 新建库存
     * @date : 2024/4/10 15:27
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public InOutRecordVO insertInventory(InOutRecordVO inOutRecordVO) {
        Inventory inventory = new Inventory();
        //仓库Id
        inventory.setWhId(inOutRecordVO.getWhId());
        //商品id
        inventory.setSkuId(inOutRecordVO.getSkuId());
        //非标号
        inventory.setNonStdCode(inOutRecordVO.getNonStdCode());
        //是负库存逻辑
        if (inOutRecordVO.getCanNegativeFlag() && !Constant.InventoryType.INBOUND.getName().equals(inOutRecordVO.getInventoryType())) {
            //库存数量
            inventory.setInvQty(inOutRecordVO.getIntoQty().abs());
        }
        //不是负库存逻辑
        else {
            //销售退货出库也是新建 但是数量要取反 因为传过来的时候负数
            if (Constant.InventoryDocCode.SALE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode())) {
                //库存数量
                inventory.setInvQty(inOutRecordVO.getIntoQty().abs());
                //可售数量（可用量）
                inventory.setUsableQty(inOutRecordVO.getIntoQty().abs());
                //库存资产
                inventory.setCostAmt(inOutRecordVO.getIntoAmt());
                //库存单价   存货资产/存货数量
                inventory.setCostPrice(inventory.getCostAmt().negate().divide(inventory.getInvQty().negate(),BigDecimal.ROUND_HALF_UP));
            } else {
                //库存数量
                inventory.setInvQty(inOutRecordVO.getIntoQty());
                //可售数量（可用量）
                inventory.setUsableQty(inOutRecordVO.getIntoQty());
                //库存资产
                inventory.setCostAmt(inOutRecordVO.getIntoAmt());
                //库存单价   存货资产/存货数量
                inventory.setCostPrice(inventory.getCostAmt().divide(inventory.getInvQty(),BigDecimal.ROUND_HALF_UP));
            }
        }

        //新建
        inventoryMapper.insert(inventory);
        //仓库Id赋值
        inOutRecordVO.setInvId(inventory.getInvId());

        return inOutRecordVO;

    }

    /**
     * @desc : 出库成本
     * @date : 2024/3/22 9:33
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public void insertOutboundItemCost(InOutRecordVO inOutRecordVO) {
        OutboundItemCost outboundItemCost = new OutboundItemCost();
        //出库明细ID
        outboundItemCost.setOutItemId(inOutRecordVO.getItemId());
        //库存ID
        outboundItemCost.setInvId(inOutRecordVO.getInvId());
        //是负库存逻辑
        if (inOutRecordVO.getCanNegativeFlag() && !Constant.InventoryType.INBOUND.getName().equals(inOutRecordVO.getInventoryType())) {
            //出库数量
            outboundItemCost.setOutQty(inOutRecordVO.getIntoQty().abs());
        }
        //不是负库存逻辑
        else {
            //采购退货入库  把传入的负数转成正数
            if (Constant.InventoryDocCode.PURCHASE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode())) {
                //出库数量
                outboundItemCost.setOutQty(inOutRecordVO.getIntoQty().abs());
                //出库单价
                outboundItemCost.setCostPrice(inOutRecordVO.getPriceInto().abs());
                //出库成本
                outboundItemCost.setCostAmt(inOutRecordVO.getIntoAmt().abs());
            } else {
                //出库数量
                outboundItemCost.setOutQty(inOutRecordVO.getIntoQty());
                //出库单价
                outboundItemCost.setCostPrice(inOutRecordVO.getPriceInto());
                //出库成本
                outboundItemCost.setCostAmt(inOutRecordVO.getIntoAmt());
            }
        }
        Map<String, Object> codeMap = commonService.getUniqueNoteCode(Constant.docNameConstant.OUTBOUNDCOST.getName(), false);
        outboundItemCost.setBatchId(codeMap.get("outId").toString());
        //新建
        outboundItemCostMapper.insert(outboundItemCost);
    }

    /**
     * @desc : 出库扣减---库存批次明细
     * @date : 2024/3/21 14:47
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public InOutRecordVO updateInventoryBatch(InOutRecordVO inOutRecordVO) {
        //查询库存批次明细  按照时间排序（正序）
        List<InventoryBatchResponse> inventoryBatchResponseList = inventoryBatchMapper.selectAmountAndQuantity(new InventoryBatchQuery().setInvId(inOutRecordVO.getInvId()));
        if (inventoryBatchResponseList.size() > 0) {
            //数量
            BigDecimal qty = inOutRecordVO.getIntoQty().abs();
            for (InventoryBatchResponse inventoryBatchResponse : inventoryBatchResponseList) {
                InventoryBatchVO inventoryBatchVO = new InventoryBatchVO();
                //判断是否为最后一次扣减当前条库存
                //是
                if (qty.abs().compareTo(inventoryBatchResponse.getInvQty()) == 0) {
                    //主键赋值
                    inventoryBatchVO.setBatchId(inventoryBatchResponse.getBatchId());
                    //库存数量
                    inventoryBatchVO.setInvQty(BigDecimal.ZERO);
                    //存货资产
                    inventoryBatchVO.setCostAmt(BigDecimal.ZERO);
                    //清零标识
                    inventoryBatchVO.setZeroFlag(true);
                    inventoryBatchMapper.updateAmountAndQuantity(inventoryBatchVO);
                    //数量
                    inOutRecordVO.setIntoQty(qty);
                    //单价
                    inOutRecordVO.setPriceInto(inventoryBatchResponse.getCostPrice());
                    //金额
                    inOutRecordVO.setIntoAmt(inOutRecordVO.getIntoQty().multiply(inventoryBatchResponse.getCostPrice()));
                    break;
                }
                //不是
                else {
                    //当前条库存批次明细够出库
                    if (qty.abs().compareTo(inventoryBatchResponse.getInvQty()) < 0) {
                        //主键赋值
                        inventoryBatchVO.setBatchId(inventoryBatchResponse.getBatchId());
                        //库存数量
                        inventoryBatchVO.setInvQty(inOutRecordVO.getIntoQty());
                        //存货资产
                        inventoryBatchVO.setCostAmt(inventoryBatchVO.getInvQty().multiply(inventoryBatchResponse.getCostPrice()));
                        //清零标识
                        inventoryBatchVO.setZeroFlag(true);
                        inventoryBatchMapper.updateAmountAndQuantity(inventoryBatchVO);
                        //数量
                        inOutRecordVO.setIntoQty(qty);
                        //单价
                        inOutRecordVO.setPriceInto(inventoryBatchResponse.getCostPrice());
                        //金额
                        inOutRecordVO.setIntoAmt(inOutRecordVO.getIntoQty().multiply(inventoryBatchResponse.getCostPrice()));
                        break;
                    }
                    //当前条库存批次明细不够出库
                    if (qty.abs().compareTo(inventoryBatchResponse.getInvQty()) > 0) {
                        //主键赋值
                        inventoryBatchVO.setBatchId(inventoryBatchResponse.getBatchId());
                        //库存数量
                        inventoryBatchVO.setInvQty(inventoryBatchResponse.getInvQty());
                        //存货资产
                        inventoryBatchVO.setCostAmt(inventoryBatchResponse.getCostAmt());
                        //清零标识
                        inventoryBatchVO.setZeroFlag(true);
                        //修改数量金额
                        inventoryBatchMapper.updateAmountAndQuantity(inventoryBatchVO);
                        //数量、金额每次更新完要重新运算
                        qty = qty.subtract(inventoryBatchResponse.getInvQty());
                        //数量
                        inOutRecordVO.setIntoQty(qty);
                        //单价
                        inOutRecordVO.setPriceInto(inventoryBatchResponse.getCostPrice());
                        //金额
                        inOutRecordVO.setIntoAmt(inOutRecordVO.getIntoQty().multiply(inventoryBatchResponse.getCostPrice()));
                    }
                }
            }
        } else {
            throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.CAN_OUTBOUND_QUANTITY_INSUFFICIENT.getMessage());
        }
        //endregion
        return inOutRecordVO;
    }

    /**
     * @desc : 删除库存
     * @date : 2024/4/10 13:09
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public void deleteInventory(List<InOutRecordVO> inOutRecordVOList) {
        for (InOutRecordVO inOutRecordVO : inOutRecordVOList) {
            //region  校验库存  根据sku，仓库，非标号查询
            InventoryResponse inventoryResponse = inventoryMapper.selectByOther(new InventoryQuery()
                    .setSkuId(inOutRecordVO.getSkuId())
                    .setWhId(inOutRecordVO.getWhId())
                    .setNonStdCode(inOutRecordVO.getNonStdCode()));
            //库存是否存在
            if (inventoryResponse == null) {
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.SKU_IS_NOT_IN_INVENTORY.getMessage());
            }
            //endregion

            //region   根据来源id和来源明细id查询数据 库存批次删除

            //region  入库 判断库存批次数量和传入数量是否一致 不一致不允许修改
            if ((Constant.InventoryType.INBOUND.getName().equals(inOutRecordVO.getInventoryType()) &&
                    !Constant.InventoryDocCode.PURCHASE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode()) ||
                    Constant.InventoryDocCode.SALE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode()))
            ) {
                InventoryBatchResponse inventoryBatchResponse = inventoryBatchMapper.selectByFromCondition(new InventoryBatchQuery()
                        .setFromId(inOutRecordVO.getBiznisId()).setFromItemId(inOutRecordVO.getBiznisItemId()));
                if (inventoryBatchResponse == null) {
                    //当前编辑的数据在库存批次中不存在
                    throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.INVENTORY_BATCH_DOES_NOT_EXIST.getMessage());
                } else {
                    //数据库中库存批次数量和传入数量一致 可以更改
                    if (inventoryResponse.getInvQty().compareTo(inOutRecordVO.getIntoQty().abs()) == 0) {
                        InventoryBatch inventoryBatch = new InventoryBatch();
                        //来源单ID
                        inventoryBatch.setFromId(inOutRecordVO.getBiznisId());
                        //来源单明细ID
                        inventoryBatch.setFromItemId(inOutRecordVO.getBiznisItemId());
                        inventoryBatchMapper.deleteData(inventoryBatch);
                    } else {
                        //不允许编辑，对应库存数据已被修改
                        throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.INVENTORY_DATA_HAS_BEEN_MODIFIED.getMessage());
                    }
                }
            }
            //endregion

            //region 出库
            if ((Constant.InventoryType.OUTBOUND.getName().equals(inOutRecordVO.getInventoryType()) &&
                    !Constant.InventoryDocCode.SALE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode())) ||
                    Constant.InventoryDocCode.PURCHASE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode())
            ) {
                //根据outItemId查找出库成本数据
                List<OutboundItemCostResponse> outboundItemCostResponses = outboundItemCostMapper.selectByCond(new OutboundItemCostQuery().setOutItemId(inOutRecordVO.getBiznisItemId()));
                for (OutboundItemCostResponse outboundItemCostResponse : outboundItemCostResponses) {
                    //查找库存批次
                    InventoryBatchResponse inventoryBatchResponse = inventoryBatchMapper.selectById(outboundItemCostResponse.getBatchId());
                    InventoryBatch inventoryBatch = new InventoryBatch();
                    inventoryBatch.setBatchId(outboundItemCostResponse.getBatchId());
                    inventoryBatch.setInvQty(inventoryBatchResponse.getInvQty().add(outboundItemCostResponse.getOutQty()));
                    inventoryBatch.setCostAmt(inventoryBatch.getInvQty().multiply(inventoryBatch.getCostPrice()));
                    inventoryBatchMapper.updateAmtAndQty(inventoryBatch);
                }
            }
            //endregion

            //endregion

            //region  修改库存数量，可用量，金额等信息
            this.updateInventoryMessageDelete(inventoryResponse, inOutRecordVO);
            //endregion

            //region  根据来源id和来源明细id查询数据 库存流水删除
            InOutRecord inOutRecord = new InOutRecord();
            //来源id
            inOutRecord.setBiznisId(inOutRecordVO.getBiznisId());
            //来源明细Id
            inOutRecord.setBiznisItemId(inOutRecordVO.getBiznisItemId());
            inOutRecordMapper.deleteData(inOutRecord);
            //endregion

            //region  判断是出库但不是销售退货出库或者是采购退货入库      出库要把出库成本也删除
            if ((Constant.InventoryType.OUTBOUND.getName().equals(inOutRecordVO.getInventoryType()) &&
                    !Constant.InventoryDocCode.SALE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode())) ||
                    Constant.InventoryDocCode.PURCHASE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode())
            ) {
                OutboundItemCost outboundItemCost = new OutboundItemCost();
                //出库明细Id
                outboundItemCost.setOutItemId(inOutRecordVO.getBiznisItemId());
                outboundItemCostMapper.deleteData(inOutRecord);
            }
            //endregion

        }
    }

    /**
     * @desc : 删除用-----修改库存数量，可用量，金额等信息
     * @date : 2024/4/10 15:05
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public void updateInventoryMessageDelete(InventoryResponse inventoryResponse, InOutRecordVO inOutRecordVO) {

        //region  根据库存id查询库存批次明细 汇总金额
        List<InventoryBatchResponse> inventoryBatchResponseList = inventoryBatchMapper.selectAmountAndQuantity(new InventoryBatchQuery().setInvId(inventoryResponse.getInvId()));
        //库存资产汇总  ---库存需要
        BigDecimal costAmt = BigDecimal.ZERO;
        if (inventoryBatchResponseList.size() > 0) {
            costAmt = inventoryBatchResponseList.stream().map(InventoryBatchResponse::getCostAmt).reduce(BigDecimal.ZERO, BigDecimal::add)
                    .setScale(6, BigDecimal.ROUND_HALF_UP);
        }
        //endregion

        //region 库存数量重算   库存数量-删除数量
        BigDecimal qty = inOutRecordVO.getQtyBeforeUpdate().compareTo(BigDecimal.ZERO)>0 ?inOutRecordVO.getQtyBeforeUpdate():inOutRecordVO.getIntoQty();
        Inventory inventory = new Inventory();
        //库存id
        inventory.setInvId(inventoryResponse.getInvId());
        //入库
        if (Constant.InventoryType.INBOUND.getName().equals(inOutRecordVO.getInventoryType())) {
            //库存数量 入库 -
            inventory.setInvQty(inventoryResponse.getInvQty().subtract(qty));
        }
        //出库
        else if (Constant.InventoryType.OUTBOUND.getName().equals(inOutRecordVO.getInventoryType())) {
            //库存数量 出库+
            inventory.setInvQty(inventoryResponse.getInvQty().add(qty));
        }
        //可用量  库存数量-出库中数量-冻结数量
        inventory.setUsableQty(inventory.getInvQty().subtract(inventoryResponse.getFreezeQty()).subtract(inventoryResponse.getOutingQty()));
        //存货资产
        inventory.setCostAmt(costAmt);
        //存货单价
        inventory.setCostPrice(costAmt.compareTo(BigDecimal.ZERO) > 0 ?
                costAmt.divide(inventory.getInvQty(),BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO);
        inventoryMapper.updateAmtAndQty(inventory);
        //endregion
    }

    /**
     * @desc : 修改源出库信息
     * @date : 2024/4/1 14:30
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public void updateOutboundPri(List<InOutRecordVO> inOutRecordVOList) {
        //根据源出库单分组
        Map<String, List<InOutRecordVO>> InOutRecordVOListMap = inOutRecordVOList.stream().collect(Collectors.groupingBy(InOutRecordVO::getSOutId));
        for (String str : InOutRecordVOListMap.keySet()) {
            //提取分组后的明细
            List<InOutRecordVO> inOutRecordVOListGroup = InOutRecordVOListMap.get(str);
            //提取总额，总量
//            BigDecimal sumOutQty = inOutRecordVOListGroup.stream().map(InOutRecordVO::getIntoQty).reduce(BigDecimal.ZERO, BigDecimal::add).setScale(6, BigDecimal.ROUND_HALF_UP);
            BigDecimal sumOutAmt = inOutRecordVOListGroup.stream().map(InOutRecordVO::getIntoAmt).reduce(BigDecimal.ZERO, BigDecimal::add).setScale(2, BigDecimal.ROUND_HALF_UP);
            for (InOutRecordVO inOutRecordVO : inOutRecordVOListGroup) {
                //修改明细
                OutboundItem outboundItem = new OutboundItem();
                outboundItem.setItemId(inOutRecordVO.getSOutItemId());
                if (!Constant.InventoryDocCode.SALE_ORDER.getValue().equals(inOutRecordVOList.get(0).getInventoryDocCode())) {
//                    outboundItem.setOutQty(inOutRecordVO.getIntoQty());
                    outboundItem.setOutAmt(inOutRecordVO.getIntoAmt());
                    outboundItem.setPriceOut(inOutRecordVO.getCostPrice());
                }
                outboundItem.setCostPrice(inOutRecordVO.getCostPrice());
                outboundItem.setCostAmt(inOutRecordVO.getIntoAmt());
                //修改
                outboundItemMapper.update(outboundItem,
                        new UpdateWrapper<OutboundItem>().lambda()
                                .eq(OutboundItem::getItemId, UUID.fromString(outboundItem.getSOutItemId()))
                );
            }
            //修改总单
            if (!Constant.InventoryDocCode.SALE_ORDER.getValue().equals(inOutRecordVOList.get(0).getInventoryDocCode())) {
                Outbound outbound = new Outbound();
                outbound.setOutId(str);
//                outbound.setOutQty(sumOutQty);
                outbound.setOutAmt(sumOutAmt);
                //修改
                outboundMapper.update(outbound,
                        new UpdateWrapper<Outbound>().lambda().eq(Outbound::getOutId, UUID.fromString(outbound.getOutId()))
                );
            }
        }
    }

    /**
     * @desc : 新建入库单---负库存用 生成其他入库
     * @date : 2024/4/12 9:34
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public List<InOutRecordVO> insertOrUpdateInbound(List<InOutRecordVO> inOutRecordVOList) {
        BigDecimal sumOutQty = inOutRecordVOList.stream().map(InOutRecordVO::getIntoQty).reduce(BigDecimal.ZERO, BigDecimal::add).setScale(6, BigDecimal.ROUND_HALF_UP);
        //新建
        if (inOutRecordVOList.get(0).getAddOrEditFlag()) {
            //region  总单
            Inbound inbound = new Inbound();
            //获取 id/单号
            Map<String, Object> codeMap = commonService.getUniqueNoteCode(Constant.docNameConstant.OTHERINBOUND.getName(), false);
            inbound.setIntoId(codeMap.get("outId").toString()).
                    setIntoNo(codeMap.get("outNote").toString());
            //入库类型
            inbound.setIntoType(Constant.IntoType.OTHER.getName());
            //已入库
            inbound.setIntoStatus(Constant.IntoStatus.YIRUKU.getName());
            //已入库数量
            inbound.setIntoQty(sumOutQty.abs());
            //来源id
            inbound.setFromId(inOutRecordVOList.get(0).getBiznisId());
            //来源单号
            inbound.setFromNo(inOutRecordVOList.get(0).getBiznisNo());
            //实体转换
            inboundMapper.insert(inbound);
            //endregion

            //region 明细
            for (InOutRecordVO inOutRecordVO : inOutRecordVOList) {
                InboundItem inboundItem = new InboundItem();
                //总单id
                inboundItem.setIntoId(inbound.getIntoId());
                //入库类型
                inboundItem.setIntoType(inbound.getIntoType());
                //出库数量
                inboundItem.setOutQty(inOutRecordVO.getIntoQty().abs());
                //已入库数量
                inboundItem.setIntoQty(inOutRecordVO.getIntoQty().abs());
                //入库状态
                inboundItem.setIntoStatus(inbound.getIntoStatus());
                //来源id
                inboundItem.setFromId(inOutRecordVOList.get(0).getBiznisId());
                //来源明细
                inboundItem.setFromItemId(inOutRecordVOList.get(0).getBiznisItemId());
                //实体转换
                inboundItemMapper.insert(inboundItem);
                inOutRecordVO.setIntoId(inbound.getIntoId());
                inOutRecordVO.setIntoItemId(inboundItem.getItemId());
            }
            //endregion
        }
        //编辑
        else {
            //region  编辑入库单数量
            InboundResponse inboundResponse = inboundMapper.selectMessageByOtherQuery(new InboundQuery().setFromId(inOutRecordVOList.get(0).getBiznisId()));
            Inbound inbound = new Inbound();
            inbound.setIntoId(inboundResponse.getIntoId());
            inbound.setIntoQty(sumOutQty.abs());
            inboundMapper.update(inbound,
                    new UpdateWrapper<Inbound>().lambda()
                            .eq(Inbound::getIntoId, UUID.fromString(inbound.getIntoId()))
            );
            //endregion

            //region 明细
            for (InOutRecordVO inOutRecordVO : inOutRecordVOList) {
                List<InboundItemResponse> inboundItemResponses = inboundItemMapper.selectByCond(new InboundItemQuery().
                        setFromId(inOutRecordVO.getBiznisId()).setFromItemId(inOutRecordVO.getBiznisItemId()));
                InboundItemResponse inboundItemResponse = inboundItemResponses.get(0);
                InboundItem inboundItem = new InboundItem();
                //总单id
                inboundItem.setItemId(inboundItemResponse.getItemId());
                //出库数量
                inboundItem.setOutQty(inOutRecordVO.getIntoQty().abs());
                //已入库数量
                inboundItem.setIntoQty(inOutRecordVO.getIntoQty().abs());
                inboundItemMapper.update(inboundItem,
                        new UpdateWrapper<InboundItem>().lambda()
                                .eq(InboundItem::getIntoId, UUID.fromString(inboundItem.getItemId()))
                );
                inOutRecordVO.setIntoId(inboundResponse.getIntoId());
                inOutRecordVO.setIntoItemId(inboundItemResponse.getItemId());
            }
            //endregion
        }

        return inOutRecordVOList;
    }

    /**
     * @desc : 操作负库存--新建和编辑
     * @date : 2024/4/12 9:57
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public void operatingNegativeInventory(List<InOutRecordVO> inOutRecordVOList) {
        for (InOutRecordVO inOutRecordVO : inOutRecordVOList) {
            //新建
            if (inOutRecordVO.getAddOrEditFlag()) {
                //校验库存是否存在
                InventoryResponse inventoryResponse = this.checkInventoryNumber(inOutRecordVO);
                //为空 新建
                if (inventoryResponse == null) {
                    //新建库存
                    this.insertInventory(inOutRecordVO);

                    //新建库存批次
                    this.insertInventoryBatch(inOutRecordVO);

                    //新建存货流水 一正一负
                    this.insertInboundRecord(inOutRecordVO);

                    //新建出库成本
                    this.insertOutboundItemCost(inOutRecordVO);
                }
            }
            //编辑
            else {
                //region  库存流水删除  ----根据来源id和来源明细id  入库出库都要删
                //入库
                InOutRecord inOutRecordInto = new InOutRecord();
                //来源id
                inOutRecordInto.setBiznisId(inOutRecordVO.getIntoId());
                //来源明细Id
                inOutRecordInto.setBiznisItemId(inOutRecordVO.getIntoItemId());
                inOutRecordMapper.deleteData(inOutRecordInto);
                //出库
                InOutRecord inOutRecord = new InOutRecord();
                //来源id
                inOutRecord.setBiznisId(inOutRecordVO.getBiznisId());
                //来源明细Id
                inOutRecord.setBiznisItemId(inOutRecordVO.getBiznisItemId());
                inOutRecordMapper.deleteData(inOutRecord);
                //endregion

                //region   要把出库成本也删除
                OutboundItemCost outboundItemCost = new OutboundItemCost();
                //出库明细Id
                outboundItemCost.setOutItemId(inOutRecordVO.getBiznisItemId());
                outboundItemCostMapper.deleteData(inOutRecord);
                //endregion

                //新建存货流水 一正一负
                this.insertInboundRecord(inOutRecordVO);
                //新建出库成本
                this.insertOutboundItemCost(inOutRecordVO);
            }
        }
    }

    /**
     * @desc : 操作负库存--删除（作废功能用目前）
     * @date : 2024/4/12 13:16
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public void operatingNegativeInventoryDelete(List<InOutRecordVO> inOutRecordVOList) {
        for (InOutRecordVO inOutRecordVO : inOutRecordVOList) {
            //region 判断是否需要删除库存
            InventoryResponse inventoryResponse = this.checkInventoryNumber(inOutRecordVO);
            if (inventoryResponse == null) {
                //删除的商品在库存中不存在
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.INVENTORY_DOES_NOT_EXIST.getMessage());
            }
            //库存数量为0 直接删除
            if (inventoryResponse.getInvQty().compareTo(BigDecimal.ZERO) == 0) {
                Inventory inventory = new Inventory();
                inventory.setInvId(inventoryResponse.getInvId());
                inventoryMapper.deleteData(inventory);
            }
            //endregion

            //region 删除库存批次
            InventoryBatch inventoryBatch = new InventoryBatch();
            //来源单ID
            inventoryBatch.setFromId(inOutRecordVO.getIntoId());
            //来源单明细ID
            inventoryBatch.setFromItemId(inOutRecordVO.getIntoItemId());
            inventoryBatchMapper.deleteData(inventoryBatch);
            //endregion


            //region  库存流水删除  ----根据来源id和来源明细id  入库出库都要删
            //入库
            InOutRecord inOutRecordInto = new InOutRecord();
            //来源id
            inOutRecordInto.setBiznisId(inOutRecordVO.getIntoId());
            //来源明细Id
            inOutRecordInto.setBiznisItemId(inOutRecordVO.getIntoItemId());
            inOutRecordMapper.deleteData(inOutRecordInto);
            //出库
            InOutRecord inOutRecord = new InOutRecord();
            //来源id
            inOutRecord.setBiznisId(inOutRecordVO.getBiznisId());
            //来源明细Id
            inOutRecord.setBiznisItemId(inOutRecordVO.getBiznisItemId());
            inOutRecordMapper.deleteData(inOutRecord);
            //endregion


            //region   要把出库成本也删除
            OutboundItemCost outboundItemCost = new OutboundItemCost();
            //出库明细Id
            outboundItemCost.setOutItemId(inOutRecordVO.getBiznisItemId());
            outboundItemCostMapper.deleteData(inOutRecord);
            //endregion
        }

    }

    /**************************************************仓位调整**********************************************************************/

    /**
     * @desc : 仓库调整出库
     * @date : 2024/4/12 15:37
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public List<InOutRecordVO> warehouseAdjustmentOut(List<InOutRecordVO> inOutRecordVOList) {
        for (InOutRecordVO inOutRecordVO : inOutRecordVOList) {
            //校验库存是否存在
            InventoryResponse inventoryResponse = this.checkInventoryNumber(inOutRecordVO);
            //region  库存不存在
            if (inventoryResponse == null) {
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.SKU_IS_NOT_IN_INVENTORY.getMessage());
            }
            //endregion

            //region  库存存在
            else {
                inOutRecordVO.setInvId(inventoryResponse.getInvId());

                //region 库存批次 编辑
                this.updateInventoryBatch(inOutRecordVO);
                //endregion

                //region  修改/新建   库存数量，可用量，金额等信息
                this.updateInventoryMessageAdd(inventoryResponse, inOutRecordVO);
                //endregion

                //region 库存流水
                this.insertInboundRecord(inOutRecordVO);
                //endregion
            }
            //endregion
        }
        return inOutRecordVOList;
    }

    /**
     * @desc : 修改出库
     * @date : 2024/4/16 9:59
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public void updateOutbound(List<InOutRecordVO> inOutRecordVOList) {
        //根据源出库单分组
        Map<String, List<InOutRecordVO>> InOutRecordVOListMap = inOutRecordVOList.stream().collect(Collectors.groupingBy(InOutRecordVO::getBiznisId));
        for (String str : InOutRecordVOListMap.keySet()) {
            //提取分组后的明细
            List<InOutRecordVO> inOutRecordVOListGroup = InOutRecordVOListMap.get(str);
            //提取总额，总量
            BigDecimal sumOutAmt = inOutRecordVOListGroup.stream().map(InOutRecordVO::getIntoAmt).reduce(BigDecimal.ZERO, BigDecimal::add).setScale(2, BigDecimal.ROUND_HALF_UP);
            for (InOutRecordVO inOutRecordVO : inOutRecordVOListGroup) {
                //修改明细
                OutboundItem outboundItem = new OutboundItem();
                outboundItem.setItemId(inOutRecordVO.getBiznisItemId());
                outboundItem.setOutAmt(inOutRecordVO.getIntoAmt());
                outboundItem.setPriceOut(inOutRecordVO.getCostPrice());
                outboundItem.setCostPrice(inOutRecordVO.getCostPrice());
                outboundItem.setCostAmt(inOutRecordVO.getIntoAmt());
                //修改
                outboundItemMapper.update(outboundItem,
                        new UpdateWrapper<OutboundItem>().lambda()
                                .eq(OutboundItem::getItemId, UUID.fromString(outboundItem.getSOutItemId()))
                );
            }
            //修改总单
            Outbound outbound = new Outbound();
            outbound.setOutId(str);
            outbound.setOutAmt(sumOutAmt);
            //修改
            outboundMapper.update(outbound,
                    new UpdateWrapper<Outbound>().lambda().eq(Outbound::getOutId, UUID.fromString(outbound.getOutId()))
            );
        }
    }

    /**
     * @desc : 仓库调整入库
     * @date : 2024/4/12 15:37
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public List<InOutRecordVO> warehouseAdjustmentInto(List<InOutRecordVO> inOutRecordVOList) {
        for (InOutRecordVO inOutRecordVO : inOutRecordVOList) {
            //校验库存是否存在
            InventoryResponse inventoryResponse = this.checkInventoryNumber(inOutRecordVO);

            //region  库存不存在---新建
            if (inventoryResponse == null) {

                //region  新建库存
                inOutRecordVO = this.insertInventory(inOutRecordVO);
                //endregion

                //region 库存批次
                this.insertInventoryBatch(inOutRecordVO);
                //endregion

                //region 库存流水
                this.insertInboundRecord(inOutRecordVO);
                //endregion
            }
            //endregion

            //region  库存存在
            else {
                inOutRecordVO.setInvId(inventoryResponse.getInvId());

                //region 库存批次
                this.insertInventoryBatch(inOutRecordVO);
                //endregion

                //region  修改/新建   库存数量，可用量，金额等信息
                this.updateInventoryMessageAdd(inventoryResponse, inOutRecordVO);
                //endregion

                //region 库存流水
                this.insertInboundRecord(inOutRecordVO);
                //endregion
            }
            //endregion
        }
        return inOutRecordVOList;
    }

    /**
     * @desc : 修改入库单---单价、金额、成本等信息
     * @date : 2024/4/16 10:18
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public void updateIntobound(List<InOutRecordVO> inOutRecordVOList) {
        BigDecimal sumOutQty = inOutRecordVOList.stream().map(InOutRecordVO::getIntoQty).reduce(BigDecimal.ZERO, BigDecimal::add).setScale(6, BigDecimal.ROUND_HALF_UP);
        BigDecimal sumOutAmt = inOutRecordVOList.stream().map(InOutRecordVO::getIntoAmt).reduce(BigDecimal.ZERO, BigDecimal::add).setScale(6, BigDecimal.ROUND_HALF_UP);
        //region  编辑入库单数量
        InboundResponse inboundResponse = inboundMapper.selectMessageByOtherQuery(new InboundQuery().setIntoId(inOutRecordVOList.get(0).getBiznisId()));
        Inbound inbound = new Inbound();
        inbound.setIntoId(inboundResponse.getIntoId());
        inbound.setIntoQty(sumOutQty.abs());
        inbound.setIntoAmt(sumOutAmt.abs());
        inboundMapper.update(inbound,
                new UpdateWrapper<Inbound>().lambda()
                        .eq(Inbound::getIntoId, UUID.fromString(inbound.getIntoId()))
        );
        //endregion

        //region 明细
        for (InOutRecordVO inOutRecordVO : inOutRecordVOList) {
           /* List<InboundItemResponse> inboundItemResponses = inboundItemMapper.selectByCond(new InboundItemQuery()
                    .setItemId(inOutRecordVO.getBiznisItemId()));*/

            InboundItem inboundItem = new InboundItem();
            //总单id
            inboundItem.setItemId(inOutRecordVO.getBiznisItemId());
            //出库数量
            inboundItem.setOutQty(inOutRecordVO.getIntoQty().abs());
            //已入库数量
            inboundItem.setIntoQty(inOutRecordVO.getIntoQty().abs());
            //已入库金额
            inboundItem.setIntoAmt(inOutRecordVO.getIntoAmt().abs());
            //成本单价
            inboundItem.setCostPrice(inOutRecordVO.getCostPrice().abs());
            //成本金额
            inboundItem.setCostAmt(inOutRecordVO.getIntoAmt().abs());
            //库存id
            inboundItem.setInvId(inOutRecordVO.getInvId());
            inboundItemMapper.update(inboundItem,
                    new UpdateWrapper<InboundItem>().lambda()
                            .eq(InboundItem::getItemId, UUID.fromString(inboundItem.getItemId()))
            );
        }
        //endregion
    }

    /**
     * @desc : 根据来源id和来源明细id查找出库单获取单价，金额等信息
     * @date : 2024/4/16 10:19
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public List<InOutRecordVO> selectOutbound(List<InOutRecordVO> inOutRecordVOList) {
        for (InOutRecordVO inOutRecordVO : inOutRecordVOList) {
            OutboundItemResponse outboundItemResponse = outboundItemMapper.selectItemIndex(inOutRecordVO.getItemIndex(),inOutRecordVO.getOutId());
            //单价
            inOutRecordVO.setPriceInto(outboundItemResponse.getPriceOut());
            //金额
            inOutRecordVO.setIntoAmt(outboundItemResponse.getOutAmt());
            //成本单价
            inOutRecordVO.setCostPrice(outboundItemResponse.getCostPrice());
        }

        return inOutRecordVOList;
    }

    /**
     * @desc : 调整仓库-入库删除
     * @date : 2024/4/10 13:09
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public void warehouseAdjustmentDelInto(List<InOutRecordVO> inOutRecordVOList) {
        for (InOutRecordVO inOutRecordVO : inOutRecordVOList) {
            //region  校验库存  根据sku，仓库，非标号查询
            InventoryResponse inventoryResponse = inventoryMapper.selectByOther(new InventoryQuery()
                    .setSkuId(inOutRecordVO.getSkuId())
                    .setWhId(inOutRecordVO.getWhId())
                    .setNonStdCode(inOutRecordVO.getNonStdCode()));
            //库存是否存在
            if (inventoryResponse == null) {
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.SKU_IS_NOT_IN_INVENTORY.getMessage());
            }
            //endregion

            //region   根据来源id和来源明细id查询数据 库存批次删除
            InventoryBatchResponse inventoryBatchResponse = inventoryBatchMapper.selectByFromCondition(new InventoryBatchQuery()
                    .setFromId(inOutRecordVO.getBiznisId()).setFromItemId(inOutRecordVO.getBiznisItemId()));
            if (inventoryBatchResponse == null) {
                //当前编辑的数据在库存批次中不存在
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.INVENTORY_BATCH_DOES_NOT_EXIST.getMessage());
            } else {
                //数据库中库存批次数量和传入数量一致 可以更改
                if (inventoryResponse.getInvQty().compareTo(inOutRecordVO.getIntoQty().abs()) == 0) {
                    InventoryBatch inventoryBatch = new InventoryBatch();
                    //来源单ID
                    inventoryBatch.setFromId(inOutRecordVO.getBiznisId());
                    //来源单明细ID
                    inventoryBatch.setFromItemId(inOutRecordVO.getBiznisItemId());
                    inventoryBatchMapper.deleteData(inventoryBatch);
                } else {
                    //不允许编辑，对应库存数据已被修改
                    throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.INVENTORY_DATA_HAS_BEEN_MODIFIED.getMessage());

                }
            }
            //endregion

            //region  修改库存数量，可用量，金额等信息
            this.updateInventoryMessageDelete(inventoryResponse, inOutRecordVO);
            //endregion

            //region  根据来源id和来源明细id查询数据 库存流水删除
            InOutRecord inOutRecord = new InOutRecord();
            //来源id
            inOutRecord.setBiznisId(inOutRecordVO.getBiznisId());
            //来源明细Id
            inOutRecord.setBiznisItemId(inOutRecordVO.getBiznisItemId());
            inOutRecordMapper.deleteData(inOutRecord);
            //endregion
        }
    }

    /**
     * @desc : 调整仓库-出库反写
     * @date : 2024/4/10 13:09
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public void warehouseAdjustmentDelOut(List<InOutRecordVO> inOutRecordVOList) {
        for (InOutRecordVO inOutRecordVO : inOutRecordVOList) {
            //region  校验库存  根据sku，仓库，非标号查询
            InventoryResponse inventoryResponse = inventoryMapper.selectByOther(new InventoryQuery()
                    .setSkuId(inOutRecordVO.getSkuId())
                    .setWhId(inOutRecordVO.getWhId())
                    .setNonStdCode(inOutRecordVO.getNonStdCode()));
            //库存是否存在
            if (inventoryResponse == null) {
                throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.SKU_IS_NOT_IN_INVENTORY.getMessage());
            }
            //endregion

            //region   根据来源id和来源明细id查询数据 库存批次删除
            if ((Constant.InventoryType.OUTBOUND.getName().equals(inOutRecordVO.getInventoryType()) &&
                    !Constant.InventoryDocCode.SALE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode())) ||
                    Constant.InventoryDocCode.PURCHASE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode())
            ) {
                //根据outItemId查找出库成本数据
                List<OutboundItemCostResponse> outboundItemCostResponses = outboundItemCostMapper.selectByCond(new OutboundItemCostQuery().setOutItemId(inOutRecordVO.getBiznisItemId()));
                for (OutboundItemCostResponse outboundItemCostResponse : outboundItemCostResponses) {
                    //查找库存批次
                    InventoryBatchResponse inventoryBatchResponse = inventoryBatchMapper.selectById(outboundItemCostResponse.getBatchId());
                    InventoryBatch inventoryBatch = new InventoryBatch();
                    inventoryBatch.setBatchId(outboundItemCostResponse.getBatchId());
                    inventoryBatch.setInvQty(inventoryBatchResponse.getInvQty().add(outboundItemCostResponse.getOutQty()));
                    inventoryBatch.setCostAmt(inventoryBatch.getInvQty().multiply(inventoryBatch.getCostPrice()));
                    inventoryBatchMapper.updateAmtAndQty(inventoryBatch);
                }
            }
            //endregion

            //region  修改库存数量，可用量，金额等信息
            this.updateInventoryMessageDelete(inventoryResponse, inOutRecordVO);
            //endregion

            //region  根据来源id和来源明细id查询数据 库存流水删除
            InOutRecord inOutRecord = new InOutRecord();
            //来源id
            inOutRecord.setBiznisId(inOutRecordVO.getBiznisId());
            //来源明细Id
            inOutRecord.setBiznisItemId(inOutRecordVO.getBiznisItemId());
            inOutRecordMapper.deleteData(inOutRecord);
            //endregion
        }
    }


    /**********************************************************************暂时废弃**********************************************************************/

    /**
     * @desc : 新建库存、库存批次，库存流水，出库成本
     * @date : 2024/3/21 14:47
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public List<InOutRecordVO> insertAllInventory(List<InOutRecordVO> inOutRecordVOList) {
        //判断库存数据是否存在，存在更细，不存在新建
        for (InOutRecordVO inOutRecordVO : inOutRecordVOList) {
            //根据sku，仓库，非标号查询
            InventoryResponse inventoryResponse = inventoryMapper.selectByOther(new InventoryQuery()
                    .setSkuId(inOutRecordVO.getSkuId())
                    .setWhId(inOutRecordVO.getWhId())
                    .setNonStdCode(inOutRecordVO.getNonStdCode()));
            //不存在  新建
            if (inventoryResponse == null) {
                //todo  先注释掉
//                //库存数量可以为负数
//                if(inOutRecordVO.getCanNegativeFlag()){
//                    //新建负数库存
//                    inOutRecordVO = this.insertNegativeInventory(inOutRecordVO);
//                }else{
//                }
                //采购退货入库  或者  是出库但不是销售退货出库
                if (Constant.InventoryDocCode.PURCHASE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode()) ||
                        (Constant.InventoryType.OUTBOUND.getName().equals(inOutRecordVO.getInventoryType()) &&
                                !Constant.InventoryDocCode.SALE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode()))
                ) {
                    throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.SKU_IS_NOT_IN_INVENTORY.getMessage());
                }
                Inventory inventory = new Inventory();
                //仓库Id
                inventory.setWhId(inOutRecordVO.getWhId());
                //商品id
                inventory.setSkuId(inOutRecordVO.getSkuId());
                //非标号
                inventory.setNonStdCode(inOutRecordVO.getNonStdCode());
                //销售退货出库也是新建 但是数量要取反 因为传过来的时候负数
                if (Constant.InventoryDocCode.SALE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode())) {
                    //库存数量
                    inventory.setInvQty(inOutRecordVO.getIntoQty().negate());
                    //可售数量（可用量）
                    inventory.setUsableQty(inOutRecordVO.getIntoQty().negate());
                    //库存资产
                    inventory.setCostAmt(inOutRecordVO.getIntoAmt().negate());
                    //库存单价   存货资产/存货数量
                    inventory.setCostPrice(inventory.getCostAmt().negate().divide(inventory.getInvQty().negate(), BigDecimal.ROUND_HALF_UP));
                } else {
                    //库存数量
                    inventory.setInvQty(inOutRecordVO.getIntoQty());
                    //可售数量（可用量）
                    inventory.setUsableQty(inOutRecordVO.getIntoQty());
                    //库存资产
                    inventory.setCostAmt(inOutRecordVO.getIntoAmt());
                    //库存单价   存货资产/存货数量
                    inventory.setCostPrice(inventory.getCostAmt().divide(inventory.getInvQty(), BigDecimal.ROUND_HALF_UP));
                }
                //新建
                inventoryMapper.insert(inventory);
                //仓库Id赋值
                inOutRecordVO.setInvId(inventory.getInvId());
                //新建批次明细
                this.insertInventoryBatch(inOutRecordVO);
                //新建库存流水
                this.insertInboundRecord(inOutRecordVO);
            }
            //存在 出库校验库存是否充足重写updateById，入库加入数据
            else {
                //仓库Id赋值
                inOutRecordVO.setInvId(inventoryResponse.getInvId());
                //根据类型判断是新建库存批次还是更新库存批次
                inOutRecordVO = this.checkInsertOrUpdateInventoryBatch(inOutRecordVO);
                //跟新库存数据
                Inventory inventory = new Inventory();
                //库存资产
                inventory.setCostAmt(inOutRecordVO.getIntoAmt());
                //实体转换
                InventoryVO inventoryVO = inventoryConvert.convertToVO(inventory);
                //采购退货入库  或者  是出库但不是销售退货出库
                if (Constant.InventoryDocCode.PURCHASE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode()) ||
                        (Constant.InventoryType.OUTBOUND.getName().equals(inOutRecordVO.getInventoryType()) && !Constant.InventoryDocCode.SALE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode()))
                ) {
                    //更新库存  判断是否是库存数量和本次出库的数量一致，一致直接为0
                    if (inOutRecordVO.getIntoQty().abs().compareTo(inventoryResponse.getUsableQty()) == 0) {
                        inventory.setCostPrice(BigDecimal.ZERO);
                        inventory.setCostAmt(BigDecimal.ZERO);
                        inventoryVO.setZeroFlag(true);
                    } else {
                        //根据上面的过滤如果是出库  数量取反（传值为正数改成负数）
                        if (Constant.InventoryType.OUTBOUND.getName().equals(inOutRecordVO.getInventoryType())) {
                            //库存数量
                            inventory.setInvQty(inOutRecordVO.getIntoQty().negate());
                            //库存资产
                            inventory.setCostAmt(inOutRecordVO.getIntoAmt().negate());
                        }
                        inventoryVO.setZeroFlag(false);
                    }
                }
                //如果是销售退货出库  数量取反  （传值为负数改成正数）
                if (Constant.InventoryDocCode.SALE_RETURN.getValue().equals(inOutRecordVO.getInventoryDocCode())) {
                    //库存数量
                    inventory.setInvQty(inOutRecordVO.getIntoQty().negate());
                    //库存资产
                    inventory.setCostAmt(inOutRecordVO.getIntoAmt().negate());
                }
                //修改库存金额、数量相关字段
                int countRow = inventoryMapper.updateAmountAndQuantity(inventoryVO);
                //数量超出
                if (countRow == 0) {
                    throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.INVENTORY_QUANTITY_HAS_EXCEEDED.getMessage());
                }
            }
        }

        return inOutRecordVOList;
    }

    /*
     * @desc   : 判断是新建还是更新库存流水
     * @date   : 2024/3/29 16:32
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public InOutRecordVO checkInsertOrUpdateInventoryBatch(InOutRecordVO inOutRecordVO) {
        //查询库存批次明细  按照时间排序（正序）
        List<InventoryBatchResponse> inventoryBatchResponseList = inventoryBatchMapper.selectAmountAndQuantity(new InventoryBatchQuery().setInvId(inOutRecordVO.getInvId()));
        if (inventoryBatchResponseList.size() > 0) {
            //数量
            BigDecimal qty = inOutRecordVO.getIntoQty().abs();
            //金额
            BigDecimal amt = BigDecimal.ZERO;
            for (InventoryBatchResponse inventoryBatchResponse : inventoryBatchResponseList) {
                InventoryBatchVO inventoryBatchVO = new InventoryBatchVO();
                //判断是否为最后一次扣减当前条库存
                //是
                if (qty.abs().compareTo(inventoryBatchResponse.getInvQty()) == 0) {
                    //主键赋值
                    inventoryBatchVO.setBatchId(inventoryBatchResponse.getBatchId());
                    //库存数量
                    inventoryBatchVO.setInvQty(BigDecimal.ZERO);
                    //存货资产
                    inventoryBatchVO.setCostAmt(BigDecimal.ZERO);
                    //清零标识
                    inventoryBatchVO.setZeroFlag(true);
                    inventoryBatchMapper.updateAmountAndQuantity(inventoryBatchVO);
                    //金额  = 传入数量 * 库存批次明细存货单价
                    amt = inventoryBatchVO.getInvQty().multiply(inventoryBatchResponse.getCostPrice());
                    inOutRecordVO.setCostPrice(inventoryBatchResponse.getCostPrice());
                    inOutRecordVO.setIntoAmt(inOutRecordVO.getIntoQty().multiply(inventoryBatchResponse.getCostPrice()));
                    //出库成本
                    this.insertOutboundItemCost(inOutRecordVO);
                    //新建库存流水
                    this.insertInboundRecord(inOutRecordVO);
                    break;
                }
                //不是
                else {
                    //当前条库存批次明细够出库
                    if (qty.abs().compareTo(inventoryBatchResponse.getInvQty()) < 0) {
                        //主键赋值
                        inventoryBatchVO.setBatchId(inventoryBatchResponse.getBatchId());
                        //库存数量
                        inventoryBatchVO.setInvQty(inOutRecordVO.getIntoQty());
                        //存货资产
                        inventoryBatchVO.setCostAmt(inventoryBatchVO.getInvQty().multiply(inventoryBatchResponse.getCostPrice()));
                        //清零标识
                        inventoryBatchVO.setZeroFlag(true);
                        inventoryBatchMapper.updateAmountAndQuantity(inventoryBatchVO);
                        //金额  = 传入数量 * 库存批次明细存货单价
                        amt = inventoryBatchVO.getInvQty().multiply(inventoryBatchResponse.getCostPrice());
                        inOutRecordVO.setCostPrice(inventoryBatchResponse.getCostPrice());
                        inOutRecordVO.setIntoAmt(inOutRecordVO.getIntoQty().multiply(inventoryBatchResponse.getCostPrice()));
                        //出库成本
                        this.insertOutboundItemCost(inOutRecordVO);
                        //新建库存流水
                        this.insertInboundRecord(inOutRecordVO);
                        break;
                    }
                    //当前条库存批次明细不够出库
                    if (qty.abs().compareTo(inventoryBatchResponse.getInvQty()) > 0) {
                        //主键赋值
                        inventoryBatchVO.setBatchId(inventoryBatchResponse.getBatchId());
                        //库存数量
                        inventoryBatchVO.setInvQty(inventoryBatchResponse.getInvQty());
                        //存货资产
                        inventoryBatchVO.setCostAmt(inventoryBatchResponse.getCostAmt());
                        //清零标识
                        inventoryBatchVO.setZeroFlag(true);
                        //修改数量金额
                        inventoryBatchMapper.updateAmountAndQuantity(inventoryBatchVO);
                        //数量、金额每次更新完要重新运算
                        qty = qty.subtract(inventoryBatchResponse.getInvQty());
                        amt = amt.add(inventoryBatchResponse.getInvQty().multiply(inventoryBatchResponse.getCostPrice()));
                        inOutRecordVO.setCostPrice(inventoryBatchResponse.getCostPrice());
                        inOutRecordVO.setIntoAmt(inventoryBatchResponse.getInvQty().multiply(inventoryBatchResponse.getCostPrice()));
                        //出库成本
                        this.insertOutboundItemCost(inOutRecordVO);
                        //新建库存流水
                        this.insertInboundRecord(inOutRecordVO);
                    }
                }
            }
            inOutRecordVO.setIntoAmt(amt);
        } else {
            throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.CAN_OUTBOUND_QUANTITY_INSUFFICIENT.getMessage());
        }
        //endregion
        return inOutRecordVO;
    }


    /**
     * @desc : 新建负数库存
     * @date : 2024/4/8 16:57
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public InOutRecordVO insertNegativeInventory(InOutRecordVO inOutRecordVO) {
        Inventory inventory = new Inventory();
        //仓库Id
        inventory.setWhId(inOutRecordVO.getWhId());
        //商品id
        inventory.setSkuId(inOutRecordVO.getSkuId());
        //非标号
        inventory.setNonStdCode(inOutRecordVO.getNonStdCode());
        //库存数量
        inventory.setInvQty(inOutRecordVO.getIntoQty().negate());
        //可售数量（可用量）
        inventory.setUsableQty(inOutRecordVO.getIntoQty().negate());
        //库存单价
        inventory.setCostPrice(inOutRecordVO.getPriceInto().negate());
        //库存资产
        inventory.setCostAmt(inOutRecordVO.getIntoAmt().negate());
        //企业id
        inventory.setCpId(inOutRecordVO.getCpId());
        //新建
        inventoryMapper.insert(inventory);
        //仓库Id赋值
        inOutRecordVO.setInvId(inventory.getInvId());
        //新建批次明细
        //todo  先校验是否有库存
        this.insertInventoryBatch(inOutRecordVO);
        //新建库存流水
        this.insertInboundRecord(inOutRecordVO);
        return inOutRecordVO;
    }

    /**
     * @desc : 可以新建负数库存使用
     * @date : 2024/4/8 17:19
     * @author : 寇珊珊
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public InOutRecordVO insertNegativeInventoryBatch(InOutRecordVO inOutRecordVO) {
        //查询库存批次明细  按照时间排序（正序）
        List<InventoryBatchResponse> inventoryBatchResponseList = inventoryBatchMapper.selectAmountAndQuantity(new InventoryBatchQuery().setInvId(inOutRecordVO.getInvId()));
        if (inventoryBatchResponseList.size() > 0) {
            //数量
            BigDecimal qty = inOutRecordVO.getIntoQty().abs();
            //金额
            BigDecimal amt = BigDecimal.ZERO;
            for (InventoryBatchResponse inventoryBatchResponse : inventoryBatchResponseList) {
                InventoryBatchVO inventoryBatchVO = new InventoryBatchVO();
                //判断是否为最后一次扣减当前条库存
                //是
                if (qty.abs().compareTo(inventoryBatchResponse.getInvQty()) == 0) {
                    //主键赋值
                    inventoryBatchVO.setBatchId(inventoryBatchResponse.getBatchId());
                    //库存数量
                    inventoryBatchVO.setInvQty(BigDecimal.ZERO);
                    //存货资产
                    inventoryBatchVO.setCostAmt(BigDecimal.ZERO);
                    //清零标识
                    inventoryBatchVO.setZeroFlag(true);
                    inventoryBatchMapper.updateAmountAndQuantity(inventoryBatchVO);
                    //金额  = 传入数量 * 库存批次明细存货单价
                    amt = inventoryBatchVO.getInvQty().multiply(inventoryBatchResponse.getCostPrice());
                    inOutRecordVO.setCostPrice(inventoryBatchResponse.getCostPrice());
                    inOutRecordVO.setIntoAmt(inOutRecordVO.getIntoQty().multiply(inventoryBatchResponse.getCostPrice()));
                    //出库成本
                    this.insertOutboundItemCost(inOutRecordVO);
                    //新建库存流水
                    this.insertInboundRecord(inOutRecordVO);
                    break;
                }
                //不是
                else {
                    //当前条库存批次明细够出库
                    if (qty.abs().compareTo(inventoryBatchResponse.getInvQty()) < 0) {
                        //主键赋值
                        inventoryBatchVO.setBatchId(inventoryBatchResponse.getBatchId());
                        //库存数量
                        inventoryBatchVO.setInvQty(inOutRecordVO.getIntoQty());
                        //存货资产
                        inventoryBatchVO.setCostAmt(inventoryBatchVO.getInvQty().multiply(inventoryBatchResponse.getCostPrice()));
                        //清零标识
                        inventoryBatchVO.setZeroFlag(true);
                        inventoryBatchMapper.updateAmountAndQuantity(inventoryBatchVO);
                        //金额  = 传入数量 * 库存批次明细存货单价
                        amt = inventoryBatchVO.getInvQty().multiply(inventoryBatchResponse.getCostPrice());
                        inOutRecordVO.setCostPrice(inventoryBatchResponse.getCostPrice());
                        inOutRecordVO.setIntoAmt(inOutRecordVO.getIntoQty().multiply(inventoryBatchResponse.getCostPrice()));
                        //出库成本
                        this.insertOutboundItemCost(inOutRecordVO);
                        //新建库存流水
                        this.insertInboundRecord(inOutRecordVO);
                        break;
                    }
                    //当前条库存批次明细不够出库
                    if (qty.abs().compareTo(inventoryBatchResponse.getInvQty()) > 0) {
                        //主键赋值
                        inventoryBatchVO.setBatchId(inventoryBatchResponse.getBatchId());
                        //库存数量
                        inventoryBatchVO.setInvQty(inventoryBatchResponse.getInvQty());
                        //存货资产
                        inventoryBatchVO.setCostAmt(inventoryBatchResponse.getCostAmt());
                        //清零标识
                        inventoryBatchVO.setZeroFlag(true);
                        //修改数量金额
                        inventoryBatchMapper.updateAmountAndQuantity(inventoryBatchVO);
                        //数量、金额每次更新完要重新运算
                        qty = qty.subtract(inventoryBatchResponse.getInvQty());
                        amt = amt.add(inventoryBatchResponse.getInvQty().multiply(inventoryBatchResponse.getCostPrice()));
                        inOutRecordVO.setCostPrice(inventoryBatchResponse.getCostPrice());
                        inOutRecordVO.setIntoAmt(inventoryBatchResponse.getInvQty().multiply(inventoryBatchResponse.getCostPrice()));
                        //出库成本
                        this.insertOutboundItemCost(inOutRecordVO);
                        //新建库存流水
                        this.insertInboundRecord(inOutRecordVO);
                    }
                }
            }
            inOutRecordVO.setIntoAmt(amt);
        }
        return inOutRecordVO;
    }


}
