LetterOfCredit.java
package com.tradecloud.domain.letterofcredit;
import com.tradecloud.common.base.PersistenceBase;
import com.tradecloud.domain.comment.AddedComment;
import com.tradecloud.domain.comment.CommentType;
import com.tradecloud.domain.comment.Commentable;
import com.tradecloud.domain.event.Event;
import com.tradecloud.domain.event.LetterOfCreditEvent;
import com.tradecloud.domain.model.ordermanagement.PurchaseOrder;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.domain.party.Bank;
import com.tradecloud.domain.state.Stateful;
import com.tradecloud.domain.supplier.OrganisationalUnitSupplier;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.ForeignKey;
import org.springframework.stereotype.Component;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.xml.bind.annotation.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
/**
* https://connect.devstream.net/display/Dev/Create+Letter+of+Credit.
*/
@Entity
@Component(value = "letterofcredit")
@Table(name = "letterofcredit")
@Access(AccessType.FIELD)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "LetterOfCredit")
public class LetterOfCredit extends PersistenceBase implements Stateful<LetterOfCreditState, LetterOfCreditEvent>,
Commentable<AddedComment> {
@NotNull(message = "Number is required")
private String number;
private String bankReference;
@ManyToOne
@ForeignKey(name = "fk_letterofcredittemplate")
private LetterOfCreditTemplate letterOfCreditTemplate;
@Temporal(javax.persistence.TemporalType.DATE)
private Date establishmentDate;
@Temporal(javax.persistence.TemporalType.DATE)
private Date submissionDate;
@NotNull(message = "Created date is required")
@Temporal(javax.persistence.TemporalType.DATE)
private Date createdDate;
@NotNull(message = "Bank charges are required")
@Enumerated(EnumType.STRING)
private LetterOfCreditBankCharges bankCharges = LetterOfCreditBankCharges.BENEFICIARY;
private String bankChargesDescription;
private int validityPeriod;
@Transient
private String instructionsToIssuingBank;
private boolean transferable;
private boolean confirm;
private boolean irrevocable = true;
@Temporal(javax.persistence.TemporalType.DATE)
private Date expiryDate;
@Transient
private String specialConditions;
@ElementCollection(fetch = FetchType.LAZY)
@CollectionTable(name = "letterofcredit_freetextcomments", joinColumns = {@JoinColumn(name = "letterofcredit_id", unique = false)})
@Column(name = "reason", unique = true)
@ForeignKey(name = "fk_letterofcredit")
@XmlElementWrapper(name = "FreeTextComments")
@XmlElement(name = "FreeTextComment")
@Fetch(value = FetchMode.SUBSELECT)
private List<AddedComment> comments = new ArrayList<AddedComment>();
@Transient
private boolean active;
private String shippingMark;
@Transient
private LetterOfCreditSyncStatus syncStatus;
@NotNull(message = "Out of sync state is required")
@Enumerated(EnumType.STRING)
private LetterOfCreditOutOfSyncState outOfSyncState = LetterOfCreditOutOfSyncState.IN_SYNC;
@Transient
private LetterOfCreditDeliveryMethod deliveryMethod;
@Column(length = 1300)
private String documents;
@Column(length = 1300)
private String conditions;
private String resolvedDocuments;
private String resolvedConditions;
@NotNull(message = "Notify By is required")
private LetterOfCreditNotification notifyBy;
@NotNull(message = "Beneficiary is required")
@ManyToOne
@ForeignKey(name = "fk_supplier")
private OrganisationalUnitSupplier beneficiary;
@NotNull(message = "Applicant is required")
@ManyToOne
@ForeignKey(name = "fk_organizationalunit")
private OrganisationalUnit applicant;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<PurchaseOrder> purchaseOrders = new ArrayList<PurchaseOrder>();
@NotNull(message = "State is required")
@Enumerated(EnumType.STRING)
private LetterOfCreditState state = LetterOfCreditState.UNFINALISED;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@Fetch(value = FetchMode.SUBSELECT)
@XmlElementWrapper(name = "LetterOfCreditEvents")
@XmlElement(name = "LetterOfCreditEvent")
@OrderBy("createDateTime")
private List<LetterOfCreditEvent> events = new ArrayList<LetterOfCreditEvent>();
// This was on the purchase order on the original lc
@NotNull(message = "Goods description is required")
private String goodsDescription;
@NotNull
@XmlElement(name = "ShippingInfo")
@OneToOne(cascade = CascadeType.ALL)
@ForeignKey(name = "fk_shippingInfo")
private LetterOfCreditShippingInfo shippingInfo = new LetterOfCreditShippingInfo();
@NotNull
@XmlElement(name = "Tenor")
@OneToOne(cascade = CascadeType.ALL)
@ForeignKey(name = "fk_tenor")
private LetterOfCreditTenor tenor = new LetterOfCreditTenor();
@NotNull(message = "Issuing bank is required")
@ManyToOne
private Bank issuingBank;
// Not using int because it must be empty so the user has to type it in.
@NotNull(message = "Presentation Period is required")
private Integer presentationPeriod;
// Maximum of 35 swift characters
@NotNull(message = "Proforma Reference is required")
@Pattern(regexp = "([a-zA-Z_0-9\\s\\/\\-\\?\\:\\(\\)\\.\\,\\'\\+\\{\\}]*$){1,35}",
message = "[ProForma Reference Can only contain:: (a-z) and (A-Z) and These special charactors (/ - ? : ( ) . , ' + { })]")
private String proFormaReference;
@NotNull(message = "Application Reference is required")
private String applicationReference;
/*Map that keep track of fields changed from the bank.
* The original field and the changed field are stored here*/
@OneToMany(mappedBy = "letterOfCredit", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@Fetch(value = FetchMode.SUBSELECT)
private List<BankChangedField> bankChangedFields = new ArrayList<BankChangedField>();
@Transient
private String bankReason;
private boolean sentToGateway;
public LetterOfCredit() {
this.expiryDate = new Date();
this.submissionDate = new Date();
this.createdDate = new Date();
this.deliveryMethod = LetterOfCreditDeliveryMethod.COURIER;
this.transferable = false;
this.active = true;
}
@Override
public LetterOfCreditState getState() {
return state;
}
@Override
public void setState(LetterOfCreditState state) {
this.state = state;
}
public void setActive(boolean active) {
this.active = active;
//todo:set active on all related entities + clear out of sync on delete
}
public void addPurchaseOrder(PurchaseOrder purchaseOrder) {
purchaseOrders.add(purchaseOrder);
purchaseOrder.setLetterOfCredit(this);
}
public void addPurchaseOrders(List<PurchaseOrder> purchaseOrders) {
for (PurchaseOrder purchaseOrder : purchaseOrders) {
addPurchaseOrder(purchaseOrder);
}
}
public void removePurchaseOrder(PurchaseOrder purchaseOrder) {
purchaseOrders.remove(purchaseOrder);
purchaseOrder.setLetterOfCredit(null);
}
public void removePurchaseOrders(Collection<PurchaseOrder> purchaseOrders) {
for (PurchaseOrder order : purchaseOrders) {
order.setOrderLetterOfCredit(null);
}
this.purchaseOrders.removeAll(purchaseOrders);
}
public LetterOfCreditSyncStatus getSyncStatus() {
return syncStatus;
}
public void setSyncStatus(LetterOfCreditSyncStatus syncStatus) {
this.syncStatus = syncStatus;
}
public LetterOfCreditDeliveryMethod getDeliveryMethod() {
return deliveryMethod;
}
public void setDeliveryMethod(LetterOfCreditDeliveryMethod deliveryMethod) {
this.deliveryMethod = deliveryMethod;
}
// Maximum of 35 swift characters
@Pattern(regexp = "([a-zA-Z_0-9\\s\\/\\-\\?\\:\\(\\)\\.\\,\\'\\+\\{\\}]*$){1,35}",
message = "[Shipping Mark Can only contain:: (a-z) and (A-Z) and These special charactors (/ - ? : ( ) . , ' + { })]")
public String getShippingMark() {
return shippingMark;
}
public void setShippingMark(String shippingMark) {
this.shippingMark = shippingMark;
}
public String getResolvedDocuments() {
return resolvedDocuments;
}
public void setResolvedDocuments(String resolvedDocuments) {
this.resolvedDocuments = resolvedDocuments;
}
public String getResolvedConditions() {
return resolvedConditions;
}
public void setResolvedConditions(String resolvedConditions) {
this.resolvedConditions = resolvedConditions;
}
public LetterOfCreditOutOfSyncState getOutOfSyncState() {
return outOfSyncState;
}
public void setOutOfSyncState(LetterOfCreditOutOfSyncState outOfSyncState) {
this.outOfSyncState = outOfSyncState;
}
public LetterOfCreditNotification getNotifyBy() {
return notifyBy;
}
public void setNotifyBy(LetterOfCreditNotification notifyBy) {
this.notifyBy = notifyBy;
}
public String getDocuments() {
return documents;
}
public void setDocuments(String documents) {
this.documents = documents;
}
public String getConditions() {
return conditions;
}
public void setConditions(String conditions) {
this.conditions = conditions;
}
public OrganisationalUnitSupplier getBeneficiary() {
return beneficiary;
}
public void setBeneficiary(OrganisationalUnitSupplier beneficiary) {
this.beneficiary = beneficiary;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getBankReference() {
return bankReference;
}
public void setBankReference(String bankReference) {
this.bankReference = bankReference;
}
public LetterOfCreditTemplate getLetterOfCreditTemplate() {
return letterOfCreditTemplate;
}
public void setLetterOfCreditTemplate(LetterOfCreditTemplate letterOfCreditTemplate) {
this.letterOfCreditTemplate = letterOfCreditTemplate;
}
public Date getEstablishmentDate() {
return establishmentDate;
}
public void setEstablishmentDate(Date establishmentDate) {
this.establishmentDate = establishmentDate;
}
public Date getSubmissionDate() {
return submissionDate;
}
public void setSubmissionDate(Date submissionDate) {
this.submissionDate = submissionDate;
}
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
public LetterOfCreditBankCharges getBankCharges() {
return bankCharges;
}
public void setBankCharges(LetterOfCreditBankCharges bankCharges) {
this.bankCharges = bankCharges;
}
public String getBankChargesDescription() {
return bankChargesDescription;
}
public void setBankChargesDescription(String bankChargesDescription) {
this.bankChargesDescription = bankChargesDescription;
}
public int getValidityPeriod() {
return validityPeriod;
}
public void setValidityPeriod(int validityPeriod) {
this.validityPeriod = validityPeriod;
}
public String getInstructionsToIssuingBank() {
return instructionsToIssuingBank;
}
public void setInstructionsToIssuingBank(String instructionsToIssuingBank) {
this.instructionsToIssuingBank = instructionsToIssuingBank;
}
public boolean isTransferable() {
return transferable;
}
public void setTransferable(boolean transferable) {
this.transferable = transferable;
}
public boolean isConfirm() {
return confirm;
}
public void setConfirm(boolean confirm) {
this.confirm = confirm;
}
public boolean isIrrevocable() {
return irrevocable;
}
public void setIrrevocable(boolean irrevocable) {
this.irrevocable = irrevocable;
}
public Date getExpiryDate() {
return expiryDate;
}
public void setExpiryDate(Date expiryDate) {
this.expiryDate = expiryDate;
}
public List<PurchaseOrder> getPurchaseOrders() {
return purchaseOrders;
}
public void setPurchaseOrders(List<PurchaseOrder> purchaseOrders) {
this.purchaseOrders = purchaseOrders;
}
public String getSpecialConditions() {
return specialConditions;
}
public void setSpecialConditions(String specialConditions) {
this.specialConditions = specialConditions;
}
public boolean isActive() {
return active;
}
@Override
public boolean inNonEditableState() {
return state != LetterOfCreditState.UNFINALISED;
}
@Override
public LetterOfCreditEvent getLastEvent() {
return Event.getLastEvent(events);
}
@Override
public List<LetterOfCreditEvent> getEvents() {
return events;
}
@Override
public int hashCode() {
return new HashCodeBuilder()
.appendSuper(super.hashCode())
.append(number)
.toHashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof LetterOfCredit)) {
return false;
}
LetterOfCredit other = (LetterOfCredit) obj;
return new EqualsBuilder()
.appendSuper(super.equals(obj))
.append(number, other.number)
.isEquals();
}
// Maximum of 35 swift characters
@Pattern(regexp = "([a-zA-Z_0-9\\s\\/\\-\\?\\:\\(\\)\\.\\,\\'\\+\\{\\}]*$){1,35}",
message = "[Goods Description Can only contain:: (a-z) and (A-Z) and These special charactors (/ - ? : ( ) . , ' + { })]")
public String getGoodsDescription() {
return goodsDescription;
}
public void setGoodsDescription(String goodsDescription) {
this.goodsDescription = goodsDescription;
}
public LetterOfCreditShippingInfo getShippingInfo() {
return shippingInfo;
}
public void setShippingInfo(LetterOfCreditShippingInfo shippingInfo) {
this.shippingInfo = shippingInfo;
}
public Bank getIssuingBank() {
return issuingBank;
}
public void setIssuingBank(Bank issuingBank) {
this.issuingBank = issuingBank;
}
@Override
public List<AddedComment> getComments() {
return comments;
}
@Override
public void setComments(List<AddedComment> comments) {
this.comments = comments;
}
public LetterOfCreditTenor getTenor() {
return tenor;
}
public void setTenor(LetterOfCreditTenor tenor) {
this.tenor = tenor;
}
public int getPresentationPeriod() {
return presentationPeriod;
}
public void setPresentationPeriod(int presentationPeriod) {
this.presentationPeriod = presentationPeriod;
}
public List<BankChangedField> getBankChangedFields() {
return bankChangedFields;
}
public void setBankChangedFields(List<BankChangedField> bankChangedFields) {
this.bankChangedFields = bankChangedFields;
}
/**
* @return the applicant
*/
public OrganisationalUnit getApplicant() {
return applicant;
}
/**
* @param applicant the applicant to set
*/
public void setApplicant(OrganisationalUnit applicant) {
this.applicant = applicant;
}
public String getProFormaReference() {
return proFormaReference;
}
public void setProFormaReference(String proFormaReference) {
this.proFormaReference = proFormaReference;
}
public String getApplicationReference() {
return applicationReference;
}
public void setApplicationReference(String applicationReference) {
this.applicationReference = applicationReference;
}
public String getBankReason() {
return bankReason;
}
public void setBankReason(String bankReason) {
this.bankReason = bankReason;
}
public boolean isSentToGateway() {
return sentToGateway;
}
public void setSentToGateway(boolean sentToGateway) {
this.sentToGateway = sentToGateway;
}
@Override
public CommentType getCommentType() {
return CommentType.LETTER_OF_CREDIT;
}
}