Package org.projectforge.fibu

Source Code of org.projectforge.fibu.AbstractRechnungsPositionDO

/////////////////////////////////////////////////////////////////////////////
//
// 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.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.IndexedEmbedded;
import org.hibernate.search.annotations.Store;
import org.projectforge.common.CurrencyHelper;
import org.projectforge.common.NumberHelper;
import org.projectforge.core.DefaultBaseDO;
import org.projectforge.core.PFPersistancyBehavior;
import org.projectforge.core.ShortDisplayNameCapable;
import org.projectforge.fibu.kost.KostZuweisungDO;

/**
* Repräsentiert eine Position innerhalb eine Rechnung.
* @author Kai Reinhard (k.reinhard@micromata.de)
*/
@MappedSuperclass
public abstract class AbstractRechnungsPositionDO extends DefaultBaseDO implements ShortDisplayNameCapable
{
  private static final long serialVersionUID = 4132530394057069876L;

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

  protected short number;

  @Field(index = Index.TOKENIZED, store = Store.NO)
  protected String text;

  protected BigDecimal menge;

  @Field(index = Index.UN_TOKENIZED, store = Store.NO)
  protected BigDecimal einzelNetto;

  @Field(index = Index.UN_TOKENIZED, store = Store.NO)
  protected BigDecimal vat;

  @PFPersistancyBehavior(autoUpdateCollectionEntries = true)
  @IndexedEmbedded(depth = 1)
  protected List<KostZuweisungDO> kostZuweisungen = null;

  @Column
  public short getNumber()
  {
    return number;
  }

  public AbstractRechnungsPositionDO setNumber(final short number)
  {
    this.number = number;
    return this;
  }

  @Column(scale = 5, precision = 18)
  public BigDecimal getMenge()
  {
    return menge;
  }

  public AbstractRechnungsPositionDO setMenge(final BigDecimal menge)
  {
    this.menge = menge;
    return this;
  }

  @Column(name = "einzel_netto", scale = 2, precision = 18)
  public BigDecimal getEinzelNetto()
  {
    return einzelNetto;
  }

  public AbstractRechnungsPositionDO setEinzelNetto(final BigDecimal einzelNetto)
  {
    this.einzelNetto = einzelNetto;
    return this;
  }

  @Column(scale = 5, precision = 10)
  public BigDecimal getVat()
  {
    return vat;
  }

  public AbstractRechnungsPositionDO setVat(final BigDecimal vat)
  {
    if (vat != null) {
      this.vat = vat.stripTrailingZeros();
    } else {
      this.vat = vat;
    }
    return this;
  }

  @Transient
  public BigDecimal getNetSum()
  {
    if (this.menge != null) {
      if (this.einzelNetto != null) {
        return CurrencyHelper.multiply(this.menge, this.einzelNetto);
      } else {
        return BigDecimal.ZERO;
      }
    } else {
      return this.einzelNetto != null ? this.einzelNetto : BigDecimal.ZERO;
    }
  }

  @Transient
  public BigDecimal getBruttoSum()
  {
    final BigDecimal netSum = getNetSum();
    if (vat != null) {
      return netSum.add(CurrencyHelper.multiply(netSum, vat));
    } else {
      return netSum;
    }
  }

  @Transient
  public BigDecimal getVatAmount()
  {
    final BigDecimal netSum = getNetSum();
    if (vat != null) {
      return CurrencyHelper.multiply(netSum, vat);
    } else {
      return BigDecimal.ZERO;
    }
  }

  @Column(name = "s_text", length = 1000)
  public String getText()
  {
    return text;
  }

  public AbstractRechnungsPositionDO setText(final String text)
  {
    this.text = text;
    return this;
  }

  /**
   * Get the position entries for this object.
   */
  @Transient
  public abstract List<KostZuweisungDO> getKostZuweisungen();

  public AbstractRechnungsPositionDO setKostZuweisungen(final List<KostZuweisungDO> kostZuweisungen)
  {
    this.kostZuweisungen = kostZuweisungen;
    return this;
  }

  /**
   * @param idx Index of the cost assignment not index of collection.
   * @return KostZuweisungDO with given index or null, if not exist.
   */
  public KostZuweisungDO getKostZuweisung(final int index)
  {
    if (kostZuweisungen == null) {
      log.error("Can't get cost assignment with index " + index + " because no cost assignments given.");
      return null;
    }
    for (final KostZuweisungDO zuweisung : kostZuweisungen) {
      if (index == zuweisung.getIndex()) {
        return zuweisung;
      }
    }
    log.error("Can't found cost assignment with index " + index);
    return null;
  }

  public AbstractRechnungsPositionDO addKostZuweisung(final KostZuweisungDO kostZuweisung)
  {
    ensureAndGetKostzuweisungen();
    short index = 0;
    for (final KostZuweisungDO zuweisung : kostZuweisungen) {
      if (zuweisung.getIndex() >= index) {
        index = zuweisung.getIndex();
        index++;
      }
    }
    kostZuweisung.setIndex(index);
    setThis(kostZuweisung);
    this.kostZuweisungen.add(kostZuweisung);
    return this;
  }

  /**
   * @return The total net sum of all assigned cost entries.
   */
  @Transient
  public BigDecimal getKostZuweisungNetSum()
  {
    if (CollectionUtils.isEmpty(this.kostZuweisungen) == true) {
      return BigDecimal.ZERO;
    }
    final BigDecimal result = BigDecimal.ZERO;
    for (final KostZuweisungDO zuweisung : this.kostZuweisungen) {
      if (zuweisung.getNetto() != null) {
        result.add(zuweisung.getNetto());
      }
    }
    return result;
  }

  /**
   * @return The total net sum of all assigned cost entries multiplied with the vat of this position.
   */
  @Transient
  public BigDecimal getKostZuweisungGrossSum()
  {
    return CurrencyHelper.getGrossAmount(getKostZuweisungNetSum(), vat);
  }

  /**
   * kostZuweisung.setEingangsrechnungsPosition(this);
   * @param kostZuweisung
   */
  protected abstract void setThis(final KostZuweisungDO kostZuweisung);

  protected abstract AbstractRechnungsPositionDO newInstance();

  /**
   * this.getEingangsrechnung()
   */
  @Transient
  protected abstract AbstractRechnungDO< ? > getRechnung();

  @Transient
  public Integer getRechnungId()
  {
    if (getRechnung() == null) {
      return null;
    } else {
      return getRechnung().getId();
    }
  }

  /**
   * setEingangsrechnung(rechnung)
   */
  protected abstract AbstractRechnungsPositionDO setRechnung(final AbstractRechnungDO< ? > rechnung);

  /**
   * Does only work for not already persisted entries (meaning entries without an id / pk) and only the last entry of the list. Otherwise
   * this method logs an error message and do nothing else.
   * @param idx
   * @see #isKostZuweisungDeletable(KostZuweisungDO)
   */
  public AbstractRechnungsPositionDO deleteKostZuweisung(final int idx)
  {
    final KostZuweisungDO zuweisung = getKostZuweisung(idx);
    if (zuweisung == null) {
      return this;
    }
    if (isKostZuweisungDeletable(zuweisung) == false) {
      log
      .error("Deleting of cost assignements which are already persisted (a id / pk already exists) or not are not the last entry is not supported. Do nothing.");
      return this;
    }
    this.kostZuweisungen.remove(zuweisung);
    return this;
  }

  /**
   * Only the last entry of cost assignments is deletable if not already persisted (no id/pk given).
   * @param zuweisung
   * @return
   */
  public boolean isKostZuweisungDeletable(final KostZuweisungDO zuweisung)
  {
    if (zuweisung == null) {
      return false;
    }
    if ((this instanceof EingangsrechnungsPositionDO && zuweisung.getEingangsrechnungsPositionId() != this.getId())
        || this instanceof RechnungsPositionDO
        && zuweisung.getRechnungsPositionId() != this.getId()) {
      log.error("Oups, given cost assignment is not assigned to this invoice position.");
      return false;
    }
    if (zuweisung.getId() != null) {
      return false;
    }
    // if (zuweisung.getIndex() + 1 < this.kostZuweisungen.size()) {
    // return false;
    // }
    return true;
  }

  public List<KostZuweisungDO> ensureAndGetKostzuweisungen()
  {
    if (this.kostZuweisungen == null) {
      setKostZuweisungen(new ArrayList<KostZuweisungDO>());
    }
    return getKostZuweisungen();
  }

  /**
   * @return The net value as sum of all cost assignements.
   */
  @Transient
  public BigDecimal getKostZuweisungsNetSum()
  {
    BigDecimal sum = BigDecimal.ZERO;
    if (CollectionUtils.isNotEmpty(this.kostZuweisungen) == true) {
      for (final KostZuweisungDO zuweisung : this.kostZuweisungen) {
        sum = NumberHelper.add(sum, zuweisung.getNetto());
      }
    }
    return sum;
  }

  @Transient
  public BigDecimal getKostZuweisungNetFehlbetrag()
  {
    return getKostZuweisungsNetSum().subtract(getNetSum());
  }

  /**
   * Clones this including cost assignments and order position (without id's).
   * @return
   */
  public AbstractRechnungsPositionDO newClone()
  {
    final AbstractRechnungsPositionDO rechnungsPosition = newInstance();
    rechnungsPosition.copyValuesFrom(this, "id", "kostZuweisungen");
    if (this.getKostZuweisungen() != null) {
      for (final KostZuweisungDO origKostZuweisung : this.getKostZuweisungen()) {
        final KostZuweisungDO kostZuweisung = origKostZuweisung.newClone();
        rechnungsPosition.addKostZuweisung(kostZuweisung);
      }
    }
    return rechnungsPosition;
  }

  @Transient
  public boolean isEmpty()
  {
    if (StringUtils.isBlank(text) == false) {
      return false;
    }
    return (NumberHelper.isNotZero(einzelNetto) == false);
  }

  @Override
  public boolean equals(final Object o)
  {
    if (o instanceof AbstractRechnungsPositionDO) {
      final AbstractRechnungsPositionDO other = (AbstractRechnungsPositionDO) o;
      if (ObjectUtils.equals(this.getNumber(), other.getNumber()) == false) {
        return false;
      }
      if (ObjectUtils.equals(this.getRechnungId(), other.getRechnungId()) == false) {
        return false;
      }
      return true;
    }
    return false;
  }

  @Override
  public int hashCode()
  {
    final HashCodeBuilder hcb = new HashCodeBuilder();
    hcb.append(getNumber());
    if (getRechnung() != null) {
      hcb.append(getRechnung().getId());
    }
    return hcb.toHashCode();
  }

  @Transient
  public String getShortDisplayName()
  {
    return String.valueOf(number);
  }
}
TOP

Related Classes of org.projectforge.fibu.AbstractRechnungsPositionDO

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.