深入浅出WMS之入库流程解析

前言

古人十大雅事本人此刻独占其四,虽没有文人风骨,不过也借此空闲之余对从校园到社会的发展做一个自我审视。记得是20年八月份从校园到临沂一家公司实习,主要业务是ERP,不过当时的更多时间是比较自由放纵的,所以对于其中的业务也不算太多了解。后来21年八月份离职来到了北京目前这家公司,主要的业务是WMS的升级改造和接口程序的对接。目前负责的是一个项目的后端开发,所以也借此机会来分享和巩固一下对于WMS这款程序的个人理解。因为仓库属性不同,所以WMS个性化定制比较多,所以就拿我手里正在开发的这款来做一个分享。
在这里插入图片描述

创建入库单

这一步是基础,也没有太多的技术要求,主要是数据的增删改查。这一步也可以配合接口来实现从上级系统下发,例如ERP或MES等等。
在这里插入图片描述
当我们输入相对应的信息后,点击保存,会把这条数据添加到入库单表中。从后端的角度来说这个也是比较简单的。无非是从前端把数据打包成一个包去调用后端。当后端接收到数据后执行一个添加操作。

入库单管理

这一步的功能就比较多,而且也相对应比较繁琐。大家从界面上也可以看到,除了基础的查询、修改、删除外,还有了审核、组盘和关单的功能。
在这里插入图片描述
查改删和审核的功能相对来说比较简单,暂不叙述。接下来我们说一下组盘和关单这两个功能。

入库单管理-组盘

组盘的作用主要是把货物和托盘进行一个绑定,同时生成相对应的入库任务。
当前端把该填写的数据传过来后,我们后端首先要做判断。最基础的判断是判断这个入库单据是否合理,其次我们要对输入的托盘号和数量进行验证。其一输入的托盘号不能是正在入库的托盘,其二不能是库存中的托盘,其三不属于是空托盘,其四这个托盘此刻不是正在出库。数量的话组盘的数量不能大于到货单也就是入库单的数量。数量可以为小数,因为不同的企业对于这个要求是不统一的。药企或者服装等等是必须有小数的,因为组盘时会有零散的。当所有的条件都满足时我们生成这个入库任务。
组完盘后,大部分是有师傅开叉车或者AGV小车来把该托盘放到输送线上。当输送线上的光电检测到货物后会发信号给PIC程序,这时候输送线就会动起来,在托盘输送线上会有侧扫来进行扫描来进行确认。一般来说立体库都是这样子的,不过我手里目前正在开发的这款是用于平面库的WMS,所以在流程上比立体库的要简单一些。而且每个WMS和WCS的交互也不太一致,所以在这里就暂且不叙述WCS和WMS的一个交互流程。

入库单管理-关单

关单就是整个流程的最后一步了,建议先跳过这部分先看下面的部分。提到关单会有另一个概念,就是一条入库单并不一定只有一个任务。例如说我有一条A物品的入库单据,数量为100,我在组盘时可以一次组完。这样的话所有货物是在一个托盘上,并且只会生成一个入库任务。但还有一些情况是一个托盘装不下那么多货物,需要多次组盘。这样的话就是一个入库单下有多个入库任务。当最后一个入库任务完成后会自动关单。为了防止有意外情况发生,所以增加了手动关单这个选项。
关单的时候我们是有个判断的,首先判断是不是强制关单,也就是手动关单。然后我们再判断入库的数量是不是和单据的状态是相符的,这个不相符的话肯定是关不了单的。最后我们判断单据的状态,是不是有没完成的入库任务等等。还需要判断入库的货位地址是不是符合条件的。如果所有的条件都满足后我们来看最后一步,也就是我们上面说的是一单一任务的情况还是一单多任务。一单一任务的话是直接把我们处理后的数据添加到库存中。如果是一单多任务的话就不需要添加了,只需要修改库存的数据。
上面说了一个大致的关单概念。那么接下来说关单的具体注意事项。首先我们在后端写程序的时候需要用事务。因为我们要的是其中某一个阶段失败后会回滚。我们关单的时候不只是添加库存,还需要删除这条入库单据和所有的入库任务,然后把入库单据信息和入库任务信息添加到历史表中,方面我们进行一个查验。那么如果不用事务的话,如果我们在添加库存的时候失败了,库存并没有添加,然后把我们的单据任务等等都删掉的话,是不是后续就比较麻烦了。所以我们在任何一步出现问题时都直接回滚所有操作,从一定程度上保证数据的准确性。当然,关单就是这条单据的终点站。

入库任务管理

在这里插入图片描述
除了基础的一些功能,我们可以看到入库完成和货位分配两个功能。那么我大致说一下这两个功能,入库完成的话就比较简单,字面意思就是这个任务的完成。货位分配的话是分为手动分配或自动分配。手动分配的话就是手动分配货位地址,经过一系列检验后,这步就是成功完成。那么重点说一下自动分配。对于使用者来说,比如我们今天有三百个入库任务,肯定不会手动挨个输货位地址,效率极低不说,对于货位状态操作人员也不会有明确的认知。所以这个时候就可以全选来进行自动分配。这一步的话就是根据客户的需求来编写代码,一般是随机分配。比如说我有六个巷道,如果货物全放到一巷道,那么一号堆垛机就会一直运动,那么二号至六号堆垛机就会闲置下来,这样十分影响效率。

入库任务管理-货位分配

这一步我们拿手动分配货位来讲。当我们输入的货位符合一系列条件后,我们需要在事务里进行入库任务的一个修改,修改成入库中对吧。那么我们该需要改什么呢?改货位!因为我们分配完货位,不是一瞬间就可以完成入库这个操作的,所以我们这一步先把这个货位地址和这个任务绑定起来,这样就可以防止其他操作人员在入库分配任务时会分配到这个货位。关于货位分配先写那么多,因为自动分配我还没写,等写完我再补上。

入库任务管理-任务撤销

这一步比较重要,因为我们当在入库单组盘时会生成相对应的任务,而且这个时候在入库单中会有一个动态的组盘数据,所以撤销绝对不是一个普通的删除操作。

 public async Task<ResultData> RevocationInTask(LOGINTASK lOGINTASK)
        {
            //使用事务进行入库任务撤销
            ResultData resultData = new ResultData();
            try
            {
                LogErpIn logErpIn = await _fsql.Select<LogErpIn>().Where(x => x.ID == Convert.ToDecimal(lOGINTASK.ERPINID)).FirstAsync();
                var quantDiff = (Convert.ToDouble(logErpIn.QUANT0) - Convert.ToDouble(lOGINTASK.QUANT)).ToString();
                //1.删除入库任务表数据
                _fsql.Transaction(() => {
                    var derows = _fsql.Delete<LOGINTASK>().Where(x => x.ID == lOGINTASK.ID).ExecuteAffrows();
                    if (derows <= 0) throw new Exception("入库任务撤销失败!");
                    if (lOGINTASK.ADDREDESC.Substring(lOGINTASK.ADDREDESC.Length - 7,7) != "9999999")
                    {
                        var uprows = _fsql.Update<LOGSTORAGE>().Set(x => x.AFLAG,"N").Set(x=>x.PALNO == "9999999").Where(x => x.ADDRE == lOGINTASK.ADDREDESC).ExecuteAffrows();
                        if (uprows <= 0) throw new Exception("库位状态撤销失败!");
                    }
                    
                    var upquant = _fsql.Update<LogErpIn>().Set(x => x.QUANT0 == quantDiff)
                    .Where(x => x.ORDNO == lOGINTASK.ORDNO && x.ITMNO == lOGINTASK.ITMNO).ExecuteAffrows();
                    if (upquant <= 0) throw new Exception("入库单组盘量撤销失败!");
                });
            }
            catch (Exception ex) 
            {
                resultData.code = 6001;
                resultData.data = ex.Message;
            }
            return resultData;
        }

这边可以看到,是在事务里进行了三步操作。首先删除这个入库任务,其次是把这个任务占用的库位状态恢复,也就是解绑,最后在入库单中把我们这个任务的数据给返回过去,因为我们毕竟撤销了这个任务,数量一定是要恢复的。

入库任务管理-入库完成

入库完成的话也比较简单,也就是修改一些相对应的状态。这里任务完成后我们并没有做对库存的一个操作,而是把对数据的操作放到了关单的业务里。这样就会多写一个功能,就是每当我们完成一个任务后,我们去判断这个任务是不是属于这个单据的最后一条任务,如果是最后一条任务的话我们进行一个自动关单。当然,目前这个功能还没写,下次和自动分配货位一块补上。无论是自动关单或手动关单,这都代表着我们这个入库的结束。看到这可以看上面关于关单的描述了。

结尾

这里我对入库的流程进行了一个大概的描述,文字描述居多,代码技术描述几乎没有。不过对于仓储这块来说,其实技术不是最重要的,最重要的是流程也就是业务,重要的是方案。因为WMS和别的程序还不一样,他还需要往下连接WCS,整个流程是有设备的一个运转,所以对于我们来说,存储过程、原生SQL、Freesql、SqlSugar等等都是一个去实现目标的技术手段而已,最主要的还是作为一个开发、测试、实施人员对于流程的掌握,对于现场的一个掌控。这次先说那么多,下期讲出库流程。

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晚风偷吻云朵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值