PDA库位商品出库适配算法

  1. 功能描述
  2. 代码实现
  3. 算法需求

回到顶部

功能描述

  

  在PDA上面,通过扫描订单号,查询该商品的款号,尺码,订单数;同时适配仓库库位商品【SKU】,显示该商品所在库位,库存数量,适配数。

  因为PDA界面小,所以对表格拆分显示为俩个,代码也相应复杂一些。

回到顶部

代码实现

  

        /// <summary>
        /// 读头数据处理
        /// </summary>
        private void HandleData(Symbol.Barcode.ReaderData TheReaderData)
        {
              //定单适配
            if (tc_container.SelectedIndex == 1)
            {
                txtWmsNo.Text = TheReaderData.Text;

                BindOrderDetailGrid(txtWmsNo.Text.Trim());
                btnAdaptor_Click(null, null);
            }
        }    
     private void BindOrderDetailGrid(string wmsID)
        {
            lv_Order.Items.Clear();

            try
            {
                _allOrderDetail = _repository.GetOrderDetail(wmsID);
                if (_allOrderDetail.Any())
                {
                    foreach (OrderDetail detail in _allOrderDetail)
                    {
                        ListViewItem item = new ListViewItem();
                        item.SubItems[0].Text = detail.StyleNo;
                        item.SubItems.Add(detail.Size);
                        item.SubItems.Add(detail.OrderNum.ToString());//订单数
                        lv_Order.Items.Add(item);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("查询出错:" + ex.Message);
                btnExit_Click(null, null);
            }
        }
     //批量适配
        private void btnAdaptor_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txtWmsNo.Text.Trim()) || txtWmsNo.Text == "扫描WMS单号…")
            {
                MessageBox.Show("请先扫描wmsID。", "操作提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
                return;
            }
            if (_repository.ExitsWmsID(txtWmsNo.Text.Trim()))
            {
                DialogResult result = MessageBox.Show("该单号已经适配过了,是否继续?", "操作提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
                if (result != DialogResult.OK)
                {
                    lv_Adaptor.Items.Clear();
                    return;
                }
            }

            _differenceQty = 0;
            _list.Clear();

            try{
                _goodList = _repository.GetGoodsList(string.Join(",",_allOrderDetail.Select(c=>"‘"+c.StyleNo+"‘").ToArray()));
             }
            catch (Exception ex)
            {
                MessageBox.Show("查询出错:" + ex.Message);
                btnExit_Click(null, null);
            }

            if (_goodList.Any())
            {
                _allOrderDetail.ForEach(order => BindAdaptorGrid(_goodList.Where(c => c.StyleNo == order.StyleNo).ToList(), order.Size, order.OrderNum, false));
            }

            if (_list.Any())
            {
                _list.ForEach(o => lv_Adaptor.Items.Add(o));

                btnSave.Enabled = true;
                lbl_difNum.Text = "总差异数:" + _differenceQty;
                lblMsg.Text = "适配成功,请保存!";
            }
            else
            {
                btnSave.Enabled = false;
                lblMsg.Text = "适配失败,请先维护库存!";
            }
        }
        /// <summary>
        /// 绑定适配表
        /// 如果数量相等,则按照库位匹配
        /// </summary>
        /// <param name="orderNum">订单数</param>
        /// <param name="isSingle">是否单款</param>
        private void BindAdaptorGrid(List<PDA_TGoods> goodsByStyleNo,string size,int orderNum,bool isSingle)
        {
            lv_Adaptor.Items.Clear();
            lblMsg.Text = string.Empty;

            _orderNum = orderNum;

            List<GoodsSummary> summary_goods = GetGoodsSummary(goodsByStyleNo);

            if (summary_goods.Any())
            {
                int stockSumNum = goodsByStyleNo.Count();        //库存数总和
                bool isBreak = false;

                //差异数算法:[订单数>=库存数总和-->差异数=订单数-库存数;订单数<库存数总和-->差异数=0]
                int singleDifNum = (_orderNum >= stockSumNum ? _orderNum - stockSumNum : 0);
                _differenceQty += singleDifNum;
                if (isSingle)
                    lbl_difNum.Text = "单款差异:" + singleDifNum;

                foreach (var g in summary_goods)
                {
                    ListViewItem item = new ListViewItem();
                    item.SubItems[0].Text = g.StyleNo;      //库位
                    item.SubItems.Add(g.StockNo.ToString()); //库存数
                    item.SubItems.Add(g.SkuNum.ToString()); //库存数   

                    //适配数算法:
                    //(1)订单数>=库存数总和-->适配数=库存数;
                    //(2)订单数<库存数总和-->适配数=任意库位的数量的分配(必须=订单数)
                    int adaptorNum = 0;
                    if (_orderNum >= stockSumNum)
                        adaptorNum = g.SkuNum;
                    else
                        adaptorNum = GetAdaptorNum(_orderNum, g.SkuNum, out isBreak);  

                    item.SubItems.Add(adaptorNum.ToString());
                    //item.SubItems.Add(g.Sku);         //条码[不可见]
                    item.SubItems.Add(size);          //尺码[不可见]

                    if (isSingle)
                       lv_Adaptor.Items.Add(item);
                    else
                        _list.Add(item);

                    if (isBreak) break;//适配到,则不再进行其他库位的适配
                }
            }
        }

        //计算适配数
        private int GetAdaptorNum(int orderNum, int stockNum,out bool isBreak)
        {
            int adptorNum = 0;
            if (orderNum >= stockNum)
            {
                adptorNum = stockNum;
                isBreak = false;
            }
            else
            {
                adptorNum = _orderNum;
                isBreak = true;
            }

            _orderNum = _orderNum - stockNum;

            if (_orderNum == 0)
                isBreak = true;

            return adptorNum;
        }
     /// <summary>
        /// 按款汇总商品总数,并做排序
        /// </summary>
        /// <param name="PDA_TGoods"></param>
        /// <returns></returns>
        private static List<GoodsSummary> GetGoodsSummary(List<PDA_TGoods> goods)
        {
            List<GoodsSummary> summary_goods = new List<GoodsSummary>();
            foreach (var g in goods.GroupBy(o => new { o.StockNo, o.StyleNo }))
            {
                GoodsSummary gt = new GoodsSummary();
                gt.SkuNum = g.Count();
                gt.StockNo = g.First().StockNo;
                gt.StyleNo = g.First().StyleNo;
                summary_goods.Add(gt);
            }

            //库存量大优先;同等数量,库位优先策略
            return summary_goods.OrderByDescending(o => o.SkuNum).ThenBy(o => o.StockNo).ToList();
        }

回到顶部

算法需求

    (1)订单数>=库存数总和 则 适配数 = 库存数;

         (2)订单数<库存数总和  则 适配数 = 任意库位的数量的分配(必须=订单数)

        (3)库存量大的库位优先适配;同等数量的库位,库位编号小的优先适配策略

时间: 2024-08-14 18:48:14

PDA库位商品出库适配算法的相关文章

生产源库位和目的库位动态过滤

实施过程中,碰到一个问题,希望生产计划人员不能看到除生产以外的其他内部库位,但缺又不能影响生产人员在仓库的正常接收货. 首先想到的是用rule来控制对库位的访问,rule的对象不能是mrp.production只能是stock.location,否则对location_src_id 和location_dest_id的限制不起作用. 只能用stock.location的rule来限制,但这样的问题是,虽然生产看不到其他内部库位了,却不能从其他库位,接收,发送物料了. 于是,二开了跟权限组挂钩的库

[易飞]取消库位规格书

程序代号: CMSB07 程序名称: 取消库位管理 Parent Class: 系统分析代号: 信息文件:BOMTD (R/W) 组合单单头 BOMTE (R/W) 组合单单身 BOMTF (R/W) 拆解单单头 BOMTG (R/W) 拆解单单身 CMSMA (R/W) 公用参数档 CMSNI (R/W) 仓库库位档 COPTH (R/W) 销货单单身信息档 COPTJ (R/W) 销退单单身信息档 COPTO (R/W) 出货通知单身档 CUSTN (R/W) 交易单据单身档 DHQTE (

根据出库、入库表,实现对库存的信息查询

数据库:mysql 要求:多个仓库.多个产品 表:1.入库凭证表 t_rkpz 2.入库明细表 t_rkpzmx 3.出库凭证表 t_ckpz 4.出库凭证表 t_ckpzmx 说明:两对主从表 [(主表:入库凭证表 t_rkpz,主键:rkbh)(从表:入库明细表 t_rkpzmx ,外键:rkbh)]   [(主表:出库凭证表 t_ckpz ,主键:rkbh)(从表:出库凭证表 t_ckpzmx ,外键:rkbh)] 建表 : 字段说明:入库编号.入库日期.仓库名称.仓库管理员 字段说明:所

原材料批次管理立体仓库库位管理生产领料管理生产线工序管理产成品系列号唯一码管理产品质量追溯管理

一支汉码盘点机,轻松帮您实现: 原材料批次管理, 采购入库管理, 立体仓库库位管理, 生产任务管理, 生产领料管理, 生产线工序管理, 产成品系列号唯一码管理, 销售出库管理, 售后维修管理, 产品质量追溯管理. 仓库管理,还有什么汉码盘点机不能干的?????? 汉码盘点机--专注于傻瓜式的仓库条码管理,帮您实现仓储物流信息化,自动化.实现现代化仓储物流管理!

出库发货扫描检测软件(方案)

产品发货扫描检测系统: 系统背景: 在仓库产品出库拣货发货的运作流程中,企业的操作一般为根据出库清单去仓库拣货,并根据出库清单发货:随着产品出库数量的增加,人工发货和手工记录将会导致产品出库发货的错误,附加着不必要的追货查货工作和及给企业带来损失. 系统特点:依据现有企业的发货清单报表(含单号.物料编码.产品名称.数量),将清单导入至软件里,仓库拣货扫描货品条码进行发货校验检测.过程进行条码扫描检测,达到对发货出库数据的准确性,从而避免人为判断导致操作错误.扫描记录产生系统报表,便于往后查询追溯

Xcode5.1 64位添加第三方库真机测试时出现 Apple Mach -O Linker Error

今天添加微信分享的时候添加微信的静态文件和我以前添加的Core-Plot第三方库发生了冲突, 出现一大堆的 "Apple  Mach  -O Linker Error" , 错误分析: 这次出现错误的原因是 Architectures不统一造成的,微信的APi要求用32位编译,而第三方库是包含了64位. 解决方法: 解决的原理很简单 ,就是把Architectures 统一,把项目的Architectures和所引用的第三反库的(如果还有pod进来的pod内的targets的内容也要修

C++笔记(6):标准模板库STL:容器、迭代器和算法

STL(Standard Template Library)是C++标准库的一部分.STL的代码从广义上讲分为三类:容器.迭代器和算法. 1.容器 2.迭代器 3.算法  -------------------------------------------------------------------------------------------------------------------------- 1.容器 顺序容器容器是特定类型对象的集合.顺序容器为程序员提供控制元素存储和访问

MySQL_产品昨日库存与历史入库历史出库成本_20161124

产品昨日库存与历史入库历史出库成本 SELECT d.ID,a.*,e.昨日订单额 ,b.昨天入库额,b.历史2天,b.历史3天,b.历史4天,b.历史5天,b.历史6天,b.历史7天,b.历史8天,b.历史9天,b.历史10天 ,b.历史11天,b.历史12天,b.历史13天,b.历史14天,b.历史15天,b.历史16天,b.历史17天,b.历史18天,b.历史19天 ,b.历史20天,b.历史21天,b.历史22天,b.历史23天,b.历史24天,b.历史25天,b.历史26天,b.历史2

使用Jasperreporter生成入库出库单打印等报表操作

项目需要打印报表:就是那种生成入库单,出库单等的操作.使用到的技术:使用iReport Designer5.1.0设计报表,使用struts2+jasperreporter生成最终填充数据的报表 首先看一下效果图 一.使用iReport Designer 设计报表 1.安装iReport Designer,过程比较简单.需要强调一下,5.1.0版本不支持jdk8,我又重新装了jdk7.然后在iReport-5.1.0\etc\ireport.conf下配置一下jdkhome,如下图所示为我的配置