context: //------------------------------------------------------------------------------------------------- 
  // <copyright file="WorkTaskTests.cs" company="Allors bvba">
  // Copyright 2002-2009 Allors bvba.
  // 
  // Dual Licensed under
  //   a) the General Public Licence v3 (GPL)
  //   b) the Allors License
  // 
  // The GPL License is included in the file gpl.txt.
  // The Allors License is an addendum to your contract.
  // 
  // Allors Platform is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  // GNU General Public License for more details.
  // 
  // For more information visit http://www.allors.com/legal
  // </copyright>
  // <summary>Defines the MediaTests type.</summary>
  //-------------------------------------------------------------------------------------------------
  
  namespace Allors.Domain
  {
      using System.Linq;
      using Xunit;
          
      public class WorkEffortInventoryAssignmentTests : DomainTest
      {
          [Fact]
          public void GivenWorkEffort_WhenAddingInventoryAssignment_ThenInventoryReservationCreated()
          {
              // Arrange
              var reasons = new InventoryTransactionReasons(this.Session);
  
              var workEffort = new WorkTaskBuilder(this.Session).WithName("Activity").Build();
              var part = new PartBuilder(this.Session)
                  .WithGoodIdentification(new PartNumberBuilder(this.Session)
                      .WithIdentification("P1")
                      .WithGoodIdentificationType(new GoodIdentificationTypes(this.Session).Part).Build())
                  .Build();
  
              // Act
              this.Session.Derive(true);
  
              // Assert
              Assert.Empty(workEffort.WorkEffortInventoryAssignmentsWhereAssignment);
              Assert.True(workEffort.WorkEffortState.IsNeedsAction);
  
              // Re-arrange
              var inventoryAssignment = new WorkEffortInventoryAssignmentBuilder(this.Session)
                  .WithAssignment(workEffort)
                  .WithPart(part)
                  .WithQuantity(10)
                  .Build();
  
              // Act
              this.Session.Derive(true);
  
              // Assert
              var transactions = inventoryAssignment.InventoryItemTransactions;
  
              Assert.Single(transactions);
              var transaction = transactions[0];
              Assert.Equal(part, transaction.Part);
              Assert.Equal(10, transaction.Quantity);
              Assert.Equal(reasons.Reservation, transaction.Reason);
  
              Assert.Equal(10, part.QuantityCommittedOut);
          }
  
          [Fact]
          public void GivenWorkEffortWithInventoryAssignment_WhenChangingPart_ThenInventoryReservationsChange()
          {
              // Arrange
              var reasons = new InventoryTransactionReasons(this.Session);
  
              var workEffort = new WorkTaskBuilder(this.Session).WithName("Activity").Build();
              var part1 = new PartBuilder(this.Session)
                  .WithGoodIdentification(new PartNumberBuilder(this.Session)
                      .WithIdentification("P1")
                      .WithGoodIdentificationType(new GoodIdentificationTypes(this.Session).Part).Build())
                  .Build();
              var part2 = new PartBuilder(this.Session)
                  .WithGoodIdentification(new PartNumberBuilder(this.Session)
                      .WithIdentification("P2")
                      .WithGoodIdentificationType(new GoodIdentificationTypes(this.Session).Part).Build())
                  .Build();
  
              this.Session.Derive(true);
  
              var inventoryAssignment = new WorkEffortInventoryAssignmentBuilder(this.Session)
                  .WithAssignment(workEffort)
                  .WithPart(part1)
                  .WithQuantity(10)
                  .Build();
  
              // Act
              this.Session.Derive(true);
  
              // Assert
              var transactions = inventoryAssignment.InventoryItemTransactions.ToArray();
  
              Assert.Single(transactions);
              Assert.Equal(part1, transactions[0].Part);
              Assert.Equal(10, transactions[0].Quantity);
              Assert.Equal(reasons.Reservation, transactions[0].Reason);
  
              // Re-arrange
              inventoryAssignment.Part = part2;
  
              // Act
              this.Session.Derive(true);
  
              // Assert
              var part1Transactions = inventoryAssignment.InventoryItemTransactions.Where(t => t.Part.Equals(part1)).ToArray();
              var part2Transactions = inventoryAssignment.InventoryItemTransactions.Where(t => t.Part.Equals(part2)).ToArray();
  
              Assert.Equal(0, part1Transactions.Sum(t => t.Quantity));
              Assert.Equal(10, part2Transactions.Sum(t => t.Quantity));
  
              Assert.Equal(0, part1.QuantityCommittedOut);
              Assert.Equal(10, part2.QuantityCommittedOut);
          }
  
          [Fact]
          public void GivenWorkEffortWithInventoryAssignment_WhenCancelling_ThenInventoryReservationCancelled()
          {
              // Arrange
              var reasons = new InventoryTransactionReasons(this.Session);
  
              var workEffort = new WorkTaskBuilder(this.Session).WithName("Activity").Build();
              var part = new PartBuilder(this.Session)
                  .WithGoodIdentification(new PartNumberBuilder(this.Session)
                      .WithIdentification("P1")
                      .WithGoodIdentificationType(new GoodIdentificationTypes(this.Session).Part).Build())
                  .Build();
  
              this.Session.Derive(true);
  
              var inventoryAssignment = new WorkEffortInventoryAssignmentBuilder(this.Session)
                  .WithAssignment(workEffort)
                  .WithPart(part)
                  .WithQuantity(10)
                  .Build();
  
              this.Session.Derive(true);
  
              // Act
              workEffort.Cancel();
              this.Session.Derive(true);
  
              // Assert
              var transactions = inventoryAssignment.InventoryItemTransactions;
  
              Assert.Equal(2, transactions.Count);
  
              var reservation = transactions.First(t => t.Reason.Equals(reasons.Reservation) && (t.Quantity > 0));
              var reservationCancellation = transactions.First(t => t.Reason.Equals(reasons.Reservation) && (t.Quantity < 0));
  
              Assert.Equal(10, reservation.Quantity);
              Assert.Equal(-10, reservationCancellation.Quantity);
  
              Assert.Equal(0, part.QuantityCommittedOut);
          }
  
          [Fact]
          public void GivenWorkEffortWithInventoryAssignment_WhenCompleting_ThenInventoryTransactionsCreated()
          {
              // Arrange
              var reasons = new InventoryTransactionReasons(this.Session);
  
              var workEffort = new WorkTaskBuilder(this.Session).WithName("Activity").Build();
              var part = new PartBuilder(this.Session)
                  .WithGoodIdentification(new PartNumberBuilder(this.Session)
                      .WithIdentification("P1")
                      .WithGoodIdentificationType(new GoodIdentificationTypes(this.Session).Part).Build())
                  .Build();
  
              new InventoryItemTransactionBuilder(this.Session).WithPart(part).WithQuantity(100).WithReason(reasons.PhysicalCount).Build();
  
              this.Session.Derive(true);
  
              var inventoryAssignment = new WorkEffortInventoryAssignmentBuilder(this.Session)
                  .WithAssignment(workEffort)
                  .WithPart(part)
                  .WithQuantity(10)
                  .Build();
  
              this.Session.Derive(true);
  
              // Act
              workEffort.Complete();
              this.Session.Derive(true);
  
              // Assert
              var transactions = inventoryAssignment.InventoryItemTransactions;
  
              Assert.Equal(2, transactions.Count);
  
              var reservation = transactions.First(t => t.Reason.Equals(reasons.Reservation) && (t.Quantity > 0));
              var consumption = transactions.First(t => t.Reason.Equals(reasons.Consumption));
  
              Assert.Equal(10, reservation.Quantity);
              Assert.Equal(10, consumption.Quantity);
  
              Assert.Equal(0, part.QuantityCommittedOut);
              Assert.Equal(90, part.QuantityOnHand);
          }
  
          [Fact]
          public void GivenWorkEffortWithInventoryAssignment_WhenCompletingThenCancelling_ThenInventoryTransactionsCancelled()
          {
              // Arrange
              var reasons = new InventoryTransactionReasons(this.Session);
  
              var workEffort = new WorkTaskBuilder(this.Session).WithName("Activity").Build();
              var part = new PartBuilder(this.Session)
                  .WithGoodIdentification(new PartNumberBuilder(this.Session)
                      .WithIdentification("P1")
                      .WithGoodIdentificationType(new GoodIdentificationTypes(this.Session).Part).Build())
                  .Build();
  
              this.Session.Derive(true);
  
              var inventoryAssignment = new WorkEffortInventoryAssignmentBuilder(this.Session)
                  .WithAssignment(workEffort)
                  .WithPart(part)
                  .WithQuantity(10)
                  .Build();
  
              this.Session.Derive(true);
  
              // Act
              workEffort.Complete();
              this.Session.Derive(true);
  
              workEffort.Cancel();
              this.Session.Derive(true);
  
              // Assert
              var transactions = inventoryAssignment.InventoryItemTransactions;
              var reservation = transactions.First(t => t.Reason.Equals(reasons.Reservation) && (t.Quantity > 0));
              var reservationCancellation = transactions.First(t => t.Reason.Equals(reasons.Reservation) && (t.Quantity < 0));
              var consumption = transactions.First(t => t.Reason.Equals(reasons.Consumption) && (t.Quantity > 0));
              var consumptionCancellation = transactions.First(t => t.Reason.Equals(reasons.Consumption) && (t.Quantity < 0));
  
              Assert.Equal(4, transactions.Count);
  
              Assert.Equal(10, reservation.Quantity);
              Assert.Equal(-10, reservationCancellation.Quantity);
              Assert.Equal(10, consumption.Quantity);
              Assert.Equal(-10, consumptionCancellation.Quantity);
  
              Assert.Equal(0, part.QuantityCommittedOut);
              Assert.Equal(0, part.QuantityOnHand);
          }
  
          [Fact]
          public void GivenWorkEffortWithInventoryAssignment_WhenChangingPartAndQuantityAndFinishing_ThenOldInventoryCancelledAndNewInventoryCreated()
          {
              // Arrange
              var reasons = new InventoryTransactionReasons(this.Session);
  
              var workEffort = new WorkTaskBuilder(this.Session).WithName("Activity").Build();
              var part1 = new PartBuilder(this.Session)
                  .WithGoodIdentification(new PartNumberBuilder(this.Session)
                      .WithIdentification("P1")
                      .WithGoodIdentificationType(new GoodIdentificationTypes(this.Session).Part).Build())
                  .Build();
  
gt:             var part2 = new PartBuilder(this.Session)