package ch27;
import ch15.Car;
import ch20.thread_.Singleton;
import java.util.*;
//신용카드, 현금카드, 기프트카드 세 종류가 있다.
//각각 물건을 구매할 때마다 거래 수수료 발생
//신용카드 (5%), 현금카드 (2%), 기프트카드(1%)
//신용카드는 구매할 때 세금이 10% 발생
//신용카드는 카드번호, 유효기간이 필요하고
//현금카드는 신용카드정보외에 계좌번호가 필요하다.
//기프트카드는 별도 정보가 필요없다.
//Kavin이 카드를 사용하면
//카드의 사용내역을 조회할 수 있어야 한다.
// 카드에 따라 수수료랑 세금이 다르니까 enum 쓰기
enum CardType{
//public static final CardType CRIDIT = new CardType(0.1, 0.05);
CRIDIT(0.1, 0.05), //신용카드
CASH(0.0, 0.03),
GIFT(0.0, 0.01);
private double tax; //세금
private double fee; //수수료
CardType (double tax, double fee){
this.tax = tax;
this.fee = fee;
}
public double getTax(){ //세금반환
return tax;
}
public double getFee(){ //수수료반환
return fee;
}
}
//사용자 정보 클래스
class User {
private Long idx;
private String email;
public User(Long idx, String email){ //생성자
this.idx = idx;
this.email = email;
}
public Long getIdx(){ //사용자 번호 반환
return idx;
}
public void setIdx(Long idx) { //사용자 번호 설정
this.idx = idx;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"idx=" + idx +
", email='" + email + '\'' +
'}';
}
}
//거래 데이터 클래스
class TransactionData{
private Date date;
private int price;
public TransactionData(Date date, int price){
this.date = date;
this.price = price;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "TransactionData{" +
"date=" + date +
", price=" + price +
'}';
}
}
//신한카드 관리 클래스 / 하나만 있어야 하니까 싱클톤으로 표현
public class SinhanCard{
private static SinhanCard INSTANCE;
private Map<User, List<Chargeable>> users;
private static Long userIdx;
private SinhanCard(){
users = new HashMap<>();
userIdx = 1L;
}
public static synchronized SinhanCard getInstance(){
if(INSTANCE == null) INSTANCE = new SinhanCard();
return INSTANCE;
}
public void createUser(String email){
users.put(new User(userIdx++, email), new ArrayList<Chargeable>());
}
public void createCard(Long idx, CardType cardType){
var user = findUser(idx);
switch (cardType){ //카드 타입에 따라
case CRIDIT -> //신용카드 생성
users.get(user).add(new CreditCard("222-2222","2323-2323", "2024-01-02"));
case CASH -> users.get(user).add(new CashCard("3333-3214", "4444-444", "2024-12-04"));
case GIFT -> users.get(user).add(new GiftCard("Chicken"));
}
}
private User findUser(Long idx){ // 사용자를 찾는 메서드
for (var user : users.keySet()){
if (Objects.equals(user.getIdx(), idx)) return user;
}
return null;
}
public List<Chargeable> findMyCard(Long idx){
return users.get(findUser(idx));
}
}
//결제 가능 카드 나타내는 클래스
class Chargeable{
protected CardType cardType;
protected List<TransactionData> datas;
protected Chargeable(CardType cardType){
this.cardType = cardType;
datas = new ArrayList<>();
}
//다빈이 코드
protected void payment(int price){
var totalPrice = totalPay(price);
datas.add(new TransactionData(new Date(), totalPrice));
}
protected void payment(){
if(cardType.name() == "GiFT"){
System.out.println("기프트 카드를 사용였습니다.");
datas.add(new TransactionData(new Date(), 0));
}else System.out.println("기프트카드로 계산하세요");
}
protected int totalPay(int price){
return (int)(price + price * (cardType.getFee()) + price * (cardType.getTax()));
}
protected void cardPaymentHistories(){ //카드 결제 내역 출력
System.out.println(cardType);
System.out.println("============");
System.out.println(datas);
}
}
class GiftCard extends Chargeable{
private String name;
public GiftCard(String name){
super(CardType.GIFT);
this.name = name;
}
public String getName(){
return name;
}
public void setName(String name) {
this.name = name;
}
}
//카드 정보 나타내는 클래스
class Card extends Chargeable{
protected String cardNumber;
protected String expireDate;
protected Card(CardType cardType){
super(cardType);
}
}
//신용카드 정보 나타내는 클래스
class CreditCard extends Card{
private String accountNumber;
public CreditCard(String accountNumber, String cardNumber, String expireDate){
super(CardType.CRIDIT);
this.accountNumber = accountNumber;
this.cardNumber = cardNumber;
this.expireDate = expireDate;
}
@Override
public String toString() {
return "CreditCard{" +
"accountNumber='" + accountNumber + '\'' +
'}';
}
}
class CashCard extends Card{
private String accountNumber;
public CashCard(String accountNumber, String cardNumber, String expireDate){
super(CardType.CASH);
this.accountNumber = accountNumber;
this.cardNumber = cardNumber;
this.expireDate =expireDate;
}
public String getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
@Override
public String toString() {
return "CashCard{" +
"accountNumber='" + accountNumber + '\'' +
'}';
}
}
class Main_{
public static void main(String[] args) {
SinhanCard.getInstance().createUser("Sojin@gmail.com");
SinhanCard.getInstance().createCard(1L, CardType.CRIDIT);
SinhanCard.getInstance().createCard(1L, CardType.CASH);
SinhanCard.getInstance().createCard(1L, CardType.GIFT);
List<Chargeable> myCards = SinhanCard.getInstance().findMyCard(1L);
Chargeable creditCard = null;
Chargeable cashCard = null;
Chargeable giftCard = null;
// 카드를 분류합니다.
for (Chargeable card : myCards) {
if (card instanceof CreditCard) {
creditCard = card;
} else if (card instanceof Card) {
if (((Card) card).cardType == CardType.CASH) {
cashCard = card;
} else if (((Card) card).cardType == CardType.GIFT) {
giftCard = card;
}
}
}
creditCard.payment(5000);
creditCard.payment(3000);
cashCard.payment(1500);
if (giftCard != null) {
giftCard.payment(0);
}
System.out.println();
creditCard.cardPaymentHistories();
cashCard.cardPaymentHistories();
if (giftCard != null) {
giftCard.cardPaymentHistories();
}
}
}