WMS手动配货和自动配货的区别-创新互联-成都快上网建站

WMS手动配货和自动配货的区别-创新互联

手动配货

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

成都创新互联公司于2013年成立,是专业互联网技术服务公司,拥有项目成都网站制作、网站设计网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元河间做网站,已为上家服务,为河间各地企业和个人服务,联系电话:13518219792查

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

public async TaskQueryPeiH(int pages, int limit, string matno, string batch, string cflag)
        {PageData pageData = new PageData();
            var list = _fsql.Select()
                .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 TaskQueryPeiH(ListlogMstores)
        {return Ok(await _erpOutService.PeiHuo2(logMstores));
        }

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

public async TaskPeiHuo2(ListlogMstores)
        {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)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 TaskPeiHuo(LOGOUTTASK lOGOUTTASK)
        {try
            {var ErpOut = await _fsql.Select().Where(x =>x.ORDNO == lOGOUTTASK.ORDNO && x.ITMNO == lOGOUTTASK.ITMNO).FirstAsync();
                string quant0 = ErpOut.QUANT0;
                var Pdian = await _fsql.Select().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().Where(x =>x.Id == Convert.ToDecimal(lOGOUTTASK.ErpoutId)).First();
                    //修改出库单已配货数量
                    var uprows = _fsql.Update().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 TaskAutomaticPicking(string guid)
        {ResultData resultData = new ResultData()
            {code = 0,
                message = "success",
            };
            try
            {ListlogMstores = new List();
                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>(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;
        }

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

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


新闻标题:WMS手动配货和自动配货的区别-创新互联
标题路径:http://kswjz.com/article/hecse.html
扫二维码与项目经理沟通

我们在微信上24小时期待你的声音

解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流