ShipmentApiService.java 17.4 KB
package com.huaheng.api.general.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huaheng.api.general.domain.ErpBill;
import com.huaheng.api.general.domain.ErpBillDetails;
import com.huaheng.api.general.domain.ShipmentDomain;
import com.huaheng.common.constant.Constants;
import com.huaheng.common.constant.QuantityConstant;
import com.huaheng.common.exception.service.ServiceException;
import com.huaheng.common.utils.StringUtils;
import com.huaheng.common.utils.security.ShiroUtils;
import com.huaheng.framework.web.domain.AjaxResult;
import com.huaheng.pc.config.company.domain.Company;
import com.huaheng.pc.config.company.service.CompanyService;
import com.huaheng.pc.config.customer.domain.Customer;
import com.huaheng.pc.config.customer.service.CustomerServiceImpl;
import com.huaheng.pc.config.material.domain.Material;
import com.huaheng.pc.config.material.service.MaterialService;
import com.huaheng.pc.config.shipmentType.domain.ShipmentType;
import com.huaheng.pc.config.shipmentType.service.ShipmentTypeService;
import com.huaheng.pc.config.warehouse.domain.Warehouse;
import com.huaheng.pc.config.warehouse.service.WarehouseService;
import com.huaheng.pc.shipment.shipmentDetail.domain.ShipmentDetail;
import com.huaheng.pc.shipment.shipmentDetail.service.ShipmentDetailService;
import com.huaheng.pc.shipment.shipmentDetailHistory.domain.ShipmentDetailHistory;
import com.huaheng.pc.shipment.shipmentDetailHistory.service.ShipmentDetailHistoryService;
import com.huaheng.pc.shipment.shipmentHeader.domain.ErpShipmentResult;
import com.huaheng.pc.shipment.shipmentHeader.domain.ShipmentHeader;
import com.huaheng.pc.shipment.shipmentHeader.service.ShipmentHeaderService;
import com.huaheng.pc.shipment.shipmentHeaderHistory.domain.ShipmentHeaderHistory;
import com.huaheng.pc.shipment.shipmentHeaderHistory.service.ShipmentHeaderHistoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ricard
 * @time   19/11/11
 *
 */


@Component
@Transactional
public class ShipmentApiService {

    @Autowired
    private ShipmentHeaderService shipmentHeaderService;

    @Autowired
    private ShipmentDetailService shipmentDetailService;

    @Autowired
    private WarehouseService warehouseService;

    @Autowired
    private CompanyService companyService;

    @Autowired
    private CustomerServiceImpl customerService;

    @Autowired
    private ShipmentTypeService shipmentTypeService;

    @Autowired
    private MaterialService materialService;

    @Resource
    private ShipmentHeaderHistoryService shipmentHeaderHistoryService;

    @Resource
    private ShipmentDetailHistoryService shipmentDetailHistoryService;

    /**
     * 从erp拉出库单
     *
     * @param erpBill 出库单
     * @return 是否下发成功
     */
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult shipment(ErpBill erpBill) {
        ShipmentDomain domain = new ShipmentDomain();
        ShipmentHeader header = new ShipmentHeader();
        header.setCompanyCode(Constants.COMPANY_CODE);
        header.setWarehouseCode(Constants.WAREHOUSE_CODE);

        header.setReferCode(erpBill.getReferCode());
        header.setShipmentType(erpBill.getErpBillType());
        header.setBillType(erpBill.getBillType());
        header.setBillCode(erpBill.getBillCode());

        List<ShipmentDetail> details = new ArrayList<>();
        for(ErpBillDetails d: erpBill.getBillDetails()) {
            //todo 同步物料
            ShipmentDetail detail = new ShipmentDetail();
            detail.setCompanyCode(header.getCompanyCode());
            detail.setWarehouseCode(header.getWarehouseCode());
            detail.setBatch(d.getBatchNo());
            detail.setMaterialCode(d.getMaterialCode());
            detail.setMaterialName(d.getMaterialName());
            detail.setQty(d.getQty());
            detail.setReferLineNum(d.getLineNum());
            details.add(detail);

            Material mt = materialService.getMaterialByCode(d.getMaterialCode());
            if(mt == null){
                mt = new Material();
                mt.setCode(d.getMaterialCode());
                mt.setName(d.getMaterialName());
                mt.setWarehouseCode(header.getWarehouseCode());
                mt.setSpec(d.getMaterialSpec());
                mt.setUnit(d.getMaterialUnit());
                mt.setCompanyCode(header.getCompanyCode());
//                mt.setEnable(QuantityConstant.STATUS ENABLE):
                boolean success = materialService.save(mt);
                if(!success){
                    throw new ServiceException("拉取单据时,创建物料失败" + d.getMaterialCode());
                }
            }
        }

        domain.setShipmentHeader(header);
        domain.setShipmentDetails(details);
        return shipment(domain);
    }

    public ShipmentDomain getReceiptByRefer(String referCode){
        LambdaQueryWrapper<ShipmentHeader> queryHeader = Wrappers.lambdaQuery();
        queryHeader.eq(ShipmentHeader::getReferCode, referCode);
        ShipmentHeader shipmentHeader = shipmentHeaderService.getOne(queryHeader);

        if(shipmentHeader == null){
            return null;
        }
        LambdaQueryWrapper<ShipmentDetail> queryDetail = Wrappers.lambdaQuery();
        queryDetail.eq(ShipmentDetail::getReferCode, referCode);
        List<ShipmentDetail> list = shipmentDetailService.list(queryDetail);
        ShipmentDomain domain = new ShipmentDomain();
        domain.setShipmentHeader(shipmentHeader);
        domain.setShipmentDetails(list);
        return domain;
    }

    /**
     *  出库单下发
     *
     * @param shipmentDomain
     * @return
     */
    @Transactional
    public AjaxResult shipment(ShipmentDomain shipmentDomain){

        //1、判断出库主单和子单列是否为空
        ShipmentHeader shipmentHeader = shipmentDomain.getShipmentHeader();
        List<ShipmentDetail> shipmentDetails = shipmentDomain.getShipmentDetails();
        if(shipmentHeader == null){
            return AjaxResult.error("出库主单为空");
        }
        if(shipmentDetails.size() < 1 || shipmentDetails == null ){
            return AjaxResult.error("出库子单为空");
        }

        //2、检查出库主单的合法性
        AjaxResult ajaxResult = this.checkShipmentHeader(shipmentHeader);

        //3、检查出库子单的合法性
        shipmentDetails =this.checkShipmentDetail(shipmentDetails,shipmentHeader);

        //4、保存出库主表
        BigDecimal totalQty = new BigDecimal(0);
        for (ShipmentDetail item: shipmentDetails) {
            totalQty =  totalQty.add(item.getQty());
        }
        shipmentHeader.setCreatedBy(QuantityConstant.PLATFORM_ERP);
        shipmentHeader.setTotalLines(shipmentDetails.size());
        shipmentHeader.setTotalQty(totalQty);
        String shipmentCode = shipmentHeaderService.createCode(shipmentHeader.getShipmentType());
        shipmentHeader.setCode(shipmentCode);
        shipmentHeader.setFirstStatus(QuantityConstant.SHIPMENT_HEADER_BUILD);
        shipmentHeader.setLastStatus(QuantityConstant.SHIPMENT_HEADER_BUILD);

        if(!shipmentHeaderService.save(shipmentHeader)){
            throw new ServiceException("保存出库主表失败");
        }

        //5、保存出库子表
        for(ShipmentDetail shipmentDetail : shipmentDetails){
            shipmentDetail.setInventorySts(QuantityConstant.GOOD);
            shipmentDetail.setShipmentId(shipmentHeader.getId());
            shipmentDetail.setShipmentCode(shipmentHeader.getCode());
            shipmentDetail.setReferCode(shipmentHeader.getReferCode());
            shipmentDetail.setCreatedBy(shipmentHeader.getCreatedBy());
            shipmentDetail.setWaveId(0);
        }

        int num = 0;
        List<ShipmentDetail> shipmentDetailList = new ArrayList<>();
        if(shipmentDetails.size() >500 ){
            for(ShipmentDetail item : shipmentDetails){
                num++;
                shipmentDetailList.add(item);
                if(num % 500 ==0 || num == shipmentDetails.size()){
                    if(!shipmentDetailService.insertDetails(shipmentDetailList)){
                        throw new ServiceException("保存出库子表失败");
                    }
                    shipmentDetailList=new ArrayList<>();
                }
            }
        }else {
            if(!shipmentDetailService.insertDetails(shipmentDetails)){
                throw new ServiceException("保存出库子表失败");
            }
        }
        shipmentDomain.setShipmentHeader(shipmentHeader);
        shipmentDomain.setShipmentDetails(shipmentDetails);
        return AjaxResult.success("出库单创建成功").setData(shipmentDomain);
    }


    /**
     * 检查出库主单的合法性
     * @param shipmentHeader
     * @return
     */
    public  AjaxResult checkShipmentHeader(ShipmentHeader shipmentHeader){
        //1、判断仓库和货主
        if(StringUtils.isEmpty(shipmentHeader.getWarehouseCode())){
            return AjaxResult.error("仓库为空");
        }
        if(StringUtils.isEmpty(shipmentHeader.getCompanyCode())){
            return AjaxResult.error("货主为空");
        }


        LambdaQueryWrapper<Warehouse> warehouseLamb = Wrappers.lambdaQuery();
        warehouseLamb.eq(Warehouse::getCode,shipmentHeader.getWarehouseCode());
        Warehouse warehouse =warehouseService.getOne(warehouseLamb);
        if(warehouse == null){
            return AjaxResult.error("wms没有此仓库");
        }

        LambdaQueryWrapper<Company> companyLamb = Wrappers.lambdaQuery();
        companyLamb.eq(Company::getCode,shipmentHeader.getCompanyCode());
        Company company =companyService.getOne(companyLamb);
        if(company == null){
            return AjaxResult.error("wms没有此货主");
        }

        //2、判断出库类型
        LambdaQueryWrapper<ShipmentType> shipmentTypeLamb = Wrappers.lambdaQuery();
        shipmentTypeLamb.eq(ShipmentType::getCode,shipmentHeader.getShipmentType())
                    .eq(ShipmentType::getWarehouseCode,shipmentHeader.getWarehouseCode());
        ShipmentType shipmentType =shipmentTypeService.getOne(shipmentTypeLamb);
        if(shipmentType == null){
            return AjaxResult.error("wms没有此出库类型");
        }

        //3、检查上游单号是否存在
        LambdaQueryWrapper<ShipmentHeader> shipmentHeaderLamb = Wrappers.lambdaQuery();
        shipmentHeaderLamb.eq(ShipmentHeader::getWarehouseCode,shipmentHeader.getWarehouseCode())
                .eq(ShipmentHeader::getReferCode,shipmentHeader.getReferCode());
        List<ShipmentHeader> shipmentHeaders = shipmentHeaderService.list(shipmentHeaderLamb);
        if(shipmentHeaders.size() > 0 || shipmentHeaders != null){
            return AjaxResult.success("出库单已经下发");
        }

        //4、检查客户
        if(StringUtils.isNotEmpty(shipmentHeader.getCustomerCode())){
            LambdaQueryWrapper<Customer> customerLamb = Wrappers.lambdaQuery();
            customerLamb.eq(Customer::getWarehouseCode,shipmentHeader.getWarehouseCode())
                    .eq(Customer::getCode,shipmentHeader.getCustomerCode());
            Customer customer = customerService.getOne(customerLamb);
            if(customer == null){
                return AjaxResult.error("wms没有此客户");
            }
        }
        return AjaxResult.success(shipmentHeader);
    }


    /**
     * 检查出库子单的合法性
     * @param shipmentDetails
     * @return
     */
    public  List<ShipmentDetail> checkShipmentDetail(List<ShipmentDetail> shipmentDetails,ShipmentHeader shipmentHeader){

        for(ShipmentDetail shipmentDetail : shipmentDetails) {
            //1、检查物料
            if(StringUtils.isEmpty(shipmentDetail.getMaterialCode())){
               throw new ServiceException("物料为空");
            }
            LambdaQueryWrapper<Material> materialLamb = Wrappers.lambdaQuery();
            materialLamb.eq(Material::getCode,shipmentDetail.getMaterialCode())
                .eq(Material::getWarehouseCode,shipmentHeader.getWarehouseCode());
            Material material = materialService.getOne(materialLamb);
            if(material == null){
                throw new ServiceException("wms没有此物料" + shipmentDetail.getMaterialCode());
            }

            //2、赋值物料属性
            shipmentDetail.setMaterialName(material.getName());
            shipmentDetail.setMaterialSpec(material.getSpec());
            shipmentDetail.setMaterialUnit(material.getUnit());
        }
        return shipmentDetails;
    }

    @Transactional
    public AjaxResult remove(List<String> shipmentCodeList) {
        LambdaQueryWrapper<ShipmentHeader> headerQueryWrapper;
        for (String shipmentCode : shipmentCodeList) {
            headerQueryWrapper = Wrappers.lambdaQuery();
            headerQueryWrapper.eq(ShipmentHeader::getCode,shipmentCode);
            ShipmentHeader shipmentHeader = shipmentHeaderService.getOne(headerQueryWrapper);
            if (shipmentHeader == null) {
                return AjaxResult.success("");
            }
            if ((shipmentHeader.getFirstStatus() >= QuantityConstant.SHIPMENT_HEADER_RETURN && shipmentHeader.getLastStatus() >= QuantityConstant.SHIPMENT_HEADER_RETURN) ||
                    (shipmentHeader.getFirstStatus() < QuantityConstant.SHIPMENT_HEADER_POOL & shipmentHeader.getLastStatus() < QuantityConstant.SHIPMENT_HEADER_POOL)) {
                ShipmentHeaderHistory shipmentHeaderHistory = new ShipmentHeaderHistory();
                List<ShipmentDetailHistory> shipmentDetailHistoryList = new ArrayList<>();
                //查询入库单明细
                LambdaQueryWrapper<ShipmentDetail> lambdaQueryWrapper = Wrappers.lambdaQuery();
                lambdaQueryWrapper.eq(ShipmentDetail::getShipmentCode, shipmentCode);
                List<ShipmentDetail> list = shipmentDetailService.list(lambdaQueryWrapper);

                //复制到入库历史实体
                com.huaheng.common.utils.bean.BeanUtils.copyBeanProp(shipmentHeaderHistory, shipmentHeader);
                for (ShipmentDetail shipmentDetail : list) {
                    ShipmentDetailHistory shipmentDetailHistory = new ShipmentDetailHistory();
                    com.huaheng.common.utils.bean.BeanUtils.copyBeanProp(shipmentDetailHistory, shipmentDetail);
                    shipmentDetailHistoryList.add(shipmentDetailHistory);
                }


                shipmentHeaderHistory.setLastUpdatedBy(ShiroUtils.getLoginName());
                if (!shipmentHeaderService.removeById(shipmentHeader.getId())) {
                    throw new ServiceException("删除头表失败");
                }
                if (!shipmentHeaderHistoryService.save(shipmentHeaderHistory)) {
                    throw new ServiceException("新增历史出库单失败");
                }
                // 当存在明细时删除
                if (list.size() != 0) {
                    //删除入库明细
                    List<Integer> shipmentDetailIds = new ArrayList<>();
                    for (int i = 0; i < shipmentDetailHistoryList.size(); i++) {
                        shipmentDetailHistoryList.get(i).setLastUpdatedBy(ShiroUtils.getLoginName());
                        shipmentDetailHistoryList.get(i).setShipmentId(shipmentHeaderHistory.getId());
                        shipmentDetailIds.add(shipmentDetailHistoryList.get(i).getId());
                    }
                    if (!shipmentDetailService.removeByIds(shipmentDetailIds)) {
                        throw new ServiceException("删除明细表失败");
                    }
                    if (!shipmentDetailHistoryService.saveBatch(shipmentDetailHistoryList)) {
                        throw new ServiceException("新增明细失败");
                    }
                }
            } else {
                return AjaxResult.success("出库单没有完成,无法删除");
            }
        }
        return AjaxResult.success("删除成功");
    }

    public AjaxResult search(String shipmentCode,String companyCode,String warehouseCode){
        if (companyCode==null){
            return AjaxResult.error("货主编码不能为空");
        }
        if (warehouseCode==null){
            return AjaxResult.error("仓库编码不能为空");
        }
        ShipmentDomain shipmentDomain = new ShipmentDomain();
        LambdaQueryWrapper<ShipmentHeader> headerLambdaQuery = Wrappers.lambdaQuery();
        LambdaQueryWrapper<ShipmentDetail> detailLambdaQuery = Wrappers.lambdaQuery();
        headerLambdaQuery.eq(ShipmentHeader::getWarehouseCode,warehouseCode)
                .eq(ShipmentHeader::getCompanyCode,companyCode)
                .eq(ShipmentHeader::getCode,shipmentCode);
        detailLambdaQuery.eq(ShipmentDetail::getWarehouseCode,warehouseCode)
                .eq(ShipmentDetail::getCompanyCode,companyCode)
                .eq(ShipmentDetail::getShipmentCode,shipmentCode);
        ShipmentHeader shipmentHeader = shipmentHeaderService.getOne(headerLambdaQuery);
        List<ShipmentDetail> shipmentDetailList = shipmentDetailService.list(detailLambdaQuery);
        shipmentDomain.setShipmentHeader(shipmentHeader);
        shipmentDomain.setShipmentDetails(shipmentDetailList);
        return AjaxResult.success("查询成功",shipmentDomain);
    }
}