| | |
| | | package com.consum.base.core; |
| | | |
| | | import com.consum.base.core.param.BaseWarehouseParam; |
| | | import com.consum.base.core.utils.DateUtil; |
| | | import com.consum.base.core.utils.IdUtil; |
| | | import com.consum.base.core.utils.SqlParameter; |
| | | 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.Propagation; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.Assert; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | |
| | | */ |
| | | @Service |
| | | @Slf4j |
| | | public class WarehouseCoreService { |
| | | @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED) |
| | | 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()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 统一出入库 |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public CheckWarehouseResult unifyCheck(CheckWarehouseParam param) { |
| | | public List<CheckUsingResult> unifyUsingCheck(CheckUsingParam 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<CheckUsingResult> results; |
| | | |
| | | |
| | | String key = param.getLending_id().toString(); |
| | | |
| | | /** |
| | | * 此处将同一个仓库下的同一个型号上锁,不同仓库、不同型号不受影响。 |
| | | */ |
| | | synchronized (key) { |
| | | if (param.getIsCheckIn()) { |
| | | result = checkin(param); |
| | | results = checkUsingIn(param); |
| | | } else { |
| | | result = checkout(param); |
| | | results = checkUsingOut(param); |
| | | } |
| | | } |
| | | return result; |
| | | return results; |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage()); |
| | | throw new RuntimeException(e.getMessage()); |
| | |
| | | } |
| | | |
| | | /** |
| | | * 统一出入库 |
| | | */ |
| | | public List<CheckWarehouseResult> unifyCheck(BaseWarehouseParam param) { |
| | | // TODO: 10/10/2023 此处加了唯一锁,会影响性能,思考是否有更合适的办法 |
| | | try { |
| | | Assert.notNull(param, "wareHouse param can not null !"); |
| | | Assert.notNull(param.getWarehouseId(), "wareHouse id can not null"); |
| | | List<CheckWarehouseResult> 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<CheckUsingResult> 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<DepFormLendingModel> modelsList = this.select(sql,new SqlParameter("MODEL_ID", param.getModel_id()) |
| | | .put("LENDING_ID",param.getLending_id()),new DepFormLendingModel()); |
| | | |
| | | List<CheckUsingResult> 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()}); |
| | | |
| | | //如果是A类物品,则需要与持有人等同 |
| | | if (goods.getClassification() == "A" && (goods.getGoodsUserName().equals(param.getUser_name()))) { |
| | | continue; |
| | | } |
| | | |
| | | //如果当前持有人持有物品数量大于出库数量,则直接减掉数量即可。 |
| | | 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<CheckUsingResult> 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<DepFormLendingGoods> goodsList = this.select(sql,new SqlParameter() |
| | | .put("LENDING_ID",lending.getId()),new DepFormLendingGoods()); |
| | | |
| | | List<CheckUsingResult> 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(IdUtil.generateId()); |
| | | 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 CheckWarehouseResult checkout(CheckWarehouseParam param) { |
| | | return new CheckWarehouseResult(); |
| | | private List<CheckWarehouseResult> checkout(BaseWarehouseParam 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(IdUtil.generateId()); |
| | | 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(BaseWarehouseParam 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(IdUtil.generateId()); |
| | | 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(); |
| | | } |
| | | |