public void ChangeTwiceOnSameDay()
        {
            var mockRepository = new MockRepository(MockBehavior.Strict);

            var id          = Guid.NewGuid();
            var transaction = mockRepository.Create <IPortfolioTransaction>();
            var properties  = new ParcelProperties(100, 1000.00m, 2000.00m);

            var parcel = new Parcel(id, new Date(2000, 01, 01), new Date(1999, 01, 01), properties, transaction.Object);

            var transaction2 = mockRepository.Create <IPortfolioTransaction>();

            parcel.Change(new Date(2010, 06, 30), 100, 200.00m, 300.00m, transaction2.Object);

            var transaction3 = mockRepository.Create <IPortfolioTransaction>();

            parcel.Change(new Date(2010, 06, 30), 200, 300.00m, 400.00m, transaction3.Object);

            using (new AssertionScope())
            {
                parcel.Properties[new Date(2010, 06, 29)].Should().Be(properties);

                parcel.Properties[new Date(2010, 06, 30)].Should().Be(new ParcelProperties(400, 1500.00m, 2700.00m));

                parcel.Audit.Should().BeEquivalentTo(new[]
                {
                    new ParcelAudit(new Date(2000, 01, 01), 100, 2000.00m, 1000.00m, transaction.Object),
                    new ParcelAudit(new Date(2010, 06, 30), 100, 300.00m, 200.00m, transaction2.Object),
                    new ParcelAudit(new Date(2010, 06, 30), 200, 400.00m, 300.00m, transaction3.Object)
                });
            }

            mockRepository.Verify();
        }
        public void ChangeReduceUnitCountToZero()
        {
            var mockRepository = new MockRepository(MockBehavior.Strict);

            var id          = Guid.NewGuid();
            var transaction = mockRepository.Create <IPortfolioTransaction>();
            var properties  = new ParcelProperties(100, 1000.00m, 2000.00m);

            var parcel = new Parcel(id, new Date(2000, 01, 01), new Date(1999, 01, 01), properties, transaction.Object);

            var transaction2 = mockRepository.Create <IPortfolioTransaction>();

            parcel.Change(new Date(2010, 06, 30), -100, 200.00m, 300.00m, transaction2.Object);

            using (new AssertionScope())
            {
                parcel.EffectivePeriod.Should().Be(new DateRange(new Date(2000, 01, 01), new Date(2010, 06, 30)));

                parcel.Properties[new Date(2010, 06, 29)].Should().Be(properties);

                parcel.Properties[new Date(2010, 06, 30)].Should().Be(new ParcelProperties(0, 0.00m, 0.00m));

                parcel.Audit.Should().BeEquivalentTo(new[]
                {
                    new ParcelAudit(new Date(2000, 01, 01), 100, 2000.00m, 1000.00m, transaction.Object),
                    new ParcelAudit(new Date(2010, 06, 30), -100, 300.00m, 200.00m, transaction2.Object)
                });
            }

            mockRepository.Verify();
        }
        public void CalculateCgtNotEnoughParcels()
        {
            var parcels = new List <Parcel>();

            var parcel1 = new Parcel(Guid.NewGuid(), new Date(2000, 01, 01), new Date(2000, 01, 01), new ParcelProperties(100, 100.00m, 100.00m), null);

            parcels.Add(parcel1);

            var parcel2 = new Parcel(Guid.NewGuid(), new Date(2002, 01, 01), new Date(2002, 01, 01), new ParcelProperties(100, 100.00m, 100.00m), null);

            parcels.Add(parcel2);

            var parcel3 = new Parcel(Guid.NewGuid(), new Date(2001, 01, 01), new Date(2001, 01, 01), new ParcelProperties(100, 100.00m, 100.00m), null);

            parcel3.Change(new Date(2005, 01, 01), -100, -100.00m, -100.00m, null);
            parcels.Add(parcel3);

            var parcel4 = new Parcel(Guid.NewGuid(), new Date(2003, 01, 01), new Date(2003, 01, 01), new ParcelProperties(100, 100.00m, 100.00m), null);

            parcels.Add(parcel4);

            var calculator = new CgtCalculator();

            var parcelsSold = calculator.Calculate(parcels, new Date(2010, 01, 01), 500, 1000.00m, new FirstInFirstOutCgtComparer());

            Action a = () => parcelsSold.ToList();

            a.Should().Throw <ArgumentException>();
        }
        public void CalculateCgtPartialSale()
        {
            var parcels = new List <Parcel>();

            var parcel1 = new Parcel(Guid.NewGuid(), new Date(2000, 01, 01), new Date(2000, 01, 01), new ParcelProperties(100, 100.00m, 110.00m), null);

            parcels.Add(parcel1);

            var parcel2 = new Parcel(Guid.NewGuid(), new Date(2009, 06, 30), new Date(2009, 01, 01), new ParcelProperties(100, 120.00m, 130.00m), null);

            parcels.Add(parcel2);

            var parcel3 = new Parcel(Guid.NewGuid(), new Date(2001, 01, 01), new Date(2001, 01, 01), new ParcelProperties(100, 130.00m, 140.00m), null);

            parcel3.Change(new Date(2005, 01, 01), -100, -100.00m, -100.00m, null);
            parcels.Add(parcel3);

            var parcel4 = new Parcel(Guid.NewGuid(), new Date(2003, 01, 01), new Date(2003, 01, 01), new ParcelProperties(100, 140.00m, 150.00m), null);

            parcels.Add(parcel4);

            var calculator = new CgtCalculator();

            var parcelsSold = calculator.Calculate(parcels, new Date(2010, 01, 01), 250, 1000.00m, new FirstInFirstOutCgtComparer()).ToArray();

            var expectedResult = new ParcelSold[]
            {
                new ParcelSold(parcel1, 100, 110.00m, 400.00m, 290.00m, CgtMethod.Discount, 145.00m),
                new ParcelSold(parcel4, 100, 150.00m, 400.00m, 250.00m, CgtMethod.Discount, 125.00m),
                new ParcelSold(parcel2, 50, 65.00m, 200.00m, 135.00m, CgtMethod.Other, 135.00m),
            };

            parcelsSold.Should().Equal(expectedResult);
        }
        public void ChangeAfterEffectivePeriod()
        {
            var mockRepository = new MockRepository(MockBehavior.Strict);

            var id          = Guid.NewGuid();
            var transaction = mockRepository.Create <IPortfolioTransaction>();
            var properties  = new ParcelProperties(100, 1000.00m, 2000.00m);

            var parcel = new Parcel(id, new Date(2000, 01, 01), new Date(1999, 01, 01), properties, transaction.Object);

            parcel.Change(new Date(2010, 01, 01), -100, 0.00m, 0.00m, transaction.Object);

            Action a = () => parcel.Change(new Date(2011, 06, 30), 10, 10.00m, 10.00m, transaction.Object);

            a.Should().Throw <EffectiveDateException>();

            mockRepository.Verify();
        }
        public void ChangeUnitsToLessThanZero()
        {
            var mockRepository = new MockRepository(MockBehavior.Strict);

            var id          = Guid.NewGuid();
            var transaction = mockRepository.Create <IPortfolioTransaction>();
            var properties  = new ParcelProperties(100, 1000.00m, 2000.00m);

            var parcel = new Parcel(id, new Date(2000, 01, 01), new Date(1999, 01, 01), properties, transaction.Object);

            Action a = () => parcel.Change(new Date(2010, 06, 30), -200, 0.00m, 0.00m, transaction.Object);

            a.Should().Throw <ArgumentException>();

            mockRepository.Verify();
        }
        public void CalculateParcelCgt(Date disposalDate, int unitsSold, decimal saleAmount, decimal expectedCostBase, decimal expectedCapitalGain, decimal expectedDiscountedGain, CgtMethod expectedCgtMethod, string because)
        {
            var aquisitionDate = new Date(2017, 01, 01);
            var properties     = new ParcelProperties(1000, 1000.00m, 2000.00m);
            var parcel         = new Parcel(Guid.NewGuid(), aquisitionDate, aquisitionDate, properties, null);

            parcel.Change(new Date(2017, 08, 01), 1000, 2000.00m, 2000.00m, null);

            var calculator = new CgtCalculator();

            var parcelSold = calculator.CalculateParcelCgt(parcel, disposalDate, unitsSold, saleAmount);

            parcelSold.Should().BeEquivalentTo(new
            {
                AmountReceived = saleAmount,
                CostBase       = expectedCostBase,
                CapitalGain    = expectedCapitalGain,
                DiscountedGain = expectedDiscountedGain,
                CgtMethod      = expectedCgtMethod
            }, because);
        }