PurchaseOrder.java
package com.tradecloud.domain.model.ordermanagement;
import com.tradecloud.domain.agent.OrganisationalUnitAgent;
import com.tradecloud.domain.common.Currency;
import com.tradecloud.domain.common.Incoterm;
import com.tradecloud.domain.dms.DocumentGroupState;
import com.tradecloud.domain.document.PaymentState;
import com.tradecloud.domain.document.invoice.UnitPricePerItem;
import com.tradecloud.domain.item.LineItem;
import com.tradecloud.domain.letterofcredit.LetterOfCredit;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.domain.model.payment.ActualPaymentBasis;
import com.tradecloud.domain.model.payment.EstimatedPaymentBasis;
import com.tradecloud.domain.model.payment.PaymentMethod;
import com.tradecloud.domain.model.payment.PaymentTerm;
import com.tradecloud.domain.party.Employee;
import com.tradecloud.domain.party.ServiceProvider;
import com.tradecloud.domain.party.base.Address;
import com.tradecloud.domain.settlement.PlannedSettlementType;
import com.tradecloud.domain.shipment.ShippingInformation;
import com.tradecloud.domain.supplier.OrganisationalUnitSupplier;
import org.hibernate.annotations.ForeignKey;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.xml.bind.annotation.*;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Set;
/**
* A purchase order is an order in the imports context.
*
* A buyer is the person responsible for arranging the import/purchase order.
* The supplier is the party that fulfils the order.
*/
@Entity
@DiscriminatorValue("PURCHASE_ORDER")
@Table(name = "purchaseorder")
@Access(AccessType.FIELD)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "PurchaseOrder")
@NamedQueries({@NamedQuery(name = "PurchaseOrder.findAllUnlinkedWithItems",
query = "from PurchaseOrder o where o.state not in ('DELETED') and o.consignment is null and o.lineItems.size > 0 and elc='f'"),
@NamedQuery(name = "PurchaseOrder.findAllUnlinkedWithItemsForOrganisationalUnit",
query = "from PurchaseOrder o where o.state not in ('DELETED') and o.consignment is null and o.lineItems.size > 0 and elc='f'" +
" and o.organisationalUnit = :organisationalUnit"),
@NamedQuery(name = "PurchaseOrder.findAllUnlinkedWithItemsForOrganisationalUnitStructure",
query = "from PurchaseOrder o where o.state not in ('DELETED') and o.consignment is null and o.lineItems.size > 0 and elc='f'" +
" and o.organisationalUnit in :organisationalUnit")})
@NamedEntityGraph(name = "graph.PurchaseOrderConsignment", attributeNodes = @NamedAttributeNode(value = "consignment"))
public class PurchaseOrder extends Order implements Exposure {
private static final long serialVersionUID = 3325149164036096080L;
/**
* The person in charge of buying this order.
*/
@ManyToOne(fetch = FetchType.LAZY)
@ForeignKey(name = "fk_buyer")
@NotNull(message = "Buyer is required")
@XmlElement(name = "Buyer", required = true)
private Employee buyer;
/**
* The party, linked to the organisational unit, that is supplying this order.
*/
@ManyToOne(fetch = FetchType.LAZY)
@ForeignKey(name = "fk_supplier")
@NotNull(message = "Supplier is required")
@XmlElement(name = "Supplier", required = true)
private OrganisationalUnitSupplier supplier;
/**
* The party, linked to the organisational unit, that is the Merchandising Agent for this order.
*/
@ManyToOne(fetch = FetchType.LAZY)
@ForeignKey(name = "fk_merchandisingagent")
@XmlElement(name = "MerchandisingAgent", required = true)
private OrganisationalUnitAgent merchandisingAgent;
/**
* The party, linked to the organisational unit, that is the Foreign Agent for this order.
*/
@ManyToOne(fetch = FetchType.LAZY)
@ForeignKey(name = "fk_foreignagent")
@XmlElement(name = "ForeignAgent", required = true)
private OrganisationalUnitAgent foreignAgent;
/**
* The party, linked to the organisational unit, that is the Sourcing Agent for this order.
*/
@ManyToOne(fetch = FetchType.LAZY)
@ForeignKey(name = "fk_sourcingagent")
@XmlElement(name = "SourcingAgent", required = true)
private OrganisationalUnitAgent sourcingAgent;
/**
* The party, linked to the organisational unit, that is the Warehousing Agent for this order.
*/
@ManyToOne(fetch = FetchType.LAZY)
@ForeignKey(name = "fk_warehousingagent")
@XmlElement(name = "WarehousingAgent", required = true)
private OrganisationalUnitAgent warehousingAgent;
/**
* A reference to the letter of credit. mostly needed so to keep easy track of the rule that an order can only be linked to one lc
* at a time.
* Need the updatable and insertable as false because this is not the owning side of the relationship
*/
@ManyToOne(fetch = FetchType.LAZY)
// @JoinTable(name = "letterofcredit_purchaseorder",
// joinColumns = @JoinColumn(name = "purchaseorders_id", updatable = false, insertable = false),
// inverseJoinColumns = @JoinColumn(name = "letterofcredit_id", updatable = false, insertable = false))
private LetterOfCredit letterOfCredit;
@ManyToOne
@ForeignKey(name = "fk_localCustomsAuthority")
@XmlElement(name = "LocalCustomsAuthority")
private ServiceProvider localCustomsAuthority;
@ManyToOne
@ForeignKey(name = "fk_localPortAuthority")
@XmlElement(name = "LocalPortAuthority")
private ServiceProvider localPortAuthority;
/**
* Indicates whether the letter of credit is required for this order or not.
*/
@XmlAttribute
private boolean lcRequired;
private String fcrNumber;
private Long liteConsignmentId;
private String liteConsignmentReference;
@Temporal(javax.persistence.TemporalType.DATE)
private Date signedOffDate;
@Transient
private boolean toBeDeleted;
@Enumerated(EnumType.STRING)
private DocumentGroupState documentGroupStatus;
private BigDecimal integratedTotalVolume;
private BigDecimal integratedTotalWeight;
//used mainly in ultralight as there multiple way to get volume or weight.We need to remember
// how integratedTotalVolume and integratedTotalWeight are calculated , order we keep loosing values.
@Enumerated(EnumType.STRING)
private VolumeOrWeightSource totalVolumeOrWeightSource = VolumeOrWeightSource.ITEM;
private String description;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@XmlElement(name = "PhysicalAddress")
private Address physicalAddress;
public PurchaseOrder() {
}
public PurchaseOrder(String number, String reference) {
setNumber(number);
setOrderReference(reference);
}
public static PurchaseOrderBuilder createBuilder() {
return new PurchaseOrderBuilder();
}
/**
* Constructor. Do not use directly. Use the Builder instead.
*/
private PurchaseOrder(String number, String orderReference, OrganisationalUnit organisationalUnit, OrganisationalUnitSupplier supplier,
Employee buyer, Set<LineItem> items, OrderDates orderDates, ShippingInformation shippingInformation, Currency currency,
PaymentMethod paymentMethod, PaymentTerm paymentTerm, Incoterm incoterm,
OrganisationalUnitAgent merchandisingAgent, OrganisationalUnitAgent foreignAgent, OrganisationalUnitAgent sourcingAgent,
OrganisationalUnitAgent warehousingAgent) {
super(number, orderReference, organisationalUnit, items, orderDates, shippingInformation, currency, paymentMethod, paymentTerm,
incoterm);
this.supplier = supplier;
this.buyer = buyer;
this.merchandisingAgent = merchandisingAgent;
this.foreignAgent = foreignAgent;
this.sourcingAgent = sourcingAgent;
this.warehousingAgent = warehousingAgent;
this.shippingInformation = shippingInformation;
this.orderDates = orderDates;
}
public Employee getBuyer() {
return buyer;
}
public void setBuyer(Employee buyer) {
this.buyer = buyer;
}
@Override
public OrderType getType() {
return OrderType.PURCHASE_ORDER;
}
public OrganisationalUnitSupplier getSupplier() {
return supplier;
}
public void setSupplier(OrganisationalUnitSupplier supplier) {
this.supplier = supplier;
}
public OrganisationalUnitAgent getMerchandisingAgent() {
return merchandisingAgent;
}
public void setMerchandisingAgent(OrganisationalUnitAgent merchandisingAgent) {
this.merchandisingAgent = merchandisingAgent;
}
public OrganisationalUnitAgent getForeignAgent() {
return foreignAgent;
}
public void setForeignAgent(OrganisationalUnitAgent foreignAgent) {
this.foreignAgent = foreignAgent;
}
public OrganisationalUnitAgent getSourcingAgent() {
return sourcingAgent;
}
public void setSourcingAgent(OrganisationalUnitAgent sourcingAgent) {
this.sourcingAgent = sourcingAgent;
}
public OrganisationalUnitAgent getWarehousingAgent() {
return warehousingAgent;
}
public void setWarehousingAgent(OrganisationalUnitAgent warehousingAgent) {
this.warehousingAgent = warehousingAgent;
}
public boolean getAllowPartShipment() {
if (supplier != null) {
return supplier.getAllowPartShipment();
}
return false;
}
public boolean getAllowTransShipment() {
if (supplier != null) {
return supplier.getAllowTransShipment();
}
return false;
}
public boolean isLcRequired() {
return lcRequired;
}
public void setLcRequired(boolean lcRequired) {
this.lcRequired = lcRequired;
}
public LetterOfCredit getLetterOfCredit() {
return letterOfCredit;
}
public void setLetterOfCredit(LetterOfCredit letterOfCredit) {
this.letterOfCredit = letterOfCredit;
}
@Override
public Employee getResponsibleEmployee() {
return getBuyer();
}
@Override
public void setResponsibleEmployee(Employee employee) {
setBuyer(employee);
}
public Long getLiteConsignmentId() {
return liteConsignmentId;
}
public void setLiteConsignmentId(Long liteConsignmentId) {
this.liteConsignmentId = liteConsignmentId;
}
public String getLiteConsignmentReference() {
return liteConsignmentReference;
}
public void setLiteConsignmentReference(String liteConsignmentReference) {
this.liteConsignmentReference = liteConsignmentReference;
}
public Date getSignedOffDate() {
return signedOffDate;
}
public void setSignedOffDate(Date signedOffDate) {
this.signedOffDate = signedOffDate;
}
public boolean isToBeDeleted() {
return toBeDeleted;
}
public void setToBeDeleted(boolean toBeDeleted) {
this.toBeDeleted = toBeDeleted;
}
@Override
public String getReference() {
return orderReference;
}
/**
* Purchase Order Builder.
*/
public static final class PurchaseOrderBuilder {
private String number;
private String orderReference;
private OrganisationalUnit organisationalUnit;
private Currency currency;
private PaymentMethod paymentMethod;
private PaymentTerm paymentTerm;
private Incoterm incoterm;
private Set<LineItem> items;
private OrderDates orderDates;
private ShippingInformation shippingInformation;
private OrganisationalUnitSupplier supplier;
private Employee buyer;
private OrganisationalUnitAgent merchandisingAgent;
private OrganisationalUnitAgent foreignAgent;
private OrganisationalUnitAgent sourcingAgent;
private OrganisationalUnitAgent warehousingAgent;
private UnitPricePerItem unitPricePerItem;
/**
* Private constructor to prevent instantiation.
*/
private PurchaseOrderBuilder() {
}
public PurchaseOrder build() {
validate();
return new PurchaseOrder(number, orderReference, organisationalUnit, supplier, buyer, items, orderDates, shippingInformation, currency,
paymentMethod, paymentTerm, incoterm, merchandisingAgent, foreignAgent, sourcingAgent, warehousingAgent);
}
public PurchaseOrderBuilder setNumber(String number) {
this.number = number;
return this;
}
public PurchaseOrderBuilder setOrderReference(String orderReference) {
this.orderReference = orderReference;
return this;
}
public PurchaseOrderBuilder setOrganisationalUnit(OrganisationalUnit organisationalUnit) {
this.organisationalUnit = organisationalUnit;
return this;
}
public PurchaseOrderBuilder setItems(Set<LineItem> items) {
this.items = items;
return this;
}
public PurchaseOrderBuilder setOrderDates(OrderDates orderDates) {
this.orderDates = orderDates;
return this;
}
public PurchaseOrderBuilder setShippingInformation(ShippingInformation shippingInformation) {
this.shippingInformation = shippingInformation;
return this;
}
public PurchaseOrderBuilder setIncoterm(Incoterm incoterm) {
this.incoterm = incoterm;
return this;
}
public PurchaseOrderBuilder setCurrency(Currency currency) {
this.currency = currency;
return this;
}
public PurchaseOrderBuilder setPaymentMethod(PaymentMethod paymentMethod) {
this.paymentMethod = paymentMethod;
return this;
}
public PurchaseOrderBuilder setPaymentTerm(PaymentTerm paymentTerm) {
this.paymentTerm = paymentTerm;
return this;
}
public PurchaseOrderBuilder setSupplier(OrganisationalUnitSupplier supplier) {
this.supplier = supplier;
return this;
}
public PurchaseOrderBuilder setMerchandisingAgent(OrganisationalUnitAgent merchandisingAgent) {
this.merchandisingAgent = merchandisingAgent;
return this;
}
public PurchaseOrderBuilder setForeignAgent(OrganisationalUnitAgent foreignAgent) {
this.foreignAgent = foreignAgent;
return this;
}
public PurchaseOrderBuilder setSourcingAgent(OrganisationalUnitAgent sourcingAgent) {
this.sourcingAgent = sourcingAgent;
return this;
}
public PurchaseOrderBuilder setWarehousingAgent(OrganisationalUnitAgent warehousingAgent) {
this.warehousingAgent = warehousingAgent;
return this;
}
public PurchaseOrderBuilder setBuyer(Employee buyer) {
this.buyer = buyer;
return this;
}
public PurchaseOrderBuilder setUnitPricePerItem(UnitPricePerItem unitPricePerItem) {
this.unitPricePerItem = unitPricePerItem;
return this;
}
private void ensureNotNull(Object object, String name) {
// if (object == null) {
// throw new IllegalArgumentException("A valid PurchaseOrder requires " + name + " to be set.");
// }
}
private void validate() {
ensureNotNull(number, "number");
ensureNotNull(orderReference, "orderReference");
ensureNotNull(organisationalUnit, "organisationalUnit");
ensureNotNull(items, "items");
ensureNotNull(currency, "currency");
ensureNotNull(paymentMethod, "paymentMethod");
ensureNotNull(paymentTerm, "paymentTerm");
ensureNotNull(buyer, "buyer");
ensureNotNull(supplier, "supplier");
}
}
@Override
public boolean isPurchaseOrder() {
return true;
}
@Override
public OrganisationalUnitSupplier getSupplierOrCustomer() {
return supplier;
}
@Override
public EstimatedPaymentBasis getEstimatedPaymentBasis() {
return supplier.getEstimatedPaymentBasis();
}
@Override
public ActualPaymentBasis getActualPaymentBasis() {
return supplier.getActualPaymentBasis();
}
@Override
public EstimatedPaymentBasis getEstimatedPaymentBasis2() {
return supplier.getSupplier().getEstimatedPaymentBasis2();
}
@Override
public PlannedSettlementType getPlannedSettlementType() {
return PlannedSettlementType.CONSIGNED_ORDER;
}
@Override
public PaymentState getPaymentState() {
return null;
}
@Override
public BigDecimal getTotalSalesValue() {
return null;
}
public String getFcrNumber() {
return fcrNumber;
}
public void setFcrNumber(String fcrNumber) {
this.fcrNumber = fcrNumber;
}
public ServiceProvider getLocalCustomsAuthority() {
return localCustomsAuthority;
}
public void setLocalCustomsAuthority(ServiceProvider localCustomsAuthority) {
this.localCustomsAuthority = localCustomsAuthority;
}
public ServiceProvider getLocalPortAuthority() {
return localPortAuthority;
}
public void setLocalPortAuthority(ServiceProvider localPortAuthority) {
this.localPortAuthority = localPortAuthority;
}
public DocumentGroupState getDocumentGroupStatus() {
return documentGroupStatus;
}
public void setDocumentGroupStatus(DocumentGroupState documentGroupStatus) {
this.documentGroupStatus = documentGroupStatus;
}
public BigDecimal getIntegratedTotalVolume() {
return integratedTotalVolume;
}
public void setIntegratedTotalVolume(BigDecimal integratedTotalVolume) {
this.integratedTotalVolume = integratedTotalVolume;
}
public BigDecimal getIntegratedTotalWeight() {
return integratedTotalWeight;
}
public void setIntegratedTotalWeight(BigDecimal integratedTotalWeight) {
this.integratedTotalWeight = integratedTotalWeight;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Address getPhysicalAddress() {
return physicalAddress;
}
public void setPhysicalAddress(Address physicalAddress) {
this.physicalAddress = physicalAddress;
}
@Override
public String toString() {
return super.toString();
}
public VolumeOrWeightSource getTotalVolumeOrWeightSource() {
return totalVolumeOrWeightSource;
}
public void setTotalVolumeOrWeightSource(VolumeOrWeightSource totalVolumeOrWeightSource) {
this.totalVolumeOrWeightSource = totalVolumeOrWeightSource;
}
}