公司最近也在开发库存系统,就拿业界比较成功的金蝶来分析学习,提高自身的业务水平 库存系统最重要的就是入库与出库,成本与利润的计算java
入库操做核心流程 mysql
出入库操做参与的角色能够在金蝶系统里的核算项目里看到,这个角色很是重要,涉及到后面的表结构设计 算法
在计量单位里能够管理物料的单位 sql
还有一个发起出入库方的角色(通常是一个公司发起出入库),这里出入库都是做者,表结构上暂时忽略学习
打开仓库管理->采购入库/销售出库,拿采购入库举例 ui
能够看到入库单核心的字段有这些编码
在金蝶的新增物料界面,能够查看当前系统支持的计价方法 spa
目前业界普遍使用有:设计
目前不考虑换算率,也就不参与库存的换算,因此单位表的字段就比较简单了 sql以下:code
CREATE TABLE `unit` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`code` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '物品编码',
`name` varchar(128) NOT NULL DEFAULT '' COMMENT '名称',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `name` (`name`) USING BTREE,
UNIQUE KEY `code` (`code`) USING BTREE COMMENT '`'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='计量单位';
复制代码
供应商在系统里是出入库的对象,入库的物料是从供应商那里买来的,出库的物料是退货给供应商
CREATE TABLE `supply` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL DEFAULT '' COMMENT '名称',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='供应商表';
复制代码
仓库表用来标识物料存在在那个仓库,同一个物料可能存在在多个仓库,入库时必须选择物料入到那个库
CREATE TABLE `warehouse` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`organization_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '门店id',
`name` varchar(32) NOT NULL DEFAULT '' COMMENT '库房名称',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='库房信息表';
复制代码
用来记录物料在不一样仓库的库存,入库和出库时须要把库存数量从批次里同步到库存表里
CREATE TABLE `inventory` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`warehouse_id` bigint(20) unsigned NOT NULL COMMENT '库房ID',
`material_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '物料id',
`count` decimal(16,2) NOT NULL DEFAULT '0.00' COMMENT '总库存',
`lock_count` decimal(16,2) NOT NULL DEFAULT '0.00' COMMENT '占用库存',
`available_count` decimal(16,2) NOT NULL DEFAULT '0.00' COMMENT '可用库存',
`cost_amount` decimal(16,4) NOT NULL DEFAULT '0.0000' COMMENT '成本总金额',
`updated_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
`created_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '建立时间',
`deleted_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '删除时间',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_group_id_label_id_relation_id_type` (`warehouse_id`,`material_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='仓库库存表';
复制代码
物料是库存操做的基本对象
CREATE TABLE `material` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`material_code` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '物品编码',
`name` varchar(45) NOT NULL COMMENT '名称',
`category_id` int(11) unsigned NOT NULL COMMENT '所属分类',
`category_name` varchar(45) NOT NULL COMMENT '分类名称',
`unit_weight` decimal(10,4) unsigned NOT NULL DEFAULT '0.0000' COMMENT '单位重量',
`base_unit_id` bigint(20) DEFAULT NULL COMMENT '主单位id',
`base_unit_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT '主单位名称',
`updated_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新日期',
`created_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '建立时期',
`deleted_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '删除时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='物料';
复制代码
单据表用来记录有多少个出入库单,和单据的一些元信息,好比这个单据的发起的供应商,操做人,单据金额,单据里的物料的数量等
CREATE TABLE `in_out` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`type` tinyint(2) unsigned NOT NULL DEFAULT '0' COMMENT '1:采购订单 2:采购收货单 3:采购退货单',
`in_out_code` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '单号',
`warehouse_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '仓库ID',
`warehouse_name` varchar(64) NOT NULL DEFAULT '' COMMENT '仓库名称',
`supply_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '供应商id',
`supply_name` varchar(64) NOT NULL DEFAULT '' COMMENT '供应商名称',
`address` varchar(45) NOT NULL DEFAULT '' COMMENT '交货地址',
`count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '物料数量',
`amount_total` decimal(18,8) unsigned NOT NULL DEFAULT '0.00000000' COMMENT '当前单据总金额',
`amount_count` decimal(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '当前单据总数量',
`created_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '建立时间',
`updated_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
`deleted_at` int(11) NOT NULL DEFAULT '0' COMMENT '删除时间',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_group_id_expense_sn` (`in_out_code`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='单据表';
复制代码
记录出入库里的物料的详细信息,好比物料的名称,编码,单位,数量,单价,金额,税额等参与库存计算的核心字段
CREATE TABLE `in_out_detail` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`warehouse_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '仓库ID',
`warehouse_name` varchar(62) NOT NULL DEFAULT '' COMMENT '仓库名称',
`in_out_code` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '单号',
`in_out_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '单号ID',
`in_out_type` tinyint(4) DEFAULT NULL COMMENT '单据类型',
`material_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '关联ID',
`material_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '关联物料名称',
`material_code` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '关联物料sn',
`unit_basic_name` varchar(32) NOT NULL DEFAULT '' COMMENT '基本单位名称',
`unit_basic_value` decimal(10,3) NOT NULL DEFAULT '1.000' COMMENT '基本单位数值',
`unit_basic_count` decimal(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '主单位数量',
`unit_basic_price` decimal(14,4) unsigned NOT NULL DEFAULT '0.0000' COMMENT '主单位不含税单价',
`unit_basic_tax_price` decimal(14,4) unsigned NOT NULL DEFAULT '0.0000' COMMENT '主单位的含税单价',
`unit_basic_total` decimal(18,8) unsigned NOT NULL DEFAULT '0.00000000' COMMENT '主单位不含税金额',
`unit_basic_tax_total` decimal(18,8) NOT NULL DEFAULT '0.00000000' COMMENT '主单位含税金额',
`tax` decimal(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '税率',
`tax_total` decimal(18,8) unsigned NOT NULL DEFAULT '0.00000000' COMMENT '税额',
`production_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '生产日期',
`created_at` int(11) unsigned NOT NULL DEFAULT '0',
`updated_at` int(11) unsigned NOT NULL DEFAULT '0',
`deleted_at` int(11) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_in_out_id_material_id` (`in_out_id`,`material_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1110 DEFAULT CHARSET=utf8 COMMENT='单据物料关联表';
复制代码
这个批次表就是记录物料的全部的批次当前的库存状态,物料一个批次的库存理论上最多用到0库存.
CREATE TABLE `batch` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`code` int(11) DEFAULT NULL COMMENT '批次代码',
`warehouse_id` bigint(20) DEFAULT NULL COMMENT '仓库id',
`in_type` int(4) DEFAULT NULL COMMENT '入库单类型',
`in_id` bigint(20) DEFAULT NULL COMMENT '入库单的id',
`material_id` bigint(20) DEFAULT NULL COMMENT '物料、菜品、套餐关联id',
`end_tax_price` decimal(14,4) DEFAULT '0.0000' COMMENT '当前含税单价',
`end_price` decimal(14,4) DEFAULT '0.0000' COMMENT '当前不含税单价',
`end_count` decimal(10,2) DEFAULT '0.00' COMMENT '当前 主单位库存数量 要减去占用数量',
`end_total_amount` decimal(18,8) DEFAULT '0.00000000' COMMENT '当前不含税总金额(发生单据后这个值会发生变化)',
`end_tax_total_amount` decimal(18,8) DEFAULT '0.00000000' COMMENT '当前含税总金额',
`end_tax_total` decimal(18,8) DEFAULT '0.00000000' COMMENT '当前结存税额',
`cost_tax_price` decimal(14,4) DEFAULT '0.0000' COMMENT '原含税单价',
`cost_price` decimal(14,4) DEFAULT '0.0000' COMMENT '原不含税单价',
`cost_count` decimal(10,2) DEFAULT '0.00' COMMENT '原主单位库存数量',
`cost_total_amount` decimal(18,8) DEFAULT '0.00000000' COMMENT '原不含税总金额',
`cost_tax_total_amount` decimal(18,8) DEFAULT '0.00000000' COMMENT '原含税总金额',
`cost_tax_total` decimal(18,8) DEFAULT '0.00000000' COMMENT '原税额',
`gross_profit` decimal(18,8) DEFAULT '0.00000000' COMMENT '利润金额(含税:入-成本/出-成本)',
`lock_count` decimal(10,2) DEFAULT '0.00' COMMENT '占用/锁定数量',
`production_at` int(11) DEFAULT NULL COMMENT '生产日期',
`status` tinyint(1) DEFAULT '1' COMMENT '冻结为0 非冻结为1',
`remark` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注',
`updated_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
`created_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '建立时间',
`deleted_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '删除时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='批次表';
复制代码
记录每次批次物料表发生变化后的快照
CREATE TABLE `batch_snapshot` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`batch_id` bigint(20) DEFAULT NULL,
`in_out_detail_type` int(4) DEFAULT NULL COMMENT '单据详情类型',
`in_out_detail_id` bigint(20) DEFAULT NULL COMMENT '入库单价',
`in_count` decimal(12,4) DEFAULT '0.0000' COMMENT '入库数量',
`in_total_amount` decimal(18,8) DEFAULT NULL,
`in_tax_total` decimal(18,8) DEFAULT '0.00000000' COMMENT '税额',
`in_tax_total_amount` decimal(18,8) DEFAULT '0.00000000' COMMENT '入库含税金额',
`out_price` decimal(14,4) DEFAULT '0.0000' COMMENT '出库单价',
`out_count` decimal(10,2) DEFAULT '0.00' COMMENT '出库数量',
`out_total_amount` decimal(18,8) DEFAULT '0.00000000' COMMENT '出库未含税金额',
`out_tax_total` decimal(18,8) DEFAULT '0.00000000' COMMENT '出库税额',
`out_tax_total_amount` decimal(18,8) DEFAULT '0.00000000' COMMENT '出库含税金额',
`out_cost_tax_price` decimal(14,4) DEFAULT '0.0000' COMMENT '出库成本单价(含税)',
`out_cost_price` decimal(14,4) DEFAULT '0.0000' COMMENT '出库成本单价(不含税)',
`out_cost_total_amount` decimal(18,8) DEFAULT '0.00000000' COMMENT '出库成本含税金额',
`out_cost_tax_total_amount` decimal(18,8) DEFAULT '0.00000000' COMMENT '出库成本不含税金额',
`out_cost_tax_total` decimal(18,8) DEFAULT '0.00000000' COMMENT '出库成本税额',
`end_price` decimal(14,4) DEFAULT '0.0000' COMMENT '当前未含税单价',
`end_tax_price` decimal(14,4) DEFAULT '0.0000' COMMENT '当前含税单价',
`end_count` decimal(10,2) DEFAULT '0.00' COMMENT '当前结存数量',
`end_total_amount` decimal(18,8) DEFAULT '0.00000000' COMMENT '当前结存未含税金额',
`end_tax_total_amount` decimal(18,8) unsigned DEFAULT '0000000000.00000000' COMMENT '当前结存含税金额',
`end_tax_total` decimal(18,8) DEFAULT '0.00000000' COMMENT '当前结存税额',
`updated_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
`created_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '建立时间',
`deleted_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '删除时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='批次快照表';
复制代码
库存系统里只要影响库存和金额的操做均可以算做库存的核心算法,其中最重要的就是物料的计价方法了,由于每次出入库都会用到这个物料的计价方法,而不一样的计价方法又会直接影响到库存的成本和利润
成本计算:成本是含税的,因此计算成本时须要把税也计算在内 1. 用户输入系统的成本是不含税的,那么系统须要用税点算出税额加到成本里 2. 用户输入系统的成本是含税的,那么系统须要减掉税点获得不含税的成本
先进先出的出库算法:先入库的先出库
金额在mysql使用decimal类型存储,在java中使用BigDecimal类型表示 批次快照表只是记录批次物料的库存快照,不参与库存和成本的计算。
持续更新...