세미 프로젝트 : 자바를 이용한 콘솔 환경에서의 POS 구현
● 상품관리는 아래 항목을 포함해 C:\DBFILE\goods.txt 파일에 상품을 추가 할 수 있어야 한다.
- 상품코드, 상품명, 상품판매가격, 재고량
각 항목은 ‘: (콜론)’을 이용하여 구분하고 상품별로 한 줄로 정보를 입력하여야 한다.
● 판매관리는 소비자의 주문 시 아래 항목을 포함해 D:\DBFILE\orders.txt 파일에 판매 기록을 저장할 수 있어야 한다.
- 주문코드 : 20210831142021(년도 4자리 + 월 2자리 + 일 2자리 + 시간 6자리)
- 상품코드 : goods.txt 파일에 등록되어 있는 상품이어야 한다.
- 상품명 : goods.txt 파일에 등록되어 있는 상품이어야 한다.
- 상품가격 : goods.txt 파일에 등록되어 있는 상품이어야 한다.
- 구매수량 : 소비자의 구매 수량을 운영자가 입력해 새롭게 생성되어져야 한다.
- 합계금액 : goods.txt파일과 소비자의 구매 수량을 기반으로 자동 계산되어 새롭게 생성되어져야 한다.
● 개인 제출사항 - 개인별 프로젝트 파일(pos.zip) - 프로젝트 개발 결과 보고서
MainController(메인 클래스)
import java.util.Scanner;
public class MainController {
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
GoodsController.loadingData(); //상품목록 불러오기
SalesController.loadingData(); //판매내역 불러오기
boolean flag = true;
while (flag) {
boolean flag2 = true;
System.out.println("------------------------------");
System.out.println("\t메뉴를 선택하세요.");
System.out.println("------------------------------");
System.out.println("1.상품관리");
System.out.println("2.상품주문");
System.out.println("3.주문내역");
System.out.println("4.총매출");
System.out.println("5.프로그램종료");
int choice1 = sc.nextInt();
if (choice1 == 1) {
while (flag2) {
System.out.println("------------------------------");
System.out.println("상품관리) 메뉴를 선택하세요.");
System.out.println("------------------------------");
System.out.println("1.상품등록");
System.out.println("2.상품수정");
System.out.println("3.상품삭제");
System.out.println("4.재고조회");
System.out.println("5.<<이전");
int choice2 = sc.nextInt();
sc.nextLine();
if (choice2 == 1) {
GoodsController.addGoods(); //상품등록
} else if (choice2 == 2) {
GoodsController.editGoods(); //상품수정
} else if (choice2 == 3) {
GoodsController.deleteGoods(); //상품삭제
} else if (choice2 == 4) {
GoodsController.goodsStock(); //재고조회
} else if (choice2 == 5) {
flag2 = false;
break;
} else {
System.out.println("해당 번호가 존재하지 않습니다.");
}
} // while end
} else if (choice1 == 2) {
SalesController.orderMenu(); //상품주문
} else if (choice1 == 3) {
SalesController.showOrderArr(); //주문내역
} else if (choice1 == 4) {
SalesController.salesTotal(); //총매출
} else if (choice1 == 5) {
System.out.println("프로그램을 종료합니다.");
GoodsController.saveData(); //상품목록 저장
SalesController.saveData(); //판매내역 저장
flag = false; //while문 빠져나감
sc.close();
break;
} else {
System.out.println("해당 번호가 존재하지 않습니다.");
}
} // while end
} // main end
}
메인 클래스이다.
대메뉴를 선택하고, 상품관리 메뉴에서는 다시 메뉴를 세분화한다.
그 외 메뉴들은 각각의 컨트롤러를 구현해서 메소드로 처리한다.
GoodsInfo(상품정보)
import java.io.Serializable;
public class GoodsInfo implements Serializable {
private String goodsCode;
private String goodsName;
private int goodsPrice;
private int goodsStock;
public int getGoodsStock() {
return goodsStock;
}
public void setGoodsStock(int goodsStock) {
this.goodsStock = goodsStock;
}
GoodsInfo(String goodsCode, String goodsName, int goodsPrice, int goodsStock) {
this.goodsName = goodsName;
this.goodsCode = goodsCode;
this.goodsPrice = goodsPrice;
this.goodsStock = goodsStock;
}
public void showGoodsInfo() {
System.out.println("상품코드 : " + goodsCode);
System.out.println("상품명 : " + goodsName);
System.out.println("상품가격 : " + goodsPrice);
System.out.println("재고수량 : " + goodsStock);
}
public String getGoodsCode() {
return goodsCode;
}
public void setGoodsCode(String goodsCode) {
this.goodsCode = goodsCode;
}
public String getGoodsName() {
return goodsName;
}
//상품명은 변경 불가함
// public void setGoodsName(String goodsName) {
// this.goodsName = goodsName;
// }
public int getGoodsPrice() {
return goodsPrice;
}
public void setGoodsPrice(int goodsPrice) {
this.goodsPrice = goodsPrice;
}
@Override
public int hashCode() {
return goodsName.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof GoodsInfo) {
GoodsInfo goods = (GoodsInfo) obj;
if (goods.getGoodsName().equals(goodsName)) {
return true;
}
}
return false;
}
}
상품 수정할 때 상품명은 변경이 불가하도록 만들었으므로 세터를 비활성화 시켰다.
GoodsInfo 는 상품의 데이터 클래스이므로 직렬화와 역직렬화를 위해 Serializable 인터페이스를 implements 했다.
GoodsController(상품관리 클래스)
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Iterator;
public class GoodsController {
static ArrayList<GoodsInfo> goodsArr = new ArrayList<GoodsInfo>();
// 상품등록
public static void addGoods() {
System.out.println("등록할 상품의 정보를 입력하세요.");
System.out.println("상품코드:상품명:상품가격:재고수량");
System.out.println("ex) 100:크림빵:700:5");
String input = MainController.sc.nextLine();
String[] strArr = input.split(":"); // split을 기준으로 문자열 가르기
String goodsNumber = strArr[0];
String goodsName = strArr[1];
int goodsPrice = Integer.parseInt(strArr[2]); // String을 int로 변환
int stock = Integer.parseInt(strArr[3]);
GoodsInfo goods = new GoodsInfo(goodsNumber, goodsName, goodsPrice, stock);
goodsArr.add(goods);
System.out.println("등록이 완료되었습니다.");
}
// 상품수정
public static void editGoods() {
System.out.println("순번\t상품코드\t상품명\t상품가격\t재고수량");
int index = 1; // 상품목록에 순번달기 (1번부터 시작)
for (GoodsInfo gi : GoodsController.goodsArr) {
System.out.println(index + ".\t" + gi.getGoodsCode() + "\t" + gi.getGoodsName() + "\t" + gi.getGoodsPrice()
+ "원\t" + gi.getGoodsStock());
index++;
} // 상품목록 보여주기
boolean run = true;
while (true) {
System.out.println("수정할 상품의 번호를 선택하세요.");
int inputIndex = MainController.sc.nextInt();
if (inputIndex <= goodsArr.size()) { // 범위 안에 있는 인덱스를 선택했다면
int goodsIndex = inputIndex - 1;
String goodsName = goodsArr.get(goodsIndex).getGoodsName();
Iterator<GoodsInfo> itr = goodsArr.iterator();
while (itr.hasNext()) {
GoodsInfo goods = itr.next();
if (goodsName.equals(goods.getGoodsName())) {
goods.showGoodsInfo();
System.out.println("수정할 데이터를 선택하세요.");
System.out.println("1.상품코드 2.상품가격 3.재고수량");
int edit = MainController.sc.nextInt();
if (edit == 1) {
System.out.println("새로운 상품코드를 입력하세요.");
String editNum = MainController.sc.next();
goods.setGoodsCode(editNum);
} else if (edit == 2) {
System.out.println("새로운 상품가격을 입력하세요.");
int editPrice = MainController.sc.nextInt();
goods.setGoodsPrice(editPrice);
} else if (edit == 3) {
System.out.println("새로운 재고수량을 입력하세요.");
int editStock = MainController.sc.nextInt();
goods.setGoodsStock(editStock);
} else {
System.out.println("잘못 입력하셨습니다.");
}
System.out.println("변경이 완료되었습니다.");
}
}
} else {
System.out.println("잘못 입력하셨습니다.");
}
}
}
// 상품삭제
public static void deleteGoods() {
System.out.println("순번\t상품코드\t상품명\t상품가격\t재고수량");
int index = 1; // 상품목록에 순번달기 (1번부터 시작)
for (GoodsInfo gi : GoodsController.goodsArr) {
System.out.println(index + ".\t" + gi.getGoodsCode() + "\t" + gi.getGoodsName() + "\t" + gi.getGoodsPrice()
+ "원\t" + gi.getGoodsStock());
index++;
} // 상품목록 보여주기
boolean run = true;
while (true) {
System.out.println("삭제할 상품의 번호를 선택하세요.");
int inputIndex = MainController.sc.nextInt();
if (inputIndex <= goodsArr.size()) { // 범위 안에 있는 인덱스를 선택했다면
int goodsIndex = inputIndex - 1;
String goodsName = goodsArr.get(goodsIndex).getGoodsName();
Iterator<GoodsInfo> itr = goodsArr.iterator();
while (itr.hasNext()) {
GoodsInfo goods = itr.next();
if (goodsName.equals(goods.getGoodsName())) {
goods.showGoodsInfo();
System.out.println("전체 데이터를 삭제하시겠습니까?\n1.예 2.아니오");
int delete = MainController.sc.nextInt();
if (delete == 1) {
goodsArr.remove(goods);
System.out.println("삭제되었습니다.");
break;
} else if (delete == 2) {
System.out.println("취소되었습니다.");
}
}
}
} else {
System.out.println("잘못 입력하셨습니다.");
}
}
}
// 재고조회
public static void goodsStock() {
System.out.println("상품코드\t상품명\t재고수량");
for (GoodsInfo gi : goodsArr) {
System.out.println(gi.getGoodsCode() + "\t" + gi.getGoodsName() + "\t" + gi.getGoodsStock());
}
}
// 데이터 불러오기
public static void loadingData() {
String path = "c:/DBFILE/goods.txt";
File dir = new File("c:/DBFILE");
if (!dir.isDirectory()) { // 폴더가 없을경우 폴더 생성
dir.mkdir();
}
File file = new File(path); // 파일이 없을경우 파일 생성
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
FileInputStream fileInput = null;
ObjectInputStream objInput = null;
try {
fileInput = new FileInputStream(file); // 파일 스트림화
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
if (fileInput.available() > 0) { // 읽을 파일이 있는지 확인
objInput = new ObjectInputStream(fileInput); // 역직렬화 준비
while (fileInput.available() > 0) { // 역직렬화
try {
goodsArr.add((GoodsInfo) objInput.readObject());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 데이터 저장하기
public static void saveData() {
String path = "c:/DBFILE/goods.txt";
File dir = new File("c:/DBFILE");
File file = new File(path);
FileOutputStream fileOut = null;
ObjectOutputStream objOut = null;
if (goodsArr != null) {
Iterator<GoodsInfo> itr = goodsArr.iterator();
try {
fileOut = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
objOut = new ObjectOutputStream(fileOut);
} catch (IOException e) {
e.printStackTrace();
}
while (itr.hasNext()) {
GoodsInfo goods = itr.next();
try {
objOut.writeObject(goods);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
objOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
상품의 수정과 삭제는 번호를 입력받아 그 번호에 해당하는 상품명과 기타 상품 정보를 얻어와 수정 및 삭제가 가능하도록 구현했으며, 범위 밖의 숫자를 지정할 경우에 잘못입력했다는 메세지가 출력하도록 했다.
각 메뉴의 구동화면이다.
상품을 주문하는 화면을 구현했다.
지금까지 해보지 않았던 내용이라 작성하는 데에 많은 시간과 노력을 투자했던 부분이다.
기존의 MainController 클래스에, 추가로 SalesController 를 만들어 판매관리 작업을 처리하도록 했다.
InCart
import java.io.Serializable;
public class InCart implements Serializable {
private String goodsName;
private int orderQuantity;
private int goodsPrice;
private int orderAmount;
private int goodsIndex;
InCart(int goodsIndex, String goodsName, int goodsPrice, int orderQuantity, int orderAmount) {
this.goodsIndex = goodsIndex;
this.goodsName = goodsName;
this.goodsPrice = goodsPrice;
this.orderQuantity = orderQuantity;
this.orderAmount = orderAmount;
}
public void showInCart() {
System.out.println(goodsName + "\t" + orderQuantity + "\t" + orderAmount + "원");
}
public String getGoodsName() {
return goodsName;
}
public int getOrderQuantity() {
return orderQuantity;
}
public int getGoodsPrice() {
return goodsPrice;
}
public int getOrderAmount() {
return orderAmount;
}
public int getGoodsIndex() {
return goodsIndex;
}
}
상품을 주문할 때, 한 품목씩 차례로 담을 수 있게 하는데 거기에 한 품목(=한 줄)을 따로 인스턴스로 만들어 관리하려고 InCart 클래스를 따로 생성했다.
InCart 인스턴스의 값은 추후 InCart의 객체배열을 생성하여 객체배열에 차례로 들어가도록 구현했다.
OrderList
import java.io.Serializable;
public class OrderList implements Serializable{
private String orderCode;
private InCart[] cart;
private int totalAmount;
private int cartCount;
OrderList(String orderCode, InCart[] cart,int cartCount, int totalAmount) {
this.orderCode = orderCode;
this.cart = cart;
this.cartCount = cartCount;
this.totalAmount = totalAmount;
}
public String getOrderCode() {
return orderCode;
}
public int getTotalAmount() {
return totalAmount;
}
public int getCartCount() {
return cartCount;
}
public InCart[] getCart() {
return cart;
}
}
주문내역에 보여지는 주문코드, 장바구니내역, 총액을 인스턴스에 넣을 수 있도록 만들었고 장바구니에 몇 개의 품목이 들어가 있는지를 계산하기 위해 cartCount 도 담을 수 있도록 했다.
SalesController
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.WriteAbortedException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
public class SalesController {
static ArrayList<OrderList> orderArr = new ArrayList<OrderList>();
// 상품주문
static void orderMenu() {
InCart[] cart = new InCart[10];
int totalAmount = 0;
int cartCount = 0; // 장바구니에 담긴 상품의 종류와 같음
boolean addCart = true;
while (addCart) {
String goodsName = null;
int orderQuantity = 0;
int goodsPrice = 0;
int orderAmount = 0;
int goodsStock = 0;
int goodsIndex = 0;
// 상품목록을 보여줌
System.out.println("----------상품목록----------");
int index = 1; // 상품목록에 순번달기 (1번부터 시작)
for (GoodsInfo gi : GoodsController.goodsArr) {
System.out.println(index + "." + gi.getGoodsName() + "\t" + gi.getGoodsPrice() + "원\t(재고"
+ gi.getGoodsStock() + "개)");
index++;
}
System.out.println("구매할 상품의 번호를 입력해주세요.");
int choiceIndex = MainController.sc.nextInt();
goodsIndex = choiceIndex - 1;
// 선택한 상품의 이름, 상품가격, 재고 찾기
goodsName = GoodsController.goodsArr.get(goodsIndex).getGoodsName();
goodsPrice = GoodsController.goodsArr.get(goodsIndex).getGoodsPrice();
goodsStock = GoodsController.goodsArr.get(goodsIndex).getGoodsStock();
System.out.println(goodsName + "의 구매수량을 입력해주세요.");
// 재고보다 많이 구매하려고 하면 구매불가
boolean available = true;
while (available) {
int inputQuantity = MainController.sc.nextInt();
if (inputQuantity > goodsStock) {
System.out.println("재고가 부족합니다. 다시 입력해주세요.");
} else { // 재고가 있을 경우
orderQuantity = inputQuantity;
goodsStock -= orderQuantity;
GoodsController.goodsArr.get(goodsIndex).setGoodsStock(goodsStock); // 재고에 반영
available = false;
System.out.println("장바구니에 추가되었습니다.");
}
}
orderAmount = goodsPrice * orderQuantity; // 구매금액 = 단가 * 수량
totalAmount += orderAmount;
// 각각 순번, 상품명, 단가, 수량, 구매금액을 넣기
InCart inCart = new InCart(goodsIndex, goodsName, goodsPrice, orderQuantity, orderAmount);
cart[cartCount++] = inCart;
// 카트에 담긴 내역 모두 불러오기
System.out.println("--------장바구니목록--------");
System.out.println("상품명\t주문수량\t금액");
for (int i = 0; i < cartCount; i++) {
cart[i].showInCart();
}
System.out.println("-------------------------");
System.out.println("합계\t\t" + totalAmount + "원");
System.out.println();
System.out.println("1.추가 2.주문하기");
int add = MainController.sc.nextInt();
if (add == 1) {
addCart = true;
} else if (add == 2) {
inCart = null; // 장바구니 초기화
addCart = false;
break;
} else {
System.out.println("번호를 다시 입력해주세요.");
}
} // while end
System.out.println("주문이 완료되었습니다.");
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddkkmmss");
String orderCode = dateFormat.format(new Date());
OrderList orderList = new OrderList(orderCode, cart, cartCount, totalAmount);
orderArr.add(orderList);
System.out.println("주문코드: " + orderList.getOrderCode());
} // orderMenu end
상품주문을 누르고 첫 번째 품목을 담으면 InCart에 들어가고, InCart의 객체배열을 만들어 그 안에 차곡차곡 쌓이게 된다.
장바구니에 원하는 품목을 모두 담고 '주문하기'를 선택하면 InCart의 배열 자체를 다시 OrderList의 ArrayList인 orderArr 안에 넣는다.
이번에는 판매관리의 모든 부분의 구현을 끝내고 데이터를 저장, 불러오기하는 부분을 구현했다.
GoodsController에서 데이터 저장/불러오기하는 부분과 거의 흡사하지만 에러가 나서 애먹기도 했었다.
GoodsController (이전과 이어짐)
// 주문내역
public static void showOrderArr() {
for (OrderList oi : orderArr) {
System.out.println("주문코드: " + oi.getOrderCode());
System.out.println("----------------------");
System.out.println("상품명\t구매수량\t금액");
InCart[] cart = oi.getCart();
for (int i = 0; i < oi.getCartCount(); i++) {
cart[i].showInCart();
}
System.out.println("----------------------");
System.out.println("합계\t\t" + oi.getTotalAmount() + "원");
System.out.println();
}
}
public static void salesTotal() {
int salesTotal = 0;
for (OrderList oi : orderArr) {
salesTotal += oi.getTotalAmount();
}
System.out.println("현재 매출 총액은 " + salesTotal + "원 입니다.");
}
// 데이터 불러오기
public static void loadingData() {
String path = "c:/DBFILE/orders.txt";
File dir = new File("c:/DBFILE");
if (!dir.isDirectory()) { // 폴더가 없을경우 폴더 생성
dir.mkdir();
}
File file = new File(path); // 파일이 없을경우 파일 생성
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
FileInputStream fileInput = null;
ObjectInputStream objInput = null;
try {
fileInput = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
if (fileInput.available() > 0) {
objInput = new ObjectInputStream(fileInput);
while (fileInput.available() > 0) {
orderArr.add((OrderList) objInput.readObject());
}
objInput.close();
}
} catch (WriteAbortedException e) {
e.printStackTrace();
} catch (EOFException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileInput.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
// 데이터 파일저장
public static void saveData() {
String path = "c:/DBFILE/orders.txt";
File file = new File(path);
FileOutputStream fileOut = null;
ObjectOutputStream objOut = null;
if (orderArr != null && orderArr.size() > 0) {
Iterator<OrderList> itr = orderArr.iterator();
try {
fileOut = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
objOut = new ObjectOutputStream(fileOut);
} catch (IOException e) {
e.printStackTrace();
}
while (itr.hasNext()) {
OrderList order = itr.next();
try {
objOut.writeObject(order);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
objOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
이전 내용에서는 상품을 주문하고 주문코드를 생성했는데, 주문내역에 들어가면 이전에 주문했던 내역들을 모두 볼 수 있다.
총 매출액 확인은 주문내역에 쌓인 totalAmount를 출력한다.
마지막으로 프로그램 종료를 선택하면 프로그램을 종료한다는 안내 메세지와 함께 지금까지의 데이터를 각각 상품관리는 goods.txt 에, 판매관리는 orders.txt 에 저장한다. (직렬화)
프로그램을 재실행하면 기존의 데이터를 다시 불러와 각각 goodsArr와 orderArr에 넣어준다. (역직렬화)
자바를 배운지도 얼마 안 됐고 이론 정리도 잘 되어있지 않은 데다가 코드를 응용하는 데에도 자신이 없었기 때문에 세미프로젝트를 진행한다는 게 처음에는 너무 막막하기만 했다.
기존에도 과제를 받았을 때 검색을 이용해 다른 사람의 코드를 따라 쓰기에 급급해하거나, 그것도 안 될 때는 코드풀이가 끝날 때까지 기다렸다가 해설을 듣고 그제야 이해하는 식으로 수업에 참여를 해왔기 때문에 더욱 그랬을 것이다.
이번 세미 프로젝트는 아직 부족한 부분도 많고 구현해내지 못한 부분도 많지만, 내가 다른 사람의 코드를 참고하지 않고 순수하게 나만의 방식으로 만든 내 작품이나 다름없다.
막막하기만 했던 초기 작업 시에도 하나하나 풀어나가다 보니까 어느 새 완성이 되어 있었다.
자바에 대한 모든 것을 배운 것도 아니고 이제 시작에 불과하지만 이번 세미 프로젝트는 나에게 자부심과 자신감을 준 계기가 되어 주었다.
앞으로도 어렵고 막막한 프로젝트를 끊임없이 접하게 되겠지만 지금의 마음가짐과 느낀 점을 토대로 그 때도 하나씩 차근차근 풀어나가봐야 겠다는 생각이 든다.
'개발입문 > JAVA 세미프로젝트' 카테고리의 다른 글
[JAVA] Stream을 이용하여 파일 저장이 가능한 전화번호부 만들기 (0) | 2022.10.12 |
---|---|
[JAVA] HashSet을 이용하여 중복값 저장이 안 되는 전화번호부 만들기 (0) | 2022.10.12 |
[JAVA] 상속과 오버라이딩을 이용하여 카테고리가 있는 전화번호부 만들기 (0) | 2022.10.12 |
[JAVA] 배열을 이용한 전화번호부 만들기 (0) | 2022.10.12 |
댓글