This commit is contained in:
dzc committed 2025-10-20 17:32:42 +08:00
commit 3672f9b5b4
34 files changed
+127 -140

No files matched your search

+55
View File
@@ -0,0 +1,55 @@
# 统一行尾符处理
* text=auto
# Java 源码文件使用 LF
*.java text eol=lf
*.kt text eol=lf
*.kts text eol=lf
*.groovy text eol=lf
# XML 配置文件使用 LF
*.xml text eol=lf
*.xsd text eol=lf
# 属性文件使用 LF
*.properties text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
# SQL 文件使用 LF
*.sql text eol=lf
# 脚本文件使用 LF
*.sh text eol=lf
*.py text eol=lf
# Web 文件使用 LF
*.js text eol=lf
*.html text eol=lf
*.css text eol=lf
*.json text eol=lf
# Markdown 文件使用 LF
*.md text eol=lf
# Windows 批处理文件使用 CRLF
*.bat text eol=crlf
*.cmd text eol=crlf
# 二进制文件
*.jar binary
*.war binary
*.ear binary
*.zip binary
*.tar.gz binary
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.pdf binary
*.xls binary
*.xlsx binary
*.doc binary
*.docx binary
@@ -38,6 +38,12 @@ public class InventoryDetailQueryDTO {
/**
* 单据类型:1=采购申请,2=采购订单,3=采购入库,4=采购退货,5=零售出库,6=零售退货,7=库存盘点
*/
@Schema(description="单据类型:3=采购入库,6=零售退货")
@Schema(description="单据类型:3=采购入库,4=采购退货,6=零售退货")
private String inventoryType;
/**
* 单据类型(多个):支持逗号分隔,如 "4,6"
*/
@Schema(description="单据类型(多个),逗号分隔,如:4,6")
private String inventoryTypes;
}
@@ -126,3 +126,4 @@ public class InventoryReportExcelDTO {
private LocalDate firstPurchaseDate;
}
@@ -37,3 +37,4 @@ public class InventoryReportQueryDTO {
private Boolean onlyChanged;
}
@@ -73,3 +73,4 @@ public class ProfitReportExcelDTO {
private Integer salesCount;
}
@@ -40,3 +40,4 @@ public class ProfitReportQueryDTO {
private Boolean onlyWithSales;
}
@@ -73,3 +73,6 @@ public class SalesReportExcelDTO {
private BigDecimal actualSalesAmount;
}
@@ -34,3 +34,4 @@ public class SalesReportQueryDTO {
private String sortBy;
}
@@ -70,3 +70,6 @@ public class StocktakeReportExcelDTO {
private String remark;
}
@@ -37,3 +37,6 @@ public class StocktakeReportQueryDTO {
private String diffType;
}
@@ -98,3 +98,4 @@ public class InventoryReportVO {
private LocalDate firstPurchaseDate;
}
@@ -58,3 +58,4 @@ public class ProfitReportVO {
private Integer salesCount;
}
@@ -58,3 +58,6 @@ public class SalesReportVO {
private BigDecimal actualSalesAmount;
}
@@ -56,3 +56,6 @@ public class StocktakeReportVO {
private String remark;
}
@@ -633,3 +633,6 @@ const getProfitColor = (margin) => {
|------|------|------|------|
| 1.0 | 2025-10-16 | 初始版本,实现所有核心报表功能 | pjcloud |
@@ -90,12 +90,12 @@ public class ReportController {
* @param inventoryDetailQueryDTO 查询条件
* @return 分页结果
*/
@Operation(summary = "分页获取退货单明细", description = "退货单明细(inventory_type=6),支持日期区间查询")
@Operation(summary = "分页获取退货单明细", description = "退货单明细(inventory_type=4采购退货,6零售退货),支持日期区间查询")
@GetMapping("/returnDetail/page")
@PreAuthorize("@pms.hasPermission('supermarket_report_view')")
public R<Object> getReturnDetailPage(@ParameterObject Page<?> page, @ParameterObject InventoryDetailQueryDTO inventoryDetailQueryDTO) {
// 固定查询退货单类型:inventory_type=6(零售退货)
inventoryDetailQueryDTO.setInventoryType("6");
// 查询退货单类型:inventory_type=4(采购退货)或 6(零售退货)
inventoryDetailQueryDTO.setInventoryTypes("4,6");
return R.ok(smErpInventoryRecordsService.getInventoryDetailPage(page, inventoryDetailQueryDTO));
}
@@ -110,8 +110,8 @@ public class ReportController {
@SysLog("导出退货单明细")
@PreAuthorize("@pms.hasPermission('supermarket_report_export')")
public List<InventoryDetailExcelDTO> exportReturnDetail(@ParameterObject InventoryDetailQueryDTO inventoryDetailQueryDTO) {
// 固定查询退货单类型:inventory_type=6(零售退货)
inventoryDetailQueryDTO.setInventoryType("6");
// 查询退货单类型:inventory_type=4(采购退货)或 6(零售退货)
inventoryDetailQueryDTO.setInventoryTypes("4,6");
return smErpInventoryRecordsService.exportInventoryDetail(inventoryDetailQueryDTO);
}
@@ -38,3 +38,4 @@ public interface InventoryReportMapper {
List<InventoryReportVO> selectInventoryReportList(@Param("param") InventoryReportQueryDTO queryDTO, @Param("dataScope") DataScope dataScope);
}
@@ -38,3 +38,4 @@ public interface ProfitReportMapper {
List<ProfitReportVO> selectProfitReportList(@Param("param") ProfitReportQueryDTO queryDTO, @Param("dataScope") DataScope dataScope);
}
@@ -38,3 +38,5 @@ public interface SalesReportMapper {
List<SalesReportVO> selectSalesReportList(@Param("param") SalesReportQueryDTO queryDTO, @Param("dataScope") DataScope dataScope);
}
@@ -38,3 +38,6 @@ public interface StocktakeReportMapper {
List<StocktakeReportVO> selectStocktakeReportList(@Param("param") StocktakeReportQueryDTO queryDTO, @Param("dataScope") DataScope dataScope);
}
@@ -41,3 +41,4 @@ public interface InventoryReportService {
List<InventoryReportExcelDTO> exportExcel(InventoryReportQueryDTO queryDTO);
}
@@ -41,3 +41,4 @@ public interface ProfitReportService {
List<ProfitReportExcelDTO> exportExcel(ProfitReportQueryDTO queryDTO);
}
@@ -41,3 +41,6 @@ public interface SalesReportService {
List<SalesReportExcelDTO> exportExcel(SalesReportQueryDTO queryDTO);
}
@@ -41,3 +41,6 @@ public interface StocktakeReportService {
List<StocktakeReportExcelDTO> exportExcel(StocktakeReportQueryDTO queryDTO);
}
@@ -49,3 +49,4 @@ public class InventoryReportServiceImpl implements InventoryReportService {
}
}
@@ -49,3 +49,4 @@ public class ProfitReportServiceImpl implements ProfitReportService {
}
}
@@ -49,3 +49,6 @@ public class SalesReportServiceImpl implements SalesReportService {
}
}
@@ -49,3 +49,6 @@ public class StocktakeReportServiceImpl implements StocktakeReportService {
}
}
@@ -56,8 +56,6 @@
base.package_num AS package_num,
base.purchase_price / 100.0 AS purchase_price,
base.retail_price / 100.0 AS retail_price,
-- 采购入库数量和金额 (inventory_type = 3)
COALESCE(SUM(CASE WHEN r.inventory_type = '3' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
@@ -66,8 +64,6 @@
END
END), 0) AS purchase_in_qty,
COALESCE(SUM(CASE WHEN r.inventory_type = '3' THEN item.total_amount END), 0) / 100.0 AS purchase_in_amount,
-- 采购退货数量和金额 (inventory_type = 4)
COALESCE(SUM(CASE WHEN r.inventory_type = '4' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
@@ -76,8 +72,6 @@
END
END), 0) AS purchase_return_qty,
COALESCE(SUM(CASE WHEN r.inventory_type = '4' THEN item.total_amount END), 0) / 100.0 AS purchase_return_amount,
-- 销售数量和金额 (inventory_type = 5)
COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
@@ -86,8 +80,6 @@
END
END), 0) AS sales_qty,
COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN item.total_amount END), 0) / 100.0 AS sales_amount,
-- 销售退货数量和金额 (inventory_type = 6)
COALESCE(SUM(CASE WHEN r.inventory_type = '6' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
@@ -96,8 +88,6 @@
END
END), 0) AS sales_return_qty,
COALESCE(SUM(CASE WHEN r.inventory_type = '6' THEN item.total_amount END), 0) / 100.0 AS sales_return_amount,
-- 实际销售数量 = 销售数量 - 销售退货数量
COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
@@ -111,12 +101,8 @@
ELSE item.quantity
END
END), 0) AS actual_sales_qty,
-- 实际销售金额 = 销售金额 - 销售退货金额
COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN item.total_amount END), 0) / 100.0
- COALESCE(SUM(CASE WHEN r.inventory_type = '6' THEN item.total_amount END), 0) / 100.0 AS actual_sales_amount,
-- 销售成本 = 实际销售数量 × 参考进价
(COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
@@ -130,17 +116,9 @@
ELSE item.quantity
END
END), 0)) * COALESCE(base.purchase_price / 100.0, 0) AS sales_cost,
-- 期末库存数量 = 当前库存
COALESCE(stock.current_stock, 0) AS closing_qty,
-- 期末库存金额 = 期末数量 × 参考进价
COALESCE(stock.current_stock, 0) * COALESCE(base.purchase_price / 100.0, 0) AS closing_amount,
-- 期末库存售额 = 期末数量 × 零售价
COALESCE(stock.current_stock, 0) * COALESCE(base.retail_price / 100.0, 0) AS closing_retail_amount,
-- 销售毛利 = 实际销售金额 - 销售成本
(COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN item.total_amount END), 0) / 100.0
- COALESCE(SUM(CASE WHEN r.inventory_type = '6' THEN item.total_amount END), 0) / 100.0)
- ((COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN
@@ -156,71 +134,9 @@
ELSE item.quantity
END
END), 0)) * COALESCE(base.purchase_price / 100.0, 0)) AS gross_profit,
-- 首次进货日
MIN(CASE WHEN r.inventory_type = '3' THEN r.inventory_date END) AS first_purchase_date,
-- 期初库存 = 期末库存 - 采购入库 + 采购退货 + 销售 - 销售退货
COALESCE(stock.current_stock, 0)
- COALESCE(SUM(CASE WHEN r.inventory_type = '3' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
THEN item.quantity * u.package_num
ELSE item.quantity
END
END), 0)
+ COALESCE(SUM(CASE WHEN r.inventory_type = '4' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
THEN item.quantity * u.package_num
ELSE item.quantity
END
END), 0)
+ COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
THEN item.quantity * u.package_num
ELSE item.quantity
END
END), 0)
- COALESCE(SUM(CASE WHEN r.inventory_type = '6' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
THEN item.quantity * u.package_num
ELSE item.quantity
END
END), 0) AS opening_qty,
-- 期初金额 = 期初库存 × 参考进价
(COALESCE(stock.current_stock, 0)
- COALESCE(SUM(CASE WHEN r.inventory_type = '3' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
THEN item.quantity * u.package_num
ELSE item.quantity
END
END), 0)
+ COALESCE(SUM(CASE WHEN r.inventory_type = '4' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
THEN item.quantity * u.package_num
ELSE item.quantity
END
END), 0)
+ COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
THEN item.quantity * u.package_num
ELSE item.quantity
END
END), 0)
- COALESCE(SUM(CASE WHEN r.inventory_type = '6' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
THEN item.quantity * u.package_num
ELSE item.quantity
END
END), 0)) * COALESCE(base.purchase_price / 100.0, 0) AS opening_amount
COALESCE(stock.base_stock, 0) AS opening_qty,
COALESCE(stock.base_stock, 0) * COALESCE(base.purchase_price / 100.0, 0) AS opening_amount
FROM sm_erp_spu spu
LEFT JOIN sm_erp_stock stock ON stock.erp_spu_id = spu.id
@@ -274,4 +190,3 @@
</select>
</mapper>
@@ -24,21 +24,18 @@
spu.category_id,
cat.name AS category_name,
base.unit AS unit,
-- 账面数量(折算基础单位)
COALESCE(SUM(
CASE WHEN item.account_number IS NOT NULL THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id AND u.package_num IS NOT NULL AND u.package_num > 0
THEN item.account_number * u.package_num ELSE item.account_number END
END
), 0) AS book_qty,
-- 实盘数量(折算基础单位)
COALESCE(SUM(
CASE WHEN item.real_number IS NOT NULL THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id AND u.package_num IS NOT NULL AND u.package_num > 0
THEN item.real_number * u.package_num ELSE item.real_number END
END
), 0) AS physical_qty,
-- 差异数量(实盘-账面)
COALESCE(SUM(
(CASE WHEN item.real_number IS NOT NULL THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id AND u.package_num IS NOT NULL AND u.package_num > 0
@@ -50,7 +47,6 @@
THEN item.account_number * u.package_num ELSE item.account_number END
END)
), 0) AS diff_qty,
-- 差异金额(元)= 差异数量 * 实际单价(元)
COALESCE(SUM(
(CASE WHEN item.real_price IS NOT NULL THEN item.real_price ELSE 0 END) *
(
@@ -72,7 +68,6 @@
LEFT JOIN sm_erp_unit u ON u.id = item.unit_id
LEFT JOIN sm_erp_category cat ON cat.id = spu.category_id
<where>
-- 仅盘点单据
r.inventory_type = '7'
<if test="param.startTime != null and param.endTime != null">
AND r.create_time &gt;= #{param.startTime}
@@ -38,8 +38,6 @@
cat.name AS category_name,
base.spec AS spec,
base.unit AS unit,
-- 销售数量 (inventory_type = 5 零售出库 - inventory_type = 6 零售退货)
COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
@@ -53,15 +51,9 @@
ELSE item.quantity
END
END), 0) AS sales_qty,
-- 销售金额
COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN item.total_amount END), 0) / 100.0
- COALESCE(SUM(CASE WHEN r.inventory_type = '6' THEN item.total_amount END), 0) / 100.0 AS sales_amount,
-- 成本单价 = 商品参考进价
COALESCE(base.purchase_price / 100.0, 0) AS cost_price,
-- 销售单价 = 销售金额 / 销售数量
CASE WHEN (COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
@@ -92,8 +84,6 @@
END), 0))
ELSE 0
END AS sales_price,
-- 销售成本 = 销售数量 × 成本单价
(COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
@@ -107,8 +97,6 @@
ELSE item.quantity
END
END), 0)) * COALESCE(base.purchase_price / 100.0, 0) AS sales_cost,
-- 销售毛利 = 销售金额 - 销售成本
(COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN item.total_amount END), 0) / 100.0
- COALESCE(SUM(CASE WHEN r.inventory_type = '6' THEN item.total_amount END), 0) / 100.0)
- ((COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN
@@ -124,8 +112,6 @@
ELSE item.quantity
END
END), 0)) * COALESCE(base.purchase_price / 100.0, 0)) AS gross_profit,
-- 毛利率 = (销售毛利 / 销售金额) × 100%
CASE WHEN (COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN item.total_amount END), 0) / 100.0
- COALESCE(SUM(CASE WHEN r.inventory_type = '6' THEN item.total_amount END), 0) / 100.0) > 0
THEN ((COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN item.total_amount END), 0) / 100.0
@@ -147,8 +133,6 @@
- COALESCE(SUM(CASE WHEN r.inventory_type = '6' THEN item.total_amount END), 0) / 100.0) * 100
ELSE 0
END AS profit_margin,
-- 销售笔数
COUNT(DISTINCT CASE WHEN r.inventory_type IN ('5', '6') THEN r.id END) AS sales_count
FROM sm_erp_spu spu
@@ -223,3 +207,4 @@
</mapper>
@@ -35,8 +35,6 @@
cat.name AS category_name,
base.spec AS spec,
base.unit AS unit,
-- 销售数量 (inventory_type = 5)
COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
@@ -44,11 +42,7 @@
ELSE item.quantity
END
END), 0) AS sales_qty,
-- 销售金额
COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN item.total_amount END), 0) / 100.0 AS sales_amount,
-- 退货数量 (inventory_type = 6)
COALESCE(SUM(CASE WHEN r.inventory_type = '6' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
@@ -56,11 +50,7 @@
ELSE item.quantity
END
END), 0) AS return_qty,
-- 退货金额
COALESCE(SUM(CASE WHEN r.inventory_type = '6' THEN item.total_amount END), 0) / 100.0 AS return_amount,
-- 实际销售数量 = 销售数量 - 退货数量
COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
@@ -74,12 +64,8 @@
ELSE item.quantity
END
END), 0) AS actual_sales_qty,
-- 实际销售金额 = 销售金额 - 退货金额
COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN item.total_amount END), 0) / 100.0
- COALESCE(SUM(CASE WHEN r.inventory_type = '6' THEN item.total_amount END), 0) / 100.0 AS actual_sales_amount,
-- 销售单价 = 销售金额 / 销售数量
CASE WHEN COALESCE(SUM(CASE WHEN r.inventory_type = '5' THEN
CASE WHEN u.id IS NOT NULL AND base.id IS NOT NULL AND u.id != base.id
AND u.package_num IS NOT NULL AND u.package_num > 0
@@ -97,8 +83,6 @@
END), 0)
ELSE 0
END AS sales_price,
-- 销售笔数
COUNT(DISTINCT CASE WHEN r.inventory_type IN ('5', '6') THEN r.id END) AS sales_count
FROM sm_erp_spu spu
@@ -159,3 +143,4 @@
</mapper>
@@ -63,7 +63,13 @@
<if test="inventoryDetailQueryDTO.orderType != null and inventoryDetailQueryDTO.orderType != ''">
and r.order_type = #{inventoryDetailQueryDTO.orderType}
</if>
<if test="inventoryDetailQueryDTO.inventoryType != null and inventoryDetailQueryDTO.inventoryType != ''">
<if test="inventoryDetailQueryDTO.inventoryTypes != null and inventoryDetailQueryDTO.inventoryTypes != ''">
and r.inventory_type IN
<foreach collection="inventoryDetailQueryDTO.inventoryTypes.split(',')" item="type" open="(" separator="," close=")">
#{type}
</foreach>
</if>
<if test="inventoryDetailQueryDTO.inventoryType != null and inventoryDetailQueryDTO.inventoryType != '' and (inventoryDetailQueryDTO.inventoryTypes == null or inventoryDetailQueryDTO.inventoryTypes == '')">
and r.inventory_type = #{inventoryDetailQueryDTO.inventoryType}
</if>
<if test="inventoryDetailQueryDTO.startDate != null">
@@ -37,19 +37,10 @@
cat.name AS category_name,
base.spec AS spec,
base.unit AS unit,
-- 账面数量(这里假设item表中有book_qty字段,如果没有则使用quantity作为账面数量)
COALESCE(item.quantity, 0) AS book_qty,
-- 实盘数量(这里假设实盘数量保存在某个字段,需要根据实际情况调整)
COALESCE(item.quantity, 0) AS physical_qty,
-- 差异数量 = 实盘 - 账面(这里简化处理,实际需要根据业务逻辑调整)
0 AS diff_qty,
-- 差异金额 = 差异数量 × 成本价
0 AS diff_amount,
r.remark
FROM sm_erp_inventory_records r
@@ -109,3 +100,4 @@
</mapper>