public async Task AddBom_Success()
        {
            const decimal amountC1 = 2;
            const decimal amountC2 = 2;
            const decimal amountC3 = 2;
            const decimal amountM2 = 2;

            //adhere
            var initial = Product1InteriorDoor.BillsOfMaterial.DeepCopy();

            //arrange
            var command = new AddBillOfMaterial()
            {
                ArticleId = Product1InteriorDoor.Id,
                Name      = "new bom for P1",
                Input     = new HashSet <(Guid, decimal)>
                {
                    (Component1Vertical.Id, amountC1),
                    (Component2Horizontal.Id, amountC2),
                    (Component3MdfFiller.Id, amountC3),
                    (Material2Foil.Id, amountM2),
                },
                Output      = 1,
                InitiatorId = GlobalAdmin.Id
            };
            var handler = new AddBillOfMaterialHandler(EntityRepository, EventTransmitter);

            //act
            await handler.HandleAsync(command);

            //assert
            Assert.That(CallsTo(EntityRepository, nameof(EntityRepository.AddAsync)), Is.EqualTo(1));
            var bom = GetRecordedEntities <BillOfMaterial>(EntityRepository, nameof(EntityRepository.AddAsync)).Single();

            Assert.That(bom.Name, Is.EqualTo(command.Name));
            Assert.That(bom.Article, Is.EqualTo(Product1InteriorDoor));
            Assert.That(bom.Output, Is.EqualTo(command.Output));
            Assert.That(bom.Input.Of(Component1Vertical).Amount, Is.EqualTo(amountC1));
            Assert.That(bom.Input.Of(Component2Horizontal).Amount, Is.EqualTo(amountC2));
            Assert.That(bom.Input.Of(Component3MdfFiller).Amount, Is.EqualTo(amountC3));
            Assert.That(bom.Input.Of(Material2Foil).Amount, Is.EqualTo(amountM2));
            Assert.That(bom.Primary, Is.EqualTo(false));

            var events = GetRecordedEvents <DomainEvent <BillOfMaterial> >();

            Assert.That(events.Count, Is.EqualTo(1));
            Assert.That(events[0].Entity, Is.EqualTo(bom));
            Assert.That(events[0].Trigger, Is.EqualTo(Trigger.Added));
            Assert.That(events[0].RaisedBy, Is.EqualTo(command.InitiatorId));

            var bomsDiff = Product1InteriorDoor.BillsOfMaterial.Except(initial).SingleOrDefault();

            Assert.That(bomsDiff, Is.EqualTo(bom));

            //annul
            Product1InteriorDoor.BillsOfMaterial = initial;
        }
        public void AddBom_FailFor_IdenticalBomExists()
        {
            //arrange
            var bom     = Product1InteriorDoor.BillsOfMaterial.First();
            var command = new AddBillOfMaterial()
            {
                ArticleId   = Product1InteriorDoor.Id,
                Name        = "new bom for P1",
                Input       = bom.Input.Select(i => (i.Article.Id, i.Amount)),
                Output      = 1,
                InitiatorId = GlobalAdmin.Id
            };
            var handler = new AddBillOfMaterialHandler(EntityRepository, EventTransmitter);

            //assert () => act
            var ex = Assert.ThrowsAsync <DomainException>(async() => await handler.HandleAsync(command));

            Assert.That(ex.Message, Is.EqualTo(IdenticalBomExists(bom)));
            Assert.That(GetRecordedEvents <DomainEvent <BillOfMaterial> >(), Is.Empty);
        }