using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Linq;
namespace ConsoleApplication176
{
class Program
{
/// <summary>
/// Путь к файлу БД
/// </summary>
const string DBFile = @"c:\\cards.bin";
/// <summary>
/// База данных с карточками
/// </summary>
private static Cards cards;
static void Main(string[] args)
{
//чтение БД
LoadDB();
//ввод пинкода
Console.Write("Введите пин-код: ");
var pin = int.Parse(Console.ReadLine());
//поиск пин кода в базе карт
var card = cards.FirstOrDefault(c=>c.Pin == pin);
if(card == null)
{
Console.WriteLine("Карта не найдена");
Console.ReadKey();
return;
}
//карта принята, начинаем диалог
StartCardDialog(card);
}
private static void StartCardDialog(Card card)
{
while(true)
{
//вывод меню
Console.Clear();
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("1 Вывод баланса карты");
Console.WriteLine("2 Зачисление денег на карту");
Console.WriteLine("3 Снять деньги с карты");
Console.WriteLine("4 Вывести историю транзакций");
Console.WriteLine("5 Выход");
Console.ResetColor();
var cmd = Console.ReadLine();
Console.Clear();
switch (cmd)
{
case "1":
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("Баланс: {0}", card.Balance);
Console.ResetColor();
break;
case "2":
TakeDialog(card);
break;
case "3":
TakeOffDialog(card);
break;
case "4":
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("История транзакций:\r\n\r\n{0}", card.History);
Console.ResetColor();
break;
case "5":
return;
break;
}
Console.WriteLine("Нажмите любую клавишу для продолжения");
Console.ReadKey();
}
}
private static void TakeDialog(Card card)
{
Console.Write("Введите зачисляемую сумму: ");
decimal summa = 0;
decimal.TryParse(Console.ReadLine(), out summa);
if (summa > 0)
{
var t = card.BeginTransaction(summa, "Занесение средств с банковского счета");
if (t.CanBeCommited)
if (t.Commit())
{
SaveDB();
Console.WriteLine("Зачисление средств выполнено");
}
}
}
private static void TakeOffDialog(Card card)
{
Console.Write("Введите снимаемую сумму: ");
decimal summa = 0;
decimal.TryParse(Console.ReadLine(), out summa);
summa = -summa;//отрицательное зачисление
if (summa < 0)
{
var t = card.BeginTransaction(summa, "Снятие наличных из банкомата");
if (t.CanBeCommited)
{
if (t.Commit())
{
SaveDB();
Console.WriteLine("Снятие средств выполнено");
}
}else
Console.WriteLine("Недостаточно средств");
}
}
private static void LoadDB()
{
try
{
using (var fs = new FileStream(DBFile, FileMode.Open))
cards = (Cards) new BinaryFormatter().Deserialize(fs);
}
catch (Exception ex)
{
//нет файла, создаем новую БД
CreateDB();
}
}
private static void CreateDB()
{
cards = new Cards();
cards.Add(new CreditCard(1234){Percent = 15});
cards.Add(new DebitCard(4422));
SaveDB();
}
private static void SaveDB()
{
try
{
using (var fs = new FileStream(DBFile, FileMode.Create))
new BinaryFormatter().Serialize(fs, cards);
}catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
/// <summary>
/// Список плтежных карт
/// </summary>
[Serializable]
public class Cards:List<Card>
{
}
/// <summary>
/// Платежная карта
/// </summary>
[Serializable]
public abstract class Card
{
/// <summary>
/// Текущий баланс
/// </summary>
public decimal Balance { get; protected set; }
/// <summary>
/// История транзакций
/// </summary>
public History History { get; private set; }
/// <summary>
/// Пин код
/// </summary>
public int Pin { get; private set; }
public Card(int pin)
{
History = new History();
this.Pin = pin;
}
/// <summary>
/// Может ли добавиться/сняться данная сумма ?
/// </summary>
protected abstract bool CanTake(decimal summa);
/// <summary>
/// изменить балан на указанную сумму
/// </summary>
/// <param name="summa"></param>
protected abstract void ChangeBalance(decimal summa);
/// <summary>
/// Начать транзакцию на изменение баланса
/// </summary>
public Transaction BeginTransaction(decimal summa, string comment)
{
return new Transaction(this, summa) { Comment = comment };
}
/// <summary>
/// Транзакция на изменение баланса карты
/// </summary>
[Serializable]
public class Transaction
{
/// <summary>
/// Карта
/// </summary>
public Card Card { get; private set; }
/// <summary>
/// Сумма транзакции (может быть отрицательной)
/// </summary>
public decimal Summa { get; private set; }
/// <summary>
/// Коментарий к транзакции
/// </summary>
public string Comment { get; set; }
/// <summary>
/// Дата транзакции
/// </summary>
public DateTime Date { get; private set; }
/// <summary>
/// Транзакция может быть выполнена?
/// </summary>
public bool CanBeCommited
{
get { return Card.CanTake(Summa); }
}
public Transaction(Card card, decimal summa)
{
this.Card = card;
this.Summa = summa;
Date = DateTime.Now;
}
/// <summary>
/// Выполнить изменение баланса
/// </summary>
public bool Commit()
{
if(CanBeCommited)
{
Date = DateTime.Now;
Card.ChangeBalance(Summa);//снимаем сумму
Card.History.Add(this);//заносим себя в историю транзакций
return true;
}
return false;
}
public override string ToString()
{
return string.Format("{0} Card: {1} Summa: {2} Comment: {3}", Date, Card, Summa, Comment);
}
}
}
/// <summary>
/// История транзакций
/// </summary>
[Serializable]
public class History : List<Card.Transaction>
{
public override string ToString()
{
var sb = new StringBuilder();
foreach (var t in this)
sb.AppendLine(t.ToString() + "\r\n");
return sb.ToString();
}
}
[Serializable]
public class DebitCard : Card
{
public DebitCard(int pin) : base(pin)
{
}
protected override bool CanTake(decimal summa)
{
return Balance + summa >= 0;
}
protected override void ChangeBalance(decimal summa)
{
Balance += summa;
}
public override string ToString()
{
return "DebitCard" + Pin;
}
}
[Serializable]
public class CreditCard : Card
{
public decimal Percent { get; set; }
public CreditCard(int pin) : base(pin)
{
}
protected override bool CanTake(decimal summa)
{
return true;
}
protected override void ChangeBalance(decimal summa)
{
if (summa < 0 && Balance + summa < 0)
//добавляем процент
summa += summa*Percent/100;
Balance += summa;
}
public override string ToString()
{
return "CreditCard" + Pin;
}
}
}