/// <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); }
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) { } }
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); }
private BaseEvent ProcessBatch(BatchEvent batchEvent) { if (batchEvent.Count == 0) return null; if (batchEvent.Count == 1) return batchEvent.Pop(); return batchEvent; }
private BaseEvent InternalEndBatch(BatchEvent stack) { BaseEvent processed = ProcessBatch(_currentBatch); if (processed != null) stack.Push(processed); _currentBatch = null; return processed; }
/// <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); }
/// <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; }
/// <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(); }
public InvalidCustomEvent(BatchEvent batch) { Batch = batch; }
public InvalidCustomEvent(BatchEvent batch) { Batch = batch; }