コード例 #1
0
        private bool BuildMessageAccordingToStock(StockOutputMessage stockOutputMessage, bool affectStockLevel)
        {
            bool outputCompleted = true;

            foreach (StockOutputOrderItem stockOutputOrderItem in stockOutputMessage.Order.Items)
            {
                // 1) get packs from stock
                List <RobotPack> availableStock = this.GetStock(stockOutputOrderItem, stockOutputMessage.TenantID);
                List <RobotPack> usedStock      = new List <RobotPack>();

                // 2) create StockOutputOrderItemPack from stock list
                stockOutputOrderItem.Packs.AddRange(this.GetOrderItemFromStock(
                                                        stockOutputMessage,
                                                        stockOutputOrderItem,
                                                        availableStock,
                                                        usedStock));


                // 3) remove packs uses
                if (affectStockLevel)
                {
                    this.RemoveUsedPackFromStock(usedStock);
                }

                // 4) update output Status
                outputCompleted &= (stockOutputOrderItem.ProcessedQuantity == stockOutputOrderItem.RequestedQuantity);
                outputCompleted &= (stockOutputOrderItem.ProcessedSubItemQuantity == stockOutputOrderItem.RequestedSubItemQuantity);
            }

            return(outputCompleted);
        }
コード例 #2
0
        /// <summary>
        /// Translates this object instance into a Mosaic message.
        /// </summary>
        /// <param name="converterStream">The converter stream instance which request the message conversion.</param>
        /// <returns>
        /// The Mosaic message representation of this object.
        /// </returns>
        public virtual MosaicMessage ToMosaicMessage(IConverterStream converterStream)
        {
            StockOutputMessage msg = new StockOutputMessage(converterStream);

            msg.ID          = this.Id;
            msg.Source      = this.Source;
            msg.Destination = this.Destination;
            msg.Order       = new StockOutputOrder();

            if (this.Details == null)
            {
                return(null);
            }

            msg.Order.Priority     = TypeConverter.ConvertOutputPriority(this.Details.Priority);
            msg.Order.OutputNumber = TypeConverter.ConvertInt(this.Details.OutputDestination);
            msg.Order.State        = TypeConverter.ConvertOrderState(this.Details.Status);

            if (this.Article != null)
            {
                foreach (var article in this.Article)
                {
                    var item = new StockOutputOrderItem()
                    {
                        RobotArticleCode = TextConverter.UnescapeInvalidXmlChars(article.Id)
                    };

                    if (article.Pack != null)
                    {
                        foreach (var pack in article.Pack)
                        {
                            item.Packs.Add(new StockOutputOrderItemPack()
                            {
                                ID          = (long)TypeConverter.ConvertULong(pack.Id),
                                BatchNumber = TextConverter.UnescapeInvalidXmlChars(pack.BatchNumber),
                                ExternalID  = TextConverter.UnescapeInvalidXmlChars(pack.ExternalId),
                                ExpiryDate  = TypeConverter.ConvertDate(pack.ExpiryDate)
                            });
                        }
                    }

                    msg.Order.Items.Add(item);
                }
            }

            return(msg);
        }
コード例 #3
0
        /// <summary>
        /// Translates this object instance into a Mosaic message.
        /// </summary>
        /// <param name="converterStream">The converter stream instance which request the message conversion.</param>
        /// <returns>
        /// The Mosaic message representation of this object.
        /// </returns>
        public override MosaicMessage ToMosaicMessage(IConverterStream converterStream)
        {
            StockOutputMessage msg = (StockOutputMessage)base.ToMosaicMessage(converterStream);

            msg.Order.OutputPoint = TypeConverter.ConvertInt(this.Details.OutputPoint);

            if (msg == null)
            {
                return(null);
            }

            if (msg.Order.Items.Count > 0)
            {
                for (int i = 0; i < msg.Order.Items.Count; ++i)
                {
                    var item = msg.Order.Items[i];

                    if (item.Packs.Count > 0)
                    {
                        for (int k = 0; k < item.Packs.Count; ++k)
                        {
                            item.Packs[k].StockInDate     = TypeConverter.ConvertDate(this.Article[i].Pack[k].StockInDate);
                            item.Packs[k].ScanCode        = TextConverter.UnescapeInvalidXmlChars(this.Article[i].Pack[k].ScanCode);
                            item.Packs[k].DeliveryNumber  = TextConverter.UnescapeInvalidXmlChars(this.Article[i].Pack[k].DeliveryNumber);
                            item.Packs[k].Depth           = TypeConverter.ConvertInt(this.Article[i].Pack[k].Depth);
                            item.Packs[k].Width           = TypeConverter.ConvertInt(this.Article[i].Pack[k].Depth);
                            item.Packs[k].Height          = TypeConverter.ConvertInt(this.Article[i].Pack[k].Depth);
                            item.Packs[k].Shape           = TypeConverter.ConvertEnum <PackShape>(this.Article[i].Pack[k].Shape, PackShape.Cuboid);
                            item.Packs[k].IsInFridge      = TypeConverter.ConvertBool(this.Article[i].Pack[k].IsInFridge);
                            item.Packs[k].BoxNumber       = this.Article[i].Pack[k].BoxNumber;
                            item.Packs[k].SubItemQuantity = TypeConverter.ConvertInt(this.Article[i].Pack[k].SubItemQuantity);
                            item.Packs[k].OutputNumber    = TypeConverter.ConvertInt(this.Article[i].Pack[k].OutputDestination);
                            item.Packs[k].OutputPoint     = TypeConverter.ConvertInt(this.Article[i].Pack[k].OutputPoint);
                            item.Packs[k].LabelState      = TypeConverter.ConvertEnum <StockOutputOrderItemPackLabelState>(this.Article[i].Pack[k].LabelStatus, StockOutputOrderItemPackLabelState.NotLabelled);
                            item.Packs[k].StockLocationID = string.IsNullOrEmpty(this.Article[i].Pack[k].StockLocationId) ? string.Empty : TextConverter.UnescapeInvalidXmlChars(this.Article[i].Pack[k].StockLocationId);
                            item.Packs[k].MachineLocation = string.IsNullOrEmpty(this.Article[i].Pack[k].MachineLocation) ? string.Empty : TextConverter.UnescapeInvalidXmlChars(this.Article[i].Pack[k].MachineLocation);
                        }
                    }
                }
            }


            return(msg);
        }
コード例 #4
0
        // should be changed to do one pack at the time ?
        private void OutputCompletedTimer(object stateInfo)
        {
            // stop feedback timer
            this.toCompleteTimer.Change(Timeout.Infinite, Timeout.Infinite);

            this.stockOutputMessage = new StockOutputMessage(this.outputRequest.ConverterStream);
            this.stockOutputMessage.AdoptHeader(this.outputRequest);
            this.stockOutputMessage.Order = this.outputRequest.Order.Clone();

            switch (this.outputResult)
            {
            case OutputResult.AlwaysComplete:
                this.BuildMessageAlwaysComplete(this.stockOutputMessage);
                this.stockOutputMessage.Order.State = StockOutputOrderState.Completed;
                break;

            case OutputResult.AlwaysIncomplete:
                this.stockOutputMessage.Order.State = StockOutputOrderState.Incomplete;
                break;

            case OutputResult.FrozenStock:
            case OutputResult.Normal:
                bool isCompleted = this.BuildMessageAccordingToStock(this.stockOutputMessage, this.outputResult == OutputResult.Normal);
                this.stockOutputMessage.Order.State = isCompleted ? StockOutputOrderState.Completed : StockOutputOrderState.Incomplete;
                break;

            default:
                this.stockOutputMessage.Order.State = StockOutputOrderState.Incomplete;
                break;
            }

            if (this.enableAutoReply)
            {
                Parallel.ForEach(this.converterStreamList, stream => stream.Write(this.stockOutputMessage));
            }

            this.DoOutputOrderUpdated();
        }
コード例 #5
0
        public SimulatorOutputOrder(
            StorageSystemStock stock,
            SimulatorTenant simulatorTenant,
            SimulatorStockLocation simulatorStockLocation,
            StockOutputRequest outputRequest,
            OutputResult outputResult,
            bool enableAutoReply,
            List <IConverterStream> converterStreamList)
        {
            this.stock                  = stock;
            this.simulatorTenant        = simulatorTenant;
            this.simulatorStockLocation = simulatorStockLocation;
            this.outputRequest          = outputRequest;
            this.outputResult           = outputResult;
            this.stockOutputMessage     = null;
            this.enableAutoReply        = enableAutoReply;
            this.cancelled              = false;
            this.converterStreamList    = converterStreamList;

            this.toCompleteTimer = new System.Threading.Timer(
                this.OutputCompletedTimer,
                null,
                5000, 5000);
        }
コード例 #6
0
        private List <StockOutputOrderItemPack> GetOrderItemFromStock(
            StockOutputMessage stockOutputMessage,
            StockOutputOrderItem stockOutputOrderItem,
            List <RobotPack> availableStock,
            List <RobotPack> usedStock)
        {
            List <StockOutputOrderItemPack> result             = new List <StockOutputOrderItemPack>();
            StorageSystemArticleInformation articleInformation = this.stock.ArticleInformationList.GetArticleInformation(string.IsNullOrWhiteSpace(stockOutputOrderItem.RobotArticleCode) ?
                                                                                                                         stockOutputOrderItem.PISArticleCode : stockOutputOrderItem.RobotArticleCode, false);
            string pickedBatchNumber     = String.Empty;
            int    subIemQuantityInStock = 0;

            // if possible pick a pack that match exactly the requested subquantity.
            foreach (RobotPack availablePack in availableStock)
            {
                if (stockOutputOrderItem.ProcessedSubItemQuantity < stockOutputOrderItem.RequestedSubItemQuantity)
                {
                    if (availablePack.SubItemQuantity == stockOutputOrderItem.RequestedSubItemQuantity)
                    {
                        stockOutputOrderItem.ProcessedSubItemQuantity += availablePack.SubItemQuantity;
                        result.Add(this.GetOrderItemPackFromStock(
                                       stockOutputMessage.Order,
                                       articleInformation,
                                       availablePack));
                        usedStock.Add(availablePack);
                        pickedBatchNumber = availablePack.BatchNumber;
                    }
                }
                subIemQuantityInStock += availablePack.SubItemQuantity;
            }

            // update available stock
            foreach (RobotPack usedPack in usedStock)
            {
                if (availableStock.Contains(usedPack))
                {
                    availableStock.Remove(usedPack);
                }
            }

            // Normal picking.
            foreach (RobotPack availablePack in availableStock)
            {
                if (availablePack.SubItemQuantity == 0)
                {
                    // Full pack
                    if ((stockOutputOrderItem.ProcessedQuantity < stockOutputOrderItem.RequestedQuantity) &&
                        (!stockOutputOrderItem.SingleBatchNumber || (pickedBatchNumber == availablePack.BatchNumber) || (String.IsNullOrEmpty(pickedBatchNumber))))
                    {
                        stockOutputOrderItem.ProcessedQuantity++;
                        result.Add(this.GetOrderItemPackFromStock(
                                       stockOutputMessage.Order,
                                       articleInformation,
                                       availablePack));
                        usedStock.Add(availablePack);
                        pickedBatchNumber = availablePack.BatchNumber;
                    }
                    else
                    {
                        // if we don't have enough open pack in stock, add full packs
                        if (subIemQuantityInStock < stockOutputOrderItem.RequestedSubItemQuantity)
                        {
                            if (articleInformation.MaxSubItemQuantity != 0)
                            {
                                if ((stockOutputOrderItem.ProcessedSubItemQuantity < stockOutputOrderItem.RequestedSubItemQuantity) &&
                                    (!stockOutputOrderItem.SingleBatchNumber || (pickedBatchNumber == availablePack.BatchNumber)))
                                {
                                    stockOutputOrderItem.ProcessedSubItemQuantity += articleInformation.MaxSubItemQuantity;
                                    result.Add(this.GetOrderItemPackFromStock(
                                                   stockOutputMessage.Order,
                                                   articleInformation,
                                                   availablePack));
                                    usedStock.Add(availablePack);
                                    pickedBatchNumber = availablePack.BatchNumber;
                                }
                            }
                            else
                            {
                                if ((stockOutputOrderItem.ProcessedSubItemQuantity < stockOutputOrderItem.RequestedSubItemQuantity) &&
                                    (!stockOutputOrderItem.SingleBatchNumber || (pickedBatchNumber == availablePack.BatchNumber)))
                                {
                                    stockOutputOrderItem.ProcessedQuantity += 1;
                                    result.Add(this.GetOrderItemPackFromStock(
                                                   stockOutputMessage.Order,
                                                   articleInformation,
                                                   availablePack));
                                    usedStock.Add(availablePack);
                                    pickedBatchNumber = availablePack.BatchNumber;
                                }
                                break;
                            }
                        }
                    }
                }
                else
                {
                    // Open pack
                    if ((stockOutputOrderItem.ProcessedSubItemQuantity < stockOutputOrderItem.RequestedSubItemQuantity) &&
                        (!stockOutputOrderItem.SingleBatchNumber || (pickedBatchNumber == availablePack.BatchNumber)))
                    {
                        stockOutputOrderItem.ProcessedSubItemQuantity += availablePack.SubItemQuantity;
                        result.Add(this.GetOrderItemPackFromStock(
                                       stockOutputMessage.Order,
                                       articleInformation,
                                       availablePack));
                        usedStock.Add(availablePack);
                        pickedBatchNumber = availablePack.BatchNumber;
                    }
                }

                if ((stockOutputOrderItem.ProcessedQuantity >= stockOutputOrderItem.RequestedQuantity) &&
                    (stockOutputOrderItem.ProcessedSubItemQuantity >= stockOutputOrderItem.RequestedSubItemQuantity))
                {
                    break;
                }
            }

            // update available stock
            foreach (RobotPack usedPack in usedStock)
            {
                if (availableStock.Contains(usedPack))
                {
                    availableStock.Remove(usedPack);
                }
            }

            return(result);
        }
コード例 #7
0
        private void BuildMessageAlwaysComplete(StockOutputMessage stockOutputMessage)
        {
            foreach (StockOutputOrderItem stockOutputOrderItem in stockOutputMessage.Order.Items)
            {
                StorageSystemArticleInformation articleInformation = this.stock.ArticleInformationList.GetArticleInformation(string.IsNullOrWhiteSpace(stockOutputOrderItem.RobotArticleCode) ?
                                                                                                                             stockOutputOrderItem.PISArticleCode : stockOutputOrderItem.RobotArticleCode, false);

                stockOutputOrderItem.ProcessedQuantity        = stockOutputOrderItem.RequestedQuantity;
                stockOutputOrderItem.ProcessedSubItemQuantity = stockOutputOrderItem.RequestedSubItemQuantity;

                if ((stockOutputOrderItem.PackID != 0) && (stockOutputOrderItem.ProcessedQuantity > 1))
                {
                    // if requesting a specific Pack ID, only this pack will be dispened.
                    stockOutputOrderItem.ProcessedQuantity = 1;
                }

                for (int i = 0; i < stockOutputOrderItem.ProcessedQuantity || (i == 0 && stockOutputOrderItem.ProcessedSubItemQuantity > 0); i++)
                {
                    StockOutputOrderItemPack newPack = new StockOutputOrderItemPack();
                    if (articleInformation != null)
                    {
                        newPack.RobotArticleCode               = articleInformation.Code;
                        newPack.RobotArticleName               = articleInformation.Name;
                        newPack.RobotArticleDosageForm         = articleInformation.DosageForm;
                        newPack.RobotArticlePackagingUnit      = articleInformation.PackagingUnit;
                        newPack.RobotArticleMaxSubItemQuantity = articleInformation.MaxSubItemQuantity;
                    }
                    else
                    {
                        newPack.RobotArticleCode = string.IsNullOrWhiteSpace(stockOutputOrderItem.RobotArticleCode) ? stockOutputOrderItem.PISArticleCode : stockOutputOrderItem.RobotArticleCode;
                    }

                    newPack.BoxNumber   = stockOutputMessage.Order.BoxNumber;
                    newPack.BatchNumber = stockOutputOrderItem.BatchNumber;
                    newPack.Depth       = 60;
                    newPack.Height      = 60;
                    newPack.Width       = 60;
                    if (stockOutputOrderItem.ExpiryDate.Ticks == 0)
                    {
                        // PMR is not requesting a specific date, we need to set a valide date.
                        newPack.ExpiryDate = DateTime.Now.AddMonths(3);
                    }
                    else
                    {
                        newPack.ExpiryDate = stockOutputOrderItem.ExpiryDate;
                    }

                    newPack.ExternalID      = stockOutputOrderItem.ExternalID;
                    newPack.ID              = stockOutputOrderItem.PackID != 0 ? stockOutputOrderItem.PackID : this.stock.GetNextPackID();;
                    newPack.LabelState      = StockOutputOrderItemPackLabelState.Labelled;
                    newPack.OutputNumber    = stockOutputMessage.Order.OutputNumber;
                    newPack.OutputPoint     = stockOutputMessage.Order.OutputPoint;
                    newPack.Shape           = PackShape.Cuboid;
                    newPack.SubItemQuantity = stockOutputOrderItem.RequestedSubItemQuantity;

                    newPack.MachineLocation          = stockOutputOrderItem.MachineLocation;
                    newPack.StockLocationID          = stockOutputOrderItem.StockLocationID;
                    newPack.StockLocationDescription = this.simulatorStockLocation.GetDescription(newPack.StockLocationID);
                    newPack.TenantID          = stockOutputOrderItem.TenantID;
                    newPack.TenantDescription = this.simulatorTenant.GetDescription(newPack.TenantID);

                    stockOutputOrderItem.Packs.Add(newPack);
                }
            }
        }
コード例 #8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="OutputMessageSmallSet"/> class.
        /// </summary>
        /// <param name="message">The message to use for initialization.</param>
        public OutputMessageSmallSet(MosaicMessage message)
        {
            StockOutputMessage msg = (StockOutputMessage)message;

            this.Id          = msg.ID;
            this.Source      = msg.Source;
            this.Destination = msg.Destination;

            this.Details                   = new Details();
            this.Details.Priority          = TypeConverter.ConvertOutputPriority(msg.Order.Priority);
            this.Details.OutputDestination = msg.Order.OutputNumber.ToString();

            switch (msg.Order.State)
            {
            case StockOutputOrderState.Completed:
            case StockOutputOrderState.Incomplete:
            case StockOutputOrderState.Aborted:
                this.Details.Status = msg.Order.State.ToString();
                break;

            default:
                this.Details.Status = StockOutputOrderState.Incomplete.ToString();
                break;
            }

            if (msg.Order.Items.Count > 0)
            {
                Dictionary <string, Article> _articleMap = new Dictionary <string, Article>();

                foreach (var orderItem in msg.Order.Items)
                {
                    foreach (var pack in orderItem.Packs)
                    {
                        if (_articleMap.ContainsKey(pack.RobotArticleCode) == false)
                        {
                            _articleMap.Add(pack.RobotArticleCode,
                                            new Article()
                            {
                                Id   = TextConverter.EscapeInvalidXmlChars(pack.RobotArticleCode),
                                Pack = new List <Types.Pack>()
                            });
                        }

                        _articleMap[pack.RobotArticleCode].Pack.Add(new Types.Pack()
                        {
                            Id          = ((ulong)pack.ID).ToString(),
                            BatchNumber = TextConverter.EscapeInvalidXmlChars(pack.BatchNumber),
                            ExternalId  = TextConverter.EscapeInvalidXmlChars(pack.ExternalID),
                            ExpiryDate  = TypeConverter.ConvertDateNull(pack.ExpiryDate)
                        });
                    }
                }

                if (_articleMap.Count > 0)
                {
                    int counter = 0;
                    this.Article = new Article[_articleMap.Count];

                    foreach (var articleKey in _articleMap.Keys)
                    {
                        this.Article[counter++] = _articleMap[articleKey];
                    }
                }
            }
        }
コード例 #9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="OutputMessage"/> class.
        /// </summary>
        /// <param name="message">The message to use for initialization.</param>
        public OutputMessage(MosaicMessage message)
            : base(message)
        {
            StockOutputMessage msg = (StockOutputMessage)message;

            this.Details.OutputPoint = msg.Order.OutputPoint != 0 ? msg.Order.OutputPoint.ToString() : null;

            var boxNumberList = new List <string>();

            if (this.Article != null)
            {
                Dictionary <string, Types.Pack> _packMap = new Dictionary <string, Types.Pack>();

                foreach (var article in this.Article)
                {
                    if (article.Pack == null)
                    {
                        continue;
                    }

                    foreach (var pack in article.Pack)
                    {
                        _packMap.Add(pack.Id, pack);
                    }
                }

                foreach (var orderItem in msg.Order.Items)
                {
                    foreach (var pack in orderItem.Packs)
                    {
                        if (_packMap.ContainsKey(((ulong)pack.ID).ToString()) == false)
                        {
                            continue;
                        }

                        var msgPack = _packMap[((ulong)pack.ID).ToString()];

                        msgPack.StockInDate       = TypeConverter.ConvertDateNull(pack.StockInDate);
                        msgPack.ScanCode          = TextConverter.EscapeInvalidXmlChars(pack.ScanCode);
                        msgPack.DeliveryNumber    = TextConverter.EscapeInvalidXmlChars(pack.DeliveryNumber);
                        msgPack.Depth             = pack.Depth.ToString();
                        msgPack.Width             = pack.Width.ToString();
                        msgPack.Height            = pack.Height.ToString();
                        msgPack.Shape             = pack.Shape.ToString();
                        msgPack.IsInFridge        = pack.IsInFridge.ToString();
                        msgPack.BoxNumber         = pack.BoxNumber;
                        msgPack.SubItemQuantity   = pack.SubItemQuantity.ToString();
                        msgPack.LabelStatus       = pack.LabelState.ToString();
                        msgPack.OutputDestination = pack.OutputNumber.ToString();
                        msgPack.OutputPoint       = pack.OutputPoint.ToString();
                        msgPack.StockLocationId   = TextConverter.EscapeInvalidXmlChars(pack.StockLocationID);
                        msgPack.MachineLocation   = TextConverter.EscapeInvalidXmlChars(pack.MachineLocation);

                        if ((string.IsNullOrEmpty(pack.BoxNumber) == false) &&
                            (boxNumberList.Contains(pack.BoxNumber) == false))
                        {
                            boxNumberList.Add(pack.BoxNumber);
                        }
                    }
                }
            }
            else if (string.IsNullOrEmpty(msg.Order.BoxNumber) == false)
            {
                if (msg.Order.BoxNumber.EndsWith(".."))
                {
                    boxNumberList.Add(msg.Order.BoxNumber.Substring(0, msg.Order.BoxNumber.Length - 2));
                }
                else
                {
                    boxNumberList.Add(msg.Order.BoxNumber);
                }
            }

            if (boxNumberList.Count > 0)
            {
                this.Box = new Box[boxNumberList.Count];

                for (int i = 0; i < this.Box.Length; ++i)
                {
                    this.Box[i] = new Box()
                    {
                        Number = boxNumberList[i]
                    };
                }
            }
        }