package io.budgetapp.dao; import io.budgetapp.application.NotFoundException; import io.budgetapp.model.Transaction; import io.budgetapp.model.User; import io.budgetapp.model.form.report.SearchFilter; import io.dropwizard.hibernate.AbstractDAO; import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.SessionFactory; import org.hibernate.criterion.Order; import org.hibernate.criterion.Restrictions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Date; import java.util.List; import java.util.Optional; /** * */ public class TransactionDAO extends AbstractDAO<Transaction> { private static final Logger LOGGER = LoggerFactory.getLogger(TransactionDAO.class); public TransactionDAO(SessionFactory sessionFactory) { super(sessionFactory); } public Transaction addTransaction(Transaction transaction) { LOGGER.debug("Add transaction {}", transaction); return persist(transaction); } public List<Transaction> find(User user, Integer limit) { Query query = currentSession().createQuery("FROM Transaction t WHERE t.budget.user = :user ORDER BY t.transactionOn DESC, t.id ASC"); query.setParameter("user", user); query.setMaxResults(limit); return list(query); } public Transaction findById(long id) { Transaction transaction = get(id); if(transaction == null) { throw new NotFoundException(); } return transaction; } public Optional<Transaction> findById(User user, long id) { Query query = currentSession().createQuery("FROM Transaction t WHERE t.id = :id AND t.budget.user = :user"); query.setParameter("user", user); query.setParameter("id", id); Transaction result = (Transaction) query.uniqueResult(); return Optional.ofNullable(result); } public List<Transaction> findByBudget(User user, long budgetId) { Criteria criteria = defaultCriteria(); criteria.createAlias("t.budget", "budget"); criteria.add(Restrictions.eq("budget.id", budgetId)); criteria.add(Restrictions.eq("budget.user", user)); return list(criteria); } public List<Transaction> findByRecurring(User user, long recurringId) { Query query = currentSession().createQuery("FROM Transaction t WHERE t.budget.user = :user AND t.recurring.id = :recurringId ORDER BY t.transactionOn DESC, t.id ASC"); query.setParameter("user", user); query.setParameter("recurringId", recurringId); return list(query); } public List<Transaction> findByRange(User user, Date start, Date end) { Query query = currentSession().createQuery("FROM Transaction t WHERE t.budget.user = :user AND t.transactionOn BETWEEN :start AND :end ORDER BY t.transactionOn DESC, t.id ASC"); query .setParameter("user", user) .setParameter("start", start) .setParameter("end", end); return list(query); } public List<Transaction> findTransactions(User user, SearchFilter filter) { Criteria criteria = defaultCriteria(); criteria.createAlias("t.budget", "budget"); criteria.add(Restrictions.eq("budget.user", user)); if(filter.isAmountRange()) { criteria.add(Restrictions.between("amount", filter.getMinAmount(), filter.getMaxAmount())); } else if(filter.getMinAmount() != null) { criteria.add(Restrictions.ge("amount", filter.getMinAmount())); } else if(filter.getMaxAmount() != null) { criteria.add(Restrictions.le("amount", filter.getMaxAmount())); } if(filter.isDateRange()) { criteria.add(Restrictions.between("transactionOn", filter.getStartOn(), filter.getEndOn())); } else if(filter.getStartOn() != null) { criteria.add(Restrictions.ge("transactionOn", filter.getStartOn())); } else if(filter.getEndOn() != null) { criteria.add(Restrictions.le("transactionOn", filter.getEndOn())); } if(Boolean.TRUE.equals(filter.getAuto())) { criteria.add(Restrictions.eq("auto", Boolean.TRUE)); } return list(criteria); } private Criteria defaultCriteria() { Criteria criteria = currentSession().createCriteria(Transaction.class, "t"); criteria.addOrder(Order.desc("transactionOn")); criteria.addOrder(Order.desc("id")); return criteria; } public void delete(Transaction transaction) { currentSession().delete(transaction); } }