|
@@ -14,6 +14,12 @@ import com.fjhx.item.entity.product.po.ProductClassify;
|
|
|
import com.fjhx.item.entity.product.po.ProductInfo;
|
|
|
import com.fjhx.item.service.product.ProductClassifyService;
|
|
|
import com.fjhx.item.service.product.ProductInfoService;
|
|
|
+import com.fjhx.item.util.excel.util.ExcelUtil;
|
|
|
+import com.fjhx.tenant.entity.dict.dto.DictTenantDataSelectDto;
|
|
|
+import com.fjhx.tenant.entity.dict.vo.DictTenantDataVo;
|
|
|
+import com.fjhx.tenant.service.dict.DictTenantDataService;
|
|
|
+import com.fjhx.wms.entity.PurchaseDetailPo;
|
|
|
+import com.fjhx.wms.entity.SubscribeDetailPo;
|
|
|
import com.fjhx.wms.entity.stock.bo.InOutBo;
|
|
|
import com.fjhx.wms.entity.stock.dto.StockDto;
|
|
|
import com.fjhx.wms.entity.stock.dto.StockJournalDetailsDto;
|
|
@@ -21,14 +27,18 @@ import com.fjhx.wms.entity.stock.dto.StockSelectDto;
|
|
|
import com.fjhx.wms.entity.stock.emums.InOutType;
|
|
|
import com.fjhx.wms.entity.stock.emums.JournalType;
|
|
|
import com.fjhx.wms.entity.stock.po.Stock;
|
|
|
+import com.fjhx.wms.entity.stock.po.StockAnalysis;
|
|
|
import com.fjhx.wms.entity.stock.po.StockJournal;
|
|
|
import com.fjhx.wms.entity.stock.po.StockJournalDetails;
|
|
|
import com.fjhx.wms.entity.stock.vo.StockVo;
|
|
|
+import com.fjhx.wms.entity.stock.vo.StockWaitDetailsVo;
|
|
|
import com.fjhx.wms.entity.warehouse.po.Warehouse;
|
|
|
import com.fjhx.wms.mapper.stock.StockMapper;
|
|
|
+import com.fjhx.wms.service.PurService;
|
|
|
import com.fjhx.wms.service.stock.StockJournalDetailsService;
|
|
|
import com.fjhx.wms.service.stock.StockJournalService;
|
|
|
import com.fjhx.wms.service.stock.StockService;
|
|
|
+import com.fjhx.wms.service.stock.StockWaitService;
|
|
|
import com.fjhx.wms.service.warehouse.WarehouseService;
|
|
|
import com.fjhx.wms.utils.CodeEnum;
|
|
|
import com.obs.services.internal.ServiceException;
|
|
@@ -36,15 +46,14 @@ import com.ruoyi.common.core.domain.BaseIdPo;
|
|
|
import com.ruoyi.common.core.domain.entity.SysDept;
|
|
|
import com.ruoyi.common.utils.SecurityUtils;
|
|
|
import com.ruoyi.common.utils.wrapper.IWrapper;
|
|
|
+import com.ruoyi.common.utils.wrapper.SqlField;
|
|
|
import com.ruoyi.system.service.ISysRoleService;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
import java.math.BigDecimal;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
-import java.util.Set;
|
|
|
+import java.util.*;
|
|
|
import java.util.function.Function;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
@@ -69,9 +78,14 @@ public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements
|
|
|
ProductClassifyService productClassifyService;
|
|
|
@Autowired
|
|
|
WarehouseService warehouseService;
|
|
|
-
|
|
|
@Autowired
|
|
|
private ISysRoleService sysRoleService;
|
|
|
+ @Autowired
|
|
|
+ private PurService purService;
|
|
|
+ @Autowired
|
|
|
+ private StockWaitService stockWaitService;
|
|
|
+ @Autowired
|
|
|
+ private DictTenantDataService dictTenantDataService;
|
|
|
|
|
|
@Override
|
|
|
public Page<StockVo> getPage(StockSelectDto dto) {
|
|
@@ -760,4 +774,175 @@ public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements
|
|
|
return baseMapper.getDepts();
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 库存分析
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Page<StockAnalysis> stockAnalysis(StockSelectDto dto) {
|
|
|
+ IWrapper<Stock> wrapper = getWrapper();
|
|
|
+ wrapper.eq("de.dept_id", dto.getDeptId());
|
|
|
+ wrapper.eq("pi.definition", dto.getDefinition());
|
|
|
+ wrapper.eq("pi.type", dto.getType());
|
|
|
+ wrapper.eq("ifnull(json_unquote( pi.victoriatourist_json -> '$.combination' ),0)", dto.getIsCombination());
|
|
|
+
|
|
|
+ wrapper.keyword(dto.getKeyword(),
|
|
|
+ new SqlField("pi.custom_code"),
|
|
|
+ new SqlField("pi.name"),
|
|
|
+ new SqlField("pi.spec")
|
|
|
+ );
|
|
|
+
|
|
|
+ wrapper.groupBy("s.product_id");
|
|
|
+ Page<StockAnalysis> page = baseMapper.getStockAnalysisPage(dto.getPage(), wrapper);
|
|
|
+ List<StockAnalysis> records = page.getRecords();
|
|
|
+ if (ObjectUtil.isEmpty(records)) {
|
|
|
+ return page;
|
|
|
+ }
|
|
|
+
|
|
|
+ //调用公共代码块处理数据
|
|
|
+ stockAnalysisComm(records);
|
|
|
+
|
|
|
+ return page;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void exportExcel(StockSelectDto dto, HttpServletResponse httpServletResponse) {
|
|
|
+ IWrapper<Stock> wrapper = getWrapper();
|
|
|
+ wrapper.eq("de.dept_id", dto.getDeptId());
|
|
|
+ wrapper.eq("pi.definition", dto.getDefinition());
|
|
|
+ wrapper.eq("pi.type", dto.getType());
|
|
|
+ wrapper.eq("ifnull(json_unquote( pi.victoriatourist_json -> '$.combination' ),0)", dto.getIsCombination());
|
|
|
+
|
|
|
+ wrapper.keyword(dto.getKeyword(),
|
|
|
+ new SqlField("pi.custom_code"),
|
|
|
+ new SqlField("pi.name"),
|
|
|
+ new SqlField("pi.spec")
|
|
|
+ );
|
|
|
+
|
|
|
+ wrapper.groupBy("s.product_id");
|
|
|
+ List<StockAnalysis> list = baseMapper.getStockAnalysisPage(wrapper);
|
|
|
+
|
|
|
+ //调用公共代码块处理数据
|
|
|
+ stockAnalysisComm(list);
|
|
|
+
|
|
|
+ //获取字典Map
|
|
|
+ Map<String, String> dictMap = getDictMap("product_type");
|
|
|
+
|
|
|
+ for (StockAnalysis stockAnalysis : list) {
|
|
|
+ String productDefinition = "0".equals(stockAnalysis.getProductDefinition()) ? "产品" : "物料";
|
|
|
+ String isCombination = "0".equals(stockAnalysis.getIsCombination()) ? "否" : "是";
|
|
|
+ String productType = dictMap.get(stockAnalysis.getProductType());
|
|
|
+
|
|
|
+ stockAnalysis.setProductDefinition(productDefinition);
|
|
|
+ stockAnalysis.setIsCombination(isCombination);
|
|
|
+ stockAnalysis.setProductType(productType);
|
|
|
+ }
|
|
|
+
|
|
|
+ //导出Excel
|
|
|
+ ExcelUtil.export(httpServletResponse, list, StockAnalysis.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 库存分析 公共代码块
|
|
|
+ */
|
|
|
+ private void stockAnalysisComm(List<StockAnalysis> stockAnalysisList) {
|
|
|
+ List<Long> ids = stockAnalysisList.stream().map(StockAnalysis::getProductId).collect(Collectors.toList());
|
|
|
+
|
|
|
+ //获取已采购数量(审批中/审批通过)
|
|
|
+ List<PurchaseDetailPo> purchaseCountList = purService.getPurchaseCountList(IWrapper.<Object>getWrapper()
|
|
|
+ .in("pd.bussiness_id", ids)
|
|
|
+ .in("p.purchase_status", 10, 30)
|
|
|
+ .groupBy("pd.bussiness_id"));
|
|
|
+ purchaseCountList = ObjectUtil.isEmpty(purchaseCountList) ? new ArrayList<>() : purchaseCountList;
|
|
|
+ //获取已申购数量(审批中/审批通过)
|
|
|
+ List<SubscribeDetailPo> subscribeCountList = purService.getSubscribeCountList(IWrapper.<Object>getWrapper()
|
|
|
+ .in("sd.bussiness_id", ids)
|
|
|
+ .in("s.subcribe_status", 10, 30)
|
|
|
+ .groupBy("sd.bussiness_id"));
|
|
|
+ subscribeCountList = ObjectUtil.isEmpty(subscribeCountList) ? new ArrayList<>() : subscribeCountList;
|
|
|
+ //获取已采购数量(审批通过)
|
|
|
+ List<PurchaseDetailPo> purchaseCountList1 = purService.getPurchaseCountList(IWrapper.<Object>getWrapper()
|
|
|
+ .in("pd.bussiness_id", ids)
|
|
|
+ .eq("p.purchase_status", 30)
|
|
|
+ .groupBy("pd.bussiness_id"));
|
|
|
+ purchaseCountList1 = ObjectUtil.isEmpty(purchaseCountList1) ? new ArrayList<>() : purchaseCountList1;
|
|
|
+ //获取已入库数量
|
|
|
+ List<StockWaitDetailsVo> stockWaitList = stockWaitService.getStockWaitList(IWrapper.<Object>getWrapper()
|
|
|
+ .in("swd.product_id", ids)
|
|
|
+ .eq("sw.type", 1)
|
|
|
+ );
|
|
|
+ stockWaitList = ObjectUtil.isEmpty(stockWaitList) ? new ArrayList<>() : stockWaitList;
|
|
|
+ //获取待出库数量
|
|
|
+ List<StockWaitDetailsVo> stockWaitOutList = stockWaitService.getStockWaitList(IWrapper.<Object>getWrapper()
|
|
|
+ .in("swd.product_id", ids)
|
|
|
+ .eq("sw.type", 2)
|
|
|
+ .in("sw.business_type", 5, 6)
|
|
|
+ );
|
|
|
+ stockWaitOutList = ObjectUtil.isEmpty(stockWaitOutList) ? new ArrayList<>() : stockWaitOutList;
|
|
|
+ //京东订单待出库数量
|
|
|
+ List<StockWaitDetailsVo> jdStockWaitOutList = stockWaitService.getStockWaitList(IWrapper.<Object>getWrapper()
|
|
|
+ .in("swd.product_id", ids)
|
|
|
+ .eq("sw.type", 2)
|
|
|
+ .eq("sw.business_type", 5)
|
|
|
+ );
|
|
|
+ jdStockWaitOutList = ObjectUtil.isEmpty(jdStockWaitOutList) ? new ArrayList<>() : jdStockWaitOutList;
|
|
|
+
|
|
|
+ for (StockAnalysis record : stockAnalysisList) {
|
|
|
+ //待采购数量(申购数-采购数)
|
|
|
+ BigDecimal subscribeCount = subscribeCountList.stream()
|
|
|
+ .filter(item -> item.getBussinessId().equals(record.getProductId()))
|
|
|
+ .map(SubscribeDetailPo::getCount).reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+ BigDecimal purchaseCount = purchaseCountList.stream()
|
|
|
+ .filter(item -> item.getBussinessId().equals(record.getProductId()))
|
|
|
+ .map(PurchaseDetailPo::getCount).reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+ BigDecimal purchaseWaitCount = subscribeCount.subtract(purchaseCount);
|
|
|
+ //待入库数量
|
|
|
+ BigDecimal purchaseCount1 = purchaseCountList1.stream()
|
|
|
+ .filter(item -> item.getBussinessId().equals(record.getProductId()))
|
|
|
+ .map(PurchaseDetailPo::getCount).reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+ BigDecimal reduce = stockWaitList.stream()
|
|
|
+ .filter(item -> item.getProductId().equals(record.getProductId()))
|
|
|
+ .map(StockWaitDetailsVo::getReceiptQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+ BigDecimal stockWaitInCount = purchaseCount1.subtract(reduce);
|
|
|
+ //待出库数量
|
|
|
+ BigDecimal stockWaitOutCount = stockWaitOutList.stream()
|
|
|
+ .filter(item -> item.getProductId().equals(record.getProductId()))
|
|
|
+ .map(item -> {
|
|
|
+ return item.getQuantity().subtract(item.getReceiptQuantity());
|
|
|
+ }).reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+ //可支配库存
|
|
|
+ BigDecimal disposableCount = record.getQuantity().subtract(stockWaitOutCount);
|
|
|
+ //京东订单待出库数量
|
|
|
+ BigDecimal jdStockWaitOutCount = jdStockWaitOutList.stream()
|
|
|
+ .filter(item -> item.getProductId().equals(record.getProductId()))
|
|
|
+ .map(item -> item.getQuantity().subtract(item.getReceiptQuantity())).reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+ //总库存
|
|
|
+ BigDecimal totalQuantity = record.getQuantity().add(record.getFrozenQuantity())
|
|
|
+ .add(record.getDefectiveQuantity()).add(stockWaitInCount).add(jdStockWaitOutCount);
|
|
|
+ //总金额
|
|
|
+ BigDecimal amount = totalQuantity.multiply(record.getUnitPrice());
|
|
|
+ amount = amount.setScale(4, BigDecimal.ROUND_HALF_DOWN);
|
|
|
+
|
|
|
+ record.setPurchaseWaitQuantity(purchaseWaitCount);
|
|
|
+ record.setStockWaitInQuantity(stockWaitInCount);
|
|
|
+ record.setStockWaitOutQuantity(stockWaitOutCount);
|
|
|
+ record.setDisposableQuantity(disposableCount);
|
|
|
+ record.setJdInTransitQuantity(jdStockWaitOutCount);
|
|
|
+ record.setTotalQuantity(totalQuantity);
|
|
|
+ record.setAmount(amount);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, String> getDictMap(String code) {
|
|
|
+ DictTenantDataSelectDto dto = new DictTenantDataSelectDto();
|
|
|
+ dto.setDictCode(code);
|
|
|
+ DynamicDataSourceContextHolder.push(SourceConstant.BASE);
|
|
|
+ List<DictTenantDataVo> dictTenantDataServiceList = dictTenantDataService.getList(dto);
|
|
|
+ DynamicDataSourceContextHolder.poll();
|
|
|
+ Map<String, String> dictMap = new HashMap<>();
|
|
|
+ if (ObjectUtil.isNotEmpty(dictTenantDataServiceList)) {
|
|
|
+ dictMap = dictTenantDataServiceList.stream().collect(Collectors.toMap(DictTenantDataVo::getDictKey, DictTenantDataVo::getDictValue));
|
|
|
+ }
|
|
|
+ return dictMap;
|
|
|
+ }
|
|
|
+
|
|
|
}
|