-- 采购申请模块。执行一次后,在角色管理中给员工分配采购申请菜单; -- “采购管理”按钮权限仅分配给采购管理员。 create table if not exists purchase_batch ( id bigint(20) not null auto_increment comment '主键', batch_no varchar(64) not null comment '采购批次编号', batch_name varchar(200) default null comment '采购批次名称', purchase_status tinyint(1) not null default 1 comment '批次状态:1规划中 2执行中 3已结束 4已归档 5已取消', progress_remark varchar(500) default null comment '进度说明', create_by varchar(64) default null comment '创建人', create_time datetime default null comment '创建时间', update_by varchar(64) default null comment '更新人', update_time datetime default null comment '更新时间', primary key (id), unique key uk_purchase_batch_no (batch_no) ) engine=innodb default charset=utf8mb4 comment='采购批次表'; alter table purchase_batch modify column purchase_status tinyint(1) not null default 1 comment '批次状态:1规划中 2执行中 3已结束 4已归档 5已取消'; create table if not exists purchase_request ( id bigint(20) not null auto_increment comment '主键', request_no varchar(64) not null comment '申请单号', product_id bigint(20) default null comment '关联库房物料ID', purchase_batch_id bigint(20) default null comment '采购批次ID', material_name varchar(200) not null comment '物料名称', material_brand varchar(100) default null comment '品牌', category varchar(100) default null comment '类别', material_params varchar(500) default null comment '参数规格', purchase_link varchar(1000) default null comment '采购链接', quantity decimal(16,3) not null default 1.000 comment '需求数量', unit varchar(32) default null comment '单位', expected_date date default null comment '期望到货日期', applicant_id bigint(20) not null comment '申请人用户ID', applicant_name varchar(64) not null comment '申请人账号', purchase_status tinyint(1) not null default 0 comment '状态:0待采购 1已下单 2采购中 3部分到货 4已到齐 5已取消', purchase_batch_no varchar(64) default null comment '采购批次', progress_remark varchar(500) default null comment '进度说明', remark varchar(500) default null comment '申请备注', create_by varchar(64) default null comment '创建人', create_time datetime default null comment '创建时间', update_by varchar(64) default null comment '更新人', update_time datetime default null comment '更新时间', primary key (id), unique key uk_purchase_request_no (request_no), key idx_purchase_request_product (product_id), key idx_purchase_request_batch_id (purchase_batch_id), key idx_purchase_request_applicant (applicant_id), key idx_purchase_request_status (purchase_status), key idx_purchase_request_batch (purchase_batch_no) ) engine=innodb default charset=utf8mb4 comment='采购申请表'; create table if not exists purchase_arrival ( id bigint(20) not null auto_increment comment '主键', arrival_no varchar(64) not null comment '到货单号', purchase_request_id bigint(20) not null comment '采购申请ID', arrival_quantity decimal(16,3) not null comment '本次到货数量', arrival_date date not null comment '到货日期', acceptance_status tinyint(1) not null default 0 comment '验收状态:0待验收 1验收通过 2验收拒绝', acceptance_remark varchar(500) default null comment '验收说明', accepted_by varchar(64) default null comment '验收人', accepted_time datetime default null comment '验收时间', pre_accept_purchase_status tinyint(1) default null comment '验收前采购状态', revoked_by varchar(64) default null comment '最近撤销人', revoked_time datetime default null comment '最近撤销时间', revoke_remark varchar(500) default null comment '最近撤销原因', remark varchar(500) default null comment '到货备注', create_by varchar(64) default null comment '创建人', create_time datetime default null comment '创建时间', update_by varchar(64) default null comment '更新人', update_time datetime default null comment '更新时间', primary key (id), unique key uk_purchase_arrival_no (arrival_no), key idx_purchase_arrival_request (purchase_request_id), key idx_purchase_arrival_status (acceptance_status) ) engine=innodb default charset=utf8mb4 comment='采购分批到货及验收记录'; -- 兼容已执行过早期脚本的数据库。 set @purchase_brand_column = ( select count(*) from information_schema.columns where table_schema = database() and table_name = 'purchase_request' and column_name = 'material_brand' ); set @purchase_brand_sql = if( @purchase_brand_column = 0, 'alter table purchase_request add column material_brand varchar(100) default null comment ''品牌'' after material_name', 'select 1' ); prepare purchase_brand_stmt from @purchase_brand_sql; execute purchase_brand_stmt; deallocate prepare purchase_brand_stmt; set @purchase_batch_id_column = ( select count(*) from information_schema.columns where table_schema = database() and table_name = 'purchase_request' and column_name = 'purchase_batch_id' ); set @purchase_batch_id_sql = if( @purchase_batch_id_column = 0, 'alter table purchase_request add column purchase_batch_id bigint(20) default null comment ''采购批次ID'' after product_id, add key idx_purchase_request_batch_id (purchase_batch_id)', 'select 1' ); prepare purchase_batch_id_stmt from @purchase_batch_id_sql; execute purchase_batch_id_stmt; deallocate prepare purchase_batch_id_stmt; set @arrival_revoke_columns = ( select count(*) from information_schema.columns where table_schema = database() and table_name = 'purchase_arrival' and column_name = 'pre_accept_purchase_status' ); set @arrival_revoke_sql = if( @arrival_revoke_columns = 0, 'alter table purchase_arrival add column pre_accept_purchase_status tinyint(1) default null comment ''验收前采购状态'' after accepted_time, add column revoked_by varchar(64) default null comment ''最近撤销人'' after pre_accept_purchase_status, add column revoked_time datetime default null comment ''最近撤销时间'' after revoked_by, add column revoke_remark varchar(500) default null comment ''最近撤销原因'' after revoked_time', 'select 1' ); prepare arrival_revoke_stmt from @arrival_revoke_sql; execute arrival_revoke_stmt; deallocate prepare arrival_revoke_stmt; alter table purchase_request modify column purchase_status tinyint(1) not null default 0 comment '状态:0待采购 1已下单 2采购中 3部分到货 4已到齐 5已取消'; -- 把旧版本中写在申请行上的批次编号迁移为批次主数据。 insert ignore into purchase_batch(batch_no, batch_name, purchase_status, progress_remark, create_by, create_time) select purchase_batch_no, purchase_batch_no, greatest(max(purchase_status), 1), max(progress_remark), 'migration', sysdate() from purchase_request where purchase_batch_no is not null and purchase_batch_no != '' group by purchase_batch_no; update purchase_request pr join purchase_batch pb on pb.batch_no = pr.purchase_batch_no set pr.purchase_batch_id = pb.id, pr.purchase_status = pb.purchase_status, pr.progress_remark = pb.progress_remark where pr.purchase_batch_id is null; -- 采购完成后先生成待入库记录,库区和入库人由仓库人员补充后再确认入库。 alter table in_record modify column area_id bigint(20) default null comment '库区id,待入库时可为空'; set @in_purchase_request_column = ( select count(*) from information_schema.columns where table_schema = database() and table_name = 'in_record' and column_name = 'purchase_request_id' ); set @in_purchase_request_sql = if( @in_purchase_request_column = 0, 'alter table in_record add column purchase_request_id bigint(20) default null comment ''采购申请ID'' after product_id', 'select 1' ); prepare in_purchase_request_stmt from @in_purchase_request_sql; execute in_purchase_request_stmt; deallocate prepare in_purchase_request_stmt; set @in_source_no_column = ( select count(*) from information_schema.columns where table_schema = database() and table_name = 'in_record' and column_name = 'source_no' ); set @in_source_no_sql = if( @in_source_no_column = 0, 'alter table in_record add column source_no varchar(64) default null comment ''来源单号'' after purchase_request_id', 'select 1' ); prepare in_source_no_stmt from @in_source_no_sql; execute in_source_no_stmt; deallocate prepare in_source_no_stmt; set @in_arrival_column = ( select count(*) from information_schema.columns where table_schema = database() and table_name = 'in_record' and column_name = 'arrival_id' ); set @in_arrival_sql = if( @in_arrival_column = 0, 'alter table in_record add column arrival_id bigint(20) default null comment ''采购到货ID'' after purchase_request_id', 'select 1' ); prepare in_arrival_stmt from @in_arrival_sql; execute in_arrival_stmt; deallocate prepare in_arrival_stmt; set @in_purchase_request_unique_index = ( select count(*) from information_schema.statistics where table_schema = database() and table_name = 'in_record' and index_name = 'uk_in_record_purchase_request' and non_unique = 0 ); set @drop_in_purchase_request_unique_sql = if( @in_purchase_request_unique_index > 0, 'alter table in_record drop index uk_in_record_purchase_request', 'select 1' ); prepare drop_in_purchase_request_unique_stmt from @drop_in_purchase_request_unique_sql; execute drop_in_purchase_request_unique_stmt; deallocate prepare drop_in_purchase_request_unique_stmt; set @in_purchase_request_index = ( select count(*) from information_schema.statistics where table_schema = database() and table_name = 'in_record' and index_name = 'idx_in_record_purchase_request' ); set @in_purchase_request_index_sql = if( @in_purchase_request_index = 0, 'alter table in_record add key idx_in_record_purchase_request (purchase_request_id)', 'select 1' ); prepare in_purchase_request_index_stmt from @in_purchase_request_index_sql; execute in_purchase_request_index_stmt; deallocate prepare in_purchase_request_index_stmt; set @in_arrival_index = ( select count(*) from information_schema.statistics where table_schema = database() and table_name = 'in_record' and index_name = 'uk_in_record_arrival' ); set @in_arrival_index_sql = if( @in_arrival_index = 0, 'alter table in_record add unique key uk_in_record_arrival (arrival_id)', 'select 1' ); prepare in_arrival_index_stmt from @in_arrival_index_sql; execute in_arrival_index_stmt; deallocate prepare in_arrival_index_stmt; -- 旧版本按批次完成自动生成、但尚未真实入库的记录没有经过验收,升级时移除。 delete from in_record where arrival_id is null and purchase_request_id is not null and in_status = 0 and in_no like 'PIN%'; -- 菜单及按钮权限 delete from sys_menu where menu_id in (2035, 2036, 2037, 2038, 2039, 2040, 2041, 2042); insert into sys_menu values('2035', '采购申请', '0', '6', 'purchase', 'warehouse/purchase/index', '', '', 1, 0, 'C', '0', '0', 'warehouse:purchase:list', 'shopping', 'admin', sysdate(), '', null, '与库存管理同级的采购申请菜单'); insert into sys_menu values('2036', '采购查询', '2035', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'warehouse:purchase:query', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('2037', '采购申请新增', '2035', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'warehouse:purchase:add', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('2038', '采购申请修改', '2035', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'warehouse:purchase:edit', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('2039', '采购申请删除', '2035', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'warehouse:purchase:remove', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('2040', '采购申请导入', '2035', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'warehouse:purchase:import', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('2041', '采购申请导出', '2035', '6', '#', '', '', '', 1, 0, 'F', '0', '0', 'warehouse:purchase:export', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('2042', '采购管理', '2035', '7', '#', '', '', '', 1, 0, 'F', '0', '0', 'warehouse:purchase:manage', '#', 'admin', sysdate(), '', null, '仅管理员分配,可查看全部申请并修改采购进度'); -- 独立采购管理员角色。该角色可分配给普通用户,不使用受保护的 admin 超级管理员角色。 insert into sys_role(role_name, role_key, role_sort, data_scope, menu_check_strictly, dept_check_strictly, status, del_flag, create_by, create_time, remark) select '采购管理员', 'purchase_manager', 3, '1', 1, 1, '0', '0', 'admin', sysdate(), '维护全部采购申请、采购批次和采购进度' where not exists ( select 1 from sys_role where role_key = 'purchase_manager' and del_flag = '0' ); set @purchase_manager_role_id = ( select role_id from sys_role where role_key = 'purchase_manager' and del_flag = '0' order by role_id limit 1 ); insert ignore into sys_role_menu(role_id, menu_id) select @purchase_manager_role_id, menu_id from sys_menu where menu_id in (2035, 2036, 2037, 2038, 2039, 2040, 2041, 2042); delete from sys_role_menu where role_id = @purchase_manager_role_id and menu_id = 2000; -- 普通采购申请人:可查看、导出全部申请,但服务端只允许修改和删除本人数据。 insert into sys_role(role_name, role_key, role_sort, data_scope, menu_check_strictly, dept_check_strictly, status, del_flag, create_by, create_time, remark) select '采购申请人', 'purchase_user', 4, '1', 1, 1, '0', '0', 'admin', sysdate(), '提交采购申请;查看和导出全部申请;修改、删除本人申请' where not exists ( select 1 from sys_role where role_key = 'purchase_user' and del_flag = '0' ); set @purchase_user_role_id = ( select role_id from sys_role where role_key = 'purchase_user' and del_flag = '0' order by role_id limit 1 ); insert ignore into sys_role_menu(role_id, menu_id) select @purchase_user_role_id, menu_id from sys_menu where menu_id in (2035, 2036, 2037, 2038, 2039, 2040, 2041); delete from sys_role_menu where role_id = @purchase_user_role_id and menu_id = 2000;