예제 #1
0
        public IEnumerable<Money> Eject(CashDeal inCash, ChangePool inReservedMoney)
        {
            try {
                if (inCash.UsedAmount == 0) {
                    return inCash.RecevedMoney.ToList();
                }

                var result = new List<KeyValuePair<Money, int>>();

                this.EjectCore(
                    inCash.ChangedAount,
                    inReservedMoney.Items.OrderByDescending(pair => pair.Key.Value()),
                    (m, totalCount, useCount) => {
                        result.Add(
                            new KeyValuePair<Money, int>(m, (int)useCount)
                        );
                    }
                );

                return result.SelectMany(r => Enumerable.Repeat(r.Key, r.Value));
            }
            finally {
                inCash.RecevedMoney.Clear();
            }
        }
예제 #2
0
        public void _利用者がお金を投入する()
        {
            var role = new CoinMeckRole ();
            var received = new CashDeal();

            Assert.True(role.Receive(received, Money.Coin10));
            Assert.True(role.Receive(received, Money.Coin50));
            Assert.True(role.Receive(received, Money.Coin100));
            Assert.True(role.Receive(received, Money.Coin500));
            Assert.True(role.Receive(received, Money.Bill1000));
            Assert.False(role.Receive(received, Money.Coin1));
            Assert.False(role.Receive(received, Money.Coin5));
            Assert.False(role.Receive(received, Money.Bill2000));
            Assert.False(role.Receive(received, Money.Bill5000));
            Assert.False(role.Receive(received, Money.Bill10000));
            Assert.True(role.Receive(received, Money.Coin10));
            Assert.True(role.Receive(received, Money.Coin50));
            Assert.True(role.Receive(received, Money.Coin100));
            Assert.True(role.Receive(received, Money.Coin500));
            Assert.True(role.Receive(received, Money.Bill1000));
            Assert.False(role.Receive(received, Money.Coin1));
            Assert.False(role.Receive(received, Money.Coin5));
            Assert.False(role.Receive(received, Money.Bill2000));
            Assert.False(role.Receive(received, Money.Bill5000));
            Assert.False(role.Receive(received, Money.Bill10000));

            Assert.False(received.RecevedMoney.Contains(Money.Coin1));
            Assert.False(received.RecevedMoney.Contains(Money.Coin5));
            Assert.False(received.RecevedMoney.Contains(Money.Bill2000));
            Assert.False(received.RecevedMoney.Contains(Money.Bill5000));
            Assert.False(received.RecevedMoney.Contains(Money.Bill10000));

            Assert.That(received.ChangedAount, Is.EqualTo(3320));
        }
예제 #3
0
        public IEnumerable <Money> Eject(CashDeal inCash, ChangePool inReservedMoney)
        {
            try {
                if (inCash.UsedAmount == 0)
                {
                    return(inCash.RecevedMoney.ToList());
                }

                var result = new List <KeyValuePair <Money, int> >();

                this.EjectCore(
                    inCash.ChangedAount,
                    inReservedMoney.Items.OrderByDescending(pair => pair.Key.Value()),
                    (m, totalCount, useCount) => {
                    result.Add(
                        new KeyValuePair <Money, int>(m, (int)useCount)
                        );
                }
                    );

                return(result.SelectMany(r => Enumerable.Repeat(r.Key, r.Value)));
            }
            finally {
                inCash.RecevedMoney.Clear();
            }
        }
예제 #4
0
        public void _お金投入による商品選択状態の変化_売り切れの場合(
            [ValueSource(typeof(商品選択状態の変化Params), "SoldOutSource")] 
            商品選択状態の変化Params.Param inParameter)
        {
            var positions = TestHelper.InitInfinityItems(ItemRackState.Soldout);

            var pool = TestHelper.InitInfinityReservedChange();
            var credit = new CashDeal();

            var coinMeckRole = new CoinMeckRole();
            var itemRackRole = new  ItemRackRole();

            foreach (var c in inParameter.Credits) {
                coinMeckRole.Receive(credit, c, 1);
            }

            foreach (var p in Enumerable.Range(0, positions.Racks.Length)) {
                var newState = itemRackRole.UpdateItemSelectionState(
                    positions.Racks[p], credit,
                    coinMeckRole.CalcChanges(credit, pool, positions.Racks[p].Item.Price)
                    );

                Assert.That(newState, Is.EqualTo(inParameter.States[p]));
            }
        }
예제 #5
0
        public void _商品を購入する()
        {
            var racks = TestHelper.InitInfinityItems(ItemRackState.CanNotPurchase);

            var pool = TestHelper.InitInfinityReservedChange();
            var credit = new CashDeal();

            var coinMeckRole = new CoinMeckRole();
            var itemRackRole = new  ItemRackRole();

            coinMeckRole.Receive(credit, Money.Coin100, 1);
            coinMeckRole.Receive(credit, Money.Coin10, 1);
            coinMeckRole.Receive(credit, Money.Coin10, 1);

            var rack = itemRackRole.FindRackAt(racks, 0);
            itemRackRole.UpdateItemSelectionState(
                rack, credit,
                coinMeckRole.CalcChanges(credit, pool, rack.Item.Price)
            );

            var svCount = rack.Count;
            Assert.That(rack.State, Is.EqualTo(ItemRackState.CanPurchase));

            coinMeckRole.CalcChanges(credit, pool, rack.Item.Price);
            var item = itemRackRole.Purchase(rack);

            Assert.That(item, Is.Not.Null);
            Assert.That(item.Name, Is.EqualTo("Item0"));

            Assert.That(rack.Count, Is.EqualTo(svCount-1));
        }
예제 #6
0
        public PurchaseContext(ChangePool inChanges, ItemRackPosition inItems)
        {
            mDealAmount = new CashDeal();
            mChanges = inChanges;
            mItems = inItems;

            mCoinMeckRole = new CoinMeckRole();
            mItemRole = new ItemRackRole();
        }
예제 #7
0
        public void _お金を入れず購入()
        {
            var role = new CoinMeckRole ();
            var received = new CashDeal();

            Assert.False(role.Purchase(received, 100));

            Assert.That(received.UsedAmount, Is.EqualTo(0));
        }
예제 #8
0
        public void _お金を入れず購入()
        {
            var role = new CoinMeckRole ();
            var received = new CashDeal();
            var pool = new CreditPool();

            var changes = role.CalcChanges(received, pool, 100);
            Assert.That(changes.TotalAmount(), Is.EqualTo(0));
        }
예제 #9
0
        public PurchaseContext(ChangePool inChanges, ItemRackPosition inItems)
        {
            mDealAmount = new CashDeal();
            mChanges    = inChanges;
            mItems      = inItems;

            mCoinMeckRole = new CoinMeckRole();
            mItemRole     = new ItemRackRole();
        }
예제 #10
0
        public bool Purchase(CashDeal inCash, int inItemValue)
        {
            if (inCash.ChangedAount >= inItemValue) {
                inCash.UsedAmount += inItemValue;

                return true;
            }

            return false;
        }
예제 #11
0
        public bool Receive(CashDeal inCash, Money inMoney)
        {
            if (this.IsAvailableMoney(inMoney)) {
                inCash.RecevedMoney.Add(inMoney);

                return true;
            }

            return false;
        }
예제 #12
0
        public bool Receive(CashDeal inCash, Money inMoney, int inCount)
        {
            if (inCount > 0 && this.IsAvailableMoney(inMoney)) {
                inCash.RecevedMoney.Credits[inMoney] += inCount;

                return true;
            }

            return false;
        }
예제 #13
0
        public bool Purchase(CashDeal inCash, int inItemValue)
        {
            if (inCash.ChangedAount >= inItemValue)
            {
                inCash.UsedAmount += inItemValue;

                return(true);
            }

            return(false);
        }
예제 #14
0
        public bool Receive(CashDeal inCash, Money inMoney)
        {
            if (this.IsAvailableMoney(inMoney))
            {
                inCash.RecevedMoney.Add(inMoney);

                return(true);
            }

            return(false);
        }
예제 #15
0
        public bool UpdateItemSelectionState(ItemRack inRack, CashDeal inCredits, ChangePool inPool)
        {
            var oldState = inRack.State;
            if (oldState == ItemRackState.Soldout) return false;

            if (inRack.Item.Price <= (inCredits.RecevedMoney.TotalAmount() - inCredits.UsedAmount)) {
                inRack.State = ItemRackState.CanPurchase;
            }

            return oldState != inRack.State;
        }
예제 #16
0
        public CreditPool CalcChanges(CashDeal inCash, CreditPool inChangePool, int inItemValue)
        {
            if (inCash.ChangedAount < inItemValue) {
                return inCash.RecevedMoney;
            }

            return this.CalcChangesCore(
                inCash.RecevedMoney.TotalAmount() - inItemValue,
                this.AppendMoneyCore(inChangePool, inCash.RecevedMoney, (pool, cash) => pool+cash).OrderByDescending(pair => pair.Key)

            );
        }
예제 #17
0
        public bool UpdateItemSelectionState(ItemRack inRack, CashDeal inCredits, ChangePool inPool)
        {
            var oldState = inRack.State;

            if (oldState == ItemRackState.Soldout)
            {
                return(false);
            }

            if (inRack.Item.Price <= (inCredits.RecevedMoney.TotalAmount() - inCredits.UsedAmount))
            {
                inRack.State = ItemRackState.CanPurchase;
            }

            return(oldState != inRack.State);
        }
예제 #18
0
        public ItemRackState UpdateItemSelectionState(ItemRack inRack, CashDeal inCredits, CreditPool inChangesPool)
        {
            if (inRack.State == ItemRackState.RackNotExist) return inRack.State;
            if (inRack.Count == 0) return inRack.State = ItemRackState.Soldout;

            var amount = inCredits.ChangedAount;
            if (inRack.Item.Price > amount) {
                return inRack.State = ItemRackState.CanNotPurchase;
            }

            if (inChangesPool.TotalAmount() != amount-inRack.Item.Price) {
                return inRack.State = ItemRackState.MissingChange;
            }

            return inRack.State = ItemRackState.CanPurchase;
        }
예제 #19
0
        public void _何も購入せずお金を排出する(Money inMoney, int inRepeat)
        {
            var role = new CoinMeckRole ();
            var received = new CashDeal();
            var pool = TestHelper.InitInfinityReservedChange();

            for (var i = 0; i < inRepeat; ++i) {
                role.Receive(received, inMoney);
            }

            var changed = role.Eject(received, pool)
                .GroupBy(m => m)
                .ToDictionary(g => g.Key, g => g)
            ;

            Assert.That(received.RecevedMoney.Count, Is.EqualTo(0));

            Assert.That(changed.Count, Is.EqualTo(1));
            Assert.True(changed.ContainsKey(inMoney));
            Assert.That(changed[inMoney].Count(), Is.EqualTo(inRepeat));
        }
예제 #20
0
        public void _何も購入せずお金を排出する(Money inMoney, int inRepeat)
        {
            var role = new CoinMeckRole ();
            var received = new CashDeal();
            var pool = TestHelper.InitInfinityReservedChange();

            role.Receive(received, inMoney, inRepeat);

            var expectReceived = received.RecevedMoney.TotalAmount();

            var changes = role.Eject(received, pool).Credits
                .Where(c => c.Value > 0)
                .ToDictionary(g => g.Key, g => g.Value)
            ;

            Assert.That(received.RecevedMoney.TotalAmount(), Is.EqualTo(expectReceived));

            Assert.That(changes.Count, Is.EqualTo(1));
            Assert.True(changes.ContainsKey(inMoney));
            Assert.That(changes[inMoney], Is.EqualTo(inRepeat));
        }
예제 #21
0
        public void _お金投入による商品選択状態の変化(
            [ValueSource(typeof(商品選択状態の変化Params), "Source")] 
            商品選択状態の変化Params.Param inParameter)
        {
            var racks = TestHelper.InitInfinityItems(ItemRackState.CanNotPurchase);

            var pool = TestHelper.InitInfinityReservedChange();
            var credit = new CashDeal();

            var coinMeckRole = new CoinMeckRole();
            var itemRackRole = new  ItemRackRole();

            foreach (var c in inParameter.Credits) {
                coinMeckRole.Receive(credit, c);
            }

            foreach (var result in racks.Items.Zip(inParameter.States, (r, s) => Tuple.Create(r, s))) {
                itemRackRole.UpdateItemSelectionState(result.Item1, credit, pool);

                Assert.That(result.Item1.State, Is.EqualTo(result.Item2));
                Assert.That(itemRackRole.CanItemPurchase(result.Item1), Is.EqualTo(result.Item2 == ItemRackState.CanPurchase));            }
        }
예제 #22
0
        public void _利用者がお金を投入する_正しくない投入枚数の場合(int inCount)
        {
            var role = new CoinMeckRole ();
            var received = new CashDeal();

            Assert.False(role.Receive(received, Money.Coin10, inCount));
            Assert.False(role.Receive(received, Money.Coin50, inCount));
            Assert.False(role.Receive(received, Money.Coin100, inCount));
            Assert.False(role.Receive(received, Money.Coin500, inCount));
            Assert.False(role.Receive(received, Money.Bill1000, inCount));
            Assert.False(role.Receive(received, Money.Coin1, inCount));
            Assert.False(role.Receive(received, Money.Coin5, inCount));
            Assert.False(role.Receive(received, Money.Bill2000, inCount));
            Assert.False(role.Receive(received, Money.Bill5000, inCount));
            Assert.False(role.Receive(received, Money.Bill10000, inCount));
            Assert.False(role.Receive(received, Money.Coin10, inCount));
            Assert.False(role.Receive(received, Money.Coin50, inCount));
            Assert.False(role.Receive(received, Money.Coin100, inCount));
            Assert.False(role.Receive(received, Money.Coin500, inCount));
            Assert.False(role.Receive(received, Money.Bill1000, inCount));
            Assert.False(role.Receive(received, Money.Coin1, inCount));
            Assert.False(role.Receive(received, Money.Coin5, inCount));
            Assert.False(role.Receive(received, Money.Bill2000, inCount));
            Assert.False(role.Receive(received, Money.Bill5000, inCount));
            Assert.False(role.Receive(received, Money.Bill10000, inCount));

            Assert.False(received.RecevedMoney.Credits.ContainsKey(Money.Coin1));
            Assert.False(received.RecevedMoney.Credits.ContainsKey(Money.Coin5));
            Assert.False(received.RecevedMoney.Credits.ContainsKey(Money.Bill2000));
            Assert.False(received.RecevedMoney.Credits.ContainsKey(Money.Bill5000));
            Assert.False(received.RecevedMoney.Credits.ContainsKey(Money.Bill10000));

            Assert.That(received.ChangedAount, Is.EqualTo(0));
        }
예제 #23
0
 public PurchaseContext(CreditPool inChanges, ItemRackPosition inItems)
 {
     mDealAmount = new CashDeal();
     mChangesPool = inChanges;
     mItems = inItems;
 }
예제 #24
0
        public void _商品購入後お金を排出する(
			    [ValueSource(typeof(_商品購入後お金を排出するParams), "Source")] 
			    _商品購入後お金を排出するParams.Parameter inParameter)
        {
            var role = new CoinMeckRole();
            var received = new CashDeal();
            var pool = TestHelper.InitInfinityReservedChange();

            foreach (var m in inParameter.ReceivedMoney) {
                for (var i = 0; i < m.Item2; ++i) {
                    role.Receive (received, m.Item1);
                }
            }

            Assert.True(role.Purchase(received, 100));

            var changed = role.Eject(received, pool)
                .GroupBy(m => m)
                .ToDictionary(g => g.Key, g => g)
            ;

            var lookup = inParameter.ChangedMoney.ToDictionary(m => m.Item1, m => m.Item2);

            Assert.That(received.RecevedMoney.Count, Is.EqualTo(0));

            Assert.That(received.UsedAmount, Is.EqualTo(100));

            Assert.That(changed.Count, Is.EqualTo(lookup.Count), "count money type (id = {0})", inParameter.Id);

            foreach (var pair in changed) {
                Assert.True(lookup.ContainsKey(pair.Key), "money ({0}) should be contained (id = {1})", pair.Key, inParameter.Id);
                Assert.That(pair.Value.Count(), Is.EqualTo (lookup[pair.Key]), "money ({0}) count should be equaled (id = {1})", pair.Key, inParameter.Id);
            }
        }
예제 #25
0
        public ItemInfo Purchase(int inPosition)
        {
            var rack = mItemRole.FindRackAt(mItems, inPosition);
            if (rack.State != ItemRackState.CanPurchase) {
                throw new Exception();
            }

            // [TODO: 1]
            // create sales
            // 準備対象外の金種はビルバリプールに振り替える
            // 管理用の文脈と購入文脈で準備金を共有できるよう大規模なリファクタリングェ ...

            var allCredits = mCoinMeckRole.TransferMoney(mChangesPool, mDealAmount.RecevedMoney, (m1, m2) => m1+m2);

            mDealAmount = new CashDeal(
                mCoinMeckRole.CalcChanges(mDealAmount, mChangesPool, rack.Item.Price)
            );
            mChangesPool = mCoinMeckRole.TransferMoney(allCredits, mDealAmount.RecevedMoney, (m1, m2) => m1-m2);

            var result = mItemRole.Purchase(rack);

            foreach (var r in mItems.Racks.Where(r => r.State != ItemRackState.RackNotExist)) {
                mItemRole.UpdateItemSelectionState(
                    r, mDealAmount,
                    mCoinMeckRole.CalcChanges(mDealAmount, mChangesPool, r.Item.Price)
                );
            }

            return result;
        }
예제 #26
0
 public CreditPool Eject(CashDeal inCash, CreditPool inChangePool)
 {
     return new CreditPool(inCash.RecevedMoney.Credits);
 }
예제 #27
0
        public void _商品購入後お金を排出する(
			    [ValueSource(typeof(_商品購入後お金を排出するParams), "Source")] 
			    _商品購入後お金を排出するParams.Parameter inParameter)
        {
            var role = new CoinMeckRole();
            var received = new CashDeal();
            var pool = TestHelper.InitInfinityReservedChange();

            foreach (var m in inParameter.ReceivedMoney) {
                for (var i = 0; i < m.Item2; ++i) {
                    role.Receive (received, m.Item1, 1);
                }
            }

            var newReceives = new CashDeal(role.CalcChanges(received, pool, 100));
            var changes = role.Eject(newReceives, pool)
                .Credits
                .Where(c => c.Value > 0)
                .ToDictionary(g => g.Key, g => g.Value)
            ;

            var lookup = inParameter.ChangedMoney.ToDictionary(m => m.Item1, m => m.Item2);

            Assert.That(changes.Count, Is.EqualTo(lookup.Count), "count money type (id = {0})", inParameter.Id);

            foreach (var pair in changes) {
                Assert.True(lookup.ContainsKey(pair.Key), "money ({0}) should be contained (id = {1})", pair.Key, inParameter.Id);
                Assert.That(pair.Value, Is.EqualTo (lookup[pair.Key]), "money ({0}) count should be equaled (id = {1})", pair.Key, inParameter.Id);
            }
        }