public void CollectCash(Coin coin, Banknote banknote, Decimal price)
 {
     this.Credit = coin.Value + banknote.Value;
     if (Credit < price)
     {
         GiveChange(0);
         throw (new Exception("Not enough money"));
     }
 }
 public void Pay(Boolean cardMode, int Id, Decimal price, Coin coin = null, Banknote banknote = null, CreditCard creditCard = null, int pin = 0)
 {
     //CardMode is "false" for cash payment and "true" for card payment
     if (cardMode)
     {
         CollectCreditCard(creditCard, pin, price);
     }
     else
     {
         CollectCash(coin, banknote, price);
     }
     paymentEvent.Notify(Id);
 }
        static void Main(string[] args)
        {
            int             paymentType = 0, id = 0, moreProducts = 1;
            PaymentTerminal payConsole = new PaymentTerminal();
            ContainableItem lays       = new ContainableItem(new Product(new ProductCategory("Snacks"), "Lays", 50, 10, 3), new Position(1, 1, 2, 2));
            ContainableItem M_m        = new ContainableItem(new Product(new ProductCategory("Sweets"), "M&M", 30, 20, 1), new Position(2, 1, 1, 1));
            ContainableItem milk       = new ContainableItem(new Product(new ProductCategory("Milk Products"), "Milk", 20, 40, 2), new Position(3, 1, 2, 3));

            ContainableItemsCollection.AddItem(lays);
            ContainableItemsCollection.AddItem(M_m);
            ContainableItemsCollection.AddItem(milk);

            ContainableItemsCollection.ShowList();
            while (moreProducts != 0)
            {
                try {
                    Console.WriteLine("Product id:");
                    id = Int32.Parse(Console.ReadLine());
                    Console.WriteLine("How do you want to pay? 1-Coins, 2-Banknote, 3-CreditCard, 0-Back");
                    paymentType = Int32.Parse(Console.ReadLine());
                } catch (Exception e) { Console.WriteLine(e); }

                switch (paymentType)
                {
                case 1:
                    Payment payCoin = new Coin();
                    payConsole.Pay(id, payCoin);
                    break;

                case 2:
                    Payment payBanknote = new Banknote();
                    payConsole.Pay(id, payBanknote);
                    break;

                case 3:
                    Payment payCreditCard = new CreditCard();
                    payConsole.Pay(id, payCreditCard);
                    break;

                default:
                    break;
                }
                Console.WriteLine(Dispenser.Message);
                try {
                    Console.WriteLine("Do you want to buy another product? 1-Yes 0-No");
                    moreProducts = Int32.Parse(Console.ReadLine());
                } catch (Exception e) { Console.WriteLine(e); }
            }

            DataAcquisition.GetInstance().GenerateReports();
        }
        public void Pay(int id, Payment payment)
        {
            Dispenser  dispenser   = new Dispenser();
            Subscriber getNotified = new Subscriber();

            getNotified.Subscribe(dispenser);
            Product wantedProduct = null;

            try {
                wantedProduct = Dispenser.GetProduct(id);

                double change = 0, accumulate = 0;
                if (payment.GetType().Equals(new Coin().GetType()))
                {
                    payment = new Coin();
                }

                if (payment.GetType().Equals(new Banknote().GetType()))
                {
                    payment = new Banknote();
                }

                if (payment.GetType().Equals(new CreditCard().GetType()))
                {
                    payment = new CreditCard();
                    CreditCardVerification card = new CreditCardVerification();
                    bool   cardIsValid          = card.validate();
                    double moneyOnCard          = 1000;
                    change = payment.change(moneyOnCard, wantedProduct.Price);
                    if (cardIsValid && payment.IsValid)
                    {
                        getNotified.Notify(id);
                        Console.WriteLine($"You have bought {wantedProduct.Name} and your change is {change}");
                    }
                    else
                    {
                        Console.WriteLine("Your card is invalid");
                    }
                }
                if (payment.GetType().Equals(new Coin().GetType()) || payment.GetType().Equals(new Banknote().GetType()))
                {
                    change = payment.change(accumulate, wantedProduct.Price);
                    if (payment.IsValid)
                    {
                        getNotified.Notify(id);
                        Console.WriteLine($"You have bought {wantedProduct.Name} and your change is {change}");
                    }
                }
            } catch (Exception e) { Console.WriteLine("PaymentTerminal " + e); }
        }