package io.budgetapp.dao; import io.budgetapp.model.Recurring; import io.budgetapp.model.RecurringType; import io.budgetapp.model.User; import io.budgetapp.model.Recurring; import io.budgetapp.model.RecurringType; import io.budgetapp.model.User; import io.budgetapp.util.Util; import io.dropwizard.hibernate.AbstractDAO; import org.hibernate.SessionFactory; import java.time.LocalDate; import java.time.temporal.ChronoField; import java.util.List; /** * */ public class RecurringDAO extends AbstractDAO<Recurring> { public RecurringDAO(SessionFactory sessionFactory) { super(sessionFactory); } public Recurring addRecurring(Recurring recurring) { return persist(recurring); } public List<Recurring> findRecurrings(User user) { return currentSession().createQuery("SELECT r FROM Recurring r JOIN r.budgetType budgetType WHERE budgetType IN (SELECT budget.budgetType FROM Budget budget WHERE budget.user = :user)") .setParameter("user", user) .list(); } public void delete(Recurring recurring) { currentSession().delete(recurring); } public Recurring find(User user, long recurringId) { return (Recurring)currentSession().createQuery("SELECT r FROM Recurring r JOIN r.budgetType budgetType WHERE budgetType IN (FROM Budget budget WHERE budget.user = :user and r.id = :id)") .setParameter("user", user) .setParameter("id", recurringId).uniqueResult(); } public List<Recurring> findByBudgetTypeId(long budgetTypeId) { return currentSession().createQuery("SELECT r FROM Recurring r WHERE r.budgetType.id = :budgetTypeId") .setParameter("budgetTypeId", budgetTypeId) .list(); } public List<Recurring> findActiveRecurrings() { LocalDate now = LocalDate.now(); return currentSession() .createQuery("SELECT r FROM Recurring r WHERE " + "(r.recurringType = :daily AND DAY(r.lastRunAt) = :yesterday) OR " + // last week with same day of week "(r.recurringType = :weekly AND WEEK(r.lastRunAt) = :lastWeek AND DAYOFWEEK(r.lastRunAt) = DAYOFWEEK(CURRENT_TIMESTAMP)) OR " + // last month with same day of month "(r.recurringType = :monthly AND MONTH(r.lastRunAt) = :lastMonth AND DAY(r.lastRunAt) = DAY(CURRENT_TIMESTAMP)) OR " + // last year with same month "(r.recurringType = :yearly AND YEAR(r.lastRunAt) = :lastYear AND MONTH(r.lastRunAt) = MONTH(CURRENT_TIMESTAMP)) OR " + "r.lastRunAt IS NULL") .setParameter("daily", RecurringType.DAILY) .setParameter("yesterday", Util.yesterday(now)) .setParameter("weekly", RecurringType.WEEKLY) .setParameter("lastWeek", Util.lastWeek(now)) .setParameter("monthly", RecurringType.MONTHLY) .setParameter("lastMonth", Util.lastMonth(now)) .setParameter("yearly", RecurringType.YEARLY) .setParameter("lastYear", now.minusYears(1).getYear()) .list(); } public void update(Recurring recurring) { persist(recurring); } }