OrganisationalUnitSupplier.java

package com.tradecloud.domain.supplier;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.tradecloud.common.base.HibernateUtils;
import com.tradecloud.domain.common.Currency;
import com.tradecloud.domain.common.Incoterm;
import com.tradecloud.domain.common.IntegratedPersistenceBase;
import com.tradecloud.domain.document.invoice.UnitPricePerItem;
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.Bank;
import com.tradecloud.domain.party.ServiceProvider;
import com.tradecloud.domain.party.base.Address;
import com.tradecloud.domain.party.base.Contact;
import com.tradecloud.domain.party.base.OrganisationalUnitCompany;
import com.tradecloud.domain.place.NamedPlace;
import com.tradecloud.domain.treasury.TreasuryBank;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.xml.bind.annotation.*;
import java.math.BigDecimal;
import java.util.List;

/**
 * This class is designed to hold any Organisational Unit specific data overrides of the supplier information.
 * E.g. If this Org Unit has negotiated a specific PAYMENT_BASIS that is different to the supplier's default Payment Basis
 * then the value should be stored in this class and will be used ahead of the Supplier's default values.
 * All values should be retrieved via the methods on this class. If the values in this class are null then
 * it will delegate to the supplier to return the default values.
 * Design details here: https://connect.devstream.net/display/Dev/Organisational+Unit+-+Supplier+Relationship
 *
 * @author ronan
 */
@Entity
@Table(name = "organisationalunitsupplier")
@Access(AccessType.FIELD)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "OrganisationalUnitSupplier")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
@NamedQueries({
        @NamedQuery(name = "findByIdOrgUnitAndSupplier",
                query = "from OrganisationalUnitSupplier orgUnitSupplier where orgUnitSupplier.organisationalUnit=:organisationalUnit " + " and " +
                        "orgUnitSupplier.supplier = :supplier"),
        @NamedQuery(name = "findByIdOrgUnitAndSupplierWhereNullAllowed",
                query = "from OrganisationalUnitSupplier orgUnitSupplier where (orgUnitSupplier.organisationalUnit=:organisationalUnit or" +
                        " orgUnitSupplier" +
                        ".organisationalUnit is null)" + " and (orgUnitSupplier.supplier = :supplier or orgUnitSupplier.supplier is null)"),
        @NamedQuery(name = "findBySupplierIncludeInactive",
                query = "from OrganisationalUnitSupplier orgUnitSupplier where orgUnitSupplier.supplier = :supplier"),
        @NamedQuery(name = "findBySupplier",
                query = "from OrganisationalUnitSupplier orgUnitSupplier where orgUnitSupplier.supplier = :supplier " +
                        "and orgUnitSupplier.supplier.state = 'ACTIVE' and orgUnitSupplier.supplier.complete = 't'")})
public class OrganisationalUnitSupplier extends IntegratedPersistenceBase implements Comparable<OrganisationalUnitSupplier>, Creditor,
        SupplierCommon, OrganisationalUnitCompany<Supplier, SupplierValueOverrides> {

    private static final long serialVersionUID = 1L;

    @ManyToOne
    @NotNull(message = "Organisational unit cannot be null")
    @XmlIDREF
    @JsonIgnore
    private OrganisationalUnit organisationalUnit;

    @ManyToOne(cascade = {CascadeType.MERGE})
    @NotNull(message = "Supplier cannot be null")
    @XmlIDREF
    @JsonIgnore
    private Supplier supplier;

    @OneToOne(mappedBy = "organisationalUnitSupplier", cascade = CascadeType.ALL)
    @XmlElement(name = "SupplierValueOverrides")
    private SupplierValueOverrides supplierValueOverrides;

    public OrganisationalUnitSupplier() {
    }

    public OrganisationalUnitSupplier(OrganisationalUnit organisationalUnit, Supplier supplier) {
        this.organisationalUnit = organisationalUnit;
        this.supplier = supplier;
    }

    public OrganisationalUnitSupplier(Supplier supplier) {
        this.supplier = supplier;
    }

    public OrganisationalUnitSupplier(IntegratedSupplier integratedSupplier) {
        // TODO Auto-generated constructor stub
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder()
                .append(organisationalUnit)
                .append(supplier)
                .toHashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!HibernateUtils.proxyClassEquals(this, obj)) {
            return false;
        }

        OrganisationalUnitSupplier other = (OrganisationalUnitSupplier) obj;
        return new EqualsBuilder()
                .append(organisationalUnit, other.getOrganisationalUnit())
                .append(supplier, other.getSupplier())
                .isEquals();
    }

    @Override
    public OrganisationalUnit getOrganisationalUnit() {
        return organisationalUnit;
    }

    @Override
    public void setOrganisationalUnit(OrganisationalUnit organisationalUnit) {
        this.organisationalUnit = organisationalUnit;
    }

    public Supplier getSupplier() {
        return supplier;
    }

    public void setSupplier(Supplier supplier) {
        this.supplier = supplier;
    }

    public SupplierValueOverrides getSupplierValueOverrides() {
        return supplierValueOverrides;
    }

    public void setSupplierValueOverrides(SupplierValueOverrides supplierValueOverrides) {
        this.supplierValueOverrides = supplierValueOverrides;
    }

    public PaymentTerm getPaymentTerm() {
        if (supplierValueOverrides != null && supplierValueOverrides.getPaymentTerm() != null) {
            return supplierValueOverrides.getPaymentTerm();
        }
        return supplier.getPaymentTerm();
    }

    public void setPaymentTerm(PaymentTerm paymentTerm) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setPaymentTerm(paymentTerm);
        } else {
            throwIllegalAccessException();
        }
    }

    public PaymentMethod getPaymentMethod() {
        if (supplierValueOverrides != null && supplierValueOverrides.getPaymentMethod() != null) {
            return supplierValueOverrides.getPaymentMethod();
        }
        return supplier.getPaymentMethod();
    }

    public void setPaymentMethod(PaymentMethod paymentMethod) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setPaymentMethod(paymentMethod);
        } else {
            throwIllegalAccessException();
        }
    }

    public EstimatedPaymentBasis getEstimatedPaymentBasis() {
        if (supplierValueOverrides != null && supplierValueOverrides.getEstimatedPaymentBasis() != null) {
            return supplierValueOverrides.getEstimatedPaymentBasis();
        }
        return supplier.getEstimatedPaymentBasis();
    }

    public void setEstimatedPaymentBasis(EstimatedPaymentBasis estimatedPaymentBasis) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setEstimatedPaymentBasis(estimatedPaymentBasis);
        } else {
            throwIllegalAccessException();
        }

    }

    public ActualPaymentBasis getActualPaymentBasis() {
        if (supplierValueOverrides != null && supplierValueOverrides.getActualPaymentBasis() != null) {
            return supplierValueOverrides.getActualPaymentBasis();
        }
        return supplier.getActualPaymentBasis();
    }

    public void setActualPaymentBasis(ActualPaymentBasis actualPaymentBasis) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setActualPaymentBasis(actualPaymentBasis);
        } else {
            throwIllegalAccessException();
        }
    }

    public Incoterm getIncoterm() {
        if (supplierValueOverrides != null && supplierValueOverrides.getIncoterm() != null) {
            return supplierValueOverrides.getIncoterm();
        }
        return supplier.getIncoterm();
    }

    public void setIncoterm(Incoterm incoterm) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setIncoterm(incoterm);
        } else {
            throwIllegalAccessException();
        }
    }

    public Currency getCurrency() {
        if (supplierValueOverrides != null && supplierValueOverrides.getCurrency() != null) {
            return supplierValueOverrides.getCurrency();
        }
        return supplier.getCurrency();
    }

    public void setCurrency(Currency currency) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setCurrency(currency);
        } else {
            throwIllegalAccessException();
        }
    }

    public UnitPricePerItem getUnitPricePerItem() {
        if (supplierValueOverrides != null && supplierValueOverrides.getUnitPricePerItem() != null) {
            return supplierValueOverrides.getUnitPricePerItem();
        }
        return supplier.getUnitPricePerItem();
    }

    public ServiceProvider getFreightForwarder() {
        if (supplierValueOverrides != null && supplierValueOverrides.getFreightForwarder() != null) {
            return supplierValueOverrides.getFreightForwarder();
        }
        return supplier.getFreightForwarder();
    }

    public void setFreightForwarder(ServiceProvider serviceProvider) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setFreightForwarder(serviceProvider);
        } else {
            throwIllegalAccessException();
        }
    }

    public ServiceProvider getClearingAgent() {
        if (supplierValueOverrides != null && supplierValueOverrides.getClearingAgent() != null) {
            return supplierValueOverrides.getClearingAgent();
        }
        return supplier.getClearingAgent();
    }

    public void setClearingAgent(ServiceProvider serviceProvider) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setClearingAgent(serviceProvider);
        } else {
            throwIllegalAccessException();
        }
    }

    public ServiceProvider getTransporter() {
        if (supplierValueOverrides != null && supplierValueOverrides.getTransporter() != null) {
            return supplierValueOverrides.getTransporter();
        }
        return supplier.getTransporter();
    }

    public Boolean getAllowPartShipment() {
        if (supplierValueOverrides != null && supplierValueOverrides.getAllowPartShipment() != null) {
            return supplierValueOverrides.getAllowPartShipment();
        }
        return supplier.getAllowPartShipment();
    }

    public void setAllowPartShipment(Boolean value) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setAllowPartShipment(value);
        } else {
            throwIllegalAccessException();
        }
    }

    public Boolean getAllowTransShipment() {
        if (supplierValueOverrides != null && supplierValueOverrides.getAllowTransShipment() != null) {
            return supplierValueOverrides.getAllowTransShipment();
        }
        return supplier.getAllowTransShipment();
    }

    public void setAllowTransShipment(Boolean value) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setAllowTransShipment(value);
        } else {
            throwIllegalAccessException();
        }
    }

    public BigDecimal getLcToleranceAbove() {
        if (supplierValueOverrides != null && supplierValueOverrides.getLcToleranceAbove() != null) {
            return supplierValueOverrides.getLcToleranceAbove();
        }
        return supplier.getLcToleranceAbove();
    }

    public void setLcToleranceAbove(BigDecimal lcToleranceAboveParam) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setLcToleranceAbove(lcToleranceAboveParam);
        } else {
            throwIllegalAccessException();
        }
    }

    public BigDecimal getLcToleranceBelow() {
        if (supplierValueOverrides != null && supplierValueOverrides.getLcToleranceBelow() != null) {
            return supplierValueOverrides.getLcToleranceBelow();
        }
        return supplier.getLcToleranceBelow();
    }

    public void setLcToleranceBelow(BigDecimal lcToleranceBelow) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setLcToleranceBelow(lcToleranceBelow);
        } else {
            throwIllegalAccessException();
        }
    }

    public Integer getPresentationDays() {
        if (supplierValueOverrides != null && supplierValueOverrides.getPresentationDays() != null) {
            return supplierValueOverrides.getPresentationDays();
        }
        return supplier.getPresentationDays();
    }

    public void setPresentationDays(Integer presentationDays) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setPresentationDays(presentationDays);
        } else {
            throwIllegalAccessException();
        }

    }

    public String getPlaceOfExpiry() {
        if (supplierValueOverrides != null && supplierValueOverrides.getPlaceOfExpiry() != null) {
            return supplierValueOverrides.getPlaceOfExpiry();
        }
        return supplier.getPlaceOfExpiry();
    }

    public void setPlaceOfExpiry(String placeOfExpiry) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setPlaceOfExpiry(placeOfExpiry);
        } else {
            throwIllegalAccessException();
        }
    }

    public Bank getAdvisingBank() {
        if (supplierValueOverrides != null && supplierValueOverrides.getAdvisingBank() != null) {
            return supplierValueOverrides.getAdvisingBank();
        }
        return supplier.getAdvisingBank();

    }

    public void setAdvisingBank(Bank bank) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setAdvisingBank(bank);
        } else {
            throwIllegalAccessException();
        }
    }

    public TreasuryBank getNominatedBank() {
        if (supplierValueOverrides != null && supplierValueOverrides.getNominatedBank() != null) {
            return supplierValueOverrides.getNominatedBank();
        }
        return supplier.getNominatedBank();

    }

    public void setNominatedBank(TreasuryBank nominatedBank) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setNominatedBank(nominatedBank);
        } else {
            throwIllegalAccessException();
        }
    }

    public NamedPlace getNamedPlace() {
        if (supplierValueOverrides != null && supplierValueOverrides.getNamedPlace() != null) {
            return supplierValueOverrides.getNamedPlace();
        }
        return supplier.getNamedPlace();
    }

    public void setNamedPlace(NamedPlace namedPlace) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setNamedPlace(namedPlace);
        } else {
            throwIllegalAccessException();
        }
    }

    @Override
    public Boolean getActive() {
        if (supplierValueOverrides != null && supplierValueOverrides.getActive() != null) {
            return supplierValueOverrides.getActive();
        }
        return supplier.getActive();
    }

    public void setActive(Boolean value) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setActive(value);
        } else {
            throwIllegalAccessException();
        }
    }

    public String getName() {
        if (supplier != null) {
            return supplier.getName();
        }
        return null;
    }

    @Override
    public String getNameAndOrgName() {
        if (supplier != null) {
            return supplier.getName() + (organisationalUnit != null ? " - " + organisationalUnit.getName() : "");
        }
        return null;
    }

    @Override
    public String getNameAndOrgNameAndExternalReference() {
        if (supplier != null) {
            String supplierName = supplier.getName();
            String orgUnitName = organisationalUnit != null ? organisationalUnit.getName() : "";
            String externalReference = supplier.getExternalReference();

            return supplierName + " - " + orgUnitName + " - " + externalReference;
        }
        return null;
    }

    public String getExternalReference() {
        return supplier.getExternalReference();
    }

    @Override
    public int compareTo(OrganisationalUnitSupplier other) {
        if (supplier.getName() != null) {
            return (getSupplier().getName()
                    + (getSupplier().getExternalReference() != null ? getSupplier().getExternalReference() : ""))
                    .compareTo(other.getSupplier().getName()
                            + (other.getSupplier().getExternalReference() != null ? other.getSupplier().getExternalReference() : ""));
        }
        return -1;
    }

    public Address getPhysicalAddress() {
        if (supplierValueOverrides != null && supplierValueOverrides.getPhysicalAddress() != null) {
            return supplierValueOverrides.getPhysicalAddress();
        }
        return supplier.getPhysicalAddress();
    }

    public void setPhysicalAddress(Address address) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setPhysicalAddress(address);
        } else {
            throwIllegalAccessException();
        }
    }

    public Address getPostalAddress() {
        if (supplierValueOverrides != null && supplierValueOverrides.getPostalAddress() != null) {
            return supplierValueOverrides.getPostalAddress();
        }
        return supplier.getPostalAddress();
    }

    public void setPostalAddress(Address address) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setPostalAddress(address);
        } else {
            throwIllegalAccessException();
        }
    }

    public List<Contact> getContacts() {
        if (supplierValueOverrides != null && supplierValueOverrides.getContacts() != null) {
            return supplierValueOverrides.getContacts();
        }
        return supplier.getContacts();
    }

    public void setContacts(List<Contact> contacts) {
        if (supplierValueOverrides != null) {
            supplierValueOverrides.setContacts(contacts);
        } else {
            throwIllegalAccessException();
        }
    }

    public String getCompanyRegistrationNumber() {
        if (supplierValueOverrides != null) {
            return supplierValueOverrides.getCompanyRegistrationNumber();
        }
        return supplier.getCompanyRegistrationNumber();
    }

    public String getSalesTaxRegistrationNumber() {
        if (supplierValueOverrides != null) {
            return supplierValueOverrides.getSalesTaxRegistrationNumber();
        }
        return supplier.getSalesTaxRegistrationNumber();
    }

    public String getVatRegistrationNumber() {
        if (supplierValueOverrides != null) {
            return supplierValueOverrides.getVatRegistrationNumber();
        }
        return supplier.getVatRegistrationNumber();
    }

    public String getWarehouseCode() {
        if (supplierValueOverrides != null) {
            return supplierValueOverrides.getWarehouseCode();
        }
        return supplier.getWarehouseCode();
    }

    public boolean isTemplate() {
        if (supplierValueOverrides != null) {
            return supplierValueOverrides.isTemplate();
        }
        return false;
    }

    private void throwIllegalAccessException() throws IllegalAccessError {
        throw new IllegalAccessError("Supplier values not being overridden currently. " + "Either create a SupplierValueOverrides object or modify " +
                "the supplier defaults directly.");
    }

    public String getSupplierAndOrgUnitName() {
        String supplierName = getSupplier().getName();
        String orgUnitName = getOrganisationalUnit().getName();

        return supplierName + " - " + orgUnitName;
    }

    @Override
    public Supplier getCompany() {
        return supplier;
    }

    @Override
    public void setCompany(Supplier company) {
        this.supplier = company;
    }

    @Override
    public SupplierValueOverrides getValueOverrides() {
        return supplierValueOverrides;
    }

    @Override
    public void setValueOverrides(SupplierValueOverrides valueOverrides) {
        this.supplierValueOverrides = valueOverrides;
    }

    @Override
    public boolean hasValueOverrides() {
        return supplierValueOverrides != null;
    }

    public void validateTypeMatch() {
        Supplier supplier = this.getSupplier();
        OrganisationalUnit organisationalUnit = this.getOrganisationalUnit();
        if (supplier != null && organisationalUnit != null
                && supplier.getType() != null && organisationalUnit.getType() != null) {
            if (!AbstractSupplier.Type.ELC.equals(supplier.getType()) && OrganisationalUnit.Type.ELC.equals(organisationalUnit.getType())) {
                throw new IllegalArgumentException(String.format("Supplier type %s and org unit type %s mismatch ", supplier.getType()
                        , organisationalUnit.getType()));
            }
        }
    }
}