package com.echo.cis.domain.model;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.hibernate.validator.Range;
import com.echo.cis.domain.util.PersistenceConstants;
/**
* Merchant entity.
*
* @author <a href="mailto:
[email protected]">Krasimir Chobantonov</a>
*/
@Entity
@Table(name = "MERCHANTS")
@SequenceGenerator(name = "entity_sequence_generator", sequenceName = "MERCHANTS_SEQ")
public class Merchant implements Persistable<Long> {
private static final long serialVersionUID = 2782166927098194371L;
private static final int HASH_CODE_INITIAL_NON_ZERO_ODD_NUMBER = 17;
private static final int HASH_CODE_MULTIPLIER_NON_ZERO_ODD_NUMBER = 37;
@Id
@Column(name = "ID", nullable = false)
@GeneratedValue(generator = "entity_sequence_generator")
private Long id;
@Column(name = "MERCHANT_ID", nullable = true, updatable = false, unique = true, length = PersistenceConstants.MERCHANT_ID_LENGTH)
private String merchantId;
@Column(name = "PHONE_NUMBER")
private String phoneNumber;
@Column(name = "DBA_NAME")
private String dbaName;
@Column(name = "LEGAL_NAME")
private String legalName;
@Column(name = "MERCHANT_DESCRIPTOR")
private String merchantDescriptor;
@Column(name = "CONTACT_NAME", length = PersistenceConstants.MERCHANT_CONTACT_NAME_LENGTH)
private String contactName;
@Column(name = "AGENT_ID")
private Long agentId;
@Column(name = "SALES_GROUP_CODE")
private Long salesGroupCode;
@Column(name = "ATTN")
private Boolean attn;
@Column(name = "AUTO_RENEWAL")
private Boolean autoRenewal;
@Column(name = "EFFECTIVE_DATE")
@Temporal(value = TemporalType.DATE)
private Date effectiveDate;
@Column(name = "FIRST_TRANSACTION_DATE")
@Temporal(value = TemporalType.DATE)
private Date firstTransactionDate;
@Column(name = "CONTRACT_TERM_IN_MONTHS")
@Range(min=1, message="Contract term must be at least 1 month or longer")
private Integer contractTermInMonths;
@Column(name = "BILLING_ADDRESS")
private String billingAddress;
@Column(name = "BILLING_CITY")
private String billingCity;
@Column(name = "BILLING_STATE")
private String billingState;
@Column(name = "BILLING_COUNTRY")
private String billingCountry;
@Column(name = "BILLING_POSTAL_CODE")
private String billingPostalCode;
@Column(name = "SEASONAL_MERCHANT")
private Boolean seasonalMerchant;
@Column(name = "SPONSOR_BANK_CODE")
private String sponsorBankCode;
@Column(name = "MERCHANT_GROUP_CODE")
private String merchantGroupCode;
@Column(name = "MAP_DISCOVER")
private String mapDiscover;
@Column(name = "IC_PLUS_FLAG")
private String icPlusFlag;
@Column(name = "MERCHANT_PORTAL")
private String merchantPortal;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "merchant", optional = true, fetch = FetchType.EAGER)
private ForeignCurrency foreignCurrency;
/*
* private Date accountStatusDate; private AccountStatus accountStatus; private Integer accountStatusReason; private
* Date accountStatusLastUpdated;
*/
@OneToMany(cascade = CascadeType.ALL, mappedBy = "merchant", fetch = FetchType.LAZY)
private Set<BillingAccount> billingAccounts = new HashSet<BillingAccount>();
@OneToMany(cascade = CascadeType.ALL, mappedBy = "merchant", fetch = FetchType.LAZY)
private Set<ProgramConfigurationItem> programConfigurationItems = new HashSet<ProgramConfigurationItem>();
@OneToMany(cascade = CascadeType.ALL, mappedBy = "merchant", fetch = FetchType.LAZY)
private Set<BillingConfigurationItem> billingConfigurationItems = new HashSet<BillingConfigurationItem>();
/**
* {@inheritDoc}
*/
public String getSponsorBankCode() {
return sponsorBankCode;
}
/**
* {@inheritDoc}
*/
public void setSponsorBankCode(String sponsorBankCode) {
this.sponsorBankCode = sponsorBankCode;
}
/**
* {@inheritDoc}
*/
public String getMerchantGroupCode() {
return merchantGroupCode;
}
/**
* {@inheritDoc}
*/
public void setMerchantGroupCode(String merchantGroupCode) {
this.merchantGroupCode = merchantGroupCode;
}
/**
* {@inheritDoc}
*/
public Long getId() {
return id;
}
/**
* Return the merchant id.
*
* @return the merchant id.
*/
public String getMerchantId() {
return merchantId;
}
/**
* Set the merchant unique id.
*
* @param aMerchantId
* The unique id that should be assigned to the merchant
*/
public void setMerchantId(final String aMerchantId) {
this.merchantId = aMerchantId;
}
/**
* Return read-only view of associated billing accounts.
*
* @return
*/
public Set<BillingAccount> getBillingAccounts() {
return Collections.unmodifiableSet(billingAccounts);
}
/**
*
* @return
*/
public String getPhoneNumber() {
return phoneNumber;
}
/**
*
* @param phoneNumber
*/
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
/**
*
* @return
*/
public String getDbaName() {
return dbaName;
}
/**
*
* @param dbaName
*/
public void setDbaName(String dbaName) {
this.dbaName = dbaName;
}
/**
*
* @return
*/
public String getLegalName() {
return legalName;
}
/**
*
* @param legalName
*/
public void setLegalName(String legalName) {
this.legalName = legalName;
}
/**
*
* @return
*/
public String getMerchantDescriptor() {
return merchantDescriptor;
}
/**
*
* @param merchantDescriptor
*/
public void setMerchantDescriptor(String merchantDescriptor) {
this.merchantDescriptor = merchantDescriptor;
}
/**
*
* @return
*/
public String getContactName() {
return contactName;
}
/**
*
* @param contactName
*/
public void setContactName(String contactName) {
this.contactName = contactName;
}
/**
*
* @return
*/
public Long getAgentId() {
return agentId;
}
/**
*
* @param agentId
*/
public void setAgentId(Long agentId) {
this.agentId = agentId;
}
/**
*
* @return
*/
public Long getSalesGroupCode() {
return salesGroupCode;
}
/**
*
* @param salesGroupCode
*/
public void setSalesGroupCode(Long salesGroupCode) {
this.salesGroupCode = salesGroupCode;
}
/**
*
* @return
*/
public Boolean getAttn() {
return attn;
}
/**
*
* @param attn
*/
public void setAttn(Boolean attn) {
this.attn = attn;
}
/**
*
* @return
*/
public String getBillingAddress() {
return billingAddress;
}
/**
*
* @param billingAddress
*/
public void setBillingAddress(String billingAddress) {
this.billingAddress = billingAddress;
}
/**
*
* @return
*/
public String getBillingCity() {
return billingCity;
}
/**
*
* @param billingCity
*/
public void setBillingCity(String billingCity) {
this.billingCity = billingCity;
}
/**
*
* @return
*/
public String getBillingState() {
return billingState;
}
/**
*
* @param billingState
*/
public void setBillingState(String billingState) {
this.billingState = billingState;
}
/**
*
* @return
*/
public String getBillingCountry() {
return billingCountry;
}
/**
*
* @param billingCountry
*/
public void setBillingCountry(String billingCountry) {
this.billingCountry = billingCountry;
}
/**
*
* @return
*/
public String getBillingPostalCode() {
return billingPostalCode;
}
/**
*
* @param billingPostalCode
*/
public void setBillingPostalCode(String billingPostalCode) {
this.billingPostalCode = billingPostalCode;
}
/**
*
* @return
*/
public Boolean getSeasonalMerchant() {
return seasonalMerchant;
}
/**
*
* @param seasonalMerchant
*/
public void setSeasonalMerchant(Boolean seasonalMerchant) {
this.seasonalMerchant = seasonalMerchant;
}
/**
*
* @return
*/
public Boolean getAutoRenewal() {
return autoRenewal;
}
/**
*
* @param autoRenewal
*/
public void setAutoRenewal(Boolean autoRenewal) {
this.autoRenewal = autoRenewal;
}
/**
*
* @return
*/
public Date getFirstTransactionDate() {
return firstTransactionDate;
}
/**
*
* @param firstTransactionDate
*/
public void setFirstTransactionDate(Date firstTransactionDate) {
this.firstTransactionDate = firstTransactionDate;
}
/**
*
* @return
*/
public Date getEffectiveDate() {
return effectiveDate;
}
/**
*
* @param effectiveDate
*/
public void setEffectiveDate(Date effectiveDate) {
this.effectiveDate = effectiveDate;
}
/**
*
* @return
*/
public Integer getContractTermInMonths() {
return contractTermInMonths;
}
/**
*
* @param contractTermInMonths
*/
public void setContractTermInMonths(Integer contractTermInMonths) {
this.contractTermInMonths = contractTermInMonths;
}
/**
*
* @return
*/
public Set<ProgramConfigurationItem> getProgramConfigurationItems() {
return Collections.unmodifiableSet(programConfigurationItems);
}
/**
*
* @return
*/
public Set<BillingConfigurationItem> getBillingConfigurationItems() {
return Collections.unmodifiableSet(billingConfigurationItems);
}
public ForeignCurrency getForeignCurrency() {
//TODO: Get foreign currency
return foreignCurrency;
}
public void setForeignCurrency(ForeignCurrency foreignCurrency) {
if (foreignCurrency == null) {
this.foreignCurrency = null;
return;
}
if (foreignCurrency.getMerchant() != null) {
if (foreignCurrency.getMerchant().getId() != null) { // foreign currency is set to persistent merchant
if (!foreignCurrency.getMerchant().getId().equals(getId())) {
throw new IllegalArgumentException("foreign currency already assigned to a merchant");
}
}
}
this.foreignCurrency = foreignCurrency;
this.foreignCurrency.setMerchant(this);
}
public ProgramConfigurationItem addProgramItem(ProgramConfigurationItem programConfigurationItem) {
if (programConfigurationItem.getMerchant() != null) {
throw new IllegalStateException("program configuration item already assigned to merchant");
}
programConfigurationItem.merchant = this;
programConfigurationItems.add(programConfigurationItem);
return programConfigurationItem;
}
public BillingConfigurationItem addBillingItem(BillingConfigurationItem billingConfigurationItem) {
if (billingConfigurationItem.getMerchant() != null) {
throw new IllegalStateException("billing configuration item already assigned to merchant");
}
billingConfigurationItem.merchant = this;
billingConfigurationItems.add(billingConfigurationItem);
return billingConfigurationItem;
}
public BillingAccount addBillingAccount(String addedBy, BillingAccount.BillingAccountType billingAccountType) {
final BillingAccount billingAccount = new BillingAccount(this, addedBy, billingAccountType);
billingAccounts.add(billingAccount);
return billingAccount;
}
/**
* Returns the remaining term in months compute based on the current date.
*
* @return
*/
public Integer getTermRemaining() {
if (contractTermInMonths == null || effectiveDate == null) {
return null; // we can't calculate the term remaining
}
Calendar endTime = Calendar.getInstance();
endTime.setTime(effectiveDate);
endTime.add(Calendar.MONTH, contractTermInMonths.intValue());
Calendar now = Calendar.getInstance();
int result = fieldDifference(now.getTime(), endTime.getTime(), Calendar.MONTH);
return new Integer(result);
}
public String getMapDiscover() {
return mapDiscover;
}
public void setMapDiscover(String mapDiscover) {
this.mapDiscover = mapDiscover;
}
public String getIcPlusFlag() {
return icPlusFlag;
}
public void setIcPlusFlag(String icPlusFlag) {
this.icPlusFlag = icPlusFlag;
}
public String getMerchantPortal() {
return merchantPortal;
}
public void setMerchantPortal(String merchantPortal) {
this.merchantPortal = merchantPortal;
}
private static int fieldDifference(Date startTime, Date endTime, int field) {
if (!startTime.before(endTime)) {
return 0;
}
Calendar start = Calendar.getInstance();
start.setTime(startTime);
// hack for now. Can be done more efficiently inside precise Calendar
for (int i = 1; ; ++i) {
start.add(field, 1);
if (start.getTime().after(endTime)) {
return i; // return difference in field
}
}
}
/**
* Perform equals on the business primary key fields: echoId.
*
* {@inheritDoc}
*/
@Override
public boolean equals(final Object obj) {
if (!(obj instanceof Merchant)) {
return false;
}
return new EqualsBuilder().append(merchantId, ((Merchant) obj).getMerchantId()).isEquals();
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return new HashCodeBuilder(HASH_CODE_INITIAL_NON_ZERO_ODD_NUMBER, HASH_CODE_MULTIPLIER_NON_ZERO_ODD_NUMBER)
.append(merchantId).toHashCode();
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return new ToStringBuilder(this)
.append("id", getId())
.append("merchantId", getMerchantId())
.append("phoneNumber", getPhoneNumber())
.append("dbaName", getDbaName())
.append("legalName",getLegalName())
.append("merchantDescriptor", getMerchantDescriptor())
.append("contactName", getContactName())
.append("agentId", getAgentId())
.append("salesGroupCode", getSalesGroupCode())
.append("attn", getAttn())
.append("billingAddress", getBillingAddress())
.append("billingCity", getBillingCity())
.append("billingState", getBillingState())
.append("billingCountry", getBillingCountry())
.append("billingPostalCode", getBillingPostalCode())
.append("seasonalMerchant", getSeasonalMerchant())
.append("autoRenewal", getAutoRenewal())
.append("effectiveDate", getEffectiveDate())
.append("contractTermInMonths", getContractTermInMonths())
.append("firstTransactionDate",getFirstTransactionDate())
.append("merchantGroupCode",getMerchantGroupCode())
.append("salesGroupCode",getSalesGroupCode())
.append("sponsorBankCode",getSponsorBankCode())
.append("mapDiscover",getMapDiscover())
.append("icPlusFlag",getIcPlusFlag())
.append("merchantPortal",getMerchantPortal())
.append("foreignCurrency", getForeignCurrency() != null ? getForeignCurrency() : "<null>")
.toString();
}
}