package com.huaheng.pc.receipt.receiptHeader.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.huaheng.api.srm.domain.ICSRuternASN;
import com.huaheng.common.utils.DateUtils;
import com.huaheng.common.utils.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaheng.common.constant.QuantityConstant;
import com.huaheng.common.exception.service.ServiceException;
import com.huaheng.common.support.Convert;
import com.huaheng.common.utils.StringUtils;
import com.huaheng.common.utils.http.HttpUtils;
import com.huaheng.common.utils.security.ShiroUtils;
import com.huaheng.framework.aspectj.ApiLogAspect;
import com.huaheng.framework.web.domain.AjaxResult;
import com.huaheng.pc.check.checkDetail.domain.CheckDetail;
import com.huaheng.pc.check.checkDetail.service.CheckDetailService;
import com.huaheng.pc.check.checkHeader.domain.CheckHeader;
import com.huaheng.pc.check.checkHeader.service.CheckHeaderService;
import com.huaheng.pc.config.address.service.AddressService;
import com.huaheng.pc.config.company.domain.CompanyU8;
import com.huaheng.pc.config.company.service.CompanyU8Service;
import com.huaheng.pc.config.container.domain.Container;
import com.huaheng.pc.config.container.service.ContainerService;
import com.huaheng.pc.config.location.domain.Location;
import com.huaheng.pc.config.location.service.LocationService;
import com.huaheng.pc.config.receiptType.domain.ReceiptType;
import com.huaheng.pc.config.receiptType.service.ReceiptTypeService;
import com.huaheng.pc.config.statusFlow.domain.StatusFlowDetail;
import com.huaheng.pc.inventory.inventoryDetail.service.InventoryDetailService;
import com.huaheng.pc.inventory.inventoryHeader.service.InventoryHeaderService;
import com.huaheng.pc.inventory.inventoryTransaction.domain.InventoryTransaction;
import com.huaheng.pc.inventory.inventoryTransaction.service.InventoryTransactionService;
import com.huaheng.pc.monitor.apilog.domain.ApiLog;
import com.huaheng.pc.receipt.receiptContainerHeader.domain.ReceiptContainerHeader;
import com.huaheng.pc.receipt.receiptContainerHeader.domain.ReceiptContainerView;
import com.huaheng.pc.receipt.receiptContainerHeader.service.ReceiptContainerHeaderService;
import com.huaheng.pc.receipt.receiptDetail.domain.ReceiptDetail;
import com.huaheng.pc.receipt.receiptDetail.service.ReceiptDetailService;
import com.huaheng.pc.receipt.receiptDetailHistory.domain.ReceiptDetailHistory;
import com.huaheng.pc.receipt.receiptDetailHistory.service.ReceiptDetailHistoryService;
import com.huaheng.pc.receipt.receiptHeader.domain.ReceiptHeader;
import com.huaheng.pc.receipt.receiptHeader.mapper.ReceiptHeaderMapper;
import com.huaheng.pc.receipt.receiptHeader.mapper.ReceiptHeaderhistoryMapper;
import com.huaheng.pc.receipt.receiptHeaderHistory.domain.ReceiptHeaderHistory;
import com.huaheng.pc.receipt.receiptHeaderHistory.service.ReceiptHeaderHistoryService;
import com.huaheng.pc.shipment.shipmentDetail.domain.ShipmentDetail;
import com.huaheng.pc.shipment.shipmentDetail.service.ShipmentDetailService;
import com.huaheng.pc.shipment.shipmentHeader.domain.ShipmentHeader;
import com.huaheng.pc.shipment.shipmentHeader.service.ShipmentHeaderService;
import com.huaheng.pc.srm.domain.MesPostBack;
import com.huaheng.pc.srm.service.ICSASNService;
import com.huaheng.pc.task.taskDetail.domain.TaskDetail;
import com.huaheng.pc.task.taskDetail.service.TaskDetailService;
import com.huaheng.pc.task.taskHeader.domain.TaskHeader;
import com.huaheng.pc.task.taskHeader.service.ReceiptTaskService;
import com.huaheng.pc.task.taskHeader.service.TaskHeaderService;
import com.huaheng.pc.u8.domain.ICSReceiptDetail;
import com.huaheng.pc.u8.domain.ICSReceiptHeader;
import com.huaheng.pc.u8.domain.ICSReceiptModel;
import com.huaheng.pc.u8.service.ICSReceiptDetailService;
import com.huaheng.pc.u8.service.ICSReceiptHeaderService;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ReceiptHeaderService extends ServiceImpl<ReceiptHeaderMapper, ReceiptHeader> {

    @Resource
    private ReceiptTypeService receiptTypeService;
    @Resource
    private ReceiptDetailService receiptDetailService;
    @Resource
    private CheckHeaderService checkHeaderService;
    @Resource
    private CheckDetailService checkDetailService;
    @Resource
    private ShipmentHeaderService shipmentHeaderService;
    @Resource
    private ReceiptHeaderMapper receiptHeaderMapper;
    @Resource
    private ReceiptHeaderhistoryMapper receiptheaderhistoryMapper;
    @Resource
    private InventoryHeaderService inventoryHeaderService;
    @Resource
    private InventoryDetailService inventoryDetailService;
    @Resource
    private ShipmentDetailService shipmentDetailService;
    @Resource
    private InventoryTransactionService inventoryTransactionService;
    @Resource
    private AddressService addressService;
    @Resource
    private CompanyU8Service companyWuService;
    @Resource
    private ICSReceiptHeaderService icsReceiptHeaderService;
    @Resource
    private ICSReceiptDetailService icsReceiptDetailService;
    @Resource
    private ContainerService containerService;
    @Resource
    private ReceiptContainerHeaderService receiptContainerHeaderService;
    @Resource
    private TaskHeaderService taskHeaderService;
    @Resource
    private TaskDetailService taskDetailService;
    @Resource
    private ReceiptTaskService receiptTaskService;
    @Resource
    private ReceiptDetailHistoryService receiptDetailHistoryService;
    @Resource
    private ReceiptHeaderHistoryService receiptheaderhistoryService;
    @Resource
    private LocationService locationService;
    @Resource
    private ICSASNService icsasnService;
    /**
     * 保存入库单
     *
     * @param receiptHeader
     * @return
     */
    public AjaxResult saveReceiptHeader(ReceiptHeader receiptHeader) {
        //根据仓库和货主以及传入单据类型编码判断单据类型是否存在
        LambdaQueryWrapper<ReceiptType> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(ReceiptType::getCode, receiptHeader.getReceiptType())
                .eq(ReceiptType::getWarehouseCode, ShiroUtils.getWarehouseCode());
//                .eq(ReceiptType::getCompanyCode, receiptHeader.getCompanyCode());
        ReceiptType receiptType = receiptTypeService.getOne(lambdaQueryWrapper);
        if (receiptType == null) {
            throw new ServiceException(ShiroUtils.getWarehouseCode(), receiptHeader.getCompanyCode(), "没有对应的入库单类型");
        }
        receiptHeader.setWarehouseCode(ShiroUtils.getWarehouseCode());
        //根据单据类型生成单号
        String code = createCode(receiptHeader.getReceiptType(),receiptHeader.getWarehouseCode());
        if (StringUtils.isEmpty(code)) {
            throw new ServiceException("根据单据类型" + receiptHeader.getReceiptType() + "生成单号失败");
        }
        receiptHeader.setCode(code);
        receiptHeader.setFirstStatus(QuantityConstant.RECEIPT_HEADER_BUILD);
        receiptHeader.setLastStatus(QuantityConstant.RECEIPT_HEADER_BUILD);

        return AjaxResult.toAjax(this.save(receiptHeader));
    }

    /**
     * 根据单据类型生成单号  规则:入库单类型 + 年月日 + 5位(排序号 + 1)
     *
     * @param receiptType
     * @return
     */
    //todo:huhai 单据生成规则,后续版本计划追加一个序列号生成规则表:统一设定前缀,填充位,流水码等
    public String createCode(String receiptType,String warehouseCode) {
        String code = null;
        int i = 1;
        Date now = new Date();
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
        LambdaQueryWrapper<ReceiptHeader> lambda = Wrappers.lambdaQuery();
        lambda.select(ReceiptHeader::getCode).eq(ReceiptHeader::getReceiptType, receiptType);
        lambda.eq(StringUtils.isNotEmpty(warehouseCode),ReceiptHeader::getWarehouseCode,warehouseCode)
                .orderByDesc(ReceiptHeader::getCode).last("Limit 1");
        //如果指定类型的最后的code存在,并且日期一致。那么 code = 入库单类型 + 年月日 + (排序号 + 1)
        String maxCode = null;
        ReceiptHeader receiptHeader = this.getOne(lambda);
        if (receiptHeader != null) {
            maxCode = this.getOne(lambda).getCode();
        }

        //todo:隐藏了BUG,请修正。 修改好  去掉todo

        while (i != 0) {
            LambdaQueryWrapper<ReceiptHeaderHistory> aa = Wrappers.lambdaQuery();
            if (maxCode != null && maxCode.substring(maxCode.length() - 13, maxCode.length() - 5).equals(df.format(now))) {
                Integer Count = Integer.valueOf(maxCode.substring(maxCode.length() - 5, maxCode.length()));
                code = receiptType + df.format(now) + String.format("%05d", Count + i++);
            } else {
                code = receiptType + df.format(now) + String.format("%05d", 0000+i++);
            }
            aa.select(ReceiptHeaderHistory::getCode).eq(ReceiptHeaderHistory::getCode, code);
            List<ReceiptHeaderHistory> list = receiptheaderhistoryMapper.selectList(aa);
            if (list.size() <= 0) {
                i=0;
            }
        }
        return code;
    }

    /**
     * 入库预约
     *
     * @param receiptHeader
     * @return
     */
    public AjaxResult reservation(ReceiptHeader receiptHeader) {
        LambdaQueryWrapper<ReceiptDetail> receiptDetailLambda = Wrappers.lambdaQuery();
        receiptDetailLambda.eq(ReceiptDetail::getReceiptId, receiptHeader.getId());
        List<ReceiptDetail> receiptDetails = receiptDetailService.list(receiptDetailLambda);
        //更新入库明细流程
        for (ReceiptDetail receiptDetail : receiptDetails) {
            receiptDetail.setProcessStamp(QuantityConstant.RECEIPT_HEADER_RESERVATION.toString());
            if (!receiptDetailService.updateById(receiptDetail)) {
                throw new ServiceException("更新入库明细处理标记失败");
            }
            receiptDetail = receiptDetailService.queryflow(receiptDetail);
            if (!receiptDetailService.updateById(receiptDetail)) {
                throw new ServiceException("更新入库明细流程失败");
            }
        }
        receiptHeader.setLastUpdatedBy(ShiroUtils.getLoginName());
        //更新入库单预约时间
        if (!this.updateById(receiptHeader)) {
            throw new ServiceException("更新入库单预约时间失败");
        }
        receiptDetailService.updateReceiptHeaderLastStatus(receiptHeader.getId());
        return AjaxResult.success("预约成功");
    }

    /**
     * 入库到货
     *
     * @param id
     * @return
     */
    public AjaxResult arrival(Integer id) {
        LambdaQueryWrapper<ReceiptDetail> receiptDetailLambda = Wrappers.lambdaQuery();
        receiptDetailLambda.eq(ReceiptDetail::getReceiptId, id)
                .eq(ReceiptDetail::getProcessStamp, QuantityConstant.RECEIPT_HEADER_ARRIVAL.toString());
        List<ReceiptDetail> receiptDetails = receiptDetailService.list(receiptDetailLambda);
        //更新入库明细流程
        for (ReceiptDetail receiptDetail : receiptDetails) {
            receiptDetailService.queryflow(receiptDetail);
        }
        //更新入库单头表
        receiptDetailService.updateReceiptHeaderLastStatus(id);
        return AjaxResult.success("已通知到货");
    }

    /**
     * 入库质检
     */
    public AjaxResult check(Integer id) {

        ReceiptHeader receiptHeader = this.getById(id);
        LambdaQueryWrapper<ReceiptDetail> receiptDetailLambda = Wrappers.lambdaQuery();
        receiptDetailLambda.eq(ReceiptDetail::getReceiptId, id);
        List<ReceiptDetail> receiptDetails = receiptDetailService.list(receiptDetailLambda);

        //判断是否已经生成了质检单
        LambdaQueryWrapper<CheckHeader> checkHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
        checkHeaderLambdaQueryWrapper.eq(CheckHeader::getCode, receiptHeader.getCode());
        CheckHeader checkHeaderQuery = checkHeaderService.getOne(checkHeaderLambdaQueryWrapper);
        if (checkHeaderQuery != null) {
            throw new ServiceException("质检单已生成");
        }
        //创建质检头表
        CheckHeader checkHeader = new CheckHeader();
        checkHeader.setCode(receiptHeader.getCode());
        checkHeader.setType(QuantityConstant.CHECK_TYPE_RECEIPT.toString());
        checkHeader.setWarehouseCode(ShiroUtils.getWarehouseCode());
        checkHeader.setReferCode(receiptHeader.getReferCode());
        checkHeader.setEnable(1);
        checkHeader.setStatus(QuantityConstant.CHECK_STATUS_BUILD.toString());
        checkHeader.setCreatedBy(ShiroUtils.getLoginName());
        checkHeader.setLastUpdatedBy(ShiroUtils.getLoginName());

        if (!checkHeaderService.save(checkHeader)) {
            throw new ServiceException("添加质检头表错误");
        }

        //查询保存后的质检头表
        LambdaQueryWrapper<CheckHeader> checkHeaderLambda = Wrappers.lambdaQuery(checkHeader);
        checkHeader = checkHeaderService.getOne(checkHeaderLambda);

        for (ReceiptDetail receiptDetail : receiptDetails) {
            CheckDetail checkDetail = new CheckDetail();
            checkDetail.setCheckHeaderId(checkHeader.getId());
            checkDetail.setWarehouseCode(ShiroUtils.getWarehouseCode());
            checkDetail.setCheckCode(checkHeader.getCode());
            checkDetail.setReceiptDetailId(receiptDetail.getId());
            checkDetail.setReceiptCode(receiptDetail.getReceiptCode());
            checkDetail.setReferCode(checkHeader.getReferCode());
            checkDetail.setMaterialCode(receiptDetail.getMaterialCode());
            checkDetail.setMaterialName(receiptDetail.getMaterialName());
            checkDetail.setMaterialSpec(receiptDetail.getMaterialSpec());
            checkDetail.setMaterialUnit(receiptDetail.getMaterialUnit());
            checkDetail.setCompanyCode(receiptDetail.getCompanyCode());
            checkDetail.setInventorySts(receiptDetail.getInventorySts());
            checkDetail.setStatus(QuantityConstant.CHECK_STATUS_BUILD.toString());
            checkDetail.setQty(receiptDetail.getQty());
            checkDetail.setCheckBy(ShiroUtils.getLoginName());
            checkDetail.setCreatedBy(ShiroUtils.getLoginName());
            checkDetail.setLastUpdatedBy(ShiroUtils.getLoginName());
            if (!checkDetailService.save(checkDetail)) {
                throw new ServiceException("保存质检明细失败");
            }
        }
        return AjaxResult.success("创建质检单成功");
    }

    /**
     * 提交审核入库单
     */
    @Transactional
    public AjaxResult submitReview(String ids) {
        String warehouseCode = ShiroUtils.getWarehouseCode();
        if (StringUtils.isEmpty(ids)) {
            return AjaxResult.error("仓库:" + warehouseCode + ",提交入库单审核,id不能为空");
        }
        Integer[] idArray = Convert.toIntArray(ids);
        for (int i = 0; i < idArray.length; i++) {
            ReceiptHeader receiptHeader = this.getById(idArray[i]);
            if (receiptHeader.getFirstStatus() > QuantityConstant.RECEIPT_HEADER_VERIFYING
                    || receiptHeader.getLastStatus() > QuantityConstant.RECEIPT_HEADER_VERIFYING) {
                return AjaxResult.error("仓库:" + warehouseCode + ",单据号:" + receiptHeader.getCode() + "入库单不需要审核");
            }
            LambdaQueryWrapper<ReceiptDetail> lambdaQueryWrapper = Wrappers.lambdaQuery();
            lambdaQueryWrapper.eq(ReceiptDetail::getReceiptId, idArray[i]);
            List<ReceiptDetail> receiptDetailList = receiptDetailService.list(lambdaQueryWrapper);
            if (receiptDetailList.isEmpty()) {
                return AjaxResult.error("仓库:" + warehouseCode + ",单据号:" + receiptHeader.getCode() + "入库单没有明细");
            }
            receiptHeader.setFirstStatus(QuantityConstant.RECEIPT_HEADER_VERIFYING);
            receiptHeader.setLastStatus(QuantityConstant.RECEIPT_HEADER_VERIFYING);
            if (!this.updateById(receiptHeader)) {
                throw new ServiceException("仓库:" + warehouseCode + ",单据号:" + receiptHeader.getCode() + " 失败");
            }
        }
        return AjaxResult.success("仓库:" + warehouseCode + ",提交审核成功");
    }

    /**
     * 到货通知
     *
     * @param id
     * @return
     */
    public AjaxResult arrivalNotice(String id) {
        LambdaQueryWrapper<ReceiptDetail> lambda = Wrappers.lambdaQuery();
        lambda.eq(ReceiptDetail::getReceiptId, id);
        List<ReceiptDetail> receiptDetails = receiptDetailService.list(lambda);
        for (ReceiptDetail receiptDetail : receiptDetails) {
            receiptDetail.setProcessStamp(QuantityConstant.RECEIPT_HEADER_ARRIVAL.toString());
            receiptDetailService.updateById(receiptDetail);
            if (!receiptDetailService.updateById(receiptDetailService.queryflow(receiptDetail))) {
                throw new ServiceException("更新入库明细处理标记出错");
            }
            receiptDetailService.updateReceiptHeaderLastStatus(receiptDetail.getReceiptId());
        }
        return AjaxResult.success("已通知到货");
    }

    /**
     * 加入订单池
     *
     * @param ids 头表id字符串
     * @return
     */
    @Transactional
    public AjaxResult addPool(String ids) {
        List<Integer> idList = Arrays.asList(Convert.toIntArray(ids));
        List<StatusFlowDetail> statusFlowDetailList = receiptDetailService.queryflow();
        List<StatusFlowDetail> verifyList = statusFlowDetailList.stream().filter(item -> {
            return "审核".equals(item.getRecordType());
        }).collect(Collectors.toList());
        Integer nessaryFlag = 0;
        for (Integer id : idList) {
            LambdaQueryWrapper<ReceiptDetail> lambdaQueryWrapper = Wrappers.lambdaQuery();
            lambdaQueryWrapper.eq(ReceiptDetail::getReceiptId, id);
            List<ReceiptDetail> list = receiptDetailService.list(lambdaQueryWrapper);
            if (list.size() != 0) {
                if (nessaryFlag.equals(verifyList.get(0).getNessary())) {
                    for (ReceiptDetail receiptDetail : list) {
                        if (Integer.parseInt(receiptDetail.getProcessStamp()) < QuantityConstant.RECEIPT_HEADER_POOL) {
                            //加入订单池
                            receiptDetail.setProcessStamp(QuantityConstant.RECEIPT_HEADER_POOL.toString());
                            ReceiptDetail receiptDetail1 = receiptDetailService.queryflow(receiptDetail);
                            if (!receiptDetailService.updateById(receiptDetail1)) {
                                throw new ServiceException("更新入库明细状态失败");
                            }
                        } else {
                            throw new ServiceException("已有入库明细进入订单池");
                        }
                    }
                } else {
                    for (ReceiptDetail receiptDetail : list) {
                        if (Integer.parseInt(receiptDetail.getProcessStamp()) < QuantityConstant.RECEIPT_HEADER_POOL) {
                            //判断入库明细是否需要审核
                            ReceiptDetail beforeReceiptDetail = receiptDetailService.queryflow(receiptDetail);
                            if (Integer.parseInt(beforeReceiptDetail.getProcessStamp()) == QuantityConstant.RECEIPT_HEADER_VERIFYING
//                                    || Integer.parseInt(beforeReceiptDetail.getProcessStamp()) == QuantityConstant.RECEIPT_HEADER_APPROVE
                            ) {
                                throw new ServiceException("请先通过审核");
                            }
                            //加入订单池
                            receiptDetail.setProcessStamp(QuantityConstant.RECEIPT_HEADER_POOL.toString());
                            ReceiptDetail receiptDetail1 = receiptDetailService.queryflow(receiptDetail);
                            if (!receiptDetailService.updateById(receiptDetail1)) {
                                throw new ServiceException("更新入库明细状态失败");
                            }
                        } else {
                            throw new ServiceException("已有入库明细进入订单池");
                        }
                    }
                }

            }
            //更新头表状态
            receiptDetailService.updateReceiptHeaderLastStatus(id);
        }
        return AjaxResult.success("加入成功");
    }


    public List<ReceiptHeader> selectListByCreated() {
        return receiptHeaderMapper.selectListByCreated();
    }


    @Transactional(rollbackFor = Exception.class)
    public Integer createTodayHeader(String companyCode) {
        String receiptType = QuantityConstant.RECEIPT_TYPE_PPI;
        String code = null;
        Date now = new Date();
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
//        String maxCode = receiptHeaderMapper.createCode(receiptType);

        LambdaQueryWrapper<ReceiptHeader> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(ReceiptHeader::getReceiptType, receiptType);
        lambdaQueryWrapper.eq(ReceiptHeader::getWarehouseCode,ShiroUtils.getWarehouseCode());
        lambdaQueryWrapper.orderByDesc(ReceiptHeader::getId);
        lambdaQueryWrapper.last("limit 1");
        ReceiptHeader receiptHeader1=this.getOne(lambdaQueryWrapper);
        String maxCode =null;
        if(receiptHeader1!=null){
            maxCode=receiptHeader1.getCode();
        }
        //如果指定类型的最后的code存在,并且日期一致。那么 code = 入库单类型 + 年月日 + (排序号 + 1)
        if (maxCode != null && maxCode.substring(maxCode.length() - 13, maxCode.length() - 5).equals(df.format(now))) {
            Integer Count = Integer.valueOf(maxCode.substring(maxCode.length() - 5, maxCode.length()));
            code = receiptType + df.format(now) + String.format("%05d", Count + 1);
        } else {
            code = receiptType + df.format(now) + "00001";
        }
        ReceiptHeader receiptHeader = new ReceiptHeader();
        receiptHeader.setId(null);
        receiptHeader.setCode(code);
        receiptHeader.setReceiptType(receiptType);
        receiptHeader.setWarehouseCode(ShiroUtils.getWarehouseCode());
        receiptHeader.setCreated(null);
        receiptHeader.setCreatedBy(ShiroUtils.getLoginName());
        receiptHeader.setLastUpdated(null);
        receiptHeader.setLastUpdatedBy(ShiroUtils.getLoginName());
        receiptHeader.setFirstStatus(200);
        receiptHeader.setLastStatus(200);
        receiptHeader.setCompanyCode(companyCode);
        this.save(receiptHeader);
        return receiptHeader.getId();
    }

    @Transactional(rollbackFor = Exception.class)
    public List<ReceiptHeader> getLatestReceipt(String warehouseCode, String companyCode) {
        return receiptHeaderMapper.getLatestReceipt(warehouseCode, companyCode);
    }

    /**
     * 修改回传后状态
     *
     * @param id
     * @return
     */
    private AjaxResult editReceiveStatus(Integer id) {
        ReceiptHeader receiptHeader = new ReceiptHeader();
        receiptHeader.setId(id);
        receiptHeader.setFirstStatus(900);
        receiptHeader.setLastStatus(900);
        if (!updateById(receiptHeader)) {
            throw new ServiceException("更新头表状态失败");
        } else {
            LambdaQueryWrapper<ReceiptDetail> lambdaQueryWrapper = Wrappers.lambdaQuery();
            lambdaQueryWrapper.eq(ReceiptDetail::getReceiptId, id);
            List<ReceiptDetail> receiptDetails = receiptDetailService.list(lambdaQueryWrapper);
            for (ReceiptDetail receiptDetail : receiptDetails) {
                receiptDetail.setProcessStamp("900");
            }
            if (!receiptDetailService.updateBatchById(receiptDetails)) {
                throw new ServiceException("更新明细失败");
            }
        }
        return AjaxResult.success("");
    }

    public AjaxResult crossLocation(String ids) {
        String containerCode = "YKR01";
        String locationCode = "YRL01";
        for (Integer id : Convert.toIntArray(ids)) {
            ReceiptHeader receiptHeader = this.getById(id);
            /* 创建出库单*/
            ShipmentHeader shipmentHeader = new ShipmentHeader();
            shipmentHeader.setWarehouseCode(receiptHeader.getWarehouseCode());
            shipmentHeader.setCompanyCode(receiptHeader.getCompanyCode());
            shipmentHeader.setCode(receiptHeader.getCode());
            shipmentHeader.setFirstStatus(QuantityConstant.SHIPMENT_CONTAINER_BUILD);
            shipmentHeader.setLastStatus(QuantityConstant.SHIPMENT_CONTAINER_BUILD);
            shipmentHeader.setShipmentType("YK");
            shipmentHeader.setTotalQty(receiptHeader.getTotalQty());
            shipmentHeader.setTotalLines(receiptHeader.getTotalLines());
            try{
                shipmentHeaderService.save(shipmentHeader);
            }catch (Exception e){
                throw new ServiceException("创建出库单失败或已越库");
            }

            List<ReceiptDetail> receiptDetailList = receiptDetailService.findByReceiptId(id);
            /* 遍历入库单明细生成出库单与库存交易记录*/
            for (ReceiptDetail receiptDetail : receiptDetailList) {

                /* 创建出库明细*/
                ShipmentDetail shipmentDetail = new ShipmentDetail();
                shipmentDetail.setShipmentId(shipmentHeader.getId());
                shipmentDetail.setWarehouseCode(shipmentHeader.getWarehouseCode());
                shipmentDetail.setCompanyCode(shipmentHeader.getCompanyCode());
                shipmentDetail.setShipmentCode(shipmentHeader.getCode());
                shipmentDetail.setMaterialCode(receiptDetail.getMaterialCode());
                shipmentDetail.setMaterialName(receiptDetail.getMaterialName());
                shipmentDetail.setMaterialSpec(receiptDetail.getMaterialSpec());
                shipmentDetail.setMaterialUnit(receiptDetail.getMaterialUnit());
                shipmentDetail.setQty(receiptDetail.getQty());
                shipmentDetail.setTaskQty(BigDecimal.ZERO);
                shipmentDetail.setBatch(receiptDetail.getBatch());
                shipmentDetail.setLot(receiptDetail.getLot());
                shipmentDetail.setProjectNo(receiptDetail.getProjectNo());
                shipmentDetail.setManufactureDate(receiptDetail.getManufactureDate());
                shipmentDetail.setExpirationDate(receiptDetail.getExpirationDate());
                shipmentDetail.setAgingDate(receiptDetail.getAgingDate());
                shipmentDetail.setInventorySts(receiptDetail.getInventorySts());
                shipmentDetail.setStatus(QuantityConstant.TASK_STATUS_BUILD);
                if (!shipmentDetailService.save(shipmentDetail)) {
                    throw new ServiceException("创建出库单明细失败");
                }

                InventoryTransaction inventoryTransaction = new InventoryTransaction();
                inventoryTransaction.setWarehouseCode(receiptHeader.getWarehouseCode());
                inventoryTransaction.setCompanyCode(receiptHeader.getCompanyCode());
                inventoryTransaction.setLocationCode(locationCode);
                inventoryTransaction.setContainerCode(containerCode);
                inventoryTransaction.setTransactionType(QuantityConstant.INVENTORY_TRANSACTION_RECEIPT);
                inventoryTransaction.setMaterialCode(receiptDetail.getMaterialCode());
                inventoryTransaction.setMaterialName(receiptDetail.getMaterialName());
                inventoryTransaction.setMaterialSpec(receiptDetail.getMaterialSpec());
                inventoryTransaction.setMaterialUnit(receiptDetail.getMaterialUnit());
                inventoryTransaction.setTaskQty(receiptDetail.getQty());
                inventoryTransaction.setInventorySts(receiptDetail.getInventorySts());
                inventoryTransaction.setReferCode(receiptDetail.getReferCode());
                inventoryTransaction.setReferDetailId(receiptDetail.getReferLineNum());
                inventoryTransaction.setBatch(receiptDetail.getBatch());
                inventoryTransaction.setLot(receiptDetail.getLot());
                inventoryTransaction.setProjectNo(receiptDetail.getProjectNo());
                inventoryTransaction.setQcCheck(receiptDetail.getQcCheck());
                inventoryTransaction.setManufactureDate(receiptDetail.getManufactureDate());
                inventoryTransaction.setExpirationDate(receiptDetail.getExpirationDate());
                inventoryTransaction.setAgingDate(receiptDetail.getAgingDate());
                inventoryTransaction.setAttribute1(receiptDetail.getAttribute1());
                inventoryTransaction.setAttribute2(receiptDetail.getAttribute2());
                inventoryTransaction.setAttribute3(receiptDetail.getAttribute3());
                inventoryTransaction.setBillCode(receiptHeader.getCode());
                inventoryTransaction.setBillDetailId(receiptDetail.getId());
                inventoryTransaction.setSupplierCode(receiptDetail.getSupplierCode());
                /*if (!inventoryTransactionService.save(inventoryTransaction)) {
                    throw new ServiceException("保存库存交易记录失败");
                }*/
                inventoryTransaction.setTransactionType(QuantityConstant.INVENTORY_TRANSACTION_SHIPMENT);
                inventoryTransaction.setBillCode(shipmentHeader.getCode());
                inventoryTransaction.setBillDetailId(shipmentDetail.getId());
                if (!inventoryTransactionService.save(inventoryTransaction)) {
                    throw new ServiceException("保存库存交易记录失败");
                }
            }

            receiptHeader.setFirstStatus(QuantityConstant.RECEIPT_HEADER_POSTING);
            receiptHeader.setLastStatus(QuantityConstant.RECEIPT_HEADER_POSTING);
            if (!this.updateById(receiptHeader)) {
                throw new ServiceException("更新入库单状态失败");
            }
            shipmentHeader.setFirstStatus(QuantityConstant.SHIPMENT_HEADER_COMPLETED);
            shipmentHeader.setLastStatus(QuantityConstant.SHIPMENT_HEADER_COMPLETED);
            if (!shipmentHeaderService.updateById(shipmentHeader)) {
                throw new ServiceException("更新入库单状态失败");
            }

        }

        return AjaxResult.success();
    }

    public List<ReceiptHeader> getByDomain(ReceiptHeader receiptHeader){
        LambdaQueryWrapper<ReceiptHeader> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(StringUtils.isNotEmpty(receiptHeader.getUserDef3()),ReceiptHeader::getUserDef3, receiptHeader.getUserDef3());
        lambdaQueryWrapper.eq(StringUtils.isNotEmpty(receiptHeader.getReferCode()),ReceiptHeader::getReferCode, receiptHeader.getReferCode());
        lambdaQueryWrapper.eq(StringUtils.isNotEmpty(receiptHeader.getCompanyCode()),ReceiptHeader::getCompanyCode, receiptHeader.getCompanyCode());
        return this.list(lambdaQueryWrapper);
    }

    /**
     * 回传U8
     * 单据类型 :PCI CI SRI SI
     * @param taskHeader
     * @param id
     * @param detailsQtyMap
     * @return
     */
    public AjaxResult postBack(TaskHeader taskHeader,String id, Map<Integer,BigDecimal> detailsQtyMap){
        AjaxResult ajaxResult = AjaxResult.error();
        ReceiptHeader receiptHeader = this.getById(id);
        String warehouseCode = receiptHeader.getWarehouseCode();
        if(receiptHeader==null){
            return AjaxResult.error("回传:入库单"+id+" 不存在。");
        }
        String type = receiptHeader.getReceiptType();
        ICSReceiptModel model = null;
        String JsonParam = null;
        String url = null;
        switch (type){
            case "PCI" :
                model = postBackByPCI(receiptHeader,type,detailsQtyMap);
                break;
            case "CI" :
                model = postBackByCI(receiptHeader,type,detailsQtyMap);
                break;
            case "SRI" :
                model = postBackBySRI(receiptHeader,type,detailsQtyMap);
                break;
            case "PI" :
                model = postBackByPI(receiptHeader,type,detailsQtyMap);
                break;
            case "SI" :
                model = postBackBySI(receiptHeader,type,taskHeader,detailsQtyMap);
                break;
            default:
                return AjaxResult.error("该类型无需回传");
        }
        switch (type){
            case "PCI" :
            case "CI" :
            case "SRI" :
            case "PI" :
            case "SI" :
                url = addressService.selectAddress(QuantityConstant.U8_RECEIPT_BACK, warehouseCode);
                JsonParam = JSON.toJSONString(model);
                break;
        }

        String result = HttpUtils.bodypost(url, JsonParam,warehouseCode);
        ajaxResult = JSON.parseObject(result, AjaxResult.class);
        return ajaxResult;
    }

    /**
     * 回传MES
     * 单据类型 : SI
     * @param taskHeader
     * @param id
     * @param detailsQtyMap
     * @return
     */
    public AjaxResult postBack2Mes(TaskHeader taskHeader,String id, Map<Integer,BigDecimal> detailsQtyMap){
        AjaxResult ajaxResult = AjaxResult.error();
        ReceiptHeader receiptHeader = this.getById(id);
        String warehouseCode = receiptHeader.getWarehouseCode();
        if(receiptHeader==null){
            return AjaxResult.error("回传:入库单"+id+" 不存在。");
        }
        String type = receiptHeader.getReceiptType();
        ICSReceiptModel model = null;
        String JsonParam = null;
        String url = null;
        switch (type){
            case "SI" :
                model = postBackBySI2Mes(receiptHeader,type,taskHeader);
                break;
        }
        switch (type){
            case "PCI" :
            case "CI" :
            case "SRI" :
            case "PI" :
            case "SI" :
                url = addressService.selectAddress(QuantityConstant.MES_RECEIPT_BACK, warehouseCode);
                JsonParam = JSON.toJSONString(model);
                break;
        }
        String msg = "接口地址错误或服务器连接不到或返回为空";
        ApiLog log = null;
        HttpHeaders headers = new HttpHeaders();
        try {
            log = ApiLogAspect.initApiLog("post", url,
                    JsonParam, headers, warehouseCode);
            String result = HttpUtils.bodypost(url, JsonParam,warehouseCode);
            if(StringUtils.isEmpty(result)){
                return AjaxResult.error("接口地址错误或服务器连接不到或返回为空");
            }
            ajaxResult = JSON.parseObject(result, AjaxResult.class);
            msg = JSON.toJSONString(ajaxResult);
        }catch (Exception e) {
            e.printStackTrace();
            ApiLogAspect.setApiLogException(log, e);
        } finally {
            ApiLogAspect.finishApiLog(log, headers, msg);
        }
        return ajaxResult;
    }

    public AjaxResult postBack2SRM(ReceiptHeader receiptHeader,List<Map> list,Map<Integer,BigDecimal> detailsQtyMap){
        String warehouseCode = receiptHeader.getWarehouseCode();
        if(QuantityConstant.PLATFORM_SRM.equals(receiptHeader.getSourcePlatform())){
            List<ICSRuternASN> icsRuternASNs = new ArrayList<>();
            for (Map map : list) {
                String returnCode=map.get("Code").toString();
                String irowno=map.get("irowno").toString();
                String autoId=map.get("AutoID").toString();

                ReceiptDetail receiptDetail = receiptDetailService.getOne(new LambdaQueryWrapper<ReceiptDetail>()
                        .eq(ReceiptDetail::getAutoId, autoId)
                        .eq(ReceiptDetail::getWarehouseCode,warehouseCode));
                if(receiptDetail !=null){
                    receiptDetail.setReferLineNum(irowno);
                    receiptDetailService.updateById(receiptDetail);
                }
                TaskDetail taskDetail = taskDetailService.getOne(new LambdaQueryWrapper<TaskDetail>()
                        .eq(TaskDetail::getBillDetailId, receiptDetail.getId())
                        .eq(TaskDetail::getWarehouseCode,warehouseCode)
                        .last("LIMIT 1"));
                ICSRuternASN icsRuternASN = new ICSRuternASN();
                String toLocation = taskDetail.getToLocation();
                Location location = locationService.getLocationByCode(toLocation, warehouseCode);
                if(location!=null) {
                    icsRuternASN.setSerial(location.getId().toString());
                }
                icsRuternASN.setReturnDoc(returnCode);
                icsRuternASN.setReturnDocLine(Integer.valueOf(irowno));
                icsRuternASN.setLotNo(receiptDetail.getUserDef2());
                icsRuternASN.setBinCode(toLocation);
                icsRuternASN.setLotQty(taskDetail.getQty().doubleValue());
                icsRuternASN.setUser(taskDetail.getLastUpdatedBy());
                icsRuternASN.setMUSERName(taskDetail.getCreatedBy());
                icsRuternASN.setMTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,DateUtils.getNowDate()));
                icsRuternASNs.add(icsRuternASN);
            }
            if(!icsRuternASNs.isEmpty()){
                AjaxResult ajaxResult = icsasnService.returnICSRuternASN(icsRuternASNs, warehouseCode);
                return ajaxResult;
            }
        }
        return AjaxResult.success();
    }

    private ICSReceiptModel postBackBySI2Mes(ReceiptHeader receiptHeader,String type,TaskHeader taskHeader){
        ICSReceiptModel model = new ICSReceiptModel();
        if(!type.equals(QuantityConstant.U8_RECEIPT_TYPE_CI)){
            return model;
        }
        MesPostBack mesPostBack = new MesPostBack();
        mesPostBack.setLotno(receiptHeader.getReferCode());
        mesPostBack.setMuser(taskHeader.getCreatedBy());
        String warehouseCode = taskHeader.getWarehouseCode();
        String companyCode = taskHeader.getCompanyCode();
        CompanyU8 companyU8 = companyWuService.getCompanyU8ByCode(companyCode, warehouseCode);
        mesPostBack.setType(companyU8.getUCompanyCode().substring(7,10));

        return model;
    }
    private ICSReceiptModel postBackBySI(ReceiptHeader receiptHeader,String type,TaskHeader taskHeader,Map<Integer,BigDecimal> detailsQtyMap){
        ICSReceiptModel model = new ICSReceiptModel();
        if(!type.equals(QuantityConstant.U8_RECEIPT_TYPE_CI)){
            return model;
        }
        List<ReceiptDetail> details = receiptDetailService.findByReceiptId(receiptHeader.getId());
        ICSReceiptHeader headerByCI = icsReceiptHeaderService.getHeaderBySI(receiptHeader,taskHeader);
        List<ICSReceiptDetail> detailsByCI = icsReceiptDetailService.getDetailsBySI(details,headerByCI,detailsQtyMap);
        model.setIcsReceiptHeader(headerByCI);
        model.setIcsReceiptDetails(detailsByCI);
        return model;
    }
    private ICSReceiptModel postBackByPCI(ReceiptHeader receiptHeader,String type,Map<Integer,BigDecimal> detailsQtyMap){
        ICSReceiptModel model = new ICSReceiptModel();
        if(!type.equals(QuantityConstant.U8_RECEIPT_TYPE_PCI)){
            return model;
        }
        ICSReceiptHeader icsReceiptHeader = new ICSReceiptHeader();
        return model;
    }
    private ICSReceiptModel postBackByCI(ReceiptHeader receiptHeader,String type,Map<Integer,BigDecimal> detailsQtyMap){
        ICSReceiptModel model = new ICSReceiptModel();
        if(!type.equals(QuantityConstant.U8_RECEIPT_TYPE_CI)){
            return model;
        }
        List<ReceiptDetail> details = receiptDetailService.findByReceiptId(receiptHeader.getId());
        ICSReceiptHeader headerByCI = icsReceiptHeaderService.getHeaderByCI(receiptHeader);
        List<ICSReceiptDetail> detailsByCI = icsReceiptDetailService.getDetailsByCI(details,headerByCI,detailsQtyMap);
        model.setIcsReceiptHeader(headerByCI);
        model.setIcsReceiptDetails(detailsByCI);
        return model;
    }
    private ICSReceiptModel postBackByPI(ReceiptHeader receiptHeader,String type,Map<Integer,BigDecimal> detailsQtyMap){
        ICSReceiptModel model = new ICSReceiptModel();
        if(!type.equals(QuantityConstant.U8_RECEIPT_TYPE_PI)){
            return model;
        }
        List<ReceiptDetail> details = receiptDetailService.findByReceiptId(receiptHeader.getId());
        ICSReceiptHeader headerByPI = icsReceiptHeaderService.getHeaderByPI(receiptHeader);
        List<ICSReceiptDetail> detailsByPI = icsReceiptDetailService.getDetailsByPI(details,headerByPI,detailsQtyMap);
        model.setIcsReceiptHeader(headerByPI);
        model.setIcsReceiptDetails(detailsByPI);
        return model;
    }
    private ICSReceiptModel postBackBySRI(ReceiptHeader receiptHeader,String type,Map<Integer,BigDecimal> detailsQtyMap){
        ICSReceiptModel model = new ICSReceiptModel();
        if(!type.equals(QuantityConstant.U8_RECEIPT_TYPE_SRI)){
            return model;
        }
        List<ReceiptDetail> details = receiptDetailService.findByReceiptId(receiptHeader.getId());
        ICSReceiptHeader headerBySRI = icsReceiptHeaderService.getHeaderBySRI(receiptHeader);
        List<ICSReceiptDetail> detailsBySRI = icsReceiptDetailService.getDetailsBySRI(details,headerBySRI,detailsQtyMap);
        model.setIcsReceiptHeader(headerBySRI);
        model.setIcsReceiptDetails(detailsBySRI);
        return model;
    }

    public List<ReceiptHeader> selectListhuichuanLimit100(ReceiptHeader receiptHeader){
        LambdaQueryWrapper<ReceiptHeader> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(StringUtils.isNull(receiptHeader.getFirstStatus()),ReceiptHeader::getFirstStatus, receiptHeader.getFirstStatus());
        lambdaQueryWrapper.eq(StringUtils.isNull(receiptHeader.getLastStatus()),ReceiptHeader::getLastStatus, receiptHeader.getLastStatus());
        lambdaQueryWrapper.eq(ReceiptHeader::getDeleted, 0);
        lambdaQueryWrapper.lt(ReceiptHeader::getCreated, DateUtils.getNowPreDay(DateUtils.YYYY_MM_DD_HH_MM_SS));
        lambdaQueryWrapper.last("limit 7");
        return this.list(lambdaQueryWrapper);
    }

    public List<ReceiptHeader> getHistoryReceiptHeader(String num){
        LambdaQueryWrapper<ReceiptHeader> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(ReceiptHeader::getFirstStatus,num);
        lambdaQueryWrapper.eq(ReceiptHeader::getDeleted, 0);
        lambdaQueryWrapper.lt(ReceiptHeader::getCreated, DateUtils.getNowPreWeek(DateUtils.YYYY_MM_DD_HH_MM_SS));
        lambdaQueryWrapper.last("limit 1");
        return this.list(lambdaQueryWrapper);
    }

    public ReceiptHeader selectFirstEntity( ReceiptHeader receiptHeader){
        LambdaQueryWrapper<ReceiptHeader> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(StringUtils.isNotEmpty(receiptHeader.getCode()),ReceiptHeader::getCode, receiptHeader.getCode());
        lambdaQueryWrapper.eq(StringUtils.isNotEmpty(receiptHeader.getCompanyCode()),ReceiptHeader::getCompanyCode, receiptHeader.getCompanyCode());
        lambdaQueryWrapper.eq(StringUtils.isNotEmpty(receiptHeader.getWarehouseCode()),ReceiptHeader::getWarehouseCode, receiptHeader.getWarehouseCode());
        lambdaQueryWrapper.eq(StringUtils.isNotEmpty(receiptHeader.getReferCode()),ReceiptHeader::getReferCode, receiptHeader.getReferCode());
        lambdaQueryWrapper.last("limit 1");
        return this.getOne(lambdaQueryWrapper);
    }

    public List<ReceiptHeader> listByCodes(Collection<String> codes,String warehouseCode){
        if(codes == null || codes.isEmpty()){
            return Collections.emptyList();
        }
        List<ReceiptHeader> receiptHeaders = this.list(new LambdaQueryWrapper<ReceiptHeader>()
                .in(ReceiptHeader::getCode, codes)
                .eq(ReceiptHeader::getWarehouseCode, warehouseCode));

        return receiptHeaders;
    }

    public AjaxResult yueku(String ids) {
        Integer[] idArray = Convert.toIntArray(ids);
        for (Integer id : idArray) {
            ReceiptHeader receiptHeader=this.getById(id);
            if(receiptHeader==null){
                return AjaxResult.error("找不到主单据");
            }
            List<ReceiptDetail> receiptDetails=receiptDetailService.getByHeaderCode(receiptHeader.getCode());
            if(receiptDetails==null && receiptDetails.size()<1){
                return AjaxResult.error("找不到子单据");
            }
            for(ReceiptDetail item :receiptDetails){
                ReceiptContainerView record=new ReceiptContainerView();
                record.setReceiptCode(receiptHeader.getCode());
                record.setReceiptDetailId(item.getId());
                record.setQty(item.getQty().subtract(item.getTaskQty()));

                //根据单据货主和仓库找到虚拟容器和库位
                Container container=containerService.getOne(new LambdaQueryWrapper<Container>()
                        .eq(Container::getWarehouseCode,ShiroUtils.getWarehouseCode())
                        .eq(Container::getContainerType,"X")
                        .orderByAsc(Container::getCode)
                        .last("limit 1"));
                if(container == null){
                    return AjaxResult.error("系统没有此货主的虚拟容器");
                }
                record.setContainerCode(container.getCode());
                record.setLocationCode(container.getLocationCode());
                //入库组盘并生成任务
                receiptContainerHeaderService.saveContainer(record);

                LambdaQueryWrapper<ReceiptContainerHeader> lambdaQueryWrapper= Wrappers.lambdaQuery();
                lambdaQueryWrapper.eq(ReceiptContainerHeader::getContainerCode,record.getContainerCode());
                lambdaQueryWrapper.le(ReceiptContainerHeader::getStatus,10);
                List<ReceiptContainerHeader> receiptContainerHeaders=receiptContainerHeaderService.list(lambdaQueryWrapper);
                for(ReceiptContainerHeader receiptContainerHeader:receiptContainerHeaders) {
                    String i = receiptContainerHeader.getId().toString();
                    Integer[] idArrays = Convert.toIntArray(i);
                    List<Integer> islist= Arrays.asList(idArrays);
                    try {
                        AjaxResult ajaxResult1=receiptTaskService.createReceiptTask(islist);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            //完成任务
            List<TaskHeader> tasks=taskHeaderService.list(new LambdaQueryWrapper<TaskHeader>().likeRight(TaskHeader::getContainerCode,"X")
                    .eq(TaskHeader::getStatus,QuantityConstant.TASK_STATUS_BUILD)
                    .eq(TaskHeader::getWarehouseCode,ShiroUtils.getWarehouseCode()));
            if(tasks!=null && tasks.size()>0) {
                for (TaskHeader tas:tasks) {
                    taskHeaderService.completeTask(tas);
                }
            }
        }
        return AjaxResult.success("越库成功");
    }

    public List<ReceiptHeader> getExpiredBill() {
        List<ReceiptHeader> receiptHeaderList = receiptHeaderMapper.getExpiredBill();
        return receiptHeaderList;
    }
    //清理入库单
    @Transactional(rollbackFor = Exception.class)
    public int cleanDocuments() {
        //查找过期的入库单据
        List<ReceiptHeader> receiptHeaderList = this.getExpiredBill();
        if (receiptHeaderList.isEmpty()) {
            return 1;
        }
        for (ReceiptHeader receiptHeader : receiptHeaderList) {
            this.deleteHeaderAndDetail(receiptHeader.getId().toString());
        }
        return 1;
    }
    public AjaxResult deleteHeaderAndDetail(String ids){
        List<Integer> idList = Arrays.asList(Convert.toIntArray(ids));
        for (Integer id : idList) {
            ReceiptHeader receiptHeader = this.getById(id);
            if (receiptHeader == null) {
                return AjaxResult.error("没有找到单据" + String.valueOf(id));
            }
            if(receiptHeader.getFirstStatus() >= QuantityConstant.RECEIPT_HEADER_POSTING) {
                return AjaxResult.error("订单状态大于800过账不能删除");
            }
            LambdaQueryWrapper<ReceiptDetail> lambdaQueryWrapper = Wrappers.lambdaQuery();
            lambdaQueryWrapper.eq(ReceiptDetail::getReceiptId, id);
            List<ReceiptDetail> list = receiptDetailService.list(lambdaQueryWrapper);
            List<ReceiptDetailHistory> receiptDetailHistoryList = new ArrayList<>();
            if (!this.removeById(receiptHeader)) {
                throw new ServiceException("删除头表失败");
            }
            List<Integer> receiptDetailIds = new ArrayList<>();
            ReceiptHeaderHistory receiptHeaderHistory = new ReceiptHeaderHistory();
            BeanUtils.copyProperties(receiptHeader, receiptHeaderHistory);
            if (!receiptheaderhistoryService.save(receiptHeaderHistory)) {
                throw new ServiceException("新增历史头表失败");
            }
            for (ReceiptDetail receiptDetail: list) {
                receiptDetailIds.add(receiptDetail.getId());
                ReceiptDetailHistory receiptDetailHistory = new ReceiptDetailHistory();
                BeanUtils.copyProperties(receiptDetail, receiptDetailHistory);
                receiptDetailHistory.setReceiptId(receiptHeaderHistory.getId());
                receiptDetailHistoryList.add(receiptDetailHistory);
            }
            if(receiptDetailIds.size() > 0) {
                if (!receiptDetailService.removeByIds(receiptDetailIds)) {
                    throw new ServiceException("删除明细表失败");
                }
            }
            if(receiptDetailHistoryList.size() > 0) {
                if (!receiptDetailHistoryService.saveBatch(receiptDetailHistoryList)) {
                    throw new ServiceException("新增历史入库明细失败");
                }
            }
        }
        return AjaxResult.success("删除成功");
    }

    public List<ReceiptHeader> selectSIComplete() {
        return receiptHeaderMapper.selectSIComplete();
    }
}