Package com.excilys.ebi.bank.dao.impl

Source Code of com.excilys.ebi.bank.dao.impl.OperationDaoImpl

/**
* Copyright 2011-2012 eBusiness Information, Groupe Excilys (www.excilys.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.excilys.ebi.bank.dao.impl;

import static com.excilys.ebi.bank.model.entity.QOperation.operation;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.transform;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.joda.time.DateTime;
import org.joda.time.Interval;
import org.joda.time.YearMonth;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.QueryDslRepositorySupport;
import org.springframework.stereotype.Repository;

import com.excilys.ebi.bank.dao.OperationDaoCustom;
import com.excilys.ebi.bank.model.entity.Card;
import com.excilys.ebi.bank.model.entity.Operation;
import com.excilys.ebi.bank.model.entity.QOperation;
import com.excilys.ebi.bank.model.entity.ref.OperationSign;
import com.excilys.ebi.bank.model.entity.ref.OperationStatus;
import com.excilys.ebi.bank.model.entity.ref.OperationType;
import com.google.common.base.Function;
import com.mysema.query.Tuple;
import com.mysema.query.jpa.JPQLQuery;
import com.mysema.query.types.Predicate;
import com.mysema.query.types.QTuple;
import com.mysema.query.types.expr.BooleanExpression;

@Repository
public class OperationDaoImpl extends QueryDslRepositorySupport implements OperationDaoCustom {

  public OperationDaoImpl() {
    super(Operation.class);
  }

  protected JPQLQuery applyPagination(JPQLQuery query, Pageable pageable) {
    return pageable != null ? query.offset(pageable.getOffset()).limit(pageable.getPageSize()) : query;
  }

  @Override
  public Page<Operation> findNonCardByAccountIdAndYearMonth(Integer accountId, YearMonth yearMonth, Pageable pageable) {

    BooleanExpression predicate = operation.type.id.ne(OperationType.CARD).and(operation.account.id.eq(accountId));
    predicate = addOperationYearMonthExpression(predicate, operation, yearMonth);

    JPQLQuery countQuery = from(operation).where(predicate);
    JPQLQuery query = applyPagination(from(operation).where(predicate).orderBy(operation.date.desc()), pageable);

    return buildPage(countQuery, query, pageable);
  }

  @Override
  public List<Operation> sumResolvedAmountByAccountIdAndYearMonthAndSignGroupByCard(Integer accountId, YearMonth yearMonth, OperationSign sign) {

    BooleanExpression predicate = operation.type.id.eq(OperationType.CARD).and(operation.status.id.eq(OperationStatus.RESOLVED)).and(operation.account.id.eq(accountId))
        .and(buildOperationSignPredicate(sign));
    predicate = addOperationYearMonthExpression(predicate, operation, yearMonth);

    List<Tuple> tuples = from(operation).where(predicate).groupBy(operation.card.id).list(new QTuple(operation.amount.sum(), operation.card.id));

    return newArrayList(transform(tuples, new Function<Tuple, Operation>() {
      @Override
      public Operation apply(Tuple input) {
        return Operation.newOperation().withAmount(input.get(operation.amount.sum())).withCard(Card.newCardBuilder().withId(input.get(operation.card.id)).build()).build();
      }
    }));
  }

  @Override
  public BigDecimal sumResolvedAmountByCardAndYearMonth(Card card, YearMonth yearMonth) {

    BooleanExpression predicate = operation.type.id.eq(OperationType.CARD).and(operation.status.id.eq(OperationStatus.RESOLVED)).and(operation.card.eq(card));
    predicate = addOperationYearMonthExpression(predicate, operation, yearMonth);

    return from(operation).where(predicate).uniqueResult(operation.amount.sum());
  }

  private Predicate buildOperationSignPredicate(OperationSign sign) {
    return sign == OperationSign.CREDIT ? operation.amount.gt(BigDecimal.ZERO) : operation.amount.lt(BigDecimal.ZERO);
  }

  @Override
  public BigDecimal sumResolvedAmountByAccountIdAndYearMonthAndSign(Integer accountId, YearMonth yearMonth, OperationSign sign) {

    BooleanExpression predicate = operation.account.id.eq(accountId).and(buildOperationSignPredicate(sign)).and(operation.status.id.eq(OperationStatus.RESOLVED));
    predicate = addOperationYearMonthExpression(predicate, operation, yearMonth);

    return from(operation).where(predicate).uniqueResult(operation.amount.sum());
  }

  @Override
  public Page<Operation> findCardOperationsByAccountIdAndYearMonthAndStatus(Integer accountId, YearMonth yearMonth, OperationStatus status, Pageable pageable) {

    BooleanExpression predicate = operation.type.id.eq(OperationType.CARD).and(operation.account.id.eq(accountId)).and(operation.status.id.eq(status));
    predicate = addOperationYearMonthExpression(predicate, operation, yearMonth);

    JPQLQuery countQuery = from(operation).where(predicate);
    JPQLQuery query = applyPagination(from(operation).where(predicate).orderBy(operation.date.desc()), pageable);

    return buildPage(countQuery, query, pageable);
  }

  @Override
  public BigDecimal sumCardAmountByAccountIdAndYearMonthAndSignAndStatus(Integer accountId, YearMonth yearMonth, OperationSign sign, OperationStatus status) {

    BooleanExpression predicate = operation.type.id.eq(OperationType.CARD).and(operation.account.id.eq(accountId)).and(buildOperationSignPredicate(sign))
        .and(operation.status.id.eq(status));
    predicate = addOperationYearMonthExpression(predicate, operation, yearMonth);

    return from(operation).where(predicate).uniqueResult(operation.amount.sum());
  }

  @Override
  public Page<Operation> findCardOperationsByCardIdAndYearMonthAndStatus(Integer cardId, YearMonth yearMonth, OperationStatus status, Pageable pageable) {

    BooleanExpression predicate = operation.type.id.eq(OperationType.CARD).and(operation.card.id.eq(cardId)).and(operation.status.id.eq(status));
    predicate = addOperationYearMonthExpression(predicate, operation, yearMonth);

    JPQLQuery countQuery = from(operation).where(predicate);
    JPQLQuery query = applyPagination(from(operation).where(predicate).orderBy(operation.date.desc()), pageable);

    return buildPage(countQuery, query, pageable);
  }

  @Override
  public BigDecimal sumCardAmountByCardIdAndYearMonthAndSignAndStatus(Integer cardId, YearMonth yearMonth, OperationSign sign, OperationStatus status) {

    BooleanExpression predicate = operation.type.id.eq(OperationType.CARD).and(operation.card.id.eq(cardId)).and(buildOperationSignPredicate(sign))
        .and(operation.status.id.eq(status));
    predicate = addOperationYearMonthExpression(predicate, operation, yearMonth);

    return from(operation).where(predicate).uniqueResult(operation.amount.sum());
  }

  @Override
  public Page<Operation> findTransferByAccountId(Integer accountId, Pageable pageable) {

    BooleanExpression predicate = operation.type.id.eq(OperationType.TRANSFER).and(operation.account.id.eq(accountId));

    JPQLQuery countQuery = from(operation).where(predicate);
    JPQLQuery query = applyPagination(from(operation).where(predicate).orderBy(operation.date.desc()), pageable);

    return buildPage(countQuery, query, pageable);
  }

  private BooleanExpression addOperationYearMonthExpression(BooleanExpression predicate, QOperation operation, YearMonth yearMonth) {

    if (yearMonth == null)
      return predicate;
    else {
      Interval range = yearMonth.toInterval();
      return predicate.and(operation.date.between(range.getStart(), range.getEnd()));
    }
  }

  private Page<Operation> buildPage(JPQLQuery countQuery, JPQLQuery query, Pageable pageable) {

    long count = countQuery.count();
    return count > 0 ? new PageImpl<Operation>(query.list(operation), pageable, count) : new PageImpl<Operation>(new ArrayList<Operation>(), pageable, 0);
  }

  @Override
  public DateTime getLastOperationDate() {
    return from(operation).uniqueResult(operation.date.max());
  }
}
TOP

Related Classes of com.excilys.ebi.bank.dao.impl.OperationDaoImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.