Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

task-jv-fruits_store_implementation #1287

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
20 changes: 20 additions & 0 deletions src/main/java/FruitStore.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import dao.TransactionDaoImpl;
import dao.TransactionsDao;
import service.CsvParseService;
import service.CsvReadService;
import service.CsvTransactionService;
import service.CsvWriteService;

public class FruitStore {
public static void main(String[] args) {
TransactionsDao transactionDao = new TransactionDaoImpl();
CsvWriteService reportGenerator = new CsvWriteService(transactionDao);
CsvParseService csvParseService = new CsvParseService();
CsvReadService csvReadService = new CsvReadService(csvParseService);
CsvTransactionService csvTransactionService =
new CsvTransactionService(transactionDao, csvReadService, csvParseService);

csvTransactionService.processCsv();
reportGenerator.exportToCsv();
}
}
9 changes: 0 additions & 9 deletions src/main/java/core/basesyntax/HelloWorld.java

This file was deleted.

61 changes: 61 additions & 0 deletions src/main/java/dao/TransactionDaoImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package dao;

import db.Storage;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import model.FruitTransaction;
import strategy.BalanceStrategy;
import strategy.PurchaseStrategy;
import strategy.ReturnStrategy;
import strategy.SupplyStrategy;
import strategy.TransactionStrategy;

public class TransactionDaoImpl implements TransactionsDao {

private final Map<FruitTransaction.Operation, TransactionStrategy> operationHandlers
= new HashMap<>();

public TransactionDaoImpl() {
operationHandlers.put(FruitTransaction.Operation.BALANCE, new BalanceStrategy());
operationHandlers.put(FruitTransaction.Operation.SUPPLY, new SupplyStrategy());
operationHandlers.put(FruitTransaction.Operation.PURCHASE, new PurchaseStrategy());
operationHandlers.put(FruitTransaction.Operation.RETURN, new ReturnStrategy());
}

@Override
public List<FruitTransaction> getAll() {
return Storage.transactions;
}

@Override
public void processTransaction(FruitTransaction transaction) {
FruitTransaction fruit = findOrCreateFruit(transaction);
operationHandlers.getOrDefault(transaction.getOperation(), (f, t) -> {
throw new IllegalArgumentException("Unknown operation: " + t.getOperation());
}).apply(fruit, transaction);
}

@Override
public void updateTransactionInfo(FruitTransaction transaction) {
Storage.transactions.add(transaction);
}

@Override
public FruitTransaction getTransactionByName(String fruitName) {
return Storage.transactions.stream()
.filter(transaction -> transaction.getFruit().equals(fruitName))
.findFirst()
.orElse(null);
}

@Override
public FruitTransaction findOrCreateFruit(FruitTransaction transaction) {
return Optional.ofNullable(getTransactionByName(transaction.getFruit()))
.orElseGet(() -> {
updateTransactionInfo(transaction);
return transaction;
});
}
}
17 changes: 17 additions & 0 deletions src/main/java/dao/TransactionsDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package dao;

import java.util.List;
import model.FruitTransaction;

public interface TransactionsDao {

void processTransaction(FruitTransaction transaction);

void updateTransactionInfo(FruitTransaction transaction);

List<FruitTransaction> getAll();

FruitTransaction getTransactionByName(String fruitName);

FruitTransaction findOrCreateFruit(FruitTransaction transaction);
}
9 changes: 9 additions & 0 deletions src/main/java/db/Storage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package db;

import java.util.ArrayList;
import java.util.List;
import model.FruitTransaction;

public class Storage {
public static final List<FruitTransaction> transactions = new ArrayList<>();
}
68 changes: 68 additions & 0 deletions src/main/java/model/FruitTransaction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package model;

public class FruitTransaction {
private Operation operation;
private String fruit;
private int quantity;

public FruitTransaction(String fruit, int quantity,Operation operation) {
setOperation(operation);
setFruit(fruit);
setQuantity(quantity);
}

public FruitTransaction(String fruit, int quantity) {
setFruit(fruit);
setQuantity(quantity);
}

public Operation getOperation() {
return operation;
}

public void setOperation(Operation operation) {
this.operation = operation;
}

public String getFruit() {
return fruit;
}

public void setFruit(String fruit) {
this.fruit = fruit;
}

public int getQuantity() {
return quantity;
}

public void setQuantity(int quantity) {
this.quantity = quantity;
}

public enum Operation {
BALANCE("b"),
SUPPLY("s"),
PURCHASE("p"),
RETURN("r");

private String operation;

Operation(String operation) {
this.operation = operation;
}

public String getOperation() {
return operation;
}

public static Operation fromCode(String code) {
for (Operation type : Operation.values()) {
if (type.operation.equalsIgnoreCase(code)) {
return type;
}
}
throw new IllegalArgumentException("Unknown transaction type: " + code);
}
}
}
20 changes: 20 additions & 0 deletions src/main/java/service/CsvParseService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package service;

import model.FruitTransaction;

public class CsvParseService implements Parser {
@Override
public FruitTransaction parseTransaction(String line) {
int fruitNameIndex = 1;
int quantityIndex = 2;
int operationTypeIndex = 0;
String[] parts = line.split(",");
if (parts.length != 3) {
throw new IllegalArgumentException("Invalid CSV format: " + line);
}
return new FruitTransaction(
parts[fruitNameIndex],
Integer.parseInt(parts[quantityIndex]),
FruitTransaction.Operation.fromCode(parts[operationTypeIndex]));
}
}
28 changes: 28 additions & 0 deletions src/main/java/service/CsvReadService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package service;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;

public class CsvReadService implements Reader {
private final CsvParseService csvParseService;

public CsvReadService(CsvParseService csvParseService) {
this.csvParseService = csvParseService;
}

@Override
public List<String> readTransactionsFromCsv(String fileName) {
String filePath = Paths.get("src", "main", "resources", fileName).toString();;
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
return br.lines()
.skip(1) // Skip header
.collect(Collectors.toList());
} catch (IOException e) {
throw new RuntimeException("Error reading CSV file: " + filePath, e);
}
}
}
28 changes: 28 additions & 0 deletions src/main/java/service/CsvTransactionService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package service;

import dao.TransactionsDao;
import java.util.List;
import model.FruitTransaction;

public class CsvTransactionService implements Processor {
private static final String INPUT_FILE_NAME = "inputFile";

private final TransactionsDao transactionsDao;
private final CsvReadService csvReadService;
private final CsvParseService csvParserService;

public CsvTransactionService(TransactionsDao transactionsDao, CsvReadService readService, CsvParseService csvParserService) {
this.transactionsDao = transactionsDao;
this.csvReadService = readService;
this.csvParserService = csvParserService;
}

@Override
public void processCsv() {
List<String> lines
= csvReadService.readTransactionsFromCsv(INPUT_FILE_NAME);
List<FruitTransaction> transactions
= lines.stream().map(csvParserService::parseTransaction).toList();
transactions.forEach(transactionsDao::processTransaction);
}
}
32 changes: 32 additions & 0 deletions src/main/java/service/CsvWriteService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package service;

import dao.TransactionsDao;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Paths;
import model.FruitTransaction;

public class CsvWriteService implements Exporter {
private static final String OUTPUT_FILE_NAME = "outputFile";
private final TransactionsDao transactionsDao;

public CsvWriteService(TransactionsDao transactionsDao) {
this.transactionsDao = transactionsDao;
}

@Override
public void exportToCsv() {
String filePath = Paths.get("src", "main", "resources", OUTPUT_FILE_NAME).toString();
try (FileWriter writer = new FileWriter(filePath)) {
writer.append("fruit,quantity\n");
for (FruitTransaction fruit : transactionsDao.getAll()) {
writer.append(fruit.getFruit())
.append(",")
.append(String.valueOf(fruit.getQuantity()))
.append("\n");
}
} catch (IOException e) {
throw new RuntimeException("Error writing to CSV file: " + filePath, e);
}
}
}
6 changes: 6 additions & 0 deletions src/main/java/service/Exporter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package service;

public interface Exporter {

void exportToCsv();
}
8 changes: 8 additions & 0 deletions src/main/java/service/Parser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package service;

import model.FruitTransaction;

public interface Parser {

FruitTransaction parseTransaction(String line);
}
6 changes: 6 additions & 0 deletions src/main/java/service/Processor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package service;

public interface Processor {

void processCsv();
}
8 changes: 8 additions & 0 deletions src/main/java/service/Reader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package service;

import java.util.List;

public interface Reader {

List<String> readTransactionsFromCsv(String fileName);
}
10 changes: 10 additions & 0 deletions src/main/java/strategy/BalanceStrategy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package strategy;

import model.FruitTransaction;

public class BalanceStrategy implements TransactionStrategy {
@Override
public void apply(FruitTransaction fruit, FruitTransaction transaction) {
fruit.setQuantity(transaction.getQuantity());
}
}
10 changes: 10 additions & 0 deletions src/main/java/strategy/PurchaseStrategy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package strategy;

import model.FruitTransaction;

public class PurchaseStrategy implements TransactionStrategy {
@Override
public void apply(FruitTransaction fruit, FruitTransaction transaction) {
fruit.setQuantity(Math.max(0, fruit.getQuantity() - transaction.getQuantity()));
}
}
10 changes: 10 additions & 0 deletions src/main/java/strategy/ReturnStrategy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package strategy;

import model.FruitTransaction;

public class ReturnStrategy implements TransactionStrategy {
@Override
public void apply(FruitTransaction fruit, FruitTransaction transaction) {
fruit.setQuantity(fruit.getQuantity() + transaction.getQuantity());
}
}
10 changes: 10 additions & 0 deletions src/main/java/strategy/SupplyStrategy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package strategy;

import model.FruitTransaction;

public class SupplyStrategy implements TransactionStrategy {
@Override
public void apply(FruitTransaction fruit, FruitTransaction transaction) {
fruit.setQuantity(fruit.getQuantity() + transaction.getQuantity());
}
}
7 changes: 7 additions & 0 deletions src/main/java/strategy/TransactionStrategy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package strategy;

import model.FruitTransaction;

public interface TransactionStrategy {
void apply(FruitTransaction fruit, FruitTransaction transaction);
}
10 changes: 10 additions & 0 deletions src/main/resources/inputFile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
type,fruit,quantity
b,banana,20
b,apple,100
s,banana,100
p,banana,13
r,apple,10
p,apple,20
p,banana,5
s,banana,50
s,banana,50
Loading
Loading