|
@@ -0,0 +1,690 @@
|
|
|
+package com.sd.business.service.statement.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.convert.Convert;
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.ruoyi.common.constant.StatusConstant;
|
|
|
+import com.ruoyi.common.core.domain.BaseIdPo;
|
|
|
+import com.ruoyi.common.core.domain.BasePo;
|
|
|
+import com.ruoyi.common.exception.ServiceException;
|
|
|
+import com.ruoyi.common.utils.PageUtils;
|
|
|
+import com.sd.business.entity.excel.enums.ExcelTypeEnum;
|
|
|
+import com.sd.business.entity.inventory.po.InventoryFinishedOrder;
|
|
|
+import com.sd.business.entity.inventory.po.InventoryFinishedOrderDetail;
|
|
|
+import com.sd.business.entity.order.enums.OrderClassifyEnum;
|
|
|
+import com.sd.business.entity.order.enums.OrderStatusEnum;
|
|
|
+import com.sd.business.entity.order.po.OrderInfo;
|
|
|
+import com.sd.business.entity.order.po.OrderSku;
|
|
|
+import com.sd.business.entity.order.po.OrderSkuProductionCost;
|
|
|
+import com.sd.business.entity.outbound.po.OutboundOrder;
|
|
|
+import com.sd.business.entity.sku.bom.SkuSpecBo;
|
|
|
+import com.sd.business.entity.sku.po.SkuSpec;
|
|
|
+import com.sd.business.entity.statement.dto.ExportDocumentDto;
|
|
|
+import com.sd.business.entity.statement.dto.GetDocumentDto;
|
|
|
+import com.sd.business.entity.statement.dto.SalesOutWarehouseDetailsDto;
|
|
|
+import com.sd.business.entity.statement.dto.SalesRevenueCostSelectDto;
|
|
|
+import com.sd.business.entity.statement.dto.StatementOfAccountMergePageDto;
|
|
|
+import com.sd.business.entity.statement.po.StatementOfAccount;
|
|
|
+import com.sd.business.entity.statement.vo.DeliveryOfGoodsVO;
|
|
|
+import com.sd.business.entity.statement.vo.DocumentByBomVo;
|
|
|
+import com.sd.business.entity.statement.vo.DocumentByOrderVo;
|
|
|
+import com.sd.business.entity.statement.vo.DocumentByRevenueCostVo;
|
|
|
+import com.sd.business.entity.statement.vo.DocumentBySkuVo;
|
|
|
+import com.sd.business.entity.statement.vo.StatementOfAccountMergePageVo;
|
|
|
+import com.sd.business.service.department.DepartmentService;
|
|
|
+import com.sd.business.service.excel.ExcelGenerateLogService;
|
|
|
+import com.sd.business.service.inventory.InventoryFinishedOrderDetailService;
|
|
|
+import com.sd.business.service.inventory.InventoryFinishedOrderService;
|
|
|
+import com.sd.business.service.inventory.InventoryFinishedService;
|
|
|
+import com.sd.business.service.order.OrderInfoService;
|
|
|
+import com.sd.business.service.order.OrderSkuProductionCostService;
|
|
|
+import com.sd.business.service.order.OrderSkuService;
|
|
|
+import com.sd.business.service.outbound.OutboundOrderService;
|
|
|
+import com.sd.business.service.sku.SkuSpecService;
|
|
|
+import com.sd.business.service.statement.StatementOfAccountExportService;
|
|
|
+import com.sd.business.service.statement.StatementOfAccountMergeService;
|
|
|
+import com.sd.business.service.statement.StatementOfAccountService;
|
|
|
+import com.sd.business.strategy.impl.DefaultExportStrategy;
|
|
|
+import com.sd.business.strategy.impl.DocumentByOrderExcelExportStrategy;
|
|
|
+import com.sd.business.strategy.impl.SalesOutWarehouseDetailsExportStrategy;
|
|
|
+import com.sd.framework.util.Assert;
|
|
|
+import com.sd.framework.util.excel.util.ExcelUtil;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.math.RoundingMode;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.Comparator;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.function.Function;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * <p>
|
|
|
+ * 对账单 服务实现类
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @author
|
|
|
+ * @since 2023-07-31
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class StatementOfAccountMergeServiceImpl implements StatementOfAccountMergeService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private HttpServletResponse response;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private StatementOfAccountService statementOfAccountService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private DepartmentService departmentService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private OrderInfoService orderInfoService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private StatementOfAccountExportService statementOfAccountExportService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ExcelGenerateLogService excelGenerateLogService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private OrderSkuService orderSkuService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private SkuSpecService skuSpecService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private OrderSkuProductionCostService orderSkuProductionCostService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private InventoryFinishedOrderDetailService inventoryFinishedOrderDetailService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private InventoryFinishedService inventoryFinishedService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private InventoryFinishedOrderService inventoryFinishedOrderService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private OutboundOrderService outboundOrderService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Page<StatementOfAccountMergePageVo> getPage(StatementOfAccountMergePageDto dto) {
|
|
|
+
|
|
|
+ QueryWrapper<StatementOfAccount> wrapper = Wrappers.query();
|
|
|
+
|
|
|
+ wrapper.eq(ObjectUtil.isNotNull(dto.getDepartmentId()), "department_id", dto.getDepartmentId());
|
|
|
+ wrapper.groupBy("department_id");
|
|
|
+ wrapper.orderByDesc("dimensionality");
|
|
|
+
|
|
|
+ switch (dto.getType()) {
|
|
|
+ // 月度
|
|
|
+ case 1:
|
|
|
+ wrapper.select("department_id AS departmentId",
|
|
|
+ "GROUP_CONCAT(id) AS idGroupConcat",
|
|
|
+ "DATE_FORMAT(time_period,'%Y/%m月') AS dimensionality");
|
|
|
+ wrapper.groupBy("dimensionality");
|
|
|
+ break;
|
|
|
+
|
|
|
+ // 季度
|
|
|
+ case 2:
|
|
|
+ wrapper.select("department_id AS departmentId",
|
|
|
+ "GROUP_CONCAT(id) AS idGroupConcat",
|
|
|
+ "CONCAT(YEAR(time_period),'/第',QUARTER(time_period),'季度') AS dimensionality");
|
|
|
+ wrapper.groupBy("dimensionality");
|
|
|
+ break;
|
|
|
+
|
|
|
+ // 年度
|
|
|
+ case 3:
|
|
|
+ wrapper.select("department_id AS departmentId",
|
|
|
+ "GROUP_CONCAT(id) AS idGroupConcat",
|
|
|
+ "YEAR(time_period) AS dimensionality");
|
|
|
+ wrapper.groupBy("dimensionality");
|
|
|
+ break;
|
|
|
+
|
|
|
+ // 自定义
|
|
|
+ case 4:
|
|
|
+ String beginTime = dto.getBeginTime() == null ? StringPool.EMPTY : DateUtil.formatDate(dto.getBeginTime());
|
|
|
+ String endTime = dto.getEndTime() == null ? StringPool.EMPTY : DateUtil.formatDate(dto.getEndTime());
|
|
|
+
|
|
|
+ wrapper.select("department_id AS departmentId",
|
|
|
+ "GROUP_CONCAT(id) AS idGroupConcat",
|
|
|
+ "'" + beginTime + " - " + endTime + "' AS dimensionality");
|
|
|
+ wrapper.ge(ObjectUtil.isNotNull(dto.getBeginTime()), "time_period", dto.getBeginTime());
|
|
|
+ wrapper.le(ObjectUtil.isNotNull(dto.getEndTime()), "time_period", dto.getEndTime());
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ throw new ServiceException("未知对账类型");
|
|
|
+ }
|
|
|
+
|
|
|
+ Page<Map<String, Object>> mapPage = statementOfAccountService.pageMaps(dto.getPage(), wrapper);
|
|
|
+ Page<StatementOfAccountMergePageVo> page = PageUtils.copyPage(mapPage, StatementOfAccountMergePageVo.class);
|
|
|
+ List<StatementOfAccountMergePageVo> records = page.getRecords();
|
|
|
+ if (records.isEmpty()) {
|
|
|
+ return page;
|
|
|
+ }
|
|
|
+
|
|
|
+ departmentService.attributeAssign(records, StatementOfAccountMergePageVo::getDepartmentId,
|
|
|
+ (item, department) -> item.setDepartmentName(department.getName()));
|
|
|
+
|
|
|
+ // 对账单id列表
|
|
|
+ List<Long> statementOfAccountIdList = records.stream()
|
|
|
+ .map(StatementOfAccountMergePageVo::getIdGroupConcat)
|
|
|
+ .flatMap(item -> Arrays.stream(item.split(",")))
|
|
|
+ .map(Convert::toLong)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ Map<Long, List<OrderInfo>> map = orderInfoService.mapKGroup(OrderInfo::getStatementOfAccountId,
|
|
|
+ q -> q.in(OrderInfo::getStatementOfAccountId, statementOfAccountIdList));
|
|
|
+
|
|
|
+ Map<Long, Integer> statementOfAccountMap = statementOfAccountService.mapKV(BaseIdPo::getId, StatementOfAccount::getCheckStatus,
|
|
|
+ q -> q.in(BaseIdPo::getId, statementOfAccountIdList));
|
|
|
+
|
|
|
+ for (StatementOfAccountMergePageVo record : records) {
|
|
|
+
|
|
|
+ String[] tempStatementOfAccountIdList = record.getIdGroupConcat().split(",");
|
|
|
+
|
|
|
+ record.setReconcilingAmount(BigDecimal.ZERO);
|
|
|
+ record.setOrderQuantity(0);
|
|
|
+ record.setQuantityOfStatement(tempStatementOfAccountIdList.length);
|
|
|
+
|
|
|
+ for (String statementOfAccountIdStr : tempStatementOfAccountIdList) {
|
|
|
+ Long statementOfAccountId = Convert.toLong(statementOfAccountIdStr);
|
|
|
+ List<OrderInfo> tempOrderInfoList = map.get(statementOfAccountId);
|
|
|
+
|
|
|
+ if (ObjectUtil.isEmpty(tempOrderInfoList)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ BigDecimal reconcilingAmount = tempOrderInfoList.stream()
|
|
|
+ .map(OrderInfo::getTotalAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+
|
|
|
+ record.setOrderQuantity(record.getOrderQuantity() + tempOrderInfoList.size());
|
|
|
+ record.setReconcilingAmount(record.getReconcilingAmount().add(reconcilingAmount));
|
|
|
+
|
|
|
+ if (ObjectUtil.notEqual(record.getCheckStatus(), StatusConstant.NO)
|
|
|
+ && ObjectUtil.equals(statementOfAccountMap.get(statementOfAccountId), StatusConstant.NO)) {
|
|
|
+ record.setCheckStatus(StatusConstant.NO);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return page;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<DocumentBySkuVo> getDocumentBySku(GetDocumentDto dto) {
|
|
|
+ return statementOfAccountService.getSkuDocument(getIdList(dto), dto.getOrderClassify());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<DocumentByBomVo> getDocumentByBom(GetDocumentDto dto) {
|
|
|
+ return statementOfAccountService.getBomDocument(getIdList(dto), dto.getOrderClassify());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<DocumentByOrderVo> getDocumentByOrder(GetDocumentDto dto) {
|
|
|
+ return statementOfAccountService.getOrderDocument(getIdList(dto), dto.getOrderClassify());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void export(ExportDocumentDto dto, int type) {
|
|
|
+
|
|
|
+ List<Long> idList = Arrays.stream(dto.getIdGroupConcat().split(","))
|
|
|
+ .map(Convert::toLong)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ String departmentName = dto.getDepartmentName();
|
|
|
+ String beginDate = dto.getBeginDate();
|
|
|
+ String endDate = dto.getEndDate();
|
|
|
+ Integer orderClassify = dto.getOrderClassify();
|
|
|
+
|
|
|
+ switch (type) {
|
|
|
+ case 1:
|
|
|
+ statementOfAccountExportService.exportDocumentBySku(idList, departmentName, beginDate, endDate, orderClassify);
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ statementOfAccountExportService.exportDocumentByBom(idList, departmentName, beginDate, endDate, orderClassify);
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ excelGenerateLogService.generateExcel(ExcelTypeEnum.STATISTICS_DOCUMENT_BY_ORDER,
|
|
|
+ new DocumentByOrderExcelExportStrategy(idList, departmentName, beginDate, endDate, orderClassify),
|
|
|
+ DateUtil.formatDate(new Date()) + " " + OrderClassifyEnum.getEnum(orderClassify).getValue() + "-订单对账报表");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new ServiceException("未知对账单类型");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Page<DocumentByOrderVo> salesOutWarehouseDetails(SalesOutWarehouseDetailsDto dto) {
|
|
|
+
|
|
|
+ // 对账单条件查询
|
|
|
+ List<StatementOfAccount> statementOfAccountList = null;
|
|
|
+ List<Long> statementOfAccountIdList = null;
|
|
|
+
|
|
|
+ if (!ObjectUtil.isAllEmpty(dto.getBeginTime(), dto.getEndTime())) {
|
|
|
+ statementOfAccountList = statementOfAccountService.list(q -> q
|
|
|
+ .ge(ObjectUtil.isNotNull(dto.getBeginTime()), BasePo::getCreateTime, dto.getBeginTime())
|
|
|
+ .le(ObjectUtil.isNotNull(dto.getEndTime()), BasePo::getCreateTime, dto.getEndTime()));
|
|
|
+
|
|
|
+ if (statementOfAccountList.isEmpty()) {
|
|
|
+ return new Page<>();
|
|
|
+ }
|
|
|
+ statementOfAccountIdList = statementOfAccountList.stream().map(BaseIdPo::getId).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ // sku条件查询
|
|
|
+ List<Long> orderIdList = null;
|
|
|
+ if (!StrUtil.isAllBlank(dto.getSkuSpecCode(), dto.getSkuSpecName())) {
|
|
|
+ List<SkuSpec> skuSpecList = skuSpecService.list(q -> q
|
|
|
+ .like(StrUtil.isNotBlank(dto.getSkuSpecCode()), SkuSpec::getCode, dto.getSkuSpecCode())
|
|
|
+ .like(StrUtil.isNotBlank(dto.getSkuSpecName()), SkuSpec::getName, dto.getSkuSpecName()));
|
|
|
+
|
|
|
+ if (skuSpecList.isEmpty()) {
|
|
|
+ return new Page<>();
|
|
|
+ }
|
|
|
+ List<Long> skuSpecIdList = skuSpecList.stream().map(BaseIdPo::getId).collect(Collectors.toList());
|
|
|
+
|
|
|
+ List<OrderSku> orderSkuList = orderSkuService.list(q -> q.in(OrderSku::getSkuSpecId, skuSpecIdList));
|
|
|
+ if (orderSkuList.isEmpty()) {
|
|
|
+ return new Page<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ orderIdList = orderSkuList.stream().map(OrderSku::getOrderId).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ Page<OrderInfo> page = dto.getPage();
|
|
|
+ page.setSearchCount(dto.getSearchCount());
|
|
|
+
|
|
|
+ // 查询订单分页
|
|
|
+ orderInfoService.page(page, Wrappers.lambdaQuery(OrderInfo.class)
|
|
|
+ .in(ObjectUtil.isNotEmpty(orderIdList), BaseIdPo::getId, orderIdList)
|
|
|
+ .in(ObjectUtil.isNotEmpty(statementOfAccountIdList), OrderInfo::getStatementOfAccountId, statementOfAccountIdList)
|
|
|
+ .isNotNull(ObjectUtil.isEmpty(statementOfAccountIdList), OrderInfo::getStatementOfAccountId)
|
|
|
+ .eq(ObjectUtil.isNotNull(dto.getDepartmentId()), OrderInfo::getDepartmentId, dto.getDepartmentId())
|
|
|
+ .and(StrUtil.isNotBlank(dto.getCode()), q -> q
|
|
|
+ .like(OrderInfo::getCode, dto.getCode()).or().like(OrderInfo::getWlnCode, dto.getCode()))
|
|
|
+ .orderByDesc(OrderInfo::getStatementOfAccountId)
|
|
|
+ );
|
|
|
+
|
|
|
+ List<OrderInfo> records = page.getRecords();
|
|
|
+
|
|
|
+ if (records.isEmpty()) {
|
|
|
+ return new Page<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 赋值订单sku,包材
|
|
|
+ List<DocumentByOrderVo> orderDocumentByOrderList = statementOfAccountService.getOrderDocumentByOrderList(records);
|
|
|
+
|
|
|
+ // 赋值事业部名称
|
|
|
+ departmentService.attributeAssign(orderDocumentByOrderList, DocumentByOrderVo::getDepartmentId, (item, department) -> {
|
|
|
+ item.setDepartmentName(department.getName());
|
|
|
+ });
|
|
|
+
|
|
|
+ // 赋值对账时间
|
|
|
+ if (statementOfAccountList == null) {
|
|
|
+ statementOfAccountList = statementOfAccountService.listByIds(
|
|
|
+ records.stream().map(OrderInfo::getStatementOfAccountId).collect(Collectors.toList()));
|
|
|
+ }
|
|
|
+ Map<Long, StatementOfAccount> map = statementOfAccountList.stream().collect(Collectors.toMap(BaseIdPo::getId, Function.identity()));
|
|
|
+
|
|
|
+ for (DocumentByOrderVo documentByOrderVo : orderDocumentByOrderList) {
|
|
|
+ Long statementOfAccountId = documentByOrderVo.getStatementOfAccountId();
|
|
|
+ StatementOfAccount statementOfAccount = map.get(statementOfAccountId);
|
|
|
+ documentByOrderVo.setStatementOfAccountTime(statementOfAccount.getCreateTime());
|
|
|
+ }
|
|
|
+
|
|
|
+ Page<DocumentByOrderVo> result = new Page<>();
|
|
|
+ result.setTotal(page.getTotal());
|
|
|
+ result.setRecords(orderDocumentByOrderList);
|
|
|
+ result.setPages(page.getPages());
|
|
|
+ result.setSize(page.getSize());
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void exportSalesOutWarehouseDetails(SalesOutWarehouseDetailsDto dto) {
|
|
|
+
|
|
|
+ excelGenerateLogService.generateExcel(ExcelTypeEnum.SALES_OUT_WAREHOUSE_DETAILS,
|
|
|
+ new SalesOutWarehouseDetailsExportStrategy(this, dto),
|
|
|
+ DateUtil.formatDate(new Date()) + " 销售出货明细");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Page<DocumentByRevenueCostVo> salesRevenueCostPage(SalesRevenueCostSelectDto dto) {
|
|
|
+ // 对账单条件查询
|
|
|
+ List<StatementOfAccount> statementOfAccountList = null;
|
|
|
+ List<Long> statementOfAccountIdList = null;
|
|
|
+
|
|
|
+ if (!ObjectUtil.isAllEmpty(dto.getBeginTime(), dto.getEndTime())) {
|
|
|
+ statementOfAccountList = statementOfAccountService.list(q -> q
|
|
|
+ .ge(ObjectUtil.isNotNull(dto.getBeginTime()), BasePo::getCreateTime, dto.getBeginTime())
|
|
|
+ .le(ObjectUtil.isNotNull(dto.getEndTime()), BasePo::getCreateTime, dto.getEndTime()));
|
|
|
+
|
|
|
+ if (statementOfAccountList.isEmpty()) {
|
|
|
+ return new Page<>();
|
|
|
+ }
|
|
|
+ statementOfAccountIdList = statementOfAccountList.stream().map(BaseIdPo::getId).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ // sku条件查询
|
|
|
+ List<Long> orderIdList = null;
|
|
|
+ if (!StrUtil.isAllBlank(dto.getSkuSpecCode(), dto.getSkuSpecName())) {
|
|
|
+ List<SkuSpec> skuSpecList = skuSpecService.list(q -> q
|
|
|
+ .like(StrUtil.isNotBlank(dto.getSkuSpecCode()), SkuSpec::getCode, dto.getSkuSpecCode())
|
|
|
+ .like(StrUtil.isNotBlank(dto.getSkuSpecName()), SkuSpec::getName, dto.getSkuSpecName()));
|
|
|
+
|
|
|
+ if (skuSpecList.isEmpty()) {
|
|
|
+ return new Page<>();
|
|
|
+ }
|
|
|
+ List<Long> skuSpecIdList = skuSpecList.stream().map(BaseIdPo::getId).collect(Collectors.toList());
|
|
|
+
|
|
|
+ List<OrderSku> orderSkuList = orderSkuService.list(q -> q.in(OrderSku::getSkuSpecId, skuSpecIdList));
|
|
|
+ if (orderSkuList.isEmpty()) {
|
|
|
+ return new Page<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ orderIdList = orderSkuList.stream().map(OrderSku::getOrderId).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ Page<OrderInfo> page = dto.getPage();
|
|
|
+
|
|
|
+ // 查询订单分页
|
|
|
+ orderInfoService.page(page, Wrappers.lambdaQuery(OrderInfo.class)
|
|
|
+ .eq(OrderInfo::getStatus, OrderStatusEnum.COMPLETION_PRODUCTION.getKey())
|
|
|
+ .in(ObjectUtil.isNotEmpty(orderIdList), BaseIdPo::getId, orderIdList)
|
|
|
+ .in(ObjectUtil.isNotEmpty(statementOfAccountIdList), OrderInfo::getStatementOfAccountId, statementOfAccountIdList)
|
|
|
+ .isNotNull(ObjectUtil.isEmpty(statementOfAccountIdList), OrderInfo::getStatementOfAccountId)
|
|
|
+ .eq(ObjectUtil.isNotNull(dto.getDepartmentId()), OrderInfo::getDepartmentId, dto.getDepartmentId())
|
|
|
+ .and(StrUtil.isNotBlank(dto.getCode()), q -> q
|
|
|
+ .like(OrderInfo::getCode, dto.getCode()).or().like(OrderInfo::getWlnCode, dto.getCode()))
|
|
|
+ .orderByDesc(OrderInfo::getStatementOfAccountId)
|
|
|
+ );
|
|
|
+
|
|
|
+ List<OrderInfo> records = page.getRecords();
|
|
|
+
|
|
|
+ if (records.isEmpty()) {
|
|
|
+ return new Page<>();
|
|
|
+ }
|
|
|
+ Map<Long, OrderInfo> orderInfoMap = records.stream().collect(Collectors.toMap(BaseIdPo::getId, item -> item, (v1, v2) -> v2));
|
|
|
+ List<Long> orderIds = records.stream().map(BaseIdPo::getId).collect(Collectors.toList());
|
|
|
+ List<OrderSku> orderSkuList = orderSkuService.list(q -> q.in(OrderSku::getOrderId, orderIds));
|
|
|
+ // 获取sku详情数据
|
|
|
+ List<Long> skuSpecIds = orderSkuList.stream().map(OrderSku::getSkuSpecId).collect(Collectors.toList());
|
|
|
+ Map<Long, SkuSpecBo> skuSpecBoMap = skuSpecService.getSkuSpecBoByIdList(skuSpecIds);
|
|
|
+ // 获取订单成品出库数据
|
|
|
+ Map<Long, InventoryFinishedOrderDetail> inventoryMap = inventoryFinishedOrderDetailService.mapKEntity(
|
|
|
+ InventoryFinishedOrderDetail::getOrderSkuId,
|
|
|
+ q -> q.eq(InventoryFinishedOrderDetail::getOperationType, 2)
|
|
|
+ .in(InventoryFinishedOrderDetail::getOrderInfoId, orderIds)
|
|
|
+ .in(InventoryFinishedOrderDetail::getOrderSkuId, skuSpecIds));
|
|
|
+ // 获取订单sku生产成本数据
|
|
|
+ Map<Long, OrderSkuProductionCost> productionCostMap = orderSkuProductionCostService.mapKEntity(OrderSkuProductionCost::getOrderSkuId,
|
|
|
+ q -> q.in(OrderSkuProductionCost::getOrderId, orderIds));
|
|
|
+ Integer[] serialNumber = {1};
|
|
|
+ List<DocumentByRevenueCostVo> documentByRevenueCostVos = orderSkuList.stream()
|
|
|
+ .map(item -> {
|
|
|
+ OrderInfo orderInfo = orderInfoMap.get(item.getOrderId());
|
|
|
+ SkuSpecBo skuSpecBo = skuSpecBoMap.get(item.getSkuSpecId());
|
|
|
+ InventoryFinishedOrderDetail inventoryDetail = inventoryMap.get(item.getSkuSpecId());
|
|
|
+ // 规格
|
|
|
+ String length = skuSpecBo.getLength() == null ? "0" : skuSpecBo.getLength().stripTrailingZeros().toPlainString();
|
|
|
+ String width = skuSpecBo.getWidth() == null ? "0" : skuSpecBo.getWidth().stripTrailingZeros().toPlainString();
|
|
|
+ String height = skuSpecBo.getHeight() == null ? "0" : skuSpecBo.getHeight().stripTrailingZeros().toPlainString();
|
|
|
+
|
|
|
+ OrderSkuProductionCost productionCost = productionCostMap.get(item.getId());
|
|
|
+ if (productionCost == null) {
|
|
|
+ productionCost = new OrderSkuProductionCost();
|
|
|
+ productionCost.setMaterialCost(BigDecimal.ZERO);
|
|
|
+ productionCost.setAuxiliaryMaterialCost(BigDecimal.ZERO);
|
|
|
+ productionCost.setProductPackagingMaterialCost(BigDecimal.ZERO);
|
|
|
+ productionCost.setLogisticsPackagingMaterialCost(BigDecimal.ZERO);
|
|
|
+ productionCost.setTotalAmount(BigDecimal.ZERO);
|
|
|
+ }
|
|
|
+
|
|
|
+ return DocumentByRevenueCostVo.builder()
|
|
|
+ .orderId(item.getOrderId())
|
|
|
+ .departmentId(orderInfo.getDepartmentId())
|
|
|
+ .statementOfAccountId(orderInfo.getStatementOfAccountId())
|
|
|
+ .salesDate(orderInfo.getShippingTime())
|
|
|
+ .serialNumber(serialNumber[0]++)
|
|
|
+ .code(orderInfo.getCode())
|
|
|
+ .wlnCode(orderInfo.getWlnCode())
|
|
|
+ .outStorageCode(inventoryDetail == null ? "" : inventoryDetail.getCode())
|
|
|
+ .skuSpecCode(skuSpecBo.getSkuSpecCode())
|
|
|
+ .skuSpecName(skuSpecBo.getSkuSpecName())
|
|
|
+ .classifyName(skuSpecBo.getSkuClassifyName())
|
|
|
+ .spec(length + " * " + width + " * " + height)
|
|
|
+ .measuringUnit("PCS")
|
|
|
+ .quantity(item.getQuantity())
|
|
|
+ .salesUnitPrice(item.getUnitPrice()
|
|
|
+ .add(item.getCustomProcessingFee())
|
|
|
+ .add(item.getLssueFee())
|
|
|
+ .add(item.getDeliveryMaterialsFee())
|
|
|
+ .add(item.getPackingLabor())
|
|
|
+ .add(item.getPackagingMaterialCost())
|
|
|
+ .add(item.getManagementFee()))
|
|
|
+ .issuingAmount(item.getLssueFee().multiply(item.getQuantity()))
|
|
|
+ .otherAmount(item.getDeliveryMaterialsFee().multiply(item.getQuantity()))
|
|
|
+ .materialCost(productionCost.getMaterialCost())
|
|
|
+ .auxiliaryMaterialCost(productionCost.getAuxiliaryMaterialCost())
|
|
|
+ .productPackagingMaterialCost(productionCost.getProductPackagingMaterialCost())
|
|
|
+ .logisticsPackagingMaterialCost(productionCost.getLogisticsPackagingMaterialCost())
|
|
|
+ .costSubtotal(productionCost.getTotalAmount())
|
|
|
+ .build();
|
|
|
+ })
|
|
|
+ .peek(item -> item.setSalesAmount(item.getQuantity().multiply(item.getSalesUnitPrice())))
|
|
|
+ .peek(item -> {
|
|
|
+ // 产品金额
|
|
|
+ item.setProductAmount(item.getSalesAmount()
|
|
|
+ .subtract(item.getIssuingAmount()).subtract(item.getOtherAmount()));
|
|
|
+ // 毛利
|
|
|
+ BigDecimal grossProfit = item.getSalesAmount().subtract(item.getCostSubtotal());
|
|
|
+ // 毛利率
|
|
|
+ String grossProfitRate;
|
|
|
+ if (ObjectUtil.equals(item.getSalesAmount(), BigDecimal.ZERO)) {
|
|
|
+ grossProfitRate = "0%";
|
|
|
+ } else {
|
|
|
+ grossProfitRate = grossProfit
|
|
|
+ .divide(item.getSalesAmount(), 4, RoundingMode.HALF_UP)
|
|
|
+ .multiply(new BigDecimal(100))
|
|
|
+ .stripTrailingZeros().toPlainString() + "%";
|
|
|
+ }
|
|
|
+ item.setGrossProfit(grossProfit);
|
|
|
+ item.setGrossProfitRate(grossProfitRate);
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 赋值事业部名称
|
|
|
+ departmentService.attributeAssign(documentByRevenueCostVos, DocumentByRevenueCostVo::getDepartmentId, (item, department) -> {
|
|
|
+ item.setCustomerName(department.getName().startsWith("胜德实业") ? "胜德实业" : department.getName());
|
|
|
+ item.setDepartmentName(department.getName());
|
|
|
+ });
|
|
|
+
|
|
|
+ // 赋值对账时间
|
|
|
+ if (statementOfAccountList == null) {
|
|
|
+ statementOfAccountList = statementOfAccountService.listByIds(
|
|
|
+ records.stream().map(OrderInfo::getStatementOfAccountId).collect(Collectors.toList()));
|
|
|
+ }
|
|
|
+ Map<Long, StatementOfAccount> map = statementOfAccountList.stream().collect(Collectors.toMap(BaseIdPo::getId, Function.identity()));
|
|
|
+
|
|
|
+ documentByRevenueCostVos.forEach(item -> {
|
|
|
+ Long statementOfAccountId = item.getStatementOfAccountId();
|
|
|
+ StatementOfAccount statementOfAccount = map.get(statementOfAccountId);
|
|
|
+ item.setSalesDate(statementOfAccount.getCreateTime());
|
|
|
+ });
|
|
|
+
|
|
|
+ Page<DocumentByRevenueCostVo> result = new Page<>();
|
|
|
+ result.setTotal(page.getTotal());
|
|
|
+ result.setRecords(documentByRevenueCostVos);
|
|
|
+ result.setPages(page.getPages());
|
|
|
+ result.setSize(page.getSize());
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void exportSalesRevenueCostData(SalesRevenueCostSelectDto dto) {
|
|
|
+ dto.setPageNum(1);
|
|
|
+ dto.setPageSize(999999999);
|
|
|
+ Page<DocumentByRevenueCostVo> page = this.salesRevenueCostPage(dto);
|
|
|
+ List<DocumentByRevenueCostVo> list = page.getRecords();
|
|
|
+ DefaultExportStrategy<DocumentByRevenueCostVo> defaultExportStrategy = new DefaultExportStrategy<>(
|
|
|
+ () -> list, DocumentByRevenueCostVo.class, "销售收入成本数据");
|
|
|
+
|
|
|
+ excelGenerateLogService.generateExcel(ExcelTypeEnum.DOCUMENT_BY_SALES_REVENUE_COST, defaultExportStrategy,
|
|
|
+ DateUtil.formatDate(new Date()) + " 销售收入成本表");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void exportDeliveryOfGoodsExcel(List<Long> idList) {
|
|
|
+ List<String> orderWlnCodeList = getOrderWlnCodeList(idList);
|
|
|
+ List<OutboundOrder> outboundOrderList = getOutboundOrderList(orderWlnCodeList);
|
|
|
+ List<DeliveryOfGoodsVO> deliveryOfGoodsVOList = getDeliveryOfGoodsVOList(outboundOrderList);
|
|
|
+ ExcelUtil.export(response, "货物交接单", "货物交接单明细", deliveryOfGoodsVOList, DeliveryOfGoodsVO.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<Long> getNotSalesOutOfWarehouseOrder(GetDocumentDto dto) {
|
|
|
+ List<OrderInfo> orderList = orderInfoService.list(q -> q.in(OrderInfo::getStatementOfAccountId, getIdList(dto))
|
|
|
+ .eq(OrderInfo::getClassify, OrderClassifyEnum.NO_REASON_ORDER.getKey()));
|
|
|
+ if (orderList.isEmpty()) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ List<Long> orderIds = orderList.stream().map(BaseIdPo::getId).collect(Collectors.toList());
|
|
|
+ return inventoryFinishedOrderService.getNotSalesOutOfWarehouseOrderByIds(orderIds);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void salesOutOfWarehouseByOrderIds(List<Long> idList) {
|
|
|
+ Assert.notEmpty(idList, "订单id不能为空");
|
|
|
+ // 查询在成品库的订单
|
|
|
+ List<InventoryFinishedOrder> list = inventoryFinishedOrderService.list(q -> q
|
|
|
+ .in(InventoryFinishedOrder::getOrderInfoId, idList)
|
|
|
+ .eq(InventoryFinishedOrder::getStatus, StatusConstant.YES));
|
|
|
+ List<Long> orderIds = list.stream().map(InventoryFinishedOrder::getOrderInfoId).collect(Collectors.toList());
|
|
|
+ // 筛选出不在库订单
|
|
|
+ idList.removeAll(orderIds);
|
|
|
+ if (!idList.isEmpty()) {
|
|
|
+ List<OrderInfo> orderInfoList = orderInfoService.listByIds(idList);
|
|
|
+ String orderCodes = orderInfoList.stream().map(OrderInfo::getWlnCode).collect(Collectors.joining(","));
|
|
|
+ throw new ServiceException("订单:" + orderCodes + "未在成品库中");
|
|
|
+ }
|
|
|
+ inventoryFinishedService.saleOutOfWarehouse(orderIds);
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<Long> getIdList(GetDocumentDto dto) {
|
|
|
+
|
|
|
+ String idGroupConcat = dto.getIdGroupConcat();
|
|
|
+
|
|
|
+ List<Long> idList = Arrays.stream(idGroupConcat.split(","))
|
|
|
+ .map(Convert::toLong)
|
|
|
+ .distinct()
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ Assert.notEmpty(idList, "对账单id集合不能为空");
|
|
|
+
|
|
|
+ return idList;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取万里牛订单编号列表
|
|
|
+ *
|
|
|
+ * @param idList 对账单id列表
|
|
|
+ * @return 万里牛订单编号列表
|
|
|
+ */
|
|
|
+ private List<String> getOrderWlnCodeList(List<Long> idList) {
|
|
|
+ if (idList.isEmpty()) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ List<OrderInfo> list = orderInfoService.list(q -> q.in(OrderInfo::getStatementOfAccountId, idList));
|
|
|
+ return list.stream().map(OrderInfo::getWlnCode).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取出库单列表
|
|
|
+ *
|
|
|
+ * @param orderWlnCodeList 万里牛订单编号列表
|
|
|
+ * @return 出库单列表
|
|
|
+ */
|
|
|
+ private List<OutboundOrder> getOutboundOrderList(List<String> orderWlnCodeList) {
|
|
|
+ if (orderWlnCodeList.isEmpty()) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ return outboundOrderService.list(q -> q.in(OutboundOrder::getOrderWlnCode, orderWlnCodeList));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取货物交接单数据列表
|
|
|
+ *
|
|
|
+ * @param outboundOrderList 出库单列表
|
|
|
+ * @return 货物交接单数据列表
|
|
|
+ */
|
|
|
+ private List<DeliveryOfGoodsVO> getDeliveryOfGoodsVOList(List<OutboundOrder> outboundOrderList) {
|
|
|
+ if (outboundOrderList.isEmpty()) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+
|
|
|
+ List<String> skuSpecCodeList = outboundOrderList.stream().map(OutboundOrder::getSkuSpecCode).distinct().collect(Collectors.toList());
|
|
|
+ Map<String, String> map = skuSpecService.mapKV(SkuSpec::getCode, SkuSpec::getName, q -> q.in(SkuSpec::getCode, skuSpecCodeList));
|
|
|
+
|
|
|
+ return outboundOrderList.stream()
|
|
|
+ .map(item -> {
|
|
|
+ DeliveryOfGoodsVO deliveryOfGoodsVO = new DeliveryOfGoodsVO();
|
|
|
+ deliveryOfGoodsVO.setReceiptNumber(item.getCode());
|
|
|
+ deliveryOfGoodsVO.setBusinessDate(item.getOutboundTime());
|
|
|
+ deliveryOfGoodsVO.setWarehouse(getWarehouseName(item.getStorageCode()));
|
|
|
+ deliveryOfGoodsVO.setSpec(map.get(item.getSkuSpecCode()));
|
|
|
+ deliveryOfGoodsVO.setOutboundQuantity(item.getQuantity());
|
|
|
+ deliveryOfGoodsVO.setOrderCode(item.getOrderCode());
|
|
|
+ deliveryOfGoodsVO.setOrderWlnCode(item.getOrderWlnCode());
|
|
|
+ deliveryOfGoodsVO.setExpress(item.getExpress());
|
|
|
+ return deliveryOfGoodsVO;
|
|
|
+ })
|
|
|
+ .sorted(Comparator.comparing(DeliveryOfGoodsVO::getBusinessDate))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通过仓库编码获取仓库名称
|
|
|
+ *
|
|
|
+ * @param code 仓库编码
|
|
|
+ * @return 仓库名称
|
|
|
+ */
|
|
|
+ private String getWarehouseName(String code) {
|
|
|
+ if (Objects.equals(code, "T007")) {
|
|
|
+ return "胜德体育仓-佰卓";
|
|
|
+ }
|
|
|
+ if (Objects.equals(code, "B012")) {
|
|
|
+ return "胜德体育仓-A9";
|
|
|
+ }
|
|
|
+ if (Objects.equals(code, "B013")) {
|
|
|
+ return "胜德体育仓-A1";
|
|
|
+ }
|
|
|
+ if (Objects.equals(code, "B014")) {
|
|
|
+ return "胜德体育仓-A8";
|
|
|
+ }
|
|
|
+
|
|
|
+ return code;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|