杨凯
2023-10-18 31fbee8d73fbdc8e2331208d69f674f9b29246ca
consum-base/src/main/java/com/consum/base/core/WarehouseCoreService.java
@@ -1,9 +1,17 @@
package com.consum.base.core;
import com.consum.base.core.tools.SqlParameter;
import com.consum.base.core.util.DateUtil;
import com.consum.model.po.*;
import com.walker.infrastructure.utils.NumberGenerator;
import com.walker.jdbc.service.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import java.util.ArrayList;
import java.util.List;
/**
@@ -11,25 +19,43 @@
 */
@Service
@Slf4j
public class WarehouseCoreService {
public class WarehouseCoreService extends BaseServiceImpl {
    public static void main(String[] args) {
        WhGoods goods = new WhGoods();
        goods.setId(1l);
        goods.setWarehouseId(111l);
        goods.setSupplier("河南金明源");
        WhGoods_mapper mapper = new WhGoods_mapper(goods);
        System.out.println(mapper.getInsertSql_().getParameters());
        System.out.println(mapper.getInsertSql_().getSql());
    }
    /**
     * 统一出入库
     */
    public CheckWarehouseResult unifyCheck(CheckWarehouseParam param) {
    public List<CheckWarehouseResult> unifyCheck(CheckWarehouseParam param) {
        // TODO: 10/10/2023 此处加了唯一锁,会影响性能,思考是否有更合适的办法
        try {
            Assert.notNull(param, "wareHouse param can not null !");
            Assert.notNull(param.getWarehouseId(), "wareHouse id can not null");
            CheckWarehouseResult result;
            synchronized (param.getWarehouseId()) {
            List<CheckWarehouseResult> results;
            String key = param.getWarehouseId().toString() + param.getModelId().toString();
            /**
             * 此处将同一个仓库下的同一个型号上锁,不同仓库、不同型号不受影响。
             */
            synchronized (key) {
                if (param.getIsCheckIn()) {
                    result = checkin(param);
                    results = new ArrayList<>();
                    results.add(checkin(param));
                } else {
                    result = checkout(param);
                    results = checkout(param);
                }
            }
            return result;
            return results;
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new RuntimeException(e.getMessage());
@@ -40,14 +66,173 @@
    /**
     * 出库
     */
    private CheckWarehouseResult checkout(CheckWarehouseParam param) {
        return new CheckWarehouseResult();
    private List<CheckWarehouseResult> checkout(CheckWarehouseParam param) {
        //查询出指定仓库、指定型号,状态为正常的的库存物品,按照采购时间倒叙、价格倒叙排列
       String sql = "SELECT\n" +
                "   * \n" +
                "FROM\n" +
                "   WH_GOODS \n" +
                "WHERE\n" +
                "   WAREHOUSE_ID =:WAREHOUSE_ID \n" +
                "   AND BASE_GOODS_MODELS_ID =:BASE_GOODS_MODELS_ID \n" +
                "   AND STATES =1 \n" +
                "   AND WH_COUNT > 0 \n" +
                "  order by PROCURE_DATE asc PRICE DESC";
        SqlParameter parameter = new SqlParameter();
        parameter.add("WAREHOUSE_ID",param.getWarehouseId())
                .add("BASE_GOODS_MODELS_ID",param.getModelId());
        List<WhGoods> goodsList = select(sql,parameter,new WhGoods());
        List<CheckWarehouseResult> resultList = new ArrayList<>();
        int shengyu = param.getCount();
        for (WhGoods goods : goodsList){
            if (shengyu <= 0 ) break;
            //如果库存数量大于出库数量,直接减库存
            if (shengyu <= goods.getWhCount()){
                shengyu = 0;
                CheckWarehouseResult result = new CheckWarehouseResult();
                result.setWhGoods(goods);
                result.setInitial_count(goods.getWhCount());
                goods.setWhCount(goods.getWhCount() - param.getCount());
                result.setEnd_count(goods.getWhCount());
                resultList.add(result);
                //如果减库存后,库存数为0,则变更状态为已删除
                if (goods.getWhCount() == 0){
                    goods.setStates(0);
                }
                update(goods);
                //如果是调拨出库 2:调拨,3:报废
                if (param.getOutput_type() == 2 || param.getOutput_type() == 3){
                    WhGoods nGoods = new WhGoods();
                    BeanUtils.copyProperties(goods,nGoods);
                    //变更状态为调拨
                    nGoods.setStates(param.getOutput_type());
                    nGoods.setWhCount(param.getCount());
                    nGoods.setId(NumberGenerator.getLongSequenceNumber());
                    insert(nGoods);
                    CheckWarehouseResult nresult = new CheckWarehouseResult();
                    nresult.setWhGoods(nGoods);
                    nresult.setInitial_count(0);
                    nresult.setEnd_count(nresult.getEnd_count());
                    resultList.add(nresult);
                }
                return resultList;
            }
            //如果库存数量小于出库数量,则需要几个库存物品一起出库。
            CheckWarehouseResult result = new CheckWarehouseResult();
            result.setInitial_count(goods.getWhCount());
            result.setEnd_count(0);
            result.setWhGoods(goods);
            resultList.add(result);
            shengyu = param.getCount() - goods.getWhCount();
            if (shengyu < 0){
                throw new RuntimeException("出库时,计算错误");
            }
            goods.setWhCount(0);
            goods.setStates(0);
            update(goods);
        }
        throw new RuntimeException("出库时,计算错误");
    }
    private BaseWarehouse getWarehouse(long id){
        BaseWarehouse w =  get(new BaseWarehouse(),"ID=?",new Object[]{id});
        return w;
    }
    /**
     * 入库
     */
    private CheckWarehouseResult checkin(CheckWarehouseParam param) {
    private CheckWarehouseResult checkin(CheckWarehouseParam param) throws RuntimeException {
        //如果是采购入库
        if (param.getFirst_input_type() ==1){
            WhFormProcureModel procureModel = get(new WhFormProcureModel(),"ID=?",new Object[]{param.getFirstInputCode()});
            WhFormProcure procure = get(new WhFormProcure(),"ID=?",new Object[]{procureModel.getWhFormProcureId()});
            WhGoods goods = new WhGoods();
            goods.setId(NumberGenerator.getLongSequenceNumber());
            goods.setBaseGoodsTemplateId(procureModel.getBaseGoodsTemplateId());
            goods.setGoodsTemplateName(procureModel.getGoodsTemplateName());
            goods.setBaseGoodsModelsId(procureModel.getBaseGoodsModelsId());
            goods.setBaseGoodsModelsName(procureModel.getBaseGoodsModelsName());
            goods.setWhCount(procureModel.getCounts());
            goods.setFirstInputCode(param.getFirstInputCode());
            goods.setFirstInputType(param.getFirst_input_type());
            goods.setFirstInputHisId(NumberGenerator.getLongSequenceNumber());
            goods.setWarehouseId(procure.getWarehouseId());
            goods.setWarehouseName(procure.getWarehouseName());
            goods.setSupplier(procureModel.getSupplier());
            goods.setUnit(procureModel.getUnit());
            goods.setPrice(procureModel.getPrice());
            goods.setProcureDate(procure.getIncomeTime());
            goods.setBackDate(procure.getIncomeTime());
            goods.setStates(1);
            insert(goods);
            CheckWarehouseResult result = new CheckWarehouseResult();
            result.setWhGoods(goods);
            result.setInitial_count(0);
            result.setEnd_count(goods.getWhCount());
            return result;
        //零星入库
        } else if (param.getFirst_input_type() ==2){
            return null;
        }
        String sql = "SELECT\n" +
                "   * \n" +
                "FROM\n" +
                "   WH_GOODS \n" +
                "WHERE\n" +
                "   WAREHOUSE_ID =:WAREHOUSE_ID \n" +
                "   AND FIRST_INPUT_CODE =:FIRST_INPUT_CODE \n" +
                "   AND BASE_GOODS_MODELS_ID =:BASE_GOODS_MODELS_ID" +
                "  order by PROCURE_DATE desc PRICE asc";
        SqlParameter parameter = new SqlParameter();
        parameter.add("WAREHOUSE_ID",param.getWarehouseId())
                .add("FIRST_INPUT_CODE",param.getFirstInputCode())
                .add("BASE_GOODS_MODELS_ID",param.getModelId());
        List<WhGoods> goodsList = select(sql,parameter,new WhGoods());
        if (goodsList == null || goodsList.size() == 0){
           new RuntimeException("查不到历史库存");
           return null;
        }
        for (WhGoods goods : goodsList){
            CheckWarehouseResult result = new CheckWarehouseResult();
            result.setWhGoods(goods);
            result.setInitial_count(goods.getWhCount());
            result.setEnd_count(goods.getWhCount() + param.getCount());
            WhGoods newGoods = new WhGoods();
            newGoods.setId(goods.getId());
            newGoods.setWhCount(result.getEnd_count());
            newGoods.setStates(1);
            newGoods.setBackDate(DateUtil.getCurrentDateFor14());
            this.update(newGoods);
            return result;
        }
        return new CheckWarehouseResult();
    }