库存报表

最近接手WMS系统库存统计的工作,整理了一下WM现有的库存统计方式。

1 库存报表相关的表

1.1 库存表warehouse_inventory

按照仓库+货主+库位+sku+品质+批次的维度,记录每个sku的实时库存:总库存、可用库存、占用库存、冻结库存。

(当SKU品质是次品时,库存存放在冻结库存;良品则存放在可用库存。)

CREATE TABLE `wms`.`warehouse_inventory` (
`id` bigint(64) NOT NULL COMMENT '库存表',
`store_id` bigint(64) NULL DEFAULT NULL COMMENT '仓库id',
`location_id` bigint(64) NULL DEFAULT NULL COMMENT '库位id',
`sku_id` bigint(64) NULL DEFAULT NULL COMMENT 'skuid',
`total_store` decimal(12,2) NULL DEFAULT NULL COMMENT '总共库存',
`apply_store` decimal(12,2) NULL DEFAULT NULL COMMENT '可用库存',
`occ_store` decimal(12,2) NULL DEFAULT NULL COMMENT '占用库存',
`frozen_store` decimal(12,2) NULL DEFAULT NULL COMMENT '冻结库存',
`customer_id` bigint(64) NULL DEFAULT NULL COMMENT '货主id',
`quality_type` tinyint(1) NULL DEFAULT NULL COMMENT '质量状态',
`batch_no` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '批次号',
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`create_user` bigint(64) NULL DEFAULT NULL,
`update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
`update_user` bigint(64) NULL DEFAULT NULL,
PRIMARY KEY (`id`) 
)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_general_ci;

1.2 库存日志表warehouse_inventory_log

记录操作库存的变化,4种库存*3种变化=12。

4种库存:总库存、可用库存、占用库存、冻结库存;

3种变化:变化前、变化、变化后。

当涉及到库存变化操作时,例如上架、入库、出库、占用库存、释放库存、确认拣货移到过渡库位、盘盈/盘亏,都需要记录库存日志。

按照货主+仓库+sku维度,记录每个SKU的四种库存的三种数量,还记录了操作类型及涉及的单据。

CREATE TABLE `wms`.`warehouse_inventory_log` (
`id` bigint(64) NOT NULL COMMENT '库存日志表',
`customer_id` bigint(64) NULL DEFAULT NULL COMMENT '货主id',
`customer_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '货主姓名',
`store_id` bigint(64) NULL DEFAULT NULL COMMENT '仓库id',
`store_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '仓库名称',
`type` tinyint(1) NULL DEFAULT NULL COMMENT '操作类型(1:增加、0:减少,2:不变)WarehouseInventoryLogTypeEnum',
`change_before_total` decimal(12,2) NULL DEFAULT NULL COMMENT '变化前总库存',
`change_after_total` decimal(12,2) NULL DEFAULT NULL COMMENT '变化后总库存',
`change_count_total` decimal(12,2) NULL DEFAULT NULL COMMENT '变化总库存',
`change_before_apply` decimal(12,2) NULL DEFAULT NULL COMMENT '变化前可用库存',
`change_after_apply` decimal(12,2) NULL DEFAULT NULL COMMENT '变化后可用库存',
`change_count_apply` decimal(12,2) NULL DEFAULT NULL COMMENT '变化可用库存',
`change_before_occ` decimal(12,2) NULL DEFAULT NULL COMMENT '变化前用库存',
`change_after_occ` decimal(12,2) NULL DEFAULT NULL COMMENT '变化后占用库存',
`change_count_occ` decimal(12,2) NULL DEFAULT NULL COMMENT '变化占用库存',
`change_before_frozen` decimal(12,2) NULL DEFAULT NULL COMMENT '变化前冻结库存',
`change_after_frozen` decimal(12,2) NULL DEFAULT NULL COMMENT '变化后冻结库存',
`change_count_frozen` decimal(12,2) NULL DEFAULT NULL COMMENT '变化冻结库存',
`sku_id` bigint(64) NULL DEFAULT NULL COMMENT 'sku',
`account_type` tinyint(1) NULL DEFAULT NULL COMMENT '业务类型 WarehouseInventoryLogAccountTypeEnum',
`account_id` bigint(64) NULL DEFAULT NULL COMMENT '业务住建',
`create_time` timestamp NULL DEFAULT NULL,
`order_create_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`) 
)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_general_ci;

操作类型account_type:

public enum WarehouseInventoryLogAccountTypeEnum {
    DEMO(0,"入库单"),
    INVOICE(1,"发运订单"),
    ASSIGNPICK(2,"捡货单占用库存"),
    RELEASEPICK(3,"捡货单释放库存"),
    RECEIVE_FREEZE(4,"收货冻结暂存区"),
    ONSHELF(5,"上架单"),
    RECEIVE_UNFROZEN(6,"收货解冻暂存区"),
    RECEIVE_CANCEL(7,"取消收货"),
    CHECK_DIFF(8,"盘点单"),;
}

操作类型type: 1- 增加,0-减少,2-不变。

type=1的操作有:采购入库,收货冻结暂存区,盘盈

type=0的操作有:发运交接,盘亏

type=2的操作:库内操作,例如占用库存,释放库存

1.3 库存报表warehouse_inventory_report

按照仓库+货主+sku的维度,记录每个SKU的期初库存、入库数、出库数、结存数。

report_time是统计时间,现在WMS每天记录库存数据。

CREATE TABLE `wms`.`warehouse_inventory_report` (
`id` bigint(64) NOT NULL COMMENT '库存报表',
`store_id` bigint(64) NULL DEFAULT NULL COMMENT '仓库id',
`customer_id` bigint(64) NULL DEFAULT NULL COMMENT '货主id',
`sku_id` bigint(64) NULL DEFAULT NULL COMMENT 'skuid',
`category_id` bigint(64) NULL DEFAULT NULL COMMENT '分类id',
`start_num` int(12) NOT NULL COMMENT '期初库存',
`add_num` int(12) NULL DEFAULT NULL COMMENT '入库',
`sub_num` int(12) NULL DEFAULT NULL COMMENT '出库',
`end_num` int(12) NULL DEFAULT NULL COMMENT '结存',
`report_time` datetime NULL DEFAULT NULL COMMENT '报表时间',
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`) 
)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_general_ci;

2. 库存统计

2.1 两种统计方式

第一种、定时任务:每天凌晨一点执行定时任务,统计前一天的SKU期初、入库、出库、结存数量。

删除历史数据,重新统计。

第二种手动执行任务。输入日期,例如输入2019-10-10,或者2019-10-10,2019-10-15,统计指定日期的SKU期初、入库、出库、结存数量。

统计后的数据保存在warehouse_inventory_report。

这样库存报表直接查询warehouse_inventory_report,提升报表的加载速度。

2.2 从库存日志表warehouse_inventory_log查询出一天的期初、入库、出库、结存。

不统计订单取消的出入库数量。

因为入库有取消功能,(出库单没有取消),所以这里account_type=7,是入库取消的库存日志,

当account_type=4采购入库时,需要判断对应的入库单是否删除了,删除了不能统计。

统计2019-09-21这天的数据。

 SELECT `store_id`,`customer_id`,`sku_id`,
        SUM(IF (t.type=1, t.change_count_total,0) ) AS `add_num`,
        SUM(IF (t.type=0, t.change_count_total,0) ) AS `sub_num`,
        SUBSTRING_INDEX(GROUP_CONCAT( change_before_total ORDER BY order_create_time,id), ',',1) AS start_num,
        SUBSTRING_INDEX(GROUP_CONCAT( change_after_total ORDER BY order_create_time,id), ',',-1) AS end_num,
        `order_create_time` AS create_time
        FROM
        (SELECT *  FROM warehouse_inventory_log
        where
            type in (0,1) and account_type!=7
            and id in (
            select id from warehouse_inventory_log where account_type=4 and EXISTS(select 1 from receive_main where id=account_id and deleted=0 )
            union
            select id  from warehouse_inventory_log where account_type!=4
            )
            and order_create_time >= '2019-09-21 00:00:00' and order_create_time <= '2019-09-21 23:59:59'
        ORDER BY order_create_time) t
        GROUP BY  store_id, sku_id,customer_id

2.3 将2.1查询出来的结果,保存到库存报表warehouse_inventory_report。

3、报表展示

3.1 即时库存报表

后台sql查询:

SELECT
`id`,
`store_id`,
`location_id`,
`sku_id`,
ifnull( sum( `total_store` ), 0 ) total_store,
ifnull( sum( `apply_store` ), 0 ) apply_store,
ifnull( sum( `occ_store` ), 0 ) occ_store,
ifnull( sum( `frozen_store` ), 0 ) frozen_store,
`customer_id`,
`quality_type`,
`batch_no`,
`create_time`,
`create_user`,
`update_time`,
`update_user` 
FROM
	warehouse_inventory 
WHERE
	store_id = 1 
	AND total_store > 0 
GROUP BY
	store_id,
	customer_id,
	sku_id 
ORDER BY
	store_id,
	customer_id 
	LIMIT 20

 

3.2   选中一条即时库存,点击“查看详情”

 

后台sql查询:

SELECT
	`id`,
	`store_id`,
	`location_id`,
	`sku_id`,
	ifnull( sum( `total_store` ), 0 ) total_store,
	ifnull( sum( `apply_store` ), 0 ) apply_store,
	ifnull( sum( `occ_store` ), 0 ) occ_store,
	ifnull( sum( `frozen_store` ), 0 ) frozen_store,
	`customer_id`,
	`quality_type`,
	`batch_no`,
	`create_time`,
	`create_user`,
	`update_time`,
	`update_user` 
FROM
	warehouse_inventory 
WHERE
	store_id = 1 
	AND sku_id = 370495141103906816 
	AND customer_id = 353104904627421184 
GROUP BY
	location_id,
	quality_type 
ORDER BY
	store_id,
	customer_id 
	LIMIT 20;

 

3.3 收发汇总表查询

后台sql查询: 

SELECT
	`id`,
	`store_id`,
	`customer_id`,
	`sku_id`,
	SUM( add_num ) AS `add_num`,
	SUM( `sub_num` ) AS sub_num,
	SUBSTRING_INDEX( GROUP_CONCAT( start_num ORDER BY report_time ), ',', 1 ) AS start_num,
	SUBSTRING_INDEX( GROUP_CONCAT( end_num ORDER BY report_time ), ',',- 1 ) AS end_num,
	`report_time`,
	`create_time` 
FROM
	( SELECT * FROM warehouse_inventory_report WHERE store_id = 393791072410554368 AND report_time >= '2019-7-26' AND report_time <= '2019-10-24' ORDER BY report_time ) a 
GROUP BY
	customer_id,
	store_id,
	sku_id 
	LIMIT 20;

统计一个仓库下,某个货主,‘2019-7-26’和‘2019-10-24’这段时间的所有sku的期初、入库、出库、结存数。

期初:该sku的第一条库存报表的期初值。

入库:该sku的库存报表所有入库数之和。

出库:该sku的库存报表所有出库数之和。

结存:该sku的最后一条库存报表的结存值。

最后期望结果 期初+入库-出库=结存。

3.4 收发汇总明细查询。

选中收货汇总的一条记录,点击明细表,就可以查询所有的出入明细记录。

入库数:11;出库数:3.

后台sql查询:

SELECT
	DATE_FORMAT( occTime, '%Y-%m-%d %H:%i:%S' ) occTime,
	temp.`store_id` AS storeId,
	temp.`account_id` AS accountId,
	accountType,
	inOrOut,
	wmsBillNo,
	cusBillNo,
IF
	( cusBillNo IS NULL OR cusBillNo = '', wmsBillNo, cusBillNo ) orderNo,
	wlog.`sku_id` AS skuId,
	wlog.`change_count_total` AS packageCount,
	temp.type type 
FROM
	( SELECT customer_id, store_id, account_id, account_type, type FROM warehouse_inventory_log l GROUP BY customer_id, store_id, account_id, account_type, type ) temp
	INNER JOIN warehouse_inventory_log wlog ON temp.account_id = wlog.`account_id` 
	AND temp.account_type = wlog.`account_type`
	INNER JOIN (
	SELECT
		t1.gmt_create occTime,
		t1.id accountId,
		'收' inOrOut,
		( CASE asn_main.type WHEN 0 THEN '采购入库' WHEN 1 THEN '生产入库' WHEN 2 THEN '销退入库' WHEN 3 THEN '调拨入库' ELSE '其他' END ) accountType,
		asn_main.NO wmsBillNo,
		asn_main.customer_order_no AS cusBillNo 
	FROM
		receive_main t1
		INNER JOIN asn_main ON asn_main.id = t1.asn_id 
	WHERE
		asn_main.deleted = 0 
		AND t1.deleted = 0 
		AND t1.id IN ( SELECT account_id FROM warehouse_inventory_log t2 WHERE account_type = 4 ) UNION
	SELECT
		t1.gmt_create occTime,
		t1.id accountId,
		'发' inOrOut,
		( CASE t1.business_type WHEN 0 THEN '销售出库' WHEN 1 THEN '仓间调拨' WHEN 2 THEN '退供应商' ELSE '其他' END ) accountType,
		t1.order_no wmsBillNo,
		t1.customer_no cusBillNo 
	FROM
		send_order_main t1 
	WHERE
		t1.deleted = 0 UNION
	SELECT
		t1.create_time occTime,
		t1.id accountId,
		( CASE t1.diff_type WHEN 0 THEN '发' WHEN 1 THEN '收' ELSE '其他' END ) inOrOut,
		( CASE t1.diff_type WHEN 0 THEN '盘亏' WHEN 1 THEN '盘盈' ELSE '其他' END ) accountType,
		t1.check_diff_no wmsBillNo,
		'' cusBillNo 
	FROM
		check_diff t1 
	WHERE
		t1.deleted = 0 
	AND t1.id IN ( SELECT account_id FROM warehouse_inventory_log t2 )) temp1 ON temp1.accountId = wlog.account_id 
WHERE
	temp.type IN ( 0, 1 ) 
	AND temp.`store_id` = 1 
	AND sku_id IN ( 370495141103906816 ) 
	AND wlog.customer_id = 353104904627421184 
	AND wlog.order_create_time >= '2019-07-26 00:00:00' 
	AND wlog.order_create_time <= '2019-10-24 23:59:59' 
ORDER BY
	occTime DESC,
	orderNo 
	LIMIT 20;

后面要过滤掉已经取消的订单。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值