Package org.projectforge.fibu.datev

Source Code of org.projectforge.fibu.datev.DatevImportDao

/////////////////////////////////////////////////////////////////////////////
//
// 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.datev;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;

import org.apache.commons.lang.Validate;
import org.hibernate.LockMode;
import org.projectforge.access.AccessChecker;
import org.projectforge.access.AccessException;
import org.projectforge.common.ImportStatus;
import org.projectforge.common.ImportStorage;
import org.projectforge.common.ImportedElement;
import org.projectforge.common.ImportedSheet;
import org.projectforge.core.ActionLog;
import org.projectforge.core.UserException;
import org.projectforge.excel.ExcelImportException;
import org.projectforge.fibu.KontoDO;
import org.projectforge.fibu.KontoDao;
import org.projectforge.fibu.KostFormatter;
import org.projectforge.fibu.kost.BuchungssatzDO;
import org.projectforge.fibu.kost.BuchungssatzDao;
import org.projectforge.fibu.kost.Kost1DO;
import org.projectforge.fibu.kost.Kost1Dao;
import org.projectforge.fibu.kost.Kost2DO;
import org.projectforge.fibu.kost.Kost2Dao;
import org.projectforge.user.UserRightId;
import org.projectforge.user.UserRightValue;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public class DatevImportDao extends HibernateDaoSupport
{
  /**
   * Size of bulk inserts. If this value is too large, exceptions are expected and as more small the value is so as more slowly is the
   * insert process.
   */
  private static final int BUCHUNGSSATZ_INSERT_BLOCK_SIZE = 50;

  /**
   * Size of bulk inserts. If this value is too large, exceptions are expected and as more small the value is so as more slowly is the
   * insert process.
   */
  private static final int KONTO_INSERT_BLOCK_SIZE = 50;

  public enum Type
  {
    KONTENPLAN, BUCHUNGSSAETZE
  }

  public static final UserRightId USER_RIGHT_ID = UserRightId.FIBU_DATEV_IMPORT;

  static final String[] KONTO_DIFF_PROPERTIES = { "nummer", "bezeichnung"};

  static final String[] BUCHUNGSSATZ_DIFF_PROPERTIES = { "satznr", "betrag", "sh", "konto", "kost2", "menge", "beleg", "datum",
    "gegenKonto", "text", "kost1", "comment"};

  private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(DatevImportDao.class);

  private AccessChecker accessChecker;

  private KontoDao kontoDao;

  private Kost1Dao kost1Dao;

  private Kost2Dao kost2Dao;

  private BuchungssatzDao buchungssatzDao;

  /**
   * Has the user the right FIBU_DATEV_IMPORT (value true)?
   * @param accessChecker
   * @see UserRightId#FIBU_DATEV_IMPORT
   * @see AccessChecker#hasRight(UserRightId, UserRightValue, boolean)
   */
  public static boolean hasRight(final AccessChecker accessChecker)
  {
    return hasRight(accessChecker, false);
  }

  /**
   * Has the user the right FIBU_DATEV_IMPORT (value true)?
   * @param accessChecker
   * @throws AccessException
   * @see UserRightId#FIBU_DATEV_IMPORT
   * @see AccessChecker#hasRight(UserRightId, UserRightValue, boolean)
   */
  public static boolean checkLoggeinUserRight(final AccessChecker accessChecker)
  {
    return hasRight(accessChecker, true);
  }

  private static boolean hasRight(final AccessChecker accessChecker, final boolean throwException)
  {
    return accessChecker.hasLoggedInUserRight(USER_RIGHT_ID, throwException, UserRightValue.TRUE);
  }

  /**
   * Liest den Kontenplan aus dem InputStream (Exceltabelle) und schreibt die gelesenen Werte des Kontenplans in ImportStorge. Der User muss
   * der FINANCE_GROUP angehören, um diese Funktionalität ausführen zu können.
   * @param is
   * @param filename
   * @return ImportStorage mit den gelesenen Daten.
   * @throws Exception
   */
  public ImportStorage<KontoDO> importKontenplan(final InputStream is, final String filename, final ActionLog actionLog) throws Exception
  {
    checkLoggeinUserRight(accessChecker);
    log.info("importKontenplan called");
    final ImportStorage<KontoDO> storage = new ImportStorage<KontoDO>(Type.KONTENPLAN);
    storage.setFilename(filename);
    final KontenplanExcelImporter imp = new KontenplanExcelImporter();
    imp.doImport(storage, is, actionLog);
    return storage;
  }

  /**
   * Liest die Buchungsdaten aus dem InputStream (Exceltabelle) und schreibt die gelesenen Werte in ImportStorge. Der User muss der
   * FINANCE_GROUP angehören, um diese Funktionalität ausführen zu können.
   * @param is
   * @param filename
   * @return ImportStorage mit den gelesenen Daten.
   * @throws Exception
   */
  public ImportStorage<BuchungssatzDO> importBuchungsdaten(final InputStream is, final String filename, final ActionLog actionLog)
      throws Exception
      {
    checkLoggeinUserRight(accessChecker);
    log.info("importBuchungsdaten called");
    final ImportStorage<BuchungssatzDO> storage = new ImportStorage<BuchungssatzDO>(Type.BUCHUNGSSAETZE);
    storage.setFilename(filename);
    final BuchungssatzExcelImporter imp = new BuchungssatzExcelImporter(storage, kontoDao, kost1Dao, kost2Dao, actionLog);
    try {
      imp.doImport(is);
    } catch (final ExcelImportException ex) {
      throw new UserException("common.import.excel.error", ex.getMessage(), ex.getRow(), ex.getColumnname());
    }
    return storage;
      }

  /**
   * Der ImportStorage wird verprobt, dass heißt ein Schreiben der importierten Werte in die Datenbank wird getestet. Ergebnis sind mögliche
   * Fehler und Statistiken, welche Werte neu geschrieben und welche geändert werden. Der User muss der FINANCE_GROUP angehören, um diese
   * Funktionalität ausführen zu können.
   * @param storage
   * @param name of sheet to reconcile.
   */
  @SuppressWarnings("unchecked")
  public void reconcile(final ImportStorage< ? > storage, final String sheetName)
  {
    checkLoggeinUserRight(accessChecker);
    Validate.notNull(storage.getSheets());
    final ImportedSheet< ? > sheet = storage.getNamedSheet(sheetName);
    Validate.notNull(sheet);
    if (storage.getId() == Type.KONTENPLAN) {
      reconcileKontenplan((ImportedSheet<KontoDO>) sheet);
    } else {
      reconcileBuchungsdaten((ImportedSheet<BuchungssatzDO>) sheet);
    }
    sheet.setNumberOfCommittedElements(-1);
  }

  @SuppressWarnings("unchecked")
  @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW, isolation = Isolation.REPEATABLE_READ)
  public void commit(final ImportStorage< ? > storage, final String sheetName)
  {
    checkLoggeinUserRight(accessChecker);
    Validate.notNull(storage.getSheets());
    final ImportedSheet< ? > sheet = storage.getNamedSheet(sheetName);
    Validate.notNull(sheet);
    if (sheet.getStatus() != ImportStatus.RECONCILED) {
      throw new UserException("common.import.action.commit.error.notReconciled");
    }
    int no = -1;
    if (storage.getId() == Type.KONTENPLAN) {
      no = commitKontenplan((ImportedSheet<KontoDO>) sheet);
    } else {
      no = commitBuchungsdaten((ImportedSheet<BuchungssatzDO>) sheet);
    }
    sheet.setNumberOfCommittedElements(no);
    sheet.setStatus(ImportStatus.IMPORTED);
  }

  private void reconcileKontenplan(final ImportedSheet<KontoDO> sheet)
  {
    log.info("Reconcile Kontenplan called");
    for (final ImportedElement<KontoDO> el : sheet.getElements()) {
      final KontoDO konto = el.getValue();
      final KontoDO dbKonto = kontoDao.getKonto(konto.getNummer());
      if (dbKonto != null) {
        el.setOldValue(dbKonto);
      }
    }
    sheet.setStatus(ImportStatus.RECONCILED);
    sheet.calculateStatistics();
  }

  private void reconcileBuchungsdaten(final ImportedSheet<BuchungssatzDO> sheet)
  {
    log.info("Reconcile Buchungsdaten called");
    for (final ImportedElement<BuchungssatzDO> el : sheet.getElements()) {
      final BuchungssatzDO satz = el.getValue();
      if (el.isFaulty() == true) {
        String kost = (String) el.getErrorProperty("kost1");
        if (kost != null) {
          final int[] vals = KostFormatter.splitKost(kost);
          final Kost1DO kost1 = kost1Dao.getKost1(vals[0], vals[1], vals[2], vals[3]);
          if (kost1 != null) {
            satz.setKost1(kost1);
            el.removeErrorProperty("kost1");
          }
        }
        kost = (String) el.getErrorProperty("kost2");
        if (kost != null) {
          final int[] vals = KostFormatter.splitKost(kost);
          final Kost2DO kost2 = kost2Dao.getKost2(vals[0], vals[1], vals[2], vals[3]);
          if (kost2 != null) {
            satz.setKost2(kost2);
            el.removeErrorProperty("kost2");
          }
        }
      }
      final BuchungssatzDO dbSatz = buchungssatzDao.getBuchungssatz(satz.getYear(), satz.getMonth(), satz.getSatznr());
      if (dbSatz != null) {
        el.setOldValue(dbSatz);
      }
    }
    sheet.setStatus(ImportStatus.RECONCILED);
    sheet.calculateStatistics();
  }

  private int commitKontenplan(final ImportedSheet<KontoDO> sheet)
  {
    log.info("Commit Kontenplan called");
    final Collection<KontoDO> col = new ArrayList<KontoDO>();
    for (final ImportedElement<KontoDO> el : sheet.getElements()) {
      final KontoDO konto = el.getValue();
      final KontoDO dbKonto = kontoDao.getKonto(konto.getNummer());
      if (dbKonto != null) {
        konto.setId(dbKonto.getId());
        if (el.isSelected() == true) {
          col.add(konto);
        }
      } else if (el.isSelected() == true) {
        col.add(konto);
      }
    }
    kontoDao.internalSaveOrUpdate(kontoDao, col, KONTO_INSERT_BLOCK_SIZE);
    return col.size();
  }

  private Object get(final Class< ? > clazz, final Integer id)
  {
    if (id == null) {
      return null;
    }
    return getHibernateTemplate().get(clazz, id, LockMode.READ);
  }

  private int commitBuchungsdaten(final ImportedSheet<BuchungssatzDO> sheet)
  {
    log.info("Commit Buchungsdaten called");
    final Collection<BuchungssatzDO> col = new ArrayList<BuchungssatzDO>();
    for (final ImportedElement<BuchungssatzDO> el : sheet.getElements()) {
      final BuchungssatzDO satz = el.getValue();
      final BuchungssatzDO dbSatz = buchungssatzDao.getBuchungssatz(satz.getYear(), satz.getMonth(), satz.getSatznr());
      boolean addSatz = false;
      if (dbSatz != null) {
        satz.setId(dbSatz.getId());
        if (el.isSelected() == true) {
          addSatz = true;
        }
      } else if (el.isSelected() == true) {
        addSatz = true;
      }
      if (addSatz == true) {
        final BuchungssatzDO newSatz = new BuchungssatzDO();
        newSatz.copyValuesFrom(satz, "konto", "gegenKonto", "kost1", "kost2");
        newSatz.setKonto((KontoDO) get(KontoDO.class, satz.getKontoId()));
        newSatz.setGegenKonto((KontoDO) get(KontoDO.class, satz.getGegenKontoId()));
        newSatz.setKost1((Kost1DO) get(Kost1DO.class, satz.getKost1Id()));
        newSatz.setKost2((Kost2DO) get(Kost2DO.class, satz.getKost2Id()));
        col.add(newSatz);
      }
    }
    buchungssatzDao.internalSaveOrUpdate(buchungssatzDao, col, BUCHUNGSSATZ_INSERT_BLOCK_SIZE);
    return col.size();
  }

  public void setAccessChecker(final AccessChecker accessChecker)
  {
    this.accessChecker = accessChecker;
  }

  public void setKontoDao(final KontoDao kontoDao)
  {
    this.kontoDao = kontoDao;
  }

  public void setKost1Dao(final Kost1Dao kost1Dao)
  {
    this.kost1Dao = kost1Dao;
  }

  public void setKost2Dao(final Kost2Dao kost2Dao)
  {
    this.kost2Dao = kost2Dao;
  }

  public void setBuchungssatzDao(final BuchungssatzDao buchungssatzDao)
  {
    this.buchungssatzDao = buchungssatzDao;
  }
}
TOP

Related Classes of org.projectforge.fibu.datev.DatevImportDao

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.