BarCodeApiService.java 14.6 KB
package com.huaheng.api.general.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.huaheng.common.utils.Wrappers;
import com.huaheng.api.erp.service.TaskReturnService;
import com.huaheng.api.general.domain.BarCodeDomain;
import com.huaheng.api.wcs.service.taskInfo.TaskInfoService;
import com.huaheng.common.constant.QuantityConstant;
import com.huaheng.common.constant.Res;
import com.huaheng.common.exception.BusinessException;
import com.huaheng.common.exception.service.ServiceException;
import com.huaheng.common.utils.DateUtils;
import com.huaheng.common.utils.bean.BeanUtils;
import com.huaheng.common.utils.security.ShiroUtils;
import com.huaheng.common.utils.spring.SpringUtils;
import com.huaheng.framework.web.domain.AjaxResult;
import com.huaheng.pc.barcode.barcodeDetail.domain.BarCodeDetail;
import com.huaheng.pc.barcode.barcodeDetail.service.BarCodeDetailService;
import com.huaheng.pc.barcode.barcodeHeader.domain.BarCodeHeader;
import com.huaheng.pc.barcode.barcodeHeader.service.BarCodeHeaderService;
import com.huaheng.pc.config.material.domain.Material;
import com.huaheng.pc.config.material.service.MaterialService;
import com.huaheng.pc.config.station.domain.Station;
import com.huaheng.pc.receipt.receiptContainerHeader.service.ReceiptContainerHeaderService;
import com.huaheng.pc.receipt.receiptDetail.domain.ReceiptDetail;
import com.huaheng.pc.receipt.receiptHeader.domain.ReceiptHeader;
import com.huaheng.pc.receipt.receiptHeader.service.ReceiptHeaderService;
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 org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

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

@Component
@Transactional(rollbackFor = Exception.class)
public class BarCodeApiService {
    @Resource
    private BarCodeHeaderService barCodeHeaderService;
    @Resource
    private MaterialService materialService;
    @Resource
    private BarCodeDetailService barCodeDetailService;
    @Resource
    private ReceiptHeaderService receiptHeaderService;
    @Resource
    private ReceiptContainerHeaderService receiptContainerHeaderService;


    @Transactional(rollbackFor = Exception.class)
    public AjaxResult addBarCodeApi(BarCodeDomain barCodeDomain) {

        AjaxResult ajaxResult = checkBarCode(barCodeDomain);
        if (ajaxResult.getCode() != 200) {
            return AjaxResult.error(ajaxResult.getMsg());
        }
        boolean result;
        BarCodeHeader header = barCodeDomain.getBarCodeHeader();
        BarCodeHeader barCodeHeader = new BarCodeHeader();
        BarCodeDetail codeDetail = barCodeDomain.getBarCodeDetails().get(0);
        if (codeDetail != null) {
            Material material = materialService.getOne(new LambdaQueryWrapper<Material>().eq(Material::getCode, codeDetail.getMaterialCode()));
            barCodeHeader.setMaterialCode(material.getCode());
            barCodeHeader.setMaterialName(material.getName());
            barCodeHeader.setMaterialUnit(material.getUnit());
            barCodeHeader.setMaterialSpec(material.getSpec());
        }
        //第一个明细的重量,就是总重量
        barCodeHeader.setTotalWeight(codeDetail.getWeight());
        barCodeHeader.setReceiptNote(header.getReceiptNote());
        barCodeHeader.setLocked(QuantityConstant.BARCODEHEADER_LOCKED);//1 未入库
        barCodeHeader.setCode(barCodeHeaderService.createCode("BZXXRK"));
        barCodeHeader.setMaterialBatch(header.getMaterialBatch());//原料批号
        barCodeHeader.setReceiptType("BZXXRK");
        barCodeHeader.setCreatedBy(QuantityConstant.PLATFORM_MES);
        barCodeHeader.setBarCodeHeaderCode(header.getCode());
        barCodeHeader.setWarehouseCode(QuantityConstant.DEFAULT_WAREHOUSE);//仓库
        barCodeHeader.setCompanyCode(QuantityConstant.DEFAULT_COMPANYCODE);//货主
        if (header.getFbillno() == null || "".equals(header.getFbillno())) {
            //生产订单号为空就不回传ERP
            barCodeHeader.setFbillno("MES自建");
        } else {
            barCodeHeader.setFbillno(header.getFbillno());
        }
        if (header.getEchelon() == null) {
            barCodeHeader.setProType("2");//拆解
        } else {
            barCodeHeader.setProType("1");//装配
        }
        barCodeHeader.setEchelon(header.getEchelon());
        result = barCodeHeaderService.save(barCodeHeader);
        if (!result) {
            throw new ServiceException("头表创建失败");
        }
        List<BarCodeDetail> barCodeDetails = barCodeDomain.getBarCodeDetails();
        BigDecimal totalQty = BigDecimal.ZERO;
        List<BarCodeDetail> bardetaillist = new ArrayList<>();
        for (BarCodeDetail detail : barCodeDetails) {
            BarCodeDetail barCodeDetail = new BarCodeDetail();
            barCodeDetail.setWarehouseCode(QuantityConstant.DEFAULT_WAREHOUSE);
            barCodeDetail.setCompanyCode(QuantityConstant.DEFAULT_COMPANYCODE);
            barCodeDetail.setReceiptId(barCodeHeader.getId());
            barCodeDetail.setCode(detail.getCode());
            barCodeDetail.setDayShift("day");
            //再生批号
            AjaxResult ajaxResultCode = barCodeDetailService.createRegenerationCode(1);
            String regenerationCode = (String) ajaxResultCode.getData();
            barCodeDetail.setRegenerationCode(regenerationCode);
            barCodeDetail.setReceiptCode(barCodeHeader.getCode());
            barCodeDetail.setSn(detail.getSn());
            if (barCodeDetail.getCode().length() == 17 || barCodeDetail.getCode().length() == 19) {
                String code = barCodeDetail.getCode();
                String productType = code.substring(3, 4);
                if (exist(productType)) {
                    barCodeDetail = addAttr(barCodeDetail.getCode(), barCodeDetail, header);
                }
            }
            String materialCode = detail.getMaterialCode();
            Material material = materialService.getOne(new LambdaQueryWrapper<Material>().eq(Material::getCode, materialCode));
            barCodeDetail.setMaterialCode(material.getCode());
            barCodeDetail.setMaterialName(material.getName());
            barCodeDetail.setMaterialSpec(material.getSpec());
            barCodeDetail.setMaterialUnit(material.getUnit());
            barCodeDetail.setTotalQty(detail.getQty());

            //平均重量(totalLines表示共有几个明细)
            BigDecimal AverageWeight = detail.getWeight().divide(new BigDecimal(barCodeDetails.size()), 3, BigDecimal.ROUND_HALF_UP);
            //-1回传重量,将平均后的重量,赋值到qty中
            if (barCodeHeader.getReceiptNote() == -1) {
                barCodeDetail.setTotalQty(AverageWeight);
            }
            barCodeDetail.setWeight(AverageWeight);
            //如果拆解明细只有一个,把receiptNote字段的值赋值到qty中 (Echelon为空就是拆解)
            if (header.getEchelon() == null && barCodeDetails.size() == 1 && barCodeHeader.getReceiptNote() > 0) {
                barCodeDetail.setTotalQty(new BigDecimal(barCodeHeader.getReceiptNote()));
            }
            //汇总明细的qty
            totalQty = totalQty.add(barCodeDetail.getTotalQty());
            bardetaillist.add(barCodeDetail);
        }
        barCodeHeader.setTotalQty(totalQty);
        barCodeHeader.setTotalLines(barCodeDetails.size());
        if (!barCodeDetailService.saveBatch(bardetaillist)) {
            throw new ServiceException("包装子信息创建失败");
        }
        if (!barCodeHeaderService.updateById(barCodeHeader)) {
            throw new ServiceException("更新入库头信息失败。");
        }
        //保存原料入库信息
        saveReceiptHeader(barCodeHeader, bardetaillist);
        return AjaxResult.toAjax(true);
    }

    public ReceiptDetail createReceiptDetail(ReceiptHeader receiptHeader) {
        ReceiptDetail receiptDetail = new ReceiptDetail();
        receiptDetail.setReceiptId(receiptHeader.getId());
        receiptDetail.setReceiptCode(receiptHeader.getCode());
        receiptDetail.setWarehouseCode(receiptHeader.getWarehouseCode());
        receiptDetail.setCompanyCode(receiptHeader.getCompanyCode());
        receiptDetail.setCreated(receiptHeader.getCreated());
        receiptDetail.setLastUpdatedBy(receiptHeader.getLastUpdatedBy());
        receiptDetail.setLastUpdated(receiptHeader.getLastUpdated());
        return receiptDetail;
    }

    /**
     * 1.先查找主条码有没有未完成的单据
     * 2.有则不新增ReceiptHeader,直接添加明细
     *
     * @param barCodeHeader
     * @param bardetaillist
     * @return
     */
    public ReceiptHeader saveReceiptHeader(BarCodeHeader barCodeHeader, List<BarCodeDetail> bardetaillist) {
        LambdaQueryWrapper<ReceiptHeader> receiptHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
        receiptHeaderLambdaQueryWrapper.eq(ReceiptHeader::getBarCodeHeaderCode, barCodeHeader.getBarCodeHeaderCode());
        receiptHeaderLambdaQueryWrapper.lt(ReceiptHeader::getFirstStatus, QuantityConstant.RECEIPT_HEADER_POSTING);
        receiptHeaderLambdaQueryWrapper.orderByDesc(ReceiptHeader::getId);
        List<ReceiptHeader> receiptHeaderList = receiptHeaderService.list(receiptHeaderLambdaQueryWrapper);
        ReceiptHeader receiptHeader = null;
        int totalQty = 0;
        int totalLines = 0;
        if (receiptHeaderList != null && receiptHeaderList.size() > 0) {
            receiptHeader = receiptHeaderList.get(0);
            totalQty = receiptHeader.getTotalQty().intValue();
            totalLines = receiptHeader.getTotalLines();
        } else {
            receiptHeader = new ReceiptHeader();
            BeanUtils.copyBeanProp(receiptHeader, barCodeHeader);
            receiptHeader.setReceiptType("CPRK");
            receiptHeader.setId(null);
            String receiptCode = receiptHeaderService.createCode(receiptHeader.getReceiptType());
            receiptHeader.setCode(receiptCode);
            receiptHeader.setBarCodeHeaderId(barCodeHeader.getId());
            receiptHeader.setBarCodeHeaderCode(barCodeHeader.getBarCodeHeaderCode());
            receiptHeader.setFirstStatus(QuantityConstant.RECEIPT_HEADER_BUILD);
            receiptHeader.setLastStatus(QuantityConstant.RECEIPT_HEADER_BUILD);

            receiptHeader.setCreatedBy(ShiroUtils.getLoginName());
            receiptHeader.setCreated(new Date());
            receiptHeader.setLastUpdatedBy(ShiroUtils.getLoginName());
            receiptHeader.setLastUpdated(new Date());

            receiptHeaderService.save(receiptHeader);
        }
        ReceiptDetail receiptDetail = createReceiptDetail(receiptHeader);
        //保存详情
        receiptContainerHeaderService.saveReceiptDetail(bardetaillist, receiptDetail, false);

        receiptHeader.setTotalQty(new BigDecimal(totalQty + barCodeHeader.getTotalQty().intValue()));
        receiptHeader.setTotalLines(totalLines + barCodeHeader.getTotalLines());
        receiptHeaderService.updateById(receiptHeader);
        return receiptHeader;
    }


    public AjaxResult checkBarCode(BarCodeDomain barCodeDomain) {
        BarCodeHeader barCodeHeader = barCodeDomain.getBarCodeHeader();
        String barCodeHeaderCode = barCodeHeader.getCode();
        if (barCodeHeaderCode == null || "".equals(barCodeHeaderCode)) {
            return AjaxResult.error("没有托盘号!");
        }

//        if(barCodeHeader.getFbillno() == null || "".equals(barCodeHeader.getFbillno())){
//            return AjaxResult.error("没有生产订单编号");
//        }

        BarCodeHeader one = barCodeHeaderService.getOne(new LambdaQueryWrapper<BarCodeHeader>()
                .eq(BarCodeHeader::getBarCodeHeaderCode, barCodeHeaderCode)
                .eq(BarCodeHeader::getFbillno, barCodeHeader.getFbillno()));
        if (one != null) {
            return AjaxResult.error("包装信息头错误:托盘号【" + barCodeHeaderCode + "】和生产订单号都重复了 " + barCodeHeader.getFbillno());
        }

        List<BarCodeDetail> barCodeDetailList = barCodeDomain.getBarCodeDetails();
        for (BarCodeDetail barCodeDetail : barCodeDetailList) {

            String materialCode = barCodeDetail.getMaterialCode();
            if (materialCode == null) {
                return AjaxResult.error("物料编码为空");
            }
            Material material = materialService.getOne(new LambdaQueryWrapper<Material>().eq(Material::getCode, barCodeDetail.getMaterialCode()));
            if (material == null) {
                return AjaxResult.error("没有该物料编码:" + materialCode);
            }
        }
        return AjaxResult.success();
    }

    private BarCodeDetail addAttr(String barCode, BarCodeDetail detail, BarCodeHeader header) {
        String type = "";
        if (barCode.length() == 17) {
            detail.setCode(barCode + "RC");
            type = "RC";
        } else if (barCode.length() == 19) {
            type = barCode.substring(17, 19);
        } else if ("1".equals(header.getEchelon())) {
            type = "RM";
        }
        String productType = barCode.substring(3, 4);
        String batteryType = barCode.substring(4, 5);
        String productDate = barCode.substring(7, 10);
        String year = productDate.substring(0, 1);
        String month = productDate.substring(1, 2);
        String day = productDate.substring(2, 3);

        String days = Res.string().dateKey(day);
        String months = Res.string().dateKey(month);
        String years = Res.string().yearKey(year);
        Date inTime = DateUtils.dateTime("yyyy-MM-dd", years + "-" + months + "-" + days);

        //默认都是 1 梯级利用 (0是再生利用 再生利用需要填type)
        detail.setStorageType("1");
//        detail.setType("1");
        detail.setConstitute(Res.string().batteryKey(type));
        detail.setProductType(Res.string().batteryKey(productType + "1"));
        detail.setBatteryModel(Res.string().batteryKey(batteryType));
        detail.setWarehouseInTime(inTime);
        return detail;
    }

    private Boolean exist(String proTypeStr) {
        if (StringUtils.isNotEmpty(proTypeStr)) {
            if (proTypeStr.contains("P")) {
                return true;
            }
            if (proTypeStr.contains("M")) {
                return true;
            }
            if (proTypeStr.contains("C")) {
                return true;
            }
        }
        return false;
    }
}