/// <summary>
        /// Add the given BatchEvent to the list of all batch events.
        /// </summary>
        /// <param name="e">
        /// Batch Event to be added.
        /// </param>
        /// <returns>
        /// A Tasks which resovles when the operation completes.
        /// </returns>
        private async Task AddBatchEventToHistory(BatchEvent e)
        {
            // Get all Batches
            List <BatchEvent> allEvents =
                await DataHandler.GetData <BatchEvent>(DataSource.BatchEvents);

            // Add the new event
            allEvents.Add(e);
            // Write the list of events
            await DataHandler.WriteData(DataSource.BatchEvents, allEvents);
        }
        /// <summary>
        /// Removes the given quantity of Portions from the Batch available stock.
        /// </summary>
        /// <param name="batchId">
        /// ID of the Batch the Portions are removed from.
        /// </param>
        /// <param name="quantity">
        /// Quantity of Portions to remove.
        /// </param>
        /// <returns>
        /// A Task which will resolve in a Batch instance with the updated data.
        /// </returns>
        public async Task <Batch> RemoveFromBatch(Guid batchId, int quantity)
        {
            // Get the list of all Batches
            List <Batch> allBatches = await DataHandler.GetData <Batch>(DataSource.Batches);

            // Get the Batch
            Batch batch = this.GetBatch(batchId, allBatches);

            if (batch.AvailableQuantity < quantity)
            {
                // Note for the reviewer:
                // This is a little bit of string concatenation
                // however it should be fine to not use StringBuilder here
                // because in the end there are only 7 strings and
                // this part of code is not expected to be hit so often.
                throw new Exception(
                          "Cannot remove the desired quantity of: "
                          + quantity
                          + " Portions from the Batch with ID: "
                          + batchId
                          + " because only "
                          + batch.AvailableQuantity
                          + " are available"
                          );
            }
            // Remove the element to be updated from the list
            allBatches.Remove(batch);
            // Change the available quantity in the batch
            batch.AvailableQuantity -= quantity;
            // Re-add it to the list
            allBatches.Add(batch);
            // Update the batches file
            await DataHandler.WriteData(DataSource.Batches, allBatches);

            // Create an event corresponding to this action
            BatchEvent e;

            if (batch.AvailableQuantity > 0)
            {
                e = BatchEvent.GetInstance(batch, BatchEventType.PortionsRemoved);
            }
            else
            {
                // the batch is now empty
                e = BatchEvent.GetInstance(batch, BatchEventType.Emptied);
            }
            // Add the event to the history
            await AddBatchEventToHistory(e);

            // Return the updated batch
            return(batch);
        }
        public InventoryControllerTest()
        {
            this.mockAccessService =
                new Mock <IDataAccessService>(MockBehavior.Strict);

            this.controller = new InventoryController(
                new NullLogger <InventoryController>(),
                this.mockAccessService.Object
                );

            testBatch1 = Batch.GetInstance(Guid.NewGuid(), 1000);
            batchList  = new List <Batch>();
            batchList.Add(testBatch1);

            testEvent1 = BatchEvent.GetInstance(testBatch1, BatchEventType.Added);
            eventList  = new List <BatchEvent>();
            eventList.Add(testEvent1);
        }
Beispiel #4
0
        public void Should_throw_if_invalid_rollback_return_type()
        {
            m.Batch(() => {
                new Circle()
                {
                    Radius = 10, Center = new Point(10, 10)
                };
            });
            BatchEvent      batchEvent = null;
            MementorChanged changed    = (_, args) => {
                batchEvent = (BatchEvent)args.Event;
            };

            m.Changed += changed;
            m.Undo();
            Assert.IsNotNull(batchEvent);

            m.Changed -= changed;
            var customEvent = new InvalidCustomEvent(batchEvent);

            m.MarkEvent(customEvent);

            try
            {
                m.Undo();
                Assert.Fail("Expected InvalidOperationException");
            }
            catch (InvalidOperationException) {
            }

            m.Reset();
            m.Batch(() => {
                m.MarkEvent(customEvent);
                m.MarkEvent(customEvent);
            });
            try
            {
                m.Undo();
                Assert.Fail("Expected InvalidOperationException");
            }
            catch (InvalidOperationException)
            {
            }
        }
Beispiel #5
0
        public async void VerifyGetBatchHistory(BatchEventType type)
        {
            BatchEvent        e    = BatchEvent.GetInstance(testBatch1, type);
            List <BatchEvent> list = new List <BatchEvent>();

            list.Add(e);

            mockDataHandler.Setup(m => m.GetData <BatchEvent>(DataSource.BatchEvents)).ReturnsAsync(list);

            IEnumerable <BatchEvent> events = await dataAccess.GetBatchHistory(testBatch1.Id);

            Assert.True(events.Count() == 1);

            BatchEvent ev = events.First();

            Assert.Equal(testBatch1.Id, ev.BatchId);

            mockDataHandler.Verify(m => m.GetData <BatchEvent>(DataSource.Products), Times.Never);
            mockDataHandler.Verify(m => m.GetData <BatchEvent>(DataSource.Batches), Times.Never);
            mockDataHandler.Verify(m => m.GetData <BatchEvent>(DataSource.BatchEvents), Times.Once);
        }
        /// <summary>
        /// Adds a new Batch to the inventory based on the passed parameters.
        /// </summary>
        /// <param name="productId">ID of the Product the Batch is made of.</param>
        /// <param name="batchSize">Number of Portions in the Batch.</param>
        /// <param name="expirationDate">Expiration Date of the Batch.</param>
        /// <returns>
        /// A Task which will resolve in a Batch instance containing the newly added Batch.
        /// </returns>
        public async Task <Batch> AddBatch(Guid productId, int batchSize, DateTime expirationDate)
        {
            // Get all Batches
            List <Batch> allBatches = await DataHandler.GetData <Batch>(DataSource.Batches);

            // Create the new Batch
            Batch newBatch = Batch.GetInstance(productId, batchSize, expirationDate);

            // Add the new Batch to the list
            allBatches.Add(newBatch);
            // Write the list into a File
            await DataHandler.WriteData(DataSource.Batches, allBatches);

            // Create an event corresponding to this action
            BatchEvent e = BatchEvent.GetInstance(newBatch, BatchEventType.Added);

            // Add the event to the history
            await AddBatchEventToHistory(e);

            // return the newly added batch
            return(newBatch);
        }
Beispiel #7
0
 private BaseEvent ProcessBatch(BatchEvent batchEvent)
 {
     if (batchEvent.Count == 0) return null;
     if (batchEvent.Count == 1) return batchEvent.Pop();
     return batchEvent;
 }
Beispiel #8
0
 private BaseEvent InternalEndBatch(BatchEvent stack)
 {
     BaseEvent processed = ProcessBatch(_currentBatch);
     if (processed != null) stack.Push(processed);
     _currentBatch = null;
     return processed;
 }
Beispiel #9
0
 /// <summary>
 /// Resets the state of this <see cref="Mementor"/> object to its initial state.
 /// This effectively clears the redo stack, undo stack and current batch (if one is active).
 /// </summary>
 public void Reset()
 {
     bool shouldNotify = UndoCount > 0 || RedoCount > 0;
     _undoStack.Clear();
     _redoStack.Clear();
     _currentBatch = null;
     IsTrackingEnabled = true;
     if (shouldNotify) NotifyChange(null);
 }
Beispiel #10
0
 /// <summary>
 /// Disposes the this mementor and clears redo and undo stacks.
 /// This method won't fire <see cref="Changed"/> event.
 /// </summary>
 public void Dispose()
 {
     Changed = null;
     _undoStack.Clear();
     _redoStack.Clear();
     _currentBatch = null;
 }
Beispiel #11
0
        /// <summary>
        /// Explicitly marks the beginning of a batch. Use this instead of <see cref="Batch"/>
        /// changes can be made in different places instead of inside one certain block of code.
        /// When finish, end the batch by invoking <see cref="EndBatch"/>.
        /// </summary>
        public void BeginBatch()
        {
            if (!IsTrackingEnabled) return;
            if (IsInBatch) throw new InvalidOperationException("Re-entrant batch is not supported");

            _currentBatch = new BatchEvent();
        }
Beispiel #12
0
 public InvalidCustomEvent(BatchEvent batch)
 {
     Batch = batch;
 }
Beispiel #13
0
 public InvalidCustomEvent(BatchEvent batch)
 {
     Batch = batch;
 }