///////////////////////////////////////////////////////////////////////////// // // Project ProjectForge Community Edition // www.projectforge.org // // Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de) // // ProjectForge is dual-licensed. // // This community edition is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as published // by the Free Software Foundation; version 3 of the License. // // This community edition is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General // Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, see http://www.gnu.org/licenses/. // ///////////////////////////////////////////////////////////////////////////// package org.projectforge.fibu; import java.math.RoundingMode; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Set; import org.apache.commons.collections.CollectionUtils; import org.hibernate.criterion.Order; import org.hibernate.criterion.Restrictions; import org.projectforge.core.BaseDao; import org.projectforge.core.BaseSearchFilter; import org.projectforge.core.DisplayHistoryEntry; import org.projectforge.core.QueryFilter; import org.projectforge.core.UserException; import org.projectforge.database.SQLHelper; import org.projectforge.fibu.kost.KostZuweisungDO; import org.projectforge.user.UserRightId; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @Transactional(readOnly = true, propagation = Propagation.SUPPORTS) public class EingangsrechnungDao extends BaseDao<EingangsrechnungDO> { private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(EingangsrechnungDao.class); public static final UserRightId USER_RIGHT_ID = UserRightId.FIBU_EINGANGSRECHNUNGEN; private static final Class< ? >[] ADDITIONAL_SEARCH_DOS = new Class[] { EingangsrechnungsPositionDO.class}; private static final String[] ADDITIONAL_SEARCH_FIELDS = new String[] { "positionen.text"}; private KontoDao kontoDao; public EingangsrechnungDao() { super(EingangsrechnungDO.class); userRightId = USER_RIGHT_ID; } /** * List of all years with invoices: select min(datum), max(datum) from t_fibu_rechnung. * @return */ @SuppressWarnings("unchecked") public int[] getYears() { final List<Object[]> list = getSession().createQuery("select min(datum), max(datum) from EingangsrechnungDO t").list(); return SQLHelper.getYears(list); } public EingangsrechnungsStatistik buildStatistik(final List<EingangsrechnungDO> list) { final EingangsrechnungsStatistik stats = new EingangsrechnungsStatistik(); if (list == null) { return stats; } for (final EingangsrechnungDO rechnung : list) { stats.add(rechnung); } return stats; } /** * @param eingangsrechnung * @param kontoId If null, then konto will be set to null; * @see BaseDao#getOrLoad(Integer) */ public void setKonto(final EingangsrechnungDO eingangsrechnung, final Integer kontoId) { final KontoDO konto = kontoDao.getOrLoad(kontoId); eingangsrechnung.setKonto(konto); } /** * Sets the scales of percentage and currency amounts. <br/> * Gutschriftsanzeigen dürfen keine Rechnungsnummer haben. Wenn eine Rechnungsnummer für neue Rechnungen gegeben wurde, so muss sie * fortlaufend sein. Berechnet das Zahlungsziel in Tagen, wenn nicht gesetzt, damit es indiziert wird. * @see org.projectforge.core.BaseDao#onSaveOrModify(org.projectforge.core.ExtendedBaseDO) */ @Override protected void onSaveOrModify(final EingangsrechnungDO obj) { if (obj.getZahlBetrag() != null) { obj.setZahlBetrag(obj.getZahlBetrag().setScale(2, RoundingMode.HALF_UP)); } obj.recalculate(); if (CollectionUtils.isEmpty(obj.getPositionen()) == true) { throw new UserException("fibu.rechnung.error.rechnungHatKeinePositionen"); } final int size = obj.getPositionen().size(); for (int i = size - 1; i > 0; i--) { // Don't remove first position, remove only the last empty positions. final EingangsrechnungsPositionDO position = obj.getPositionen().get(i); if (position.getId() == null && position.isEmpty() == true) { obj.getPositionen().remove(i); } else { break; } } RechnungDao.writeUiStatusToXml(obj); } @Override protected void afterLoad(final EingangsrechnungDO obj) { RechnungDao.readUiStatusFromXml(obj); } @Override protected String[] getAdditionalSearchFields() { return ADDITIONAL_SEARCH_FIELDS; } @Override public List<EingangsrechnungDO> getList(final BaseSearchFilter filter) { final RechnungFilter myFilter; if (filter instanceof RechnungFilter) { myFilter = (RechnungFilter) filter; } else { myFilter = new RechnungFilter(filter); } final QueryFilter queryFilter = new QueryFilter(myFilter); if (myFilter.getFromDate() != null || myFilter.getToDate() != null) { if (myFilter.getFromDate() != null && myFilter.getToDate() != null) { queryFilter.add(Restrictions.between("datum", myFilter.getFromDate(), myFilter.getToDate())); } else if (myFilter.getFromDate() != null) { queryFilter.add(Restrictions.ge("datum", myFilter.getFromDate())); } else if (myFilter.getToDate() != null) { queryFilter.add(Restrictions.le("datum", myFilter.getToDate())); } } else { queryFilter.setYearAndMonth("datum", myFilter.getYear(), myFilter.getMonth()); } queryFilter.addOrder(Order.desc("datum")); queryFilter.addOrder(Order.desc("kreditor")); final List<EingangsrechnungDO> list = getList(queryFilter); if (myFilter.isShowAll() == true || myFilter.isDeleted() == true) { return list; } final List<EingangsrechnungDO> result = new ArrayList<EingangsrechnungDO>(); for (final EingangsrechnungDO rechnung : list) { if (myFilter.isShowUnbezahlt() == true) { if (rechnung.isBezahlt() == false) { result.add(rechnung); } } else if (myFilter.isShowBezahlt() == true) { if (rechnung.isBezahlt() == true) { result.add(rechnung); } } else if (myFilter.isShowUeberFaellig() == true) { if (rechnung.isUeberfaellig() == true) { result.add(rechnung); } } else { log.debug("Unknown filter setting (probably caused by serialize/de-serialize problems): " + myFilter.listType); } } return result; } /** * Gets history entries of super and adds all history entries of the EingangsrechnungsPositionDO childs. * @see org.projectforge.core.BaseDao#getDisplayHistoryEntries(org.projectforge.core.ExtendedBaseDO) */ @Override public List<DisplayHistoryEntry> getDisplayHistoryEntries(final EingangsrechnungDO obj) { final List<DisplayHistoryEntry> list = super.getDisplayHistoryEntries(obj); if (hasLoggedInUserHistoryAccess(obj, false) == false) { return list; } if (CollectionUtils.isNotEmpty(obj.getPositionen()) == true) { for (final EingangsrechnungsPositionDO position : obj.getPositionen()) { final List<DisplayHistoryEntry> entries = internalGetDisplayHistoryEntries(position); for (final DisplayHistoryEntry entry : entries) { final String propertyName = entry.getPropertyName(); if (propertyName != null) { entry.setPropertyName("#" + position.getNumber() + ":" + entry.getPropertyName()); // Prepend number of positon. } else { entry.setPropertyName("#" + position.getNumber()); } } list.addAll(entries); if (CollectionUtils.isNotEmpty(position.getKostZuweisungen()) == true) { for (final KostZuweisungDO zuweisung : position.getKostZuweisungen()) { final List<DisplayHistoryEntry> kostEntries = internalGetDisplayHistoryEntries(zuweisung); for (final DisplayHistoryEntry entry : kostEntries) { final String propertyName = entry.getPropertyName(); if (propertyName != null) { entry.setPropertyName("#" + position.getNumber() + ".kost#" + zuweisung.getIndex() + ":" + entry.getPropertyName()); // Prepend // number of positon and index of zuweisung. } else { entry.setPropertyName("#" + position.getNumber() + ".kost#" + zuweisung.getIndex()); } } list.addAll(kostEntries); } } } } Collections.sort(list, new Comparator<DisplayHistoryEntry>() { public int compare(final DisplayHistoryEntry o1, final DisplayHistoryEntry o2) { return (o2.getTimestamp().compareTo(o1.getTimestamp())); } }); return list; } @Override protected Class< ? >[] getAdditionalHistorySearchDOs() { return ADDITIONAL_SEARCH_DOS; } /** * Returns also true, if idSet contains the id of any order position. * @see org.projectforge.core.BaseDao#contains(java.util.Set, org.projectforge.core.ExtendedBaseDO) */ @Override protected boolean contains(final Set<Integer> idSet, final EingangsrechnungDO entry) { if (super.contains(idSet, entry) == true) { return true; } for (final EingangsrechnungsPositionDO pos : entry.getPositionen()) { if (idSet.contains(pos.getId()) == true) { return true; } } return false; } @Override protected List<EingangsrechnungDO> sort(final List<EingangsrechnungDO> list) { Collections.sort(list); return list; } @Override public EingangsrechnungDO newInstance() { return new EingangsrechnungDO(); } public void setKontoDao(final KontoDao kontoDao) { this.kontoDao = kontoDao; } /** * @see org.projectforge.core.BaseDao#useOwnCriteriaCacheRegion() */ @Override protected boolean useOwnCriteriaCacheRegion() { return true; } }