CommercialInvoice.java
package com.tradecloud.domain.document.invoice;
import com.tradecloud.domain.configuration.clearing.za.ClearingPaymentTerm;
import com.tradecloud.domain.configuration.clearing.za.PermitType;
import com.tradecloud.domain.document.DocumentState;
import com.tradecloud.domain.document.DocumentType;
import com.tradecloud.domain.document.PaymentState;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.domain.settlement.PlannedSettlement;
import com.tradecloud.domain.settlement.PlannedSettlementType;
import com.tradecloud.domain.supplier.OrganisationalUnitSupplier;
import org.apache.commons.collections4.keyvalue.MultiKey;
import org.springframework.stereotype.Component;
import javax.persistence.*;
import javax.xml.bind.annotation.*;
import java.math.BigDecimal;
import java.util.*;
/**
* The commercial invoice.
* Used for capturing direct or supply costs from suppliers
*
* @author ronan
*/
@Entity
@Component(value = "commercialinvoice")
@Table(name = "commercialinvoice")
@NamedQueries({
@NamedQuery(name = "commercialInvoice.byShipment",
query = "from CommercialInvoice ci where ci.shipment.id = :id and ci.state != 'DELETED'"),
@NamedQuery(name = "commercialInvoice.byReference",
query = "from CommercialInvoice ci where ci.reference = :reference"),
@NamedQuery(name = "commercialInvoice.byReferenceAndSupplier",
query = "from CommercialInvoice ci where ci.reference = :reference and ci.supplier = :supplier"),
@NamedQuery(name = "commercialInvoice.byIdWithPlannedSettlementsLoaded",
query = "from CommercialInvoice ci left join fetch ci.plannedSettlements where ci.id=:id")})
@Access(AccessType.FIELD)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "CommercialInvoice")
public class CommercialInvoice extends BaseCommercialInvoice {
private static final long serialVersionUID = 1L;
@XmlAttribute
private boolean closedOff;
private String permitNumber;
@Enumerated(EnumType.STRING)
private PermitType permitType;
public final static Collection<DocumentState> PAYABLE_STATES = Arrays.asList(DocumentState.SIGNED_OFF, DocumentState.SENT_TO_ERP,
DocumentState.AWAITING_TREASURY_RATES, DocumentState.COMPLETE, DocumentState.FINALISED,
DocumentState.PAYMENT_INITIATED, DocumentState.REJECTED_BY_ERP, DocumentState.ACCEPTED_BY_ERP);
/**
* Set of planned settlements contained on the invoice.
*/
@XmlElementWrapper(name = "PlannedSettlements")
@XmlElement(name = "PlannedSettlement")
// left out CascadeType.MERGE, do manual merge or fix CascadeType.MERGE
// issues.when saving CI.
@OneToMany(cascade = {CascadeType.ALL}, orphanRemoval = true,
fetch = FetchType.LAZY,mappedBy = "invoice")
@OrderBy("settlementDate, amount")
private Set<PlannedSettlement> plannedSettlements = new HashSet<>();
@Enumerated(EnumType.STRING)
private ClearingPaymentTerm clearingPaymentTerm;
@Transient
private PlannedSettlementHelper plannedSettlementHelper;
public boolean isClosedOff() {
return closedOff;
}
public void setClosedOff(boolean closedOff) {
this.closedOff = closedOff;
}
@Override
public Set<PlannedSettlement> getPlannedSettlements() {
return plannedSettlements;
}
public CommercialInvoice() {
}
public CommercialInvoice(OrganisationalUnit organisationalUnit, OrganisationalUnitSupplier supplier, BigDecimal quantity,
UnitPricePerItem unitPricePerItem, Set<PlannedSettlement> plannedSettlements) {
super(organisationalUnit, supplier, quantity, unitPricePerItem);
this.plannedSettlements = plannedSettlements;
}
/**
* Wraps the Set with some useful helper methods.
*
* @return
*/
@Override
public PlannedSettlementHelper getPlannedSettlementHelper() {
if (plannedSettlementHelper == null) {
plannedSettlementHelper = new PlannedSettlementHelper(getPlannedSettlements());
}
// reset the planned settlements every time this helper is retrieved
plannedSettlementHelper.setPlannedSettlements(plannedSettlements);
return plannedSettlementHelper;
}
@Override
public List<PlannedSettlement> getPlannedSettlementList() {
return new ArrayList<>(plannedSettlements);
}
@Override
public void setPlannedSettlements(Set<PlannedSettlement> plannedSettlements) {
this.plannedSettlements = plannedSettlements;
}
@Override
public DocumentType getDocumentType() {
return DocumentType.COMMERCIAL_INVOICE;
}
@Override
public Object getTraversalKey() {
return new MultiKey(CommercialInvoice.class, reference);
}
public void addPlannedSettlement(PlannedSettlement plannedSettlement) {
plannedSettlements.add(plannedSettlement);
}
public void removePlannedSettlement(PlannedSettlement plannedSettlement) {
plannedSettlements.remove(plannedSettlement);
}
@Override
public void clearPlannedSettlements() {
plannedSettlements.clear();
}
@Override
public BigDecimal getWeightedAverageForwardRateOfExchange() {
return getPlannedSettlementHelper().getWeightedAverageForwardRateOfExchange();
}
@Override
public BigDecimal getWeightedAverageSpotRateOfExchange() {
return getPlannedSettlementHelper().getWeightedAverageSpotRateOfExchange();
}
@Override
public BigDecimal getCostingCurrencyTotalValue() {
return getPlannedSettlementHelper().getCostingCurrencyTotalValue();
}
@Override
public String getKey() {
return new StringBuilder(getClass().getCanonicalName()).append("-").append(hashCode()).toString();
}
@Override
public PaymentState getPaymentState() {
return PaymentState.UNSETTLED;
}
@Override
public PlannedSettlementType getPlannedSettlementType() {
return PlannedSettlementType.COMMERCIAL_INVOICE;
}
@Transient
@Override
public String getType() {
return "CI";
}
public String getPermitNumber() {
return permitNumber;
}
public void setPermitNumber(String permitNumber) {
this.permitNumber = permitNumber;
}
public PermitType getPermitType() {
return permitType;
}
public void setPermitType(PermitType permitType) {
this.permitType = permitType;
}
public ClearingPaymentTerm getClearingPaymentTerm() {
return clearingPaymentTerm;
}
public void setClearingPaymentTerm(ClearingPaymentTerm clearingPaymentTerm) {
this.clearingPaymentTerm = clearingPaymentTerm;
}
}