在2013即将结束的最后一个月里,我跑客户的时间时间达到了26天,作为一个技术出身的我这是非常不可思议的,在多年前我敢都不敢想! 在历史上一个月里我连续工作的天数也就27天,当然这是呆在公司办公室里,负责码代码,不会与直接客户面对面接触的(目前大多数技术人员都是如此)。这段时间的持续改变让我不得不深思!

 

  一. 代码的价值

    案例1:

    最近有个项目实施难度有点大,当然我本身是技术出身,所以有时候还是比较有优势,因为可以当场为客户解决问题。我们是为一家生产型企业实施一个生产仓库管理系统,现在条件比较复杂,反正就是涉及到生产,出入库等!实施到一个出库的时候,有个功能是这样的:

    客户要求公司客服人员直接查询仓库库存,然后根据订单配货,这个配货是可以合并多个订单的,做好配货单要系统生成一个拣货清单[也就是告诉仓库人员到哪里去拿货,在货架哪里,在货架第几层,是否需要拆托盘,是否要拆箱等等],仓库人员拿着清单直接到仓库将实施项目--你明白软件的价值和个人的价值么?取货让后用叉车搬到代发货区域。然后发货人员拿着PDA(非常老式的那种)去扫描箱码或者托盘条码进行配货校验,最后打印发运标签(每个箱子上都要贴这种标签,每个单子估计都有几百上千箱货)。 

    现在有个问题就是这搬出来的货要自动分配到不同的订单中去,而且要满足订单情况。

    比如A订单 产品P 需要数量 16,000 ; B 订单需要产品 P 数量为 54,000; C订单需要产品P数量 16,000; C 订单需要产品P1  2,000; 

    仓库拣货数量为: 16,000+54,000+16,000 (P产品) ; 2,000 (P1产品)

    P产品包装: 标准包装5,000   P1产品包装: 标准包装 600

     实际拣货为: 4*5000(整箱) + 10*5000(整箱)+ 2*5000(整箱) + 2000(零箱)+ 4000(零箱) --P产品;  3*600(整箱)+200(零箱) 

     那上面分配货品有很多种分配方式,不同的订单可以共箱(在一个箱子上贴两个标签 200 + 400 分别是不同的订单)。

    至于具体情况如何,这个也不是一会能够描述清楚的,做过拣货的朋友应该清楚:

    问题是我写了一段代码,自动分配拣货的,大概花了我4天左右的时间,总共代码行估计接近一千行了,代码部分如下:

int qty = detail.Qty;
                        int fullBoxNum = packageNum != 0 ? qty / packageNum : 0; //理论整箱箱数
                        int sinQty = packageNum != 0 ? qty % packageNum : 0; //理论零箱数
                        int sinBoxNum = sinQty == 0 ? 0 : 1; //理论零箱箱数
                        string PO = detail.OrderNum;//PO
                        ShipLableEntity ship = null;

                        /**
                         * 当拣货得到的箱子中整箱数大于0的情况:
                         * 当拣货得到的箱子中整箱数==0的情况: 说明所有的拣货都要从零箱中去组合得到
                         * */
                        if (listFullBoxes.Count > 0)
                        {
                            //当理论拣货整箱箱数大于0 且 实际整箱也大于0的时候
                            if (fullBoxNum > 0)
                            {
                                //如果理论总箱数小于或等于实际总箱数则扣除实际理论箱数,并且判断是否有零箱
                                if (fullBoxNum <= listFullBoxes.Count)
                                {
                                    ship = FormatShipLable(product, PO, outNum, listFullBoxes.First(), orderEntity, index, fullBoxNum, listDefault, listBills);
                                    listShipLables.Add(ship);
                                    listFullBoxes.RemoveRange(0, fullBoxNum);
                                    index++;
                                    //判断有零箱的情况,找到最适合的箱数,没有就要拆箱分组. 如果没有零箱什么都不用处理 所以不需要else
                                    if (sinBoxNum == 1)
                                    {
                                        //如果存在理论零箱的时候,先要实际零箱的箱数是否大于0且零箱的总数也大于理论零箱的数量
                                        if (listSinBoxes.Count > 0 && listSinBoxes.Sum(a=>a.QTY)>=sinQty)
                                        {
                                            //升序排列,查找大于等于零箱数的第一个箱拆分
                                            listSinBoxes = listSinBoxes.OrderBy(a => a.QTY).ToList();
                                            OutBillEntity tempBill = listSinBoxes.Where(a => a.QTY >= sinQty).FirstOrDefault();
                                            //如果存在满足上面条件的箱,则需要拆分处理
                                            if (tempBill != null)
                                            {
                                                //如果数量刚好满足则直接生成标签 如果不满足则拆分为两个
                                                if (tempBill.QTY == sinQty)
                                                {
                                                    ship = FormatShipLable(product, PO, outNum, tempBill, orderEntity, index, 1, listDefault, listBills);
                                                    listShipLables.Add(ship);
                                                    listSinBoxes.Remove(tempBill);
                                                    index++;
                                                }
                                                else
                                                {
                                                    tempBill.QTY = tempBill.QTY - sinQty;
                                                    OutBillEntity billNew = new OutBillEntity();
                                                    billNew.LairdPN = tempBill.LairdPN;
                                                    billNew.CustomerPN = tempBill.CustomerPN;
                                                    billNew.StackBarCode = tempBill.StackBarCode;
                                                    billNew.BoxBarCode = tempBill.BoxBarCode;
                                                    billNew.QTY = sinQty;
                                                    ship = FormatShipLable(product, PO, outNum, billNew, orderEntity, index, 1, listDefault, listBills);
                                                    listShipLables.Add(ship);
                                                    if (tempBill.QTY <= 0)
                                                    {
                                                        listSinBoxes.Remove(tempBill);
                                                    }
                                                    index++;
                                                }
                                            }
                                            else
                                            {
                                                //如果不存在则需要组合得到,查询组合求和数量小于等于零箱的数量
                                                int zuQty = 0; //计算总和
                                                int sinIndex = 0; //满足条件之后停止的索引
                                                for (int i = 0; i < listSinBoxes.Count; i++)
                                                {
                                                    zuQty += listSinBoxes[i].QTY;
                                                    if (zuQty >= sinQty)
                                                    {
                                                        sinIndex = i;
                                                        break;
                                                    }
                                                }
                                                //如果刚好满足则生成相应的标签,并且删除
                                                if (zuQty == sinQty)
                                                {
                                                    for (int i = 0; i <= sinIndex; i++)
                                                    {
                                                        ship = FormatShipLable(product, PO, outNum, listSinBoxes[i], orderEntity, index, 1, listDefault, listBills);
                                                        listShipLables.Add(ship);
                                                        index++;
                                                    }
                                                    listSinBoxes.RemoveRange(0, sinIndex + 1);
                                                }
                                                else
                                                {
                                                    //删除之前的,最后一个拆分
                                                    int beforeQty = 0;
                                                    for (int i = 0; i <= sinIndex - 1; i++)
                                                    {
                                                        beforeQty += listSinBoxes[i].QTY;
                                                        ship = FormatShipLable(product, PO, outNum, listSinBoxes[i], orderEntity, index, 1, listDefault, listBills);
                                                        listShipLables.Add(ship);
                                                        index++;
                                                    }
                                                    tempBill = listSinBoxes[sinIndex];
                                                    tempBill.QTY = tempBill.QTY - (sinQty - beforeQty);
                                                    OutBillEntity billNew = new OutBillEntity();
                                                    billNew.LairdPN = tempBill.LairdPN;
                                                    billNew.CustomerPN = tempBill.CustomerPN;
                                                    billNew.StackBarCode = tempBill.StackBarCode;
                                                    billNew.BoxBarCode = tempBill.BoxBarCode;
                                                    billNew.QTY = sinQty - beforeQty;
                                                    ship = FormatShipLable(product, PO, outNum, billNew, orderEntity, index, 1, listDefault, listBills);
                                                    listShipLables.Add(ship);
                                                    index++;
                                                    listSinBoxes.RemoveRange(0, sinIndex);
                                                }
                                            }
                                        }
                                        else
                                        { 
                                            //如果实际零箱数为0 或者实际零箱数小于理论零箱数,那么就要拆整箱,因为实际整箱大于理论整箱所以拆整箱
                                            if (listFullBoxes.Count > 0)
                                            {
                                                OutBillEntity tempBill = listFullBoxes.First();
                                                tempBill.QTY = tempBill.QTY - sinQty;
                                                listFullBoxes.Remove(tempBill);
                                                listSinBoxes.Add(tempBill);
                                                OutBillEntity billNew = new OutBillEntity();
                                                billNew.LairdPN = tempBill.LairdPN;
                                                billNew.CustomerPN = tempBill.CustomerPN;
                                                billNew.StackBarCode = tempBill.StackBarCode;
                                                billNew.BoxBarCode = tempBill.BoxBarCode;
                                                billNew.QTY = sinQty;
                                                ship = FormatShipLable(product, PO, outNum, billNew, orderEntity, index, 1, listDefault, listBills);
                                                listShipLables.Add(ship);
                                                index++;
                                            }
                                        }
                                    }
                                }
智能拣货分配部分代码

相关文章: