package com.fjhx.stock.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.constants.StatusConstant;
import com.fjhx.entity.stock.StockBackPlan;
import com.fjhx.entity.stock.StockBackPlanDetails;
import com.fjhx.stock.mapper.StockBackPlanMapper;
import com.fjhx.stock.service.StockBackPlanDetailsService;
import com.fjhx.stock.service.StockBackPlanService;
import com.fjhx.utils.BigDecimalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

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

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2022-09-02
 */
@Service
public class StockBackPlanServiceImpl extends ServiceImpl<StockBackPlanMapper, StockBackPlan> implements StockBackPlanService {

    private static final RestTemplate restTemplate = new RestTemplate();

    private static final Object obj = new Object();

    private static final List<String> materialNameList = Arrays.asList(
            "黑色 170克100%精梳棉",
            "灰色 170克100%精梳棉",
            "空白鼠标垫+密锁边",
            "法兰绒"
    );

    @Autowired
    private StockBackPlanDetailsService stockBackPlanDetailsService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void getScheduleTask(int offset) {

        synchronized (obj) {

            // 请求v3接口获取token
            String token = getToken();

            // 请求v3接口获取所有人领料信息
            Date date = new Date();

            String beginDate = DateUtil.format(DateUtil.offsetDay(date, -offset), "yyyy-MM-dd 00:00:00");
            String endDate = DateUtil.format(date, "yyyy-MM-dd 23:59:59");

            String url = "http://mes.cfmfactory.com:8087/MesWeb/planPersonOutAction.do?action=list&beginDate="
                    + beginDate + "&endDate=" + endDate + "&access_token=" + token;

            String resultStr = restTemplate.getForEntity(url, String.class).getBody();
            JSONObject resultMap = JSONObject.parseObject(resultStr);
            // 接收到的消息
            List<JSONObject> items = (List<JSONObject>) resultMap.get("items");

            remove(Wrappers.<StockBackPlan>lambdaQuery().between(StockBackPlan::getPlanTime, beginDate, endDate));

            Map<String, StockBackPlan> flagMap = new HashMap<>();

            Date newDate = new Date();

            // 循环领料信息
            items.forEach(item -> {
                // 喷印人员工号
                String distributor = item.get("distributor").toString();
                // 打纸人员工号
                String paperMan = item.get("paperMan").toString();
                // 排班面积
                BigDecimal plantotalsquare = new BigDecimal(item.get("plantotalsquare").toString());
                // 物料名称
                String material = item.get("material").toString();
                // 排班时间
                String planDate = item.get("planDate").toString();

                if (materialNameList.contains(material)) {
                    return;
                }

                // 喷印人员工号添加领料记录标记
                addOrEditFlagMap(flagMap, distributor, plantotalsquare, planDate, material, newDate);

                // 打纸人员工号添加领料记录标记
                addOrEditFlagMap(flagMap, paperMan, plantotalsquare, planDate, "热转印纸", newDate);

            });

//        List<Map<String, Object>> list = baseMapper.getList(Wrappers.<Scheduling>lambdaQuery()
//                .between(Scheduling::getPlanDate, beginDate, endDate));
//
//        for (Map<String, Object> map : list) {
//            Long jobNo = Long.valueOf(map.get("jobNo").toString());
//            BigDecimal quantity = BigDecimalUtil.keepDecimals(map.get("quantity"));
//            String planDate = DateUtil.format((Date) map.get("planDate"), "yyyy-MM-dd");
//            String materialName = map.get("materialName").toString().split("-")[0];
//
//            addOrEditFlagMap(flagMap, jobNo, quantity, planDate, materialName, newDate);
//        }

            // 更新当天的出库单
            saveBatch(new ArrayList<>(flagMap.values()));

        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void statisticsScheduleDateTask(int offset) {

        synchronized (obj) {

            // 统计近 offset 天排班
            Date endDate = new Date();
            Date beginDate = DateUtil.beginOfDay(DateUtil.offsetDay(endDate, -offset));

            List<StockBackPlan> list = list(Wrappers.<StockBackPlan>lambdaQuery()
                    .between(StockBackPlan::getPlanTime, beginDate, endDate));

            stockBackPlanDetailsService.remove(Wrappers.<StockBackPlanDetails>lambdaQuery()
                    .between(StockBackPlanDetails::getPlanTime, beginDate, endDate));

            // 工号，物料名称，排班时间封装成key，对象为value
            Map<String, StockBackPlanDetails> stockBackPlanMap = list.stream().collect(Collectors.toMap(
                    item -> item.getJobNo() + item.getPlanMaterial() + item.getPlanTime(),
                    item -> {
                        StockBackPlanDetails stockBackPlanDetails =
                                createStockBackPlanDetails(item.getJobNo(), item.getPlanMaterial(), item.getPlanTime());
                        stockBackPlanDetails.setQuantity(item.getQuantity());
                        return stockBackPlanDetails;
                    }
            ));

            // 查询出库
            issue(beginDate, stockBackPlanMap);

            // 转印部门出库
            issueA008(beginDate, stockBackPlanMap);

            // 回仓
            returnWarehouse(beginDate, stockBackPlanMap);

            // 转印部门回仓
            returnWarehouseA008(beginDate, stockBackPlanMap);

            // 物料修正
            correct(beginDate, stockBackPlanMap);

            // 转入
            transferIn(beginDate, stockBackPlanMap);

            // 转出
            transferOut(beginDate, stockBackPlanMap);

            stockBackPlanDetailsService.saveBatch(new ArrayList<>(stockBackPlanMap.values()));

        }

    }

    private StockBackPlanDetails createStockBackPlanDetails(String jobNo, String materialName, Date planDate) {
        StockBackPlanDetails stockBackPlanDetails = new StockBackPlanDetails();
        stockBackPlanDetails.setPlanMaterial(materialName);
        stockBackPlanDetails.setPlanTime(planDate);
        stockBackPlanDetails.setQuantity(BigDecimal.ZERO);
        stockBackPlanDetails.setJobNo(jobNo);
        stockBackPlanDetails.setCorrectArea(BigDecimal.ZERO);

        stockBackPlanDetails.setPickingMoney(BigDecimal.ZERO);
        stockBackPlanDetails.setPickingNum(0);
        stockBackPlanDetails.setPickingMeters(BigDecimal.ZERO);
        stockBackPlanDetails.setPickingArea(BigDecimal.ZERO);

        stockBackPlanDetails.setBackMoney(BigDecimal.ZERO);
        stockBackPlanDetails.setBackNum(0);
        stockBackPlanDetails.setBackMeters(BigDecimal.ZERO);
        stockBackPlanDetails.setBackArea(BigDecimal.ZERO);

        stockBackPlanDetails.setTransferOutMoney(BigDecimal.ZERO);
        stockBackPlanDetails.setTransferOutMeters(BigDecimal.ZERO);
        stockBackPlanDetails.setTransferOutArea(BigDecimal.ZERO);
        stockBackPlanDetails.setTransferOutNum(0);

        stockBackPlanDetails.setTransferInMoney(BigDecimal.ZERO);
        stockBackPlanDetails.setTransferInMeters(BigDecimal.ZERO);
        stockBackPlanDetails.setTransferInArea(BigDecimal.ZERO);
        stockBackPlanDetails.setTransferInNum(0);

        stockBackPlanDetails.setCreateTime(new Date());

        return stockBackPlanDetails;
    }

    /**
     * 获取token
     */
    private String getToken() {
        String url = "http://mes.cfmfactory.com:8087/portal/getAccessTokenAction.do?AppId=1&AppSecret=a2b1c2d3";
        String result = restTemplate.getForEntity(url, String.class).getBody();
        if (ObjectUtil.isEmpty(result)) {
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(result);
        return jsonObject.getString("token");
    }

    /**
     * 赋值排班数据
     */
    private void addOrEditFlagMap(Map<String, StockBackPlan> flagMap, String jobNo, BigDecimal plantotalsquare, String planDate, String material, Date date) {
        if (Objects.equals(jobNo, "0")) {
            return;
        }

        String key = jobNo + material + planDate;
        StockBackPlan stockBackPlan = flagMap.get(key);

        if (stockBackPlan == null) {
            stockBackPlan = new StockBackPlan();
            stockBackPlan.setJobNo(jobNo);
            stockBackPlan.setPlanMaterial(material.trim());
            stockBackPlan.setPlanTime(DateUtil.parse(planDate));
            stockBackPlan.setQuantity(plantotalsquare);
            stockBackPlan.setCreateTime(date);

            flagMap.put(key, stockBackPlan);
        } else {
            BigDecimal quantity = stockBackPlan.getQuantity();
            stockBackPlan.setQuantity(quantity.add(plantotalsquare));
        }
    }

    /**
     * 出库
     */
    private void issue(Date beginDate, Map<String, StockBackPlanDetails> stockBackPlanMap) {
        List<Map<String, Object>> pickingList = baseMapper.getWater(Wrappers.query()
                .ge("swd.CreatedTime", DateUtil.format(beginDate, "yyyy-MM-dd 7:00:00"))
                .in("swd.StockChangeType", 20, 23)
                .eq("uu.IsDelete", 0)
                .in("uu.DepartmentID", "A007", "A012", "A017")
//                .likeRight("m.Code", "01.")
//                .notIn("m.Code", "01.002.0045", "01.002.0124", "01.002.0381", "01.002.0383")
                .notIn("m.CategoryCode", "99.999.", "01.007.")
                .isNotNull("uu.JobNo"));

        for (Map<String, Object> map : pickingList) {

            // 出库时间
            Date createTime = (Date) map.get("createTime");
            // 时
            int h = Integer.parseInt(DateUtil.format(createTime, "H"));
            // 分
//            int m = Integer.parseInt(DateUtil.format(createTime, "m"));
            // 小于7点30算前一日
            if (h < 7) {
                createTime = DateUtil.offsetDay(createTime, -1);
            }

            // 排班时间
            Date planDate = DateUtil.beginOfDay(createTime);
            // 工号
            String jobNo = map.get("jobNo").toString();
            // 物料名称
            String materialName = map.get("materialName").toString().split("-")[0];
            // 数量
            BigDecimal changeNum = BigDecimalUtil.keepDecimals(map.get("changeNum"));
            // 单价
            BigDecimal price = BigDecimalUtil.keepDecimals(map.get("price"));
            // 门幅
            BigDecimal width = BigDecimalUtil.keepDecimals(map.get("width"));

            // 排班对象
            StockBackPlanDetails stockBackPlanDetails = stockBackPlanMap.get(jobNo + materialName + planDate);
            if (stockBackPlanDetails == null) {
                stockBackPlanDetails = createStockBackPlanDetails(jobNo, materialName, planDate);
                stockBackPlanMap.put(jobNo + materialName + planDate, stockBackPlanDetails);
            }

            // 金额
            stockBackPlanDetails.setPickingMoney(
                    BigDecimalUtil.init(stockBackPlanDetails.getPickingMoney()).add(price.multiply(changeNum)).getValue(2));

            // 数量
            stockBackPlanDetails.setPickingNum(stockBackPlanDetails.getPickingNum() + 1);

            // 米
            stockBackPlanDetails.setPickingMeters(stockBackPlanDetails.getPickingMeters().add(changeNum));

            // 面积
            stockBackPlanDetails.setPickingArea(stockBackPlanDetails.getPickingArea().add(
                    BigDecimalUtil.init(changeNum).multiply(width).divide(100, 2).getValue()));
        }
    }

    private void issueA008(Date beginDate, Map<String, StockBackPlanDetails> stockBackPlanMap) {

        List<Map<String, Object>> pickingList = baseMapper.getWater(Wrappers.query()
                .ge("swd.CreatedTime", DateUtil.format(beginDate, "yyyy-MM-dd 8:30:00"))
                .in("swd.StockChangeType", 20, 23)
                .eq("uu.IsDelete", 0)
                .eq("uu.DepartmentID", "A008")
//                .likeRight("m.Code", "01.")
//                .notIn("m.Code", "01.002.0045", "01.002.0124", "01.002.0381", "01.002.0383")
                .notIn("m.CategoryCode", "99.999.", "01.007.")
                .isNotNull("uu.JobNo"));

        for (Map<String, Object> map : pickingList) {

            // 出库时间
            Date createTime = (Date) map.get("createTime");
            // 时
            int h = Integer.parseInt(DateUtil.format(createTime, "H"));
            // 分
            int m = Integer.parseInt(DateUtil.format(createTime, "m"));
            // 小于7点30算前一日
            if (h < 8 || (h == 8 && m <= 30)) {
//            if (h < 8) {
                createTime = DateUtil.offsetDay(createTime, -1);
            }

            // 排班时间
            Date planDate = DateUtil.beginOfDay(createTime);
            // 工号
            String jobNo = map.get("jobNo").toString();
            // 物料名称
            String materialName = map.get("materialName").toString().split("-")[0];
            // 数量
            BigDecimal changeNum = BigDecimalUtil.keepDecimals(map.get("changeNum"));
            // 单价
            BigDecimal price = BigDecimalUtil.keepDecimals(map.get("price"));
            // 门幅
            BigDecimal width = BigDecimalUtil.keepDecimals(map.get("width"));

            // 排班对象
            StockBackPlanDetails stockBackPlanDetails = stockBackPlanMap.get(jobNo + materialName + planDate);
            if (stockBackPlanDetails == null) {
                stockBackPlanDetails = createStockBackPlanDetails(jobNo, materialName, planDate);
                stockBackPlanMap.put(jobNo + materialName + planDate, stockBackPlanDetails);
            }

            // 金额
            stockBackPlanDetails.setPickingMoney(
                    BigDecimalUtil.init(stockBackPlanDetails.getPickingMoney()).add(price.multiply(changeNum)).getValue(2));

            // 数量
            stockBackPlanDetails.setPickingNum(stockBackPlanDetails.getPickingNum() + 1);

            // 米
            stockBackPlanDetails.setPickingMeters(stockBackPlanDetails.getPickingMeters().add(changeNum));

            // 面积
            stockBackPlanDetails.setPickingArea(stockBackPlanDetails.getPickingArea().add(
                    BigDecimalUtil.init(changeNum).multiply(width).divide(100, 2).getValue()));
        }

    }


    /**
     * 回仓
     */
    private void returnWarehouse(Date beginDate, Map<String, StockBackPlanDetails> stockBackPlanMap) {
        List<Map<String, Object>> backList = baseMapper.getReturnWarehouse(Wrappers.query()
                        .ge("sb.operation_time", DateUtil.format(beginDate, "yyyy-MM-dd 10:00:00"))
                        .eq("uu.IsDelete", 0)
                        .in("uu.DepartmentID", "A007", "A012", "A017")
                        .isNotNull("uu.JobNo")
                        .notIn("m.CategoryCode", "99.999.", "01.007.")
//                .likeRight("m.Code", "01.")
//                .notIn("m.Code", "01.002.0045", "01.002.0124", "01.002.0381", "01.002.0383")

        );

        for (Map<String, Object> map : backList) {

            // 出库时间
            Date createTime = (Date) map.get("createTime");

            int h = Integer.parseInt(DateUtil.format(createTime, "H"));
            // int m = Integer.parseInt(DateUtil.format(createTime, "m"));
            // 小于10点算前一日
            if (h < 10) {
                createTime = DateUtil.offsetDay(createTime, -1);
            }
            // 排班时间
            Date planDate = DateUtil.beginOfDay(createTime);
            // 工号
            String jobNo = map.get("jobNo").toString();
            // 物料名称
            String materialName = map.get("materialName").toString().split("-")[0];
            // 数量
            BigDecimal changeNum = BigDecimalUtil.keepDecimals(map.get("changeNum"));
            // 单价
            BigDecimal price = BigDecimalUtil.keepDecimals(map.get("price"));
            // 门幅
            BigDecimal width = BigDecimalUtil.keepDecimals(map.get("width"));

            // 排班对象
            StockBackPlanDetails stockBackPlanDetails = stockBackPlanMap.get(jobNo + materialName + planDate);
            if (stockBackPlanDetails == null) {
                stockBackPlanDetails = createStockBackPlanDetails(jobNo, materialName, planDate);
                stockBackPlanMap.put(jobNo + materialName + planDate, stockBackPlanDetails);
            }

            // 金额
            stockBackPlanDetails.setBackMoney(
                    BigDecimalUtil.init(stockBackPlanDetails.getBackMoney()).add(price.multiply(changeNum)).getValue(2));

            // 数量
            stockBackPlanDetails.setBackNum(stockBackPlanDetails.getBackNum() + 1);

            // 米
            stockBackPlanDetails.setBackMeters(stockBackPlanDetails.getBackMeters().add(changeNum));

            // 面积
            stockBackPlanDetails.setBackArea(stockBackPlanDetails.getBackArea().add(
                    BigDecimalUtil.init(changeNum).multiply(width).divide(100, 2).getValue()));
        }
    }


    private void returnWarehouseA008(Date beginDate, Map<String, StockBackPlanDetails> stockBackPlanMap) {
        List<Map<String, Object>> backList = baseMapper.getReturnWarehouse(Wrappers.query()
                        .ge("sb.operation_time", DateUtil.format(beginDate, "yyyy-MM-dd 10:00:00"))
                        .eq("uu.IsDelete", 0)
                        .eq("uu.DepartmentID", "A008")
                        .isNotNull("uu.JobNo")
                        .notIn("m.CategoryCode", "99.999.", "01.007.")
//                .likeRight("m.Code", "01.")
//                .notIn("m.Code", "01.002.0045", "01.002.0124", "01.002.0381", "01.002.0383")
        );

        for (Map<String, Object> map : backList) {

            // 出库时间
            Date createTime = (Date) map.get("createTime");

            int h = Integer.parseInt(DateUtil.format(createTime, "H"));
            // int m = Integer.parseInt(DateUtil.format(createTime, "m"));
            // 小于10点算前一日
            if (h < 10) {
                createTime = DateUtil.offsetDay(createTime, -1);
            }
            // 排班时间
            Date planDate = DateUtil.beginOfDay(createTime);
            // 工号
            String jobNo = map.get("jobNo").toString();
            // 物料名称
            String materialName = map.get("materialName").toString().split("-")[0];
            // 数量
            BigDecimal changeNum = BigDecimalUtil.keepDecimals(map.get("changeNum"));
            // 单价
            BigDecimal price = BigDecimalUtil.keepDecimals(map.get("price"));
            // 门幅
            BigDecimal width = BigDecimalUtil.keepDecimals(map.get("width"));

            // 排班对象
            StockBackPlanDetails stockBackPlanDetails = stockBackPlanMap.get(jobNo + materialName + planDate);
            if (stockBackPlanDetails == null) {
                stockBackPlanDetails = createStockBackPlanDetails(jobNo, materialName, planDate);
                stockBackPlanMap.put(jobNo + materialName + planDate, stockBackPlanDetails);
            }

            // 金额
            stockBackPlanDetails.setBackMoney(
                    BigDecimalUtil.init(stockBackPlanDetails.getBackMoney()).add(price.multiply(changeNum)).getValue(2));

            // 数量
            stockBackPlanDetails.setBackNum(stockBackPlanDetails.getBackNum() + 1);

            // 米
            stockBackPlanDetails.setBackMeters(stockBackPlanDetails.getBackMeters().add(changeNum));

            // 面积
            stockBackPlanDetails.setBackArea(stockBackPlanDetails.getBackArea().add(
                    BigDecimalUtil.init(changeNum).multiply(width).divide(100, 2).getValue()));
        }

    }


    /**
     * 修正
     */
    private void correct(Date beginDate, Map<String, StockBackPlanDetails> stockBackPlanMap) {
        List<Map<String, Object>> correctList = baseMapper.getCorrect(Wrappers.query()
                        .gt("sbc.correct_time", DateUtil.format(beginDate, "yyyy-MM-dd 00:00:00"))
                        .isNotNull("uu.JobNo")
//                .notIn("m.Code", "01.002.0045", "01.002.0124", "01.002.0381", "01.002.0383")
                        .notIn("m.CategoryCode", "99.999.", "01.007.")
        );
        for (Map<String, Object> map : correctList) {
            // 出库时间
            Date createTime = (Date) map.get("createTime");
            // 排班时间
            Date planDate = DateUtil.beginOfDay(createTime);
            // 工号
            String jobNo = map.get("jobNo").toString();
            // 物料名称
            String materialName = map.get("materialName").toString().split("-")[0];
            // 数量
            BigDecimal correctArea = BigDecimalUtil.keepDecimals(map.get("correctArea"));

            // 排班对象
            StockBackPlanDetails stockBackPlanDetails = stockBackPlanMap.get(jobNo + materialName + planDate);
            if (stockBackPlanDetails == null) {
                stockBackPlanDetails = createStockBackPlanDetails(jobNo, materialName, planDate);
                stockBackPlanMap.put(jobNo + materialName + planDate, stockBackPlanDetails);
            }
            // 金额
            stockBackPlanDetails.setCorrectArea(stockBackPlanDetails.getCorrectArea().add(correctArea));
        }
    }

    /**
     * 转入
     */
    private void transferIn(Date beginDate, Map<String, StockBackPlanDetails> stockBackPlanMap) {
        List<Map<String, Object>> transferPickingList = baseMapper.getTransferPickingList(Wrappers.query()
                        .ge("st.submit_time", DateUtil.format(beginDate, "yyyy-MM-dd 00:00:00"))
                        .eq("st.status", StatusConstant.YES)
                        .eq("st.del_flag", 0)
//                .notIn("m.Code", "01.002.0045", "01.002.0124", "01.002.0381", "01.002.0383")
                        .notIn("m.CategoryCode", "99.999.", "01.007.")
        );

        for (Map<String, Object> map : transferPickingList) {

            // 出库时间
            Date createTime = (Date) map.get("createTime");
            // 时
//            int h = Integer.parseInt(DateUtil.format(createTime, "H"));
            // 分
//            int m = Integer.parseInt(DateUtil.format(createTime, "m"));
            // 小于7点30算前一日
//            if (h < 10) {
//                createTime = DateUtil.offsetDay(createTime, -1);
//            }

            // 排班时间
            Date planDate = DateUtil.beginOfDay(createTime);
            // 工号
            String jobNo = map.get("jobNo").toString();
            // 物料名称
            String materialName = map.get("materialName").toString().split("-")[0];
            // 数量
            BigDecimal changeNum = BigDecimalUtil.keepDecimals(map.get("changeNum"));
            // 单价
            BigDecimal price = BigDecimalUtil.keepDecimals(map.get("price"));
            // 门幅
            BigDecimal width = BigDecimalUtil.keepDecimals(map.get("width"));

            // 排班对象
            StockBackPlanDetails stockBackPlanDetails = stockBackPlanMap.get(jobNo + materialName + planDate);
            if (stockBackPlanDetails == null) {
                stockBackPlanDetails = createStockBackPlanDetails(jobNo, materialName, planDate);
                stockBackPlanMap.put(jobNo + materialName + planDate, stockBackPlanDetails);
            }

            // 金额
            stockBackPlanDetails.setTransferInMoney(
                    BigDecimalUtil.init(stockBackPlanDetails.getTransferInMoney()).add(price.multiply(changeNum)).getValue(2));

            // 数量
            stockBackPlanDetails.setTransferInNum(stockBackPlanDetails.getTransferInNum() + 1);

            // 米
            stockBackPlanDetails.setTransferInMeters(stockBackPlanDetails.getTransferInMeters().add(changeNum));

            // 面积
            stockBackPlanDetails.setTransferInArea(stockBackPlanDetails.getTransferInArea().add(
                    BigDecimalUtil.init(changeNum).multiply(width).divide(100, 2).getValue()));
        }

    }

    /**
     * 转出
     */
    private void transferOut(Date beginDate, Map<String, StockBackPlanDetails> stockBackPlanMap) {

        List<Map<String, Object>> transferBackList = baseMapper.getTransferBackList(Wrappers.query()
                        .ge("st.submit_time", DateUtil.format(beginDate, "yyyy-MM-dd 10:00:00"))
                        .eq("st.status", StatusConstant.YES)
                        .eq("st.del_flag", 0)
//                .notIn("m.Code", "01.002.0045", "01.002.0124", "01.002.0381", "01.002.0383")
                        .notIn("m.CategoryCode", "99.999.", "01.007.")
        );

        for (Map<String, Object> map : transferBackList) {

            // 出库时间
            Date createTime = (Date) map.get("createTime");

            int h = Integer.parseInt(DateUtil.format(createTime, "H"));
//            int m = Integer.parseInt(DateUtil.format(createTime, "m"));
            // 小于7点30点算前一日
            if (h < 10) {
                createTime = DateUtil.offsetDay(createTime, -1);
            }
            // 排班时间
            Date planDate = DateUtil.beginOfDay(createTime);
            // 工号
            String jobNo = map.get("jobNo").toString();
            // 物料名称
            String materialName = map.get("materialName").toString().split("-")[0];
            // 数量
            BigDecimal changeNum = BigDecimalUtil.keepDecimals(map.get("changeNum"));
            // 单价
            BigDecimal price = BigDecimalUtil.keepDecimals(map.get("price"));
            // 门幅
            BigDecimal width = BigDecimalUtil.keepDecimals(map.get("width"));

            // 排班对象
            StockBackPlanDetails stockBackPlanDetails = stockBackPlanMap.get(jobNo + materialName + planDate);
            if (stockBackPlanDetails == null) {
                stockBackPlanDetails = createStockBackPlanDetails(jobNo, materialName, planDate);
                stockBackPlanMap.put(jobNo + materialName + planDate, stockBackPlanDetails);
            }

            // 金额
            stockBackPlanDetails.setTransferOutMoney(
                    BigDecimalUtil.init(stockBackPlanDetails.getTransferOutMoney()).add(price.multiply(changeNum)).getValue(2));

            // 数量
            stockBackPlanDetails.setTransferOutNum(stockBackPlanDetails.getTransferOutNum() + 1);

            // 米
            stockBackPlanDetails.setTransferOutMeters(stockBackPlanDetails.getTransferOutMeters().add(changeNum));

            // 面积
            stockBackPlanDetails.setTransferOutArea(stockBackPlanDetails.getTransferOutArea().add(
                    BigDecimalUtil.init(changeNum).multiply(width).divide(100, 2).getValue()));
        }
    }

}
