public KanbanScan CreateKanbanScan(KanbanCard card, FlowDetail matchDetail, User scanUser, DateTime? scanTime)
        {
            KanbanScan scan = new KanbanScan();
            if (card != null && matchDetail != null && scanUser != null)
            {
                scan = Mapper.Map<KanbanCard, KanbanScan>(card);
                scan.ScanUserId = scanUser.Id;
                scan.ScanUserName = scanUser.Name;
                scan.ScanTime = scanTime;
                scan.ReferenceItemCode = card.ReferenceItemCode;
                //用物流中心记工位
                scan.LogisticCenterCode = matchDetail.BinTo;
                //FlowDetail fd = this.genericMgr.FindAll<FlowDetail>("from FlowDetail where Id = ? ", card.FlowDetailId).SingleOrDefault();
                scan.ScanQty = matchDetail.MinUnitCount;
                scan.IsOrdered = false;

                this.genericMgr.Create(scan);
                card.ScanId = scan.Id;
                return scan;
            }
            return scan;
        }
        public ActionResult Edit(KanbanScan scan)
        {

            ViewBag.ScanQty = scan.ScanQty.ToString("0.##");
            ViewBag.TempKanbanCard = scan.TempKanbanCard;
            if (scan.ScanQty > scan.UnitCount)
            {
                SaveErrorMessage("扫描数不能大于看板数。");
                return View(scan);
            }
            if (string.IsNullOrEmpty(scan.TempKanbanCard))
            {
                SaveErrorMessage("临时看板卡号不能为空。");
                return View(scan);
            }
            this.kanbanScanMgr.ModifyScanQty(scan, scan.ScanQty, scan.TempKanbanCard, this.CurrentUser);
            SaveSuccessMessage(Resources.KB.KanbanScan.KanbanScan_Updated);

            return View(scan);
        }
        public void ImportkanbanScanXls(Stream inputStream)
        {
            if (inputStream.Length == 0)
            {
                throw new BusinessException("Import.Stream.Empty");
            }
            BusinessException businessException = new BusinessException();
            HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
            ISheet sheet = workbook.GetSheetAt(0);
            IEnumerator rows = sheet.GetRowEnumerator();
            ImportHelper.JumpRows(rows, 10);

            #region 列定义
            int colFlowCode = 1; // 路线代码
            int colTempCardNo = 2; // 临时看板卡号
            int colItemCode = 3; // 物料
            int colQty = 4; // 数量

            #endregion
            IList<KanbanScan> exactKanbanScanList = new List<KanbanScan>();
            int i = 0;
            while (rows.MoveNext())
            {
                i++;
                HSSFRow row = (HSSFRow)rows.Current;
                if (!ImportHelper.CheckValidDataRow(row, 0, 2))
                {
                    break;//边界
                }
                KanbanScan kanbanScan = new KanbanScan();
                string flowCode = string.Empty;
                string tempCardNo = string.Empty;
                string itemCode = string.Empty;
                int qty = 0;

                #region 读取数据

                #region 读取路线代码
                flowCode = ImportHelper.GetCellStringValue(row.GetCell(colFlowCode));
                if (string.IsNullOrWhiteSpace(flowCode))
                {
                    businessException.AddMessage(string.Format("第{0}行路线不能为空", i));
                }
                else
                {
                }
                kanbanScan.Flow = flowCode;
                #endregion

                #region 读取临时看板卡号
                tempCardNo = ImportHelper.GetCellStringValue(row.GetCell(colTempCardNo));
                if (string.IsNullOrWhiteSpace(tempCardNo))
                {
                    businessException.AddMessage(string.Format("第{0}行临时看板卡号不能为空", i));
                }
                else
                {


                }
                kanbanScan.TempKanbanCard = tempCardNo;
                #endregion
                #region 件号
                itemCode = ImportHelper.GetCellStringValue(row.GetCell(colItemCode));
                if (string.IsNullOrWhiteSpace(itemCode))
                {
                    businessException.AddMessage(string.Format("第{0}行数量不能为空", i));
                }
                else
                {

                }
                kanbanScan.Item = itemCode;
                #endregion

                #region 读取数量
                string readQty = ImportHelper.GetCellStringValue(row.GetCell(colQty));
                if (string.IsNullOrWhiteSpace(readQty))
                {
                    businessException.AddMessage(string.Format("第{0}行数量不能为空", i));
                }
                else
                {
                    if (!int.TryParse(readQty, out qty))
                    {
                        businessException.AddMessage(string.Format("第{0}行数量输入有误。", i));
                    }
                    if (qty < 0)
                    {
                        businessException.AddMessage(string.Format("第{0}行数量输入有误。", i));
                    }
                }
                kanbanScan.OrderQty = qty;
                #endregion

                exactKanbanScanList.Add(kanbanScan);

                #endregion
            }
            if (businessException.HasMessage)
            {
                throw businessException;
            }
            this.Scan(exactKanbanScanList);
        }
        public IList<KanbanScan> OrderCard(string region, string supplier, string lccode, string orderTime, string scanIds, User orderUser, ref string orderNos)
        {
            DateTime dt = DateTime.Now;
            IList<KanbanScan> result = new List<KanbanScan>();

            string hql = "from KanbanScan where IsOrdered = ? and Id in (" + scanIds + ")";
            IList<object> paraList = new List<object>();
            paraList.Add(false);

            IList<KanbanScan> scans = null;
            scans = this.genericMgr.FindAll<KanbanScan>(hql, paraList.ToArray());

            if (scans != null)
            {
                IDictionary<string, IList<KanbanScan>> flowScanDict = new Dictionary<string, IList<KanbanScan>>();
                //flow-item-qty
                IDictionary<string, IDictionary<string, decimal>> flowItemQty = new Dictionary<string, IDictionary<string, decimal>>();
                // 把同一个flow的kanbanscan放到一起
                IDictionary<string, KanbanScan> flowItemPONo = new Dictionary<string, KanbanScan>();
                //flow-item-iskit
                IDictionary<string, HashSet<string>> flowNonKitItems = new Dictionary<string, HashSet<string>>();
                IDictionary<string, HashSet<string>> flowKitItems = new Dictionary<string, HashSet<string>>();

                foreach (KanbanScan scan in scans)
                {
                    if (flowScanDict.ContainsKey(scan.Flow))
                    {
                        flowScanDict[scan.Flow].Add(scan);
                    }
                    else
                    {
                        IList<KanbanScan> scanSameFlow = new List<KanbanScan>();
                        scanSameFlow.Add(scan);
                        flowScanDict.Add(scan.Flow, scanSameFlow);
                    }

                    if (scan.IsKit)
                    {
                        if (flowKitItems.ContainsKey(scan.Flow))
                        {
                            flowKitItems[scan.Flow].Add(scan.Item);
                        }
                        else
                        {
                            HashSet<string> kitItems = new HashSet<string>();
                            kitItems.Add(scan.Item);

                            flowKitItems.Add(scan.Flow, kitItems);
                        }
                    }
                    else
                    {
                        if (flowNonKitItems.ContainsKey(scan.Flow))
                        {
                            flowNonKitItems[scan.Flow].Add(scan.Item);
                        }
                        else
                        {
                            HashSet<string> nonKitItems = new HashSet<string>();
                            nonKitItems.Add(scan.Item);

                            flowNonKitItems.Add(scan.Flow, nonKitItems);
                        }
                    }

                    if (!string.IsNullOrEmpty(scan.PONo) && !string.IsNullOrEmpty(scan.POLineNo)
                         && !flowItemPONo.ContainsKey(scan.Flow + scan.Item))
                    {
                        flowItemPONo.Add(scan.Flow + scan.Item, scan);
                    }

                    if (flowItemQty.ContainsKey(scan.Flow))
                    {
                        if (flowItemQty[scan.Flow].ContainsKey(scan.Item))
                        {
                            flowItemQty[scan.Flow][scan.Item] += scan.ScanQty;
                        }
                        else
                        {
                            flowItemQty[scan.Flow].Add(scan.Item, scan.ScanQty);
                        }
                    }
                    else
                    {
                        IDictionary<string, decimal> itemQty = new Dictionary<string, decimal>();
                        itemQty.Add(scan.Item, scan.ScanQty);

                        flowItemQty.Add(scan.Flow, itemQty);
                    }
                }

                //IDictionary<string, WorkingCalendar> regionWcCache = new Dictionary<string, WorkingCalendar>();
                foreach (KeyValuePair<string, IList<KanbanScan>> k in flowScanDict)
                {
                    IList<KanbanScan> sameFlow = k.Value;

                    FlowMaster fm = this.genericMgr.FindAll<FlowMaster>("from FlowMaster where Code = ? ", k.Key).SingleOrDefault();
                    if (fm == null)
                    {
                        KanbanScan res = new KanbanScan();
                        res.Flow = k.Key;
                        res.Ret = KBProcessCode.NoFlowMaster;
                        res.Msg = Resources.KB.KanbanCard.Process_NoFlowMaster;
                        result.Add(res);
                    }
                    else
                    {
                        //考虑跨天,fm.partyto等于kanbanscan上的region
                        //WorkingCalendar currentWorkcalendar = null;
                        //if (regionWcCache.ContainsKey(fm.PartyTo))
                        //{
                        //    currentWorkcalendar = regionWcCache[fm.PartyTo];
                        //}
                        //else
                        //{
                        //    currentWorkcalendar = workingCalendarMgr.GetWorkingCalendarByDatetimeAndRegion(dt, fm.PartyTo);
                        //    if (currentWorkcalendar == null)
                        //    {
                        //        KanbanScan res = new KanbanScan();
                        //        res.Region = region;
                        //        res.Ret = KBProcessCode.NoWorkingCalendar;
                        //        res.Msg = Resources.KB.KanbanCard.Process_NoWorkingCalendar + ":Region=" + fm.PartyTo + " Date=" + dt;
                        //        result.Add(res);
                        //        continue;
                        //    }
                        //    else {
                        //        regionWcCache.Add(fm.PartyTo, currentWorkcalendar);
                        //    }
                        //}

                        //交货时段开始和结束时间
                        //考虑跨天
                        //StartEndTime seTime = ForwardCalculateNextDeliveryForSpecificWorkCalendar(currentWorkcalendar, dt, fm, this.flowMgr.GetFlowStrategy(fm.Code));
                        //if (KanbanUtility.IsMinAndMaxDateTime(seTime.StartTime, seTime.EndTime))
                        //{
                        //    KanbanScan res = new KanbanScan();
                        //    res.Flow = k.Key;
                        //    res.Ret = KBProcessCode.NoFlowShiftDetail;
                        //    res.Msg = Resources.KB.KanbanCard.Process_NoFlowShiftDetail + ":WorkDate-" + currentWorkcalendar.WorkingDate.Date;
                        //    result.Add(res);
                        //}
                        //else
                        //{

                        //IList<string> items = flowItemQty[k.Key].Keys.ToList<string>();
                        OrderMaster newOrder = null;
                        if (flowNonKitItems.ContainsKey(k.Key))
                        {
                            IList<string> items = flowNonKitItems[k.Key].ToList<string>();
                            newOrder = orderMgr.TransferFlow2Order(fm, items, dt, true);
                        }
                        else if (flowKitItems.ContainsKey(k.Key))
                        {
                            newOrder = orderMgr.TransferFlow2Order(fm, null, dt, false);
                        }

                        if (newOrder != null)
                        {
                            string[] setimestring = orderTime.Split('~');
                            newOrder.IsAutoRelease = true;
                            newOrder.StartTime = DateTime.Parse(setimestring[0]);
                            newOrder.WindowTime = DateTime.Parse(setimestring[1]);

                            //non kit items
                            if (newOrder.OrderDetails != null)
                            {
                                for (int i = 0; i < newOrder.OrderDetails.Count; i++)
                                {
                                    newOrder.OrderDetails[i].RequiredQty = flowItemQty[k.Key][newOrder.OrderDetails[i].Item];
                                    newOrder.OrderDetails[i].OrderedQty = flowItemQty[k.Key][newOrder.OrderDetails[i].Item];

                                    //if (flowItemPONo.ContainsKey(k.Key + newOrder.OrderDetails[i].Item))
                                    //{
                                    //    newOrder.OrderDetails[i].PONo = flowItemPONo[k.Key + newOrder.OrderDetails[i].Item].PONo;
                                    //    newOrder.OrderDetails[i].POLineNo = flowItemPONo[k.Key + newOrder.OrderDetails[i].Item].POLineNo;
                                    //}
                                }
                            }

                            //kit items
                            if (flowKitItems.ContainsKey(k.Key))
                            {
                                IList<string> kitItems = flowKitItems[k.Key].ToList<string>();
                                foreach (string kitItem in kitItems)
                                {
                                    decimal kitQty = flowItemQty[k.Key][kitItem];
                                    IList<ItemKit> itemKits = itemMgr.GetKitItemChildren(kitItem);
                                    if (itemKits != null && itemKits.Count > 0)
                                    {
                                        foreach (ItemKit ik in itemKits)
                                        {
                                            OrderDetail od = new OrderDetail();
                                            od.Item = ik.ChildItem.Code;
                                            Item itemkkk = this.genericMgr.FindById<Item>(od.Item);
                                            od.ItemDescription = itemkkk.Description;
                                            od.Uom = itemkkk.Uom;
                                            od.BillAddress = newOrder.BillAddress;
                                            od.BillAddressDescription = newOrder.BillAddressDescription;
                                            //od.TraceCode = kitItem;
                                            od.RequiredQty = kitQty * ik.Qty;
                                            od.OrderedQty = kitQty * ik.Qty;

                                            //if (flowItemPONo.ContainsKey(k.Key + kitItem))
                                            //{
                                            //    od.PONo = flowItemPONo[k.Key + kitItem].PONo;
                                            //    od.POLineNo = flowItemPONo[k.Key + kitItem].POLineNo;
                                            //}

                                            newOrder.AddOrderDetail(od);
                                        }
                                    }
                                }
                            }

                            try
                            {
                                orderMgr.CreateOrder(newOrder);
                                orderNos = orderNos + newOrder.OrderNo + ";";
                                for (int j = 0; j < sameFlow.Count; j++)
                                {
                                    //设置kanbanscan上的结转数量,日期等
                                    sameFlow[j].IsOrdered = true;
                                    sameFlow[j].OrderQty = sameFlow[j].ScanQty;
                                    sameFlow[j].OrderUserId = orderUser.Id;
                                    sameFlow[j].OrderUserName = orderUser.Name;
                                    sameFlow[j].OrderTime = dt;
                                    sameFlow[j].OrderNo = newOrder.OrderNo;
                                    this.genericMgr.Update(sameFlow[j]);
                                    //设置看板卡状态到Ordered
                                    KanbanCard card = this.kanbanCardMgr.GetByCardNo(sameFlow[j].CardNo);
                                    card.Status = KBStatus.Ordered;
                                    this.genericMgr.Update(card);
                                    //如果看板卡是多轨,结转时累加多轨循环量,在扫描的时候处理
                                    //if (this.multiSupplyGroupMgr.IsKanbanCardMultiSupplyGroupEnabled(card))
                                    //{
                                    //    this.multiSupplyGroupMgr.KBAccumulateCycleAmount(card, sameFlow[j].OrderQty);
                                    //}
                                    //记录看板order事务
                                    this.kanbanTransactionMgr.RecordKanbanTransaction(card, orderUser, dt, KBTransType.Order);

                                    sameFlow[j].Ret = KBProcessCode.Ok;
                                    sameFlow[j].Msg = Resources.KB.KanbanCard.Process_Ok;
                                    result.Add(sameFlow[j]);
                                }
                            }
                            catch (BusinessException be)
                            {
                                KanbanScan res = new KanbanScan();
                                res.Flow = k.Key;
                                res.Ret = KBProcessCode.CreateOrderFailed;
                                res.Msg = Resources.KB.KanbanCard.Process_CreateOrderFailed + ":" + be.GetMessages()[0].GetMessageString();
                                result.Add(res);
                            }
                        }
                        else
                        {
                            KanbanScan res = new KanbanScan();
                            res.Flow = k.Key;
                            res.Ret = KBProcessCode.OrderTransferError;
                            res.Msg = Resources.KB.KanbanCard.Process_OrderTransferError;
                            result.Add(res);
                        }
                        //}
                    }
                }
            }

            return result;
        }
        public void ModifyScanQty(KanbanScan scan, decimal newQty, string tempKanbanCard, User modifyUser)
        {
            DateTime dt = DateTime.Now;
            scan.ScanQty = newQty;
            scan.TempKanbanCard = tempKanbanCard;
            this.genericMgr.Update(scan);

            KanbanCard card = this.kanbanCardMgr.GetByCardNo(scan.CardNo);
            this.kanbanTransactionMgr.RecordKanbanTransaction(card, modifyUser, dt, KBTransType.ModifyScan);
        }
        public void Scan(IList<KanbanScan> kanbanScanList)
        {
            BusinessException bussinessException = new BusinessException();
            IList<KanbanScan> exactKanbanScanList = new List<KanbanScan>();
            foreach (KanbanScan kanbanScan in kanbanScanList)
            {
                FlowDetail flowDetail = genericMgr.FindAll<FlowDetail>("from FlowDetail d where d.Flow = ? and d.Item = ?", new object[] { kanbanScan.Flow, kanbanScan.Item }).FirstOrDefault();

                if (flowDetail == null)
                {
                    bussinessException.AddMessage("没有维护路线{0}物料代码{1}", kanbanScan.Flow, kanbanScan.Item);
                }
                else
                {
                    FlowMaster flowMaster = genericMgr.FindById<FlowMaster>(flowDetail.Flow);
                    User scanUser = SecurityContextHolder.Get();
                    KanbanScan scan = new KanbanScan();
                    scan.CardNo = kanbanScan.TempKanbanCard;
                    scan.Flow = flowMaster.Code;
                    scan.Item = flowDetail.Item;
                    scan.FlowDetailId = flowDetail.Id;
                    scan.ItemDescription = genericMgr.FindById<Item>(flowDetail.Item).Description;
                    Party fromParty = genericMgr.FindById<Party>(flowMaster.PartyFrom);
                    scan.Supplier = flowMaster.PartyFrom;
                    scan.SupplierName = fromParty.Name;
                    //if (fromParty is Supplier)
                    //{
                    //    scan.LogisticCenterCode = ((Supplier)fromParty).LogisticsCentre;
                    //}
                    scan.Region = flowMaster.PartyTo;
                    scan.RegionName = genericMgr.FindById<Party>(flowMaster.PartyTo).Name;
                    scan.ScanUserId = scanUser.Id;
                    scan.ScanUserName = scanUser.Name;
                    scan.ScanTime = DateTime.Now;
                    scan.ScanQty = kanbanScan.OrderQty;
                    scan.OrderQty = 0;
                    scan.TempKanbanCard = kanbanScan.TempKanbanCard;
                    scan.Sequence = "0";
                    scan.IsOrdered = false;

                    exactKanbanScanList.Add(scan);
                }
            }
            if (bussinessException.HasMessage)
            {
                throw bussinessException;
            }
            foreach (KanbanScan kb in exactKanbanScanList)
            {
                genericMgr.Create(kb);
            }
        }
        public KanbanScan Scan(string cardNo, User scanUser, Boolean isScanBySD)
        {
            KanbanScan kbscan = new KanbanScan();
            KanbanCard card = this.kanbanCardMgr.GetByCardNo(cardNo);

            //是否有效(未冻结)
            if (this.kanbanCardMgr.IsEffectiveCard(card))
            {
                if (this.kanbanCardMgr.IsFrozenCard(card))
                {
                    card.OpTime = DateTime.Now;
                    SetCardRetMsg(card, KBProcessCode.Frozen, Resources.KB.KanbanCard.Process_Frozen);
                }
                else
                {
                    FlowDetail fd = this.genericMgr.FindAll<FlowDetail>("from FlowDetail where Id = ? ", card.FlowDetailId).SingleOrDefault();
                    DateTime dt = DateTime.Now;
                    //if (!string.IsNullOrEmpty(card.MultiSupplyGroup))
                    //{
                    //    CreateKanbanScan(card, card.Qty, scanUser, dt);
                    //}
                    //else
                    //{
                    kbscan = CreateKanbanScan(card, fd, scanUser, dt);
                    //}
                    card.Status = KBStatus.Scanned;
                    card.LastUseDate = dt;
                    card.OpTime = dt;
                    this.genericMgr.Update(card);
                    this.kanbanTransactionMgr.RecordKanbanTransaction(card, scanUser, dt, KBTransType.Scan);
                }
            }
            else
            {
                card.OpTime = DateTime.Now;
                SetCardRetMsg(card, KBProcessCode.NotEffective, Resources.KB.KanbanCard.Process_NotEffective);
            }
            return kbscan;
        }
        public void DeleteKanbanScan(KanbanScan scan, User deleteUser)
        {
            if (scan.IsOrdered)
            {
                throw new BusinessException("扫描记录已结转,不能删除");
            }

            KanbanCard card = this.kanbanCardMgr.GetByCardNo(scan.CardNo);
            if (card != null)
            {
                card.Status = KBStatus.Loop;
                this.genericMgr.Update(card);
                this.kanbanTransactionMgr.RecordKanbanTransaction(card, deleteUser, DateTime.Now, KBTransType.UnScan);

                #region 记到双轨溢出量
                //if (!string.IsNullOrEmpty(card.MultiSupplyGroup))
                //{
                //    MultiSupplyGroup msg = genericMgr.FindAll<MultiSupplyGroup>("from MultiSupplyGroup m where m.GroupNo = ?", card.MultiSupplyGroup).FirstOrDefault();
                //    if (msg != null)
                //    {
                //        if (msg.KBEffSupplier == card.Supplier && msg.KBAccumulateQty >= scan.ScanQty)
                //        {
                //            msg.KBAccumulateQty -= scan.ScanQty;
                //            genericMgr.Update(msg);
                //        }
                //        else
                //        {
                //            MultiSupplySupplier mss = genericMgr.FindAll<MultiSupplySupplier>("from MultiSupplySupplier s where s.GroupNo = ? and s.Supplier = ?", new object[] { card.MultiSupplyGroup, card.Supplier }).FirstOrDefault();
                //            mss.KanbanSpillQty -= Convert.ToInt32(scan.ScanQty);
                //            genericMgr.Update(mss);
                //        }
                //    }
                //}
                #endregion
            }
            this.genericMgr.Delete(scan);
            this.kanbanTransactionMgr.RecordKanbanTransaction(card, deleteUser, DateTime.Now, KBTransType.DeleteScan);
        }