예제 #1
0
        public void _Pool間でお金の移動を行う()
        {
            var pool1 = new CreditPool();
            var pool2 = new CreditPool(new Dictionary<Money, int> {
                {Money.Bill1000, 1},
                {Money.Coin500, 10},
                {Money.Coin100, 5}
            });

            var pool2Keys = new HashSet<Money>(pool2.Credits.Keys);

            var role = new CoinMeckRole();

            var pool4 = role.TransferMoney(pool1, pool2, (m1, m2) => m1+m2);

            Assert.That(pool4, Is.Not.EqualTo(pool2));
            Assert.That(pool4.Credits.Keys.All(m => pool2Keys.Contains(m)), Is.True);
            foreach (var k in pool2Keys) {
                Assert.That(pool4.Credits[k], Is.EqualTo(pool2.Credits[k]));
            }

            var pool5 = role.TransferMoney(pool4, pool2, (m1, m2) => m1-m2);

            Assert.That(pool5, Is.Not.EqualTo(pool1));
            foreach (var k in pool2Keys) {
                Assert.That(pool4.Credits[k], Is.EqualTo(pool2.Credits[k]));
                Assert.That(pool5.Credits[k], Is.EqualTo(0));
            }
        }
예제 #2
0
        public void _釣り銭を補充する_正しくない枚数の場合(Money inMoney, int inCount)
        {
            var pool = new CreditPool();

            var role = new ChangePoolRole();

            Assert.Throws<Exception>(() => role.Append(pool, inMoney, inCount));
        }
예제 #3
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));
        }
예제 #4
0
 private IEnumerable<KeyValuePair<Money, int>> AppendMoneyCore(CreditPool inChangePool, CreditPool inReceivedCredit, Func<int, int, int> inCallback)
 {
     return Enumerable.Join(
             inChangePool.Credits, inReceivedCredit.Credits,
             (outer) => outer.Key, (inner) => inner.Key,
             (outer, inner) => new KeyValuePair<Money, int>(outer.Key, inCallback(outer.Value, inner.Value))
         )
     ;
 }
예제 #5
0
        public void _釣り銭を補充する_対象外金種の場合(Money inMoney, int inCount)
        {
            var pool = new CreditPool();

            var role = new ChangePoolRole();
            var newPool = role.Append(pool, inMoney, inCount);

            Assert.That(newPool.Credits.Where(c => c.Value > 0).Any(), Is.False);
        }
예제 #6
0
        public void _釣り銭を補充する(Money inMoney, int inCount)
        {
            var pool = new CreditPool();

            var role = new ChangePoolRole();
            var newPool = role.Append(pool, inMoney, inCount);

            Assert.That(newPool.Credits.Where(c => c.Value > 0).Any(), Is.True);
            Assert.That(newPool.Credits[inMoney], Is.EqualTo(inCount));
        }
예제 #7
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)

            );
        }
예제 #8
0
        public CreditPool Append(CreditPool inPool, Money inMoney, int inCount)
        {
            if (inCount <= 0) {
                throw new Exception("Invalid number of money");
            }

            var result = new CreditPool(inPool.Credits);

            var resolved = MoneyResolver.Resolve(inMoney);
            if (resolved.Style == MoneyStyle.Coin && resolved.Status == MoneyStatus.Available) {
                result.Credits[inMoney] += inCount;
            }

            return result;
        }
예제 #9
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;
        }
        public static CreditPool InitInfinityReservedChange()
        {
            var result = new CreditPool();

            var credits = EnumHeler.Values<Money>()
                .Where (m => m != Money.Unknown)
                .Select(m => MoneyResolver.Resolve(m))
                .Where(m => m.Status == MoneyStatus.Available)
                .Where(m => m.Style == MoneyStyle.Coin)
            ;

            foreach (var m in credits) {
                result.Credits[m.Type] = 10000;
            }

            return result;
        }
예제 #11
0
 public CreditPool TransferMoney(CreditPool inTransferTo, CreditPool inTransferFrom, Func<int, int, int> inCallback)
 {
     return new CreditPool(
         this.AppendMoneyCore(inTransferTo, inTransferFrom, inCallback)
     );
 }
예제 #12
0
 public CreditPool Eject(CashDeal inCash, CreditPool inChangePool)
 {
     return new CreditPool(inCash.RecevedMoney.Credits);
 }
예제 #13
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;
        }
예제 #14
0
 public PurchaseContext(CreditPool inChanges, ItemRackPosition inItems)
 {
     mDealAmount = new CashDeal();
     mChangesPool = inChanges;
     mItems = inItems;
 }
예제 #15
0
 public CashDeal(CreditPool inMoney)
 {
     this.RecevedMoney = new CreditPool(inMoney.Credits);
 }