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.security.core.parameters.P; import org.springframework.stereotype.Service; import org.springframework.util.Assert; import java.util.ArrayList; import java.util.List; /** * 核心出入库接口 */ @Service @Slf4j 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 List unifyUsingCheck(CheckUsingParam param) { // TODO: 10/10/2023 此处加了唯一锁,会影响性能,思考是否有更合适的办法 try { List results; String key = param.getLending_id(); /** * 此处将同一个仓库下的同一个型号上锁,不同仓库、不同型号不受影响。 */ synchronized (key) { if (param.getIsCheckIn()) { results = checkUsingIn(param); } else { results = checkUsingOut(param); } } return results; } catch (Exception e) { log.error(e.getMessage()); throw new RuntimeException(e.getMessage()); } } /** * 统一出入库 */ public List 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"); List results; String key = param.getWarehouseId().toString() + param.getModelId().toString(); /** * 此处将同一个仓库下的同一个型号上锁,不同仓库、不同型号不受影响。 */ synchronized (key) { if (param.getIsCheckIn()) { results = new ArrayList<>(); results.add(checkin(param)); } else { results = checkout(param); } } return results; } catch (Exception e) { log.error(e.getMessage()); throw new RuntimeException(e.getMessage()); } } /** * 在用物品出库 * @param param * @return */ private List checkUsingOut(CheckUsingParam param){ String sql = "SELECT\n" + " * \n" + "FROM\n" + " DEP_FORM_LENDING_MODEL a \n" + "WHERE\n" + " a.BASE_GOODS_MODELS_ID =:MODEL_ID \n" + " AND DEP_FORM_LENDING_ID =:LENDING_ID \n" + " AND USING_COUNT > 0\n" + "ORDER BY\n" + " PROCURE_DATE ASC PRICE DESC"; List modelsList = this.select(sql,new SqlParameter("MODEL_ID", param.getModel_id()) .put("LENDING_ID",param.getLending_id()),new DepFormLendingModel()); List resultList = new ArrayList<>(); int shengyu = param.getOutputCount(); for (DepFormLendingModel model : modelsList) { CheckUsingResult result = new CheckUsingResult(); DepFormLendingGoods goods = get(new DepFormLendingGoods(),"id=?",new Object[]{model.getDepFormLendingGoodsId()}); //如果当前持有人持有物品数量大于出库数量,则直接减掉数量即可。 if (model.getUsingCount() > shengyu){ result.setInitial_count(model.getUsingCount()); result.setLendingModel(model); model.setUsingCount(model.getCounts() - param.getOutputCount()); result.setEnd_count(model.getUsingCount()); update(model); resultList.add(result); goods.setUsingCount(goods.getUsingCount() - param.getOutputCount()); update(goods); return resultList; } shengyu = shengyu - model.getUsingCount(); goods.setUsingCount(goods.getUsingCount() - model.getUsingCount()); result.setInitial_count(model.getUsingCount()); result.setLendingModel(model); model.setUsingCount(0); result.setEnd_count(0); update(model); resultList.add(result); update(goods); } return resultList; } /** * 在用物品入 * @param param * @return */ private List checkUsingIn(CheckUsingParam param){ DepFormLending lending = get(new DepFormLending(),"id=?",new Object[]{param.getLending_id()}); String sql = "SELECT\n" + " * \n" + "FROM\n" + " DEP_FORM_LENDING_GOODS A \n" + "WHERE\n" + " A.DEP_FORM_LENDING_ID = :LENDING_ID"; List goodsList = this.select(sql,new SqlParameter() .put("LENDING_ID",lending.getId()),new DepFormLendingGoods()); List resultList = new ArrayList<>(); for (DepFormLendingGoods goods : goodsList) { for (CheckWarehouseResult output : param.getOutputList()) { //如果出库的型号与分发单里的型号相同 if (goods.getBaseGoodsModelsId().longValue() == output.getWhGoods().getBaseGoodsModelsId().longValue()){ DepFormLendingModel model = new DepFormLendingModel(); model.setId(NumberGenerator.getLongSequenceNumber()); model.setCounts(goods.getCounts()); model.setDepFormLendingGoodsId(goods.getId()); model.setDepFormLendingId(goods.getDepFormLendingId()); model.setWhGoodsDetailsId(output.getWh_goods_detail_id()); model.setNowUserName(goods.getGoodsUserName()); model.setNowUserPhone(goods.getGoodsUserPhone()); model.setWhGoodsId(output.getWhGoods().getId()); //当前可使用数量 model.setUsingCount(model.getCounts()); model.setWarehouseId(output.getWhGoods().getWarehouseId()); model.setWarehouseName(output.getWhGoods().getWarehouseName()); model.setAgencyId(lending.getAgencyId()); model.setAgencyName(lending.getAgencyName()); model.setDepartmentId(lending.getDepartmentId()); model.setDepartmentName(lending.getDepartmentName()); insert(model); CheckUsingResult result = new CheckUsingResult(); result.setLendingModel(model); result.setInitial_count(0); result.setEnd_count(output.getInitial_count()-output.getEnd_count()); resultList.add(result); } } } return resultList; } /** * 出库 */ private List 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 goodsList = select(sql,parameter,new WhGoods()); List 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) 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 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(); } }