public async Task Should_save_a_laboratory_reading()
        {
            using (var store = NewDocumentStore())
            {
                using (var session = store.OpenAsyncSession())
                {
                    // Arrange
                    var lot = new Lot {Id = "lots/2015/1"};
                    await SaveEntity(lot, session);

                    var dto = new RawMaterialLabReadingDto
                    {
                        Id = null,
                        Date = new DateTime(2015, 4, 18),
                        LotId = "lots/2015/1",
                        RawMaterialAnalysis = new RawMaterialAnalysis
                        {
                            Moisture = 24.5,
                            SampleSize = 1000.0,
                            MeasurementPodre = 10,
                            MeasurementChocha = 4,
                            MeasurementUmbigo = 3
                        }
                    };

                    // Act
                    var service = GetRawMaterialLabReadingsService(session);
                    var model = await service.Save(dto);

                    // Assert
                    model.Success.Should().BeTrue();
                    model.Message.Should().Be("Criou analisis de podre/chocha para lote 2015/1");
                    model.Entity.Id.Should().Be("RawMaterialLabReadings-1");

                    var actual = await session.LoadAsync<RawMaterialLabReading>(model.Entity.Id);

                    actual.Date.Should().Be(new DateTime(2015, 4, 18));
                    actual.LotId.Should().Be("lots/2015/1");

                    actual.RawMaterialAnalysis.Moisture.Should().Be(24.5);
                    actual.RawMaterialAnalysis.SampleSize.Should().Be(1000.0);
                    actual.RawMaterialAnalysis.MeasurementPodre.Should().Be(10);
                    actual.RawMaterialAnalysis.MeasurementChocha.Should().Be(4);
                    actual.RawMaterialAnalysis.MeasurementUmbigo.Should().Be(3);
                    actual.RawMaterialAnalysis.PercentPodre.Should().Be(10/1000.0);
                    actual.RawMaterialAnalysis.PercentChocha.Should().Be(4/1000.0);
                    actual.RawMaterialAnalysis.PercentUmbigo.Should().Be(3/1000.0);

                    actual.AuditInfo.Username.Should().NotBeNullOrEmpty();
                    actual.AuditInfo.Updated.Should().BeCloseTo(DateTime.Now, 2000);
                }
            }
        }
        public async Task<RawMaterialLabReadingDto> GetById(string id)
        {
            if (id.IsNullOrEmpty()) throw new ArgumentNullException(nameof(id));

            var entity = await Session.LoadAsync<RawMaterialLabReading>(id);

            if (entity == null)
            {
                throw new NotFoundException($"{id} não existe");
            }

            var dto = new RawMaterialLabReadingDto
            {
                Id = entity.Id,                
                Date = entity.Date,
                LotId = entity.LotId,
                RawMaterialAnalysis = entity.RawMaterialAnalysis,
                PhysicalCharacteristics = entity.PhysicalCharacteristics,
                Sizing = entity.Sizing
            };

            return dto;
        }
        public async Task<BaseUpdateModel<RawMaterialLabReadingDto>> Save(RawMaterialLabReadingDto dto)
        {
            if (!dto.Sizing.AreMeasurementsValid())
            {
                throw new InvalidOperationException(
                    $"A soma dos tamanhos ({dto.Sizing.Measurements()} gms/amendoas) deve ser igual o tamanho da amostra, ou seja {dto.Sizing.SampleSize} gms/amendoas");
            }

            var entity = dto.Id.IsNullOrEmpty()
                ? new RawMaterialLabReading()
                : await Session.LoadAsync<RawMaterialLabReading>(dto.Id) ?? new RawMaterialLabReading();

            SetUpdateText(dto);

            Mapper.Map(dto, entity);
            UpdateAuditInfo(entity);

            await Session.StoreAsync(entity);
            await Session.SaveChangesAsync();

            dto.Id = entity.Id;

            return new BaseUpdateModel<RawMaterialLabReadingDto>(dto, $"{UpdateText} analisis de podre/chocha para lote {entity.LotId.ToLotNumber()}", true);
        }
        public async Task Should_get_a_laboratory_reading_with_nut_characteristics_and_sizing()
        {
            using (var store = NewDocumentStore())
            {
                // Arrange
                SAMPLE_SIZE_GMS = 1105;

                using (var session = store.OpenAsyncSession())
                {
                    var dto = new RawMaterialLabReadingDto
                    {
                        Id = null,
                        Date = new DateTime(2015, 4, 18),
                        LotId = "lots/2015/1",
                        RawMaterialAnalysis = new RawMaterialAnalysis
                        {
                            Moisture = 24.5,
                            SampleSize = 1000.0,
                            MeasurementPodre = 10,
                            MeasurementChocha = 4,
                            MeasurementUmbigo = 3
                        },
                        PhysicalCharacteristics = new PhysicalCharacteristics
                        {
                            ShellThickness = 2.0,
                            DiameterMillimeteres = 15,
                            LengthMillimeteres = 60
                        },
                        Sizing = new RawNutSizing
                        {
                            SampleSize = SAMPLE_SIZE_GMS,
                            MeasurementExtraLarge = 25,
                            MeasurementLarge = 400,
                            MeasurementMedia1 = 300,
                            MeasurementMedia2 = 150,
                            MeasurementPequena = 220
                        }
                    };

                    var service = GetRawMaterialLabReadingsService(session);

                    await service.Save(dto);
                }

                using (var session = store.OpenAsyncSession())
                {
                    // Act
                    var service = GetRawMaterialLabReadingsService(session);

                    var actual = await service.GetById(RAW_MATERIAL_LAB_READINGS_1);

                    // Assert
                    actual.RawMaterialAnalysis.Moisture.Should().Be(24.5);
                    actual.RawMaterialAnalysis.SampleSize.Should().Be(1000.0);
                    actual.RawMaterialAnalysis.MeasurementPodre.Should().Be(10);
                    actual.RawMaterialAnalysis.MeasurementChocha.Should().Be(4);
                    actual.RawMaterialAnalysis.MeasurementUmbigo.Should().Be(3);

                    actual.RawMaterialAnalysis.PercentPodre.Should().Be(10/1000.0);
                    actual.RawMaterialAnalysis.PercentChocha.Should().Be(4/1000.0);
                    actual.RawMaterialAnalysis.PercentUmbigo.Should().Be(3/1000.0);

                    actual.PhysicalCharacteristics.ShellThickness.Should().Be(2.0);
                    actual.PhysicalCharacteristics.DiameterMillimeteres.Should().Be(15);
                    actual.PhysicalCharacteristics.LengthMillimeteres.Should().Be(60);
                    actual.PhysicalCharacteristics.LengthToDiameterRatio.Should().Be(60/15.0);

                    actual.Sizing.SampleSize.Should().Be(SAMPLE_SIZE_GMS);
                    actual.Sizing.MeasurementExtraLarge.Should().Be(25);
                    actual.Sizing.MeasurementLarge.Should().Be(400);
                    actual.Sizing.MeasurementMedia1.Should().Be(300);
                    actual.Sizing.MeasurementMedia2.Should().Be(150);
                    actual.Sizing.MeasurementPequena.Should().Be(220);

                    actual.Sizing.PercentExtraLarge.Should().Be(25/SAMPLE_SIZE_GMS);
                    actual.Sizing.PercentLarge.Should().Be(400/SAMPLE_SIZE_GMS);
                    actual.Sizing.PercentMedia1.Should().Be(300/SAMPLE_SIZE_GMS);
                    actual.Sizing.PercentMedia2.Should().Be(150/SAMPLE_SIZE_GMS);
                    actual.Sizing.PercentPequena.Should().Be(220/SAMPLE_SIZE_GMS);
                }
            }
        }