WMS手动配货和自动配货的区别

news2024/9/22 13:30:59

手动配货

不知道配货流程的朋友可以看一下前面的文章链接: 深入浅出WMS之出库流程里面有对出库的解释说明,其中也有对配货的解释。前端页面也可以在前面的那篇文章中看到,这里我们来说一下后端部分。

手动配货是选中出库单的某条数据,然后点击手动配货,这个时候前端会把这个出库单的guid传给后端,这个时候我们有guid了,就可以去出库单表里去找到这条数据,取出其中的订单号、批次号等等信息。这个时候我们要做的就很简单,去库存里找符合我们可以出库的信息。

 public async Task<PageData> QueryPeiH(int pages, int limit, string matno, string batch, string cflag)
        {
            PageData pageData = new PageData();
            var list = _fsql.Select<LogMstore, LOGMATERIAL,LOGSTORAGE>()
                .LeftJoin((a, b, c) => a.MATNO == b.MATNO)
                .LeftJoin((a, b, c) => a.ADDRE == c.ADDRE);
            if (!string.IsNullOrWhiteSpace(matno))
            {
                list = list.Where((a,b,c) => a.MATNO == matno);
            }
            if (!string.IsNullOrWhiteSpace(batch))
            {
                list = list.Where((a, b, c) => a.BATCH == batch);
            }
            if (!string.IsNullOrWhiteSpace(cflag))
            {
                list = list.Where((a, b, c) => a.CFLAG == cflag);
            }
            //在这里添加我们对库存信息的限制条件
            list = list.Where((a, b, c) => Convert.ToDouble(a.QUANT) - Convert.ToDouble(a.QUANTOUT) > 0);
            list = list.Where((a, b, c) => c.PkFlag != "PK");
            //
            if (limit <= 0)
            {
                //pageData.pageData = await list.Count(out var total).ToListAsync();
                //pageData.total = (int)total;
                pageData.pageData = await list.Count(out var total).ToListAsync((a, b, c) => new {
                    a.MATNO,
                    b.MNAME,
                    b.SZNO,
                    a.BATCH,
                    keyong = Convert.ToDouble(a.QUANT) - Convert.ToDouble(a.QUANTOUT),
                    a.ADDRE,
                    a.PALNO,
                    a.SECTN,
                    a.CFLAG
                });
                pageData.total = (int)total;
            }
            else
            {
                pageData.pageData = await list.Count(out var total).Skip((pages - 1) * limit).Take(limit).ToListAsync((a, b, c) => new {
                    a.MATNO,
                    b.MNAME,
                    b.SZNO,
                    a.BATCH,
                    keyong = Convert.ToDouble(a.QUANT) - Convert.ToDouble(a.QUANTOUT),
                    a.ADDRE,
                    a.PALNO,
                    a.SECTN,
                    a.CFLAG
                });
                pageData.total = (int)total;
            }

            return pageData;
        }

当我们查到所有符合条件的库存信息后,把数据返回给前端。这个时候也就是当前端选中出库单点击手动配货按钮时,会弹出一个页面,也就是我们上面执行的查询结果。这个时候又操作人员来进行货位分配。例如我们要出750个A货物,然后有符合出库的8个托盘,每个托盘上有100个A物品,这个时候我们手动配货是可以选择每个托盘出多少的,比如说第一个托盘出90个,第二个托盘出80等。当配完货后会生成相对应的出库任务,那么接下来我们看一下这个业务是怎么用代码来实现的。

        [HttpPost]
        public async Task<IActionResult> QueryPeiH(List<LogMstore> logMstores)
        {
            return Ok(await _erpOutService.PeiHuo2(logMstores));
        }

这个是我们的配货接口,这个时候前端会发一个list过来,写list的目的是为了把配货的数据一次性发给后端,而不是一直调用接口。
这个时候可以看到我们调用了server层。我们来看一下server层对业务的处理。

public async Task<ResultData> PeiHuo2(List<LogMstore> logMstores)
        {
            try
            {
            //循环list
                LOGOUTTASK lOGOUTTASK = new LOGOUTTASK();
                for (int i = 0; i < logMstores.Count; i++)
                {
                    string quant = logMstores[i].QUANTOUT;
                    string palno = logMstores[i].PALNO;
                    string ordno = logMstores[i].DEMO1;
                    string itmno = logMstores[i].DEMO2;
                    string keyong = logMstores[i].DEMO3;
                    //通过订单号和行号查询出库表
                    var ErpOut = await _erpOutRepository.QueryMI(ordno, itmno);
                    //通过托盘号查询库存表
                    var OutMstore = await _mstoreRepository.QueryPalno(palno);
                    #region 赋值给出库任务做添加
                    lOGOUTTASK.ErpoutId = ErpOut.Id.ToString();
                    lOGOUTTASK.TICNO = "";
                    lOGOUTTASK.SEQNO = "";
                    lOGOUTTASK.INTASKID = OutMstore.INTASKID;
                    lOGOUTTASK.ORDNO = ordno;
                    lOGOUTTASK.ITMNO = itmno;
                    lOGOUTTASK.RECTYPE = ErpOut.RECTYPE;
                    lOGOUTTASK.MATNO = ErpOut.MATNO;
                    lOGOUTTASK.MUNIT = ErpOut.MUNIT;
                    lOGOUTTASK.QUANT = quant;
                    lOGOUTTASK.QUANT0 = keyong;
                    lOGOUTTASK.QuantQy = "0";
                    lOGOUTTASK.JIAN = ErpOut.JIAN;
                    lOGOUTTASK.STANO = "0";
                    lOGOUTTASK.ADDRESRC = OutMstore.ADDRE;
                    lOGOUTTASK.ADDREDESC = "-";
                    lOGOUTTASK.PALNO = OutMstore.PALNO;
                    lOGOUTTASK.MstoreId = OutMstore.MstoreId.ToString();
                    lOGOUTTASK.CFLAG = ErpOut.CFLAG;
                    lOGOUTTASK.BATCH = ErpOut.BATCH;
                    lOGOUTTASK.LOTNO = ErpOut.LOTNO;
                    lOGOUTTASK.CUSTOM = ErpOut.CUSTOM;
                    lOGOUTTASK.CustAddress = "-";
                    lOGOUTTASK.WORKS = "-";
                    lOGOUTTASK.STORE = ErpOut.STORE;
                    lOGOUTTASK.VCDSCR = ErpOut.VCDSCR;
                    lOGOUTTASK.PONO = ErpOut.PONO;
                    lOGOUTTASK.POITEM = ErpOut.POITEM;
                    lOGOUTTASK.STYPE = "N";
                    lOGOUTTASK.ATTACHMENT = "N";
                    lOGOUTTASK.SECTN = ErpOut.SECTN;
                    lOGOUTTASK.PRDAT = ErpOut.PRDAT;
                    lOGOUTTASK.QUDAT = ErpOut.QUDAT;
                    lOGOUTTASK.PRICE = "-";
                    lOGOUTTASK.KEEPER = "-";
                    lOGOUTTASK.PRNNO = "-";
                    lOGOUTTASK.TKDAT = DateTime.Now;
                    lOGOUTTASK.COMDAT = DateTime.Now;
                    lOGOUTTASK.IFDO = "O";
                    lOGOUTTASK.OPUSER = ErpOut.OPUSER;
                    lOGOUTTASK.USERID = "";
                    lOGOUTTASK.OutPort = "";
                    lOGOUTTASK.OutportJ = "";
                    lOGOUTTASK.Deviceno = "";
                    lOGOUTTASK.DEMO1 = ordno;
                    lOGOUTTASK.DEMO2 = itmno;
                    lOGOUTTASK.DEMO3= logMstores[i].DEMO3;
                    lOGOUTTASK.Tasktype = "N";
                    lOGOUTTASK.DEMO19 = "自建";
                    lOGOUTTASK.DEMO24 = ErpOut.DEMO24;
                    #endregion
                    if (Convert.ToDouble(OutMstore.QUANT) <Convert.ToDouble(quant))
                    {
                        throw new Exception("库存数量不足!");
                    }
                    if (await _erpOutRepository.PeiHuo(lOGOUTTASK) == 0)
                    {
                        resultData.code = 0;
                        resultData.message = "配货成功!";
                    }
                  
                }
            }
            catch (Exception ex)
            {
                resultData.code = 1;
                resultData.message = ex.Message;
            }
            return resultData;
        }

在这里面我们又调用了一层,因为这层是处理业务的,会有另外一层专门写增删改查等操作,这样的话也是为了提高代码的利用率,这也符合我们写代码的原则“高内聚,低耦合”。

        public async Task<int> PeiHuo(LOGOUTTASK lOGOUTTASK)
        {
            try
            {
                var ErpOut = await _fsql.Select<LogErpOut>().Where(x => x.ORDNO == lOGOUTTASK.ORDNO && x.ITMNO == lOGOUTTASK.ITMNO).FirstAsync();
                string quant0 = ErpOut.QUANT0;
                var Pdian = await _fsql.Select<LOGSTORAGE>().Where(x => x.ADDRE == lOGOUTTASK.ADDRESRC).FirstAsync();
                if (Pdian.PkFlag == "PK") return 6001;
                quant0 = (Convert.ToDouble(quant0) + Convert.ToDouble(lOGOUTTASK.QUANT)).ToString();
                _fsql.Transaction(() => {
                    //添加出库任务
                    var inrows = _fsql.Insert(lOGOUTTASK).ExecuteAffrows();
                    if (inrows <= 0) throw new Exception("出库任务添加失败!");

                    //var erpin = _fsql.Select<LogErpOut>().Where(x => x.Id == Convert.ToDecimal(lOGOUTTASK.ErpoutId)).First();
                    //修改出库单已配货数量
                    var uprows = _fsql.Update<LogErpOut>().Set(x =>x.QUANT0 == quant0)
                    .Set(x => x.IfDo == "O")
                    .Where(x => x.ORDNO == lOGOUTTASK.ORDNO && x.ITMNO == lOGOUTTASK.ITMNO).ExecuteAffrows();
                    if (uprows <= 0) throw new Exception("配货数量回写失败!");
                    //库存表可用数量加上

                });
                return 0;
            }
            catch (Exception ex)
            {
                return 1;
            }
        }

这里我们需要使用到事务,以防数据出现错误。手动配货的相比较自动配货来说比较简单,了解业务之后就可以一步一步的往下写。而且一般来说不会出现什么错误,只需要多注意数据的增减。例如配货成功后出库单的已配货数量,未配货数量,出库任务的出库数量,库存的剩余数量,可用数量等等。假如对这个配货还不太懂的话,可以看一下前面的文章,里面有出库的整个流程,其中对配货也有一定说明。接下来我们来说一下重点-自动配货。

自动配货

自动配货前端写起来比较简单,因为只需要写一个按钮就可以。自动配货相对手动配货来说第一步的查询是一样的,只不过区别是手动配货需要我们把查出来的数据返回给前端,让操作人员进行分配,然后再把分配完的数据再传给后端。自动配货的话就是我们查出来数据后,我们后端自己处理。
在这里插入图片描述
上面的是我初次写的自动配货,如今已弃用,下面的是优化过的。还是那么一个简简单单的接口,只需要前端给我们传一个guid,我们就去server层自己玩。说明我写在下面代码的注释里,方便大家了解流程。

public async Task<ResultData> AutomaticPicking(string guid)
        {
            ResultData resultData = new ResultData()
            {
                code = 0,
                message = "success",
            };
            try
            {
                List<LogMstore> logMstores = new List<LogMstore>();
                var ErpOut = await _erpOutRepository.Queryguid(guid);//根据guid查询出库单
                string quantout = ErpOut.QUANT;//出库单计划出库数量
                string matno = ErpOut.MATNO;
                string batch = ErpOut.BATCH;
                string cflag = ErpOut.CFLAG;
                //查询符合条件的库存信息
                var logmstore = await _mstoreRepository.QueryZiDong(1, 20, matno, batch, cflag);
                //序列化查询符合条件的库存信息
                var json = JsonConvert.SerializeObject(logmstore.pageData, Formatting.Indented);
                var newdynamicData = JsonConvert.DeserializeObject<List<dynamic>>(json);
                //未配货数量 = 计划数量 - 已配货数量
                Double UnshippedQuantity = Convert.ToDouble(ErpOut.QUANT) - Convert.ToDouble(ErpOut.QUANT0);
                //符合条件的数据循环插入到List集合中
                for (int i = 0; i < newdynamicData.Count; i++)
                {
                    //如果大于0说明是整托出库,例如750个的货,每个托盘100个,那么前7个托盘就是整托出库,最后的一个托盘就是拣选出库,因为我们只需要50,剩下的50还需要再回库。
                    if((UnshippedQuantity - Convert.ToDouble(newdynamicData[i].QUANT)) >= 0)
                    {
                        UnshippedQuantity = UnshippedQuantity - Convert.ToDouble(newdynamicData[i].QUANT);
                        logMstores.Add(new LogMstore
                        {
                            ADDRE = newdynamicData[i].ADDRE,//货位地址
                            BATCH = newdynamicData[i].BATCH,//批次号
                            CFLAG = newdynamicData[i].CFLAG,
                            DEMO1 = ErpOut.ORDNO,//订单号
                            DEMO2 = ErpOut.ITMNO,//行号
                            MATNO = newdynamicData[i].MATNO,//物料编码
                            PALNO = newdynamicData[i].PALNO,
                            QUDAT = newdynamicData[i].QUDAT,
                            SECTN = newdynamicData[i].SECTN,
                            //QUANT = newdynamicData[i].QUANT //库存数量
                            QUANTOUT = newdynamicData[i].QUANT
                        });
                    }
                    else
                    {
                        
                        logMstores.Add(new LogMstore
                        {
                            ADDRE = newdynamicData[i].ADDRE,//货位地址
                            BATCH = newdynamicData[i].BATCH,//批次号
                            CFLAG = newdynamicData[i].CFLAG,
                            DEMO1 = ErpOut.ORDNO,//订单号
                            DEMO2 = ErpOut.ITMNO,//行号
                            MATNO = newdynamicData[i].MATNO,//物料编码
                            PALNO = newdynamicData[i].PALNO,
                            QUDAT = newdynamicData[i].QUDAT,
                            SECTN = newdynamicData[i].SECTN,
                            //QUANT = newdynamicData[i].QUANT //库存数量
                            QUANTOUT = UnshippedQuantity.ToString()
                        });
                        break;
                    }                   
                }
               await ZiDong(logMstores);//这一步和手动配货一样
            }
            catch (Exception ex)
            {
                resultData.code = 1;
                resultData.message = ex.Message;
            }
            return resultData;
        }

自动配货的话一般有先入先出原则,也有随机出库原则等等,这个都是根据甲方需求来写。先入先出原则比较简单,查询的时候按时间进行排序查询结果就可以。这里我们用的也是先入先出原则。自动配货的话一般来说比较常用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/57775.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文教你从Linux内核角度探秘JDK NIO文件读写本质(上)

1. 前言 在深入讲解Netty那些事儿之从内核角度看IO模型一文中曾对 Socket 文件在内核中的相关数据结构为大家做了详尽的阐述。 Socket内核结构.png 又在此基础之上介绍了针对 socket 文件的相关操作及其对应在内核中的处理流程&#xff1a; 系统IO调用结构.png 并与 epoll 的…

由阿里三位专家撰写:数据库高效优化:架构、规范SQL技巧文档

引言 学习是一种基础性的能力。然而&#xff0c;“吾生也有涯&#xff0c;而知也无涯。”&#xff0c;如果学习不注意方法&#xff0c;则会“以有涯随无涯&#xff0c;殆矣”。 学习就像吃饭睡觉一样&#xff0c;是人的一种本能&#xff0c;人人都有学习的能力。我们在刚出生…

[附源码]计算机毕业设计springboot作业管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

词袋模型(Bag-of-words model)

词袋模型词袋模型简介示例计算机视觉中的词袋模型词袋模型 简介 词袋模型&#xff08;Bag-of-words model&#xff09;是用于自然语言处理和信息检索中的一种简单的文档表示方法。通过这一模型&#xff0c;一篇文档可以通过统计所有单词的数目来表示&#xff0c;这种方法不考…

redis安装

版本号&#xff1a;redis-6.2.1 下载redis-6.2.1.tar.gz放/opt目录 解压命令&#xff1a;tar -zxvf redis-6.2.1.tar.gz 解压完成后进入目录&#xff1a;cd redis-6.2.1 在redis-6.2.1目录下执行make命令 出现make test 执行make install 查看redis默认安装路径&#xff1a;/u…

二、CANdelaStudio入门-版本介绍

本专栏将由浅入深的展开诊断实际开发与测试的数据库编辑,包含大量实际开发过程中的步骤、使用技巧与少量对Autosar标准的解读。希望能对大家有所帮助,与大家共同成长,早日成为一名车载诊断、通信全栈工程师。 本文介绍CANdelaStudio的各个版本,欢迎各位朋友订阅、评论,可以…

PbootCMS简单两步增加自动清理日志功能

问&#xff1a;网站没人访问触发不了清理怎么办&#xff1f; 答&#xff1a;我建议你不要关心这个&#xff0c;都没人访问你的网站&#xff0c;你还有个锤子东西需要清理&#xff1f; 问&#xff1a;听人说前台插入script触发会不安全&#xff1f; 答&#xff1a;都是成年人…

Web应用程序,简单的日志系统解决方案

一、简介 今天介绍一下&#xff0c;当你的程序没有日志系统时&#xff0c;如何快速方便查看当前程序日志的解决方案。如果你的程序有日志系统&#xff0c;可以不看本篇博客哈。本文实例是使用 C# 讲解&#xff0c;当然实现的核心思想适用于其他语言开发的系统。 二、解决方案…

nexus搭建测试dockermavennpm仓库

JAVA下载 https://www.oracle.com/java/technologies/downloads/archive/ https://login.oracle.com/mysso/signon.jsp QQq951699. [rootvm1 ~]# mkdir -p /data [rootvm1 ~]# mv jdk-8u221-linux-i586.tar.gz /data [rootvm1 ~]# cd /data;tar xf jdk-8u221-linux-i586.tar.g…

222页8万字智慧园区IOC平台运维管理平台解决方案

目 录 第一章 项目概述 7 1.1 园区格局的变化 7 1.1.1 传统安防面临的不足与挑战 7 1.1.2 园区安防未来的发展趋势 7 1.2 需求分析 8 1.2.1 平台集成化 8 1.2.2 数据可视化 8 1.2.3 管控全面化 8 1.2.4 覆盖高清化 9 1.2.5 指挥简易化 9 1.2.6 建设智能化 9 1.3 建设思路 9 1.3…

基于物联网设计的自反馈深紫外杀菌消毒系统(STM32F407)

一、前言 目前常态化防控病毒有很多种,其中主要是人工喷洒消毒液这种消毒方式,这种消毒效果无法得到量化,同时还可能存在喷洒盲区,也会对公民的呼吸道产生刺激,腐蚀损坏公共设施,而对于室内公共空间的消毒的要求会更高,基于这样的状况,人工喷洒消毒液这种方式肯定不太…

[附源码]JAVA毕业设计教学成果管理平台(系统+LW)

[附源码]JAVA毕业设计教学成果管理平台&#xff08;系统LW&#xff09; 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术…

C语言——利用矩阵LU分解法求逆、行列式

本章介绍了LU分解法&#xff0c;以及如何利用LU分解法求逆、行列式&#xff0c;针对每个公式、原理、代码进行了详细介绍&#xff0c;希望可以给大家带来帮助。 目录 LU分解法 概念 确定L、U矩阵 LU分解法的意义 程序设计 LUP求逆 1&#xff09;代码 2&#xff09;代…

uniapp 监听通知栏消息插件(支持白名单、黑名单、过滤) Ba-NotifyListener

简介&#xff08;下载地址&#xff09; Ba-NotifyListener 是一款实时监听通知栏消息的uniapp插件。支持白名单、黑名单&#xff1b;支持监听消息移除&#xff1b;支持自定义过滤条件&#xff08;如短信验证码&#xff09;等。 支持监听所有通知栏消息&#xff08;包含id、ti…

springboot整合layui排坑

参考&#xff1a;thymeleaflayui加载页面渲染时TemplateProcessingException: Could not parse as expression: "_yaoshengting的博客-CSDN博客 目录 1.table渲染问题 2.解决方式 1.将clos后的[[ ]]分成四行写 2.加上 th:inline"none 1.table渲染问题 源代码&…

[附源码]Python计算机毕业设计Django拉勾教育课程管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

spark shuffle·读写流程 和 rdd持久化

1.对比mapreduce和spark mapreduce里 map的第3条就是说&#xff0c;比如我存了很多条数据&#xff0c;如果一条一条写进磁盘&#xff0c;肯定有很多次IO&#xff0c;我先归并到一个缓存里面再溢写磁盘。 spark与其的差别就是用map代替了buffer&#xff0c;因为map存的key唯一&…

[附源码]JAVA毕业设计教学辅助系统(系统+LW)

[附源码]JAVA毕业设计教学辅助系统&#xff08;系统LW&#xff09; 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&…

[附源码]计算机毕业设计springboo酒店客房管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【小5聊】使用div+css布局绘制32支球队比赛对阵图,拭目以待冠军花落谁家

虽然不是狂爱足球爱好者&#xff0c;但多少会有关注下&#xff0c;像梅西和C罗是经常听到的 可能是没有我们队的原因&#xff0c;关注会比较少&#xff0c;只看个结果&#xff0c;所以 趁着这次机会&#xff0c;通过js前端技术divcss布局方式绘制本次世界杯足球比赛对阵图 2022…