///////////////////////////////////////////////////////////////////////////// // // 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.List; import java.util.Set; import java.util.TreeSet; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.Transient; import org.hibernate.annotations.IndexColumn; import org.hibernate.search.annotations.Field; import org.hibernate.search.annotations.Index; import org.hibernate.search.annotations.Indexed; import org.hibernate.search.annotations.IndexedEmbedded; import org.hibernate.search.annotations.Store; import org.projectforge.core.AbstractHistorizableBaseDO; import org.projectforge.core.PropertyInfo; /** * Geplante und gestellte Rechnungen. * @author Kai Reinhard (k.reinhard@micromata.de) */ @Entity @Indexed @Table(name = "t_fibu_rechnung") public class RechnungDO extends AbstractRechnungDO<RechnungsPositionDO> implements Comparable<RechnungDO> { private static final long serialVersionUID = 8143023040624332677L; @PropertyInfo(i18nKey = "fibu.rechnung.nummer") @Field(index = Index.UN_TOKENIZED, store = Store.NO) private Integer nummer; @PropertyInfo(i18nKey = "fibu.kunde") @IndexedEmbedded(depth = 1) private KundeDO kunde; @PropertyInfo(i18nKey = "fibu.kunde") @Field(index = Index.TOKENIZED, store = Store.NO) private String kundeText; @PropertyInfo(i18nKey = "fibu.projekt") @IndexedEmbedded(depth = 2) private ProjektDO projekt; @PropertyInfo(i18nKey = "fibu.rechnung.status") @Field(index = Index.UN_TOKENIZED, store = Store.NO) private RechnungStatus status; @PropertyInfo(i18nKey = "fibu.rechnung.typ") @Field(index = Index.TOKENIZED, store = Store.NO) private RechnungTyp typ; static { AbstractHistorizableBaseDO.putNonHistorizableProperty(RechnungDO.class, "uiStatusAsXml", "uiStatus"); } /** * Rechnungsempfänger. Dieser Kunde kann vom Kunden, der mit dem Projekt verbunden ist abweichen. */ @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "kunde_id", nullable = true) public KundeDO getKunde() { return kunde; } public RechnungDO setKunde(final KundeDO kunde) { this.kunde = kunde; return this; } @Transient public Integer getKundeId() { if (this.kunde == null) return null; return kunde.getId(); } /** * Freitextfeld, falls Kunde nicht aus Liste gewählt werden kann bzw. für Rückwärtskompatibilität mit alten Kunden. */ @Column(name = "kunde_text") public String getKundeText() { return kundeText; } public RechnungDO setKundeText(final String kundeText) { this.kundeText = kundeText; return this; } @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "projekt_id", nullable = true) public ProjektDO getProjekt() { return projekt; } public RechnungDO setProjekt(final ProjektDO projekt) { this.projekt = projekt; return this; } @Transient public Integer getProjektId() { if (this.projekt == null) return null; return projekt.getId(); } @Column(unique = true, nullable = true) public Integer getNummer() { return nummer; } public RechnungDO setNummer(final Integer nummer) { this.nummer = nummer; return this; } @Enumerated(EnumType.STRING) @Column(length = 30) public RechnungStatus getStatus() { return status; } public RechnungDO setStatus(final RechnungStatus status) { this.status = status; return this; } @Enumerated(EnumType.STRING) @Column(length = 40) public RechnungTyp getTyp() { return typ; } public RechnungDO setTyp(final RechnungTyp typ) { this.typ = typ; return this; } /** * (this.status == RechnungStatus.BEZAHLT && this.bezahlDatum != null && this.zahlBetrag != null) */ @Override @Transient public boolean isBezahlt() { if (this.getNetSum() == null || this.getNetSum().compareTo(BigDecimal.ZERO) == 0) { return true; } return (this.status == RechnungStatus.BEZAHLT && this.bezahlDatum != null && this.zahlBetrag != null); } @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "rechnung") @IndexColumn(name = "number", base = 1) @Override public List<RechnungsPositionDO> getPositionen() { return this.positionen; } @Transient public Set<AuftragsPositionVO> getAuftragsPositionVOs() { if (this.positionen == null) { return null; } Set<AuftragsPositionVO> set = null; for (final RechnungsPositionDO pos : this.positionen) { if (pos.getAuftragsPosition() == null) { continue; } else if (set == null) { set = new TreeSet<AuftragsPositionVO>(); } set.add(new AuftragsPositionVO(pos.getAuftragsPosition())); } return set; } /** * @see KundeFormatter#formatKundeAsString(KundeDO, String) */ @Transient public String getKundeAsString() { return KundeFormatter.formatKundeAsString(this.kunde, this.kundeText); } public int compareTo(final RechnungDO o) { if (this.datum != null && o.datum != null) { final int r = this.datum.compareTo(o.datum); if (r != 0) { return -r; } } if (this.nummer == null) { return (o.nummer == null) ? 0 : 1; } if (o.nummer == null) { return -1; } return this.nummer.compareTo(o.nummer); } }