OrganisationalUnit.java

package com.tradecloud.domain.model.organisationalunit;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.tradecloud.common.base.HibernateUtils;
import com.tradecloud.domain.PrimeInterestRate;
import com.tradecloud.domain.agent.OrganisationalUnitAgent;
import com.tradecloud.domain.clearing.CustomsAccount;
import com.tradecloud.domain.clearing.CustomsClearanceDeclarationLevel;
import com.tradecloud.domain.common.IntegratedPersistenceBase;
import com.tradecloud.domain.common.Percentage;
import com.tradecloud.domain.configuration.external.ExternalApiConfiguration;
import com.tradecloud.domain.item.NaturalStringSorting;
import com.tradecloud.domain.model.ConvertableToDefaultDTO;
import com.tradecloud.domain.model.ForexGroup;
import com.tradecloud.domain.model.organisationalunit.tradefinance.MarginPercentage;
import com.tradecloud.domain.model.organisationalunit.tradefinance.ServiceFee;
import com.tradecloud.domain.party.Employee;
import com.tradecloud.domain.party.ServiceProvider;
import com.tradecloud.domain.party.base.Address;
import com.tradecloud.domain.party.base.Contact;
import com.tradecloud.domain.rate.RateSourceType;
import com.tradecloud.domain.supplier.OrganisationalUnitSupplier;
import com.tradecloud.domain.supplier.SwiftCompliantAddress;
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.hibernate.annotations.NaturalId;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.xml.bind.annotation.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * The transactional unit is required so that the service propagates the
 * transaction to this class if it needs to call the recursive methods.
 */

@NamedQueries({@NamedQuery(name = "orgUnit.byName", query = "from OrganisationalUnit where lower(name) like :name"),
        @NamedQuery(name = "orgUnit.byNameAllowSupplier", query =
                "from OrganisationalUnit where lower(name) like :name and allowsSuppliers = TRUE"),
        @NamedQuery(name = "orgUnit.byTierAllowSupplier", query = "from OrganisationalUnit where tier = :tier and type=:type "
                + "and allowsSuppliers = TRUE order by name"),
        @NamedQuery(name = "orgUnit.placeOrders", query =
                "select ou from OrganisationalUnit as ou where ou.placeOrders=true and type=:type  "
                        + "order by ou.name"),
        @NamedQuery(name = "orgUnit.exporter", query =
                "select ou from OrganisationalUnit as ou where ou.exportUnit=true and ou.active=true order by ou.name"),
        @NamedQuery(name = "orgUnit.hasItems", query =
                "select ou from OrganisationalUnit as ou where ou.hasItems=true order by ou.name"),
        @NamedQuery(name = "orgUnit.hasInvoice", query =
                "select ou from OrganisationalUnit as ou where ou.hasInvoice=true and type=:type  order by ou.name"),
        @NamedQuery(name = "orgUnit.byCode", query = "from OrganisationalUnit where lower(code) like :code")
})
@Entity(name = "OrganisationalUnit")
@Table(name = "organisationalunit", uniqueConstraints = {@UniqueConstraint(columnNames = {"code"})})
@Access(AccessType.FIELD)
@XmlRootElement(name = "OrganisationalUnit")
@XmlAccessorType(XmlAccessType.FIELD)
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class OrganisationalUnit extends IntegratedPersistenceBase
        implements Comparable<OrganisationalUnit>, NaturalStringSorting, ConvertableToDefaultDTO, LogoHolder {

    public static enum Type {
        FULL, ELC
    }

    private static final long serialVersionUID = 1L;

    /**
     * TODO - Need to look at these rules. Not really a great design.Default rate
     * source
     */
    private static final RateSourceType DEFAULT_RATE_SOURCE = RateSourceType.RATES_FEED;
    public static final String FOREX_GROUP_RATE_SOURCE_RULE_CODE = "forex_group_rate_source"; // todo refactor this...
    public static final String ORGANISATIONAL_UNIT_RATE_SOURCE_RULE_CODE = "has_rate_source"; // todo refactor this...

    @NaturalId(mutable = true)
    @NotNull(message = "Code is required")
    @XmlID
    private String code;

    @XmlAttribute
    @NotNull(message = "Name is required")
    private String name;

    @XmlAttribute
    private Boolean active = Boolean.TRUE;

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private ExternalApiConfiguration externalApiConfiguration;
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<CustomsAccount> customsAccounts;

    /**
     * Denotes if this org unit is valid to place orders against.
     */
    private boolean placeOrders;

    /**
     * Denotes if this org unit is the destination of the orders items.
     */
    private boolean hasItems;

    /**
     * Denotes if this org unit is valid for invoicing.
     */
    private boolean hasInvoice;

    /**
     * Indicates if the organisation is a Letter of Credit applicant. If the rule is
     * selected, the user will be able to add an address for the org unit. The
     * address will be swift compliant
     */
    private boolean letterOfCreditApplicant;

    private boolean generateShippingReference;

    private transient AtomicInteger orderShippingRefAtomicCounter;
    /**
     * keeps the last counter in db in the readable format. This field works
     * together with orderShippingRefAtomicCounter.
     */
    private Integer orderShippingRefCounter;

    @Pattern(regexp = "\\S+", message = "Spaces are not allowed")
    private String codeForShippingReference;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
    @Fetch(FetchMode.SELECT)
    @JoinColumn(name = "orgunit_id")
    @XmlTransient
    @JsonIgnore
    private Collection<Rule> rules = new ArrayList<>();

    @ManyToOne(cascade = CascadeType.PERSIST)
    @XmlTransient
    @JsonIgnore
    private OrganisationalUnit parent;

    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @Fetch(FetchMode.SELECT)
    @XmlTransient
    @JsonIgnore
    private Set<OrganisationalUnit> children = new HashSet<>();

    @XmlTransient
    @ManyToMany(cascade = CascadeType.PERSIST)
    @JsonIgnore
    private Set<Employee> employees = new HashSet<>();

    @Enumerated(EnumType.STRING)
    private CustomsClearanceDeclarationLevel customsClearanceDeclarationLevel;
    /**
     * This is mostly for speed reasons. Gathering the suppliers for 1000+ org units
     * is costly when 95% of them don't have suppliers. The fetch of the collection
     * is slow, even if empty. Can remove if this is no longer a problem
     */
    private boolean allowsSuppliers;

    @XmlTransient
    @OneToMany(mappedBy = "organisationalUnit")
    @JsonIgnore
    private Set<OrganisationalUnitSupplier> organisationalUnitSuppliers = new HashSet<>();

    /**
     * This is mostly for speed reasons. Gathering the suppliers for 1000+ org units
     * is costly when 95% of them don't have agents. The fetch of the collection is
     * slow, even if empty. Can remove if this is no longer a problem
     */
    private boolean allowsAgents;

    private boolean isLegalEntity;

    private boolean isCustomsValueRequired;

    @XmlTransient
    @OneToMany(mappedBy = "organisationalUnit", cascade = CascadeType.ALL)
    @JsonIgnore
    private Set<OrganisationalUnitAgent> organisationalUnitAgents = new HashSet<>();

    /**
     * This is mostly for speed reasons. Gathering the suppliers for 1000+ org units
     * is costly when 95% of them don't have service providers. The fetch of the
     * collection is slow, even if empty. Can remove if this is no longer a problem
     */
    private boolean allowsServiceProviders;

    @XmlTransient
    @ManyToMany
    @JsonIgnore
    private Set<ServiceProvider> serviceProviders = new HashSet<ServiceProvider>();

    @ManyToOne
    @XmlElement(name = "Tier")
    private OrganisationalUnitTier tier;

    // needs configuration
    @Transient
    @XmlTransient
    @JsonIgnore
    private int daysFinance = 0;

    @Transient
    @XmlTransient
    @JsonIgnore
    private RateSourceType ratesSource;

    @Transient
    @XmlTransient
    @JsonIgnore
    private Percentage spotRateMargin;

    @Transient
    private Percentage forwardRateMargin;

    @Transient
    private String codeName;

    private boolean importUnit;
    private boolean useOnIntegrationEvents;
    private boolean exportUnit;
    private boolean consignee;

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @XmlElement(name = "PhysicalAddress")
    private Address physicalAddress;

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @XmlElement(name = "PostalAddress")
    private Address postalAddress;

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @XmlElement(name = "SwiftCompliantAddress")
    @ForeignKey(name = "fk_swiftaddress")
    private SwiftCompliantAddress swiftCompliantAddress;

    @XmlAttribute
    private String customsCode;

    @XmlAttribute
    private String salesTaxRegistrationNumber;

    @XmlAttribute
    private String vatRegistrationNumber;

    @XmlAttribute
    private String companyRegistrationNumber;

    @XmlTransient
    @JsonIgnore
    @OneToOne(fetch = FetchType.LAZY, cascade = {})
    private Logo logoImage;

    private boolean allowSampleAndSparePart;

    private boolean sabsEnabled;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "organisationalUnit", orphanRemoval = true, fetch = FetchType.LAZY)
    @JsonIgnore
    private List<ServiceFee> serviceFeeList;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "organisationalUnit", orphanRemoval = true, fetch = FetchType.LAZY)
    @JsonIgnore
    private List<MarginPercentage> marginPercentageList;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "organisationalUnit", orphanRemoval = true, fetch = FetchType.LAZY)
    @JsonIgnore
    private List<PrimeInterestRate> primeInterestRateList;

    private int creditTerm;

    @XmlTransient
    @OneToMany(cascade = CascadeType.ALL)
    @JsonIgnore
    @JoinTable(name = "organisationalunit_paymentBasisKeyValues")
    private Set<PaymentBasisKeyValue> paymentBasisKeyValues = new HashSet<>();

    private BigDecimal containerUtilization;

    @XmlTransient
    @Enumerated(EnumType.STRING)
    private Type type = Type.FULL;

    @OneToMany(cascade = CascadeType.ALL)
    @JsonIgnore
    @JoinTable(name = "organisationalunit_contacts")
    @XmlElement(name = "Contact")
    private List<Contact> contacts = new ArrayList<>();

    @XmlTransient
    @JsonIgnore
    private String accountNumber;

    @Deprecated //remove from db and config
    private boolean uniqueLineNumber;

    @XmlTransient
    @JsonIgnore
    private String bulkOrderNumber;

    @XmlTransient
    @JsonIgnore
    private String insurancePolicyNumber;

    @XmlTransient
    @JsonIgnore
    private String insurer;

    private boolean stockLevel;

    public OrganisationalUnit(String code) {
        this.code = code;
    }

    public OrganisationalUnit(String code, String name, OrganisationalUnitTier tier) {
        this.code = code;
        this.name = name;
        this.tier = tier;
    }

    public OrganisationalUnit(String code, String name) {
        this.code = code;
        this.name = name;
    }

    public OrganisationalUnit() {
    }

    public OrganisationalUnit(Long orgUnitId, String orgName) {
        this.name = orgName;
        this.id = orgUnitId;
    }

    @Override
    public String getName() {
        return name;
    }

    public OrganisationalUnit getParent() {
        return parent;
    }

    public void setParent(OrganisationalUnit parent) {
        this.parent = parent;
    }

    public Collection<OrganisationalUnit> getChildren() {
        return children;
    }

    public void setChildren(Set<OrganisationalUnit> children) {
        this.children = children;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public void removeRule(Rule rule) {
        rules.remove(rule);
    }

    public void addRule(Rule rule) {
        rules.add(rule);
    }

    public Collection<Rule> getRules() {
        return rules;
    }

    public void setRules(Collection<Rule> rules) {
        this.rules = rules;
    }

    public String getCodeName() {
        return this.getCode() + "," + this.getName();
    }

    public String getNameCode() {
        return this.getName() + " " + this.getCode();
    }

    @Override
    public Boolean getActive() {
        return active;
    }

    public void setActive(Boolean active) {
        this.active = active;
    }

    @Override
    public String toString() {
        return "id=" + getId() + ",name=" + name + ",code=" + code + ",tier=" + tier;
    }

    public Collection<String> getAccessableOrganisationCodes() {
        Set<String> accessableOrgCodes = new HashSet<>();

        // Add the Org code for the Organisation
        accessableOrgCodes.add(getCode());

        // Then add
        for (OrganisationalUnit childUnit : this.getChildren()) {
            accessableOrgCodes.addAll(childUnit.getAccessableOrganisationCodes());
        }
        return accessableOrgCodes;
    }

    public boolean isPlaceOrders() {
        return placeOrders;
    }

    public void setPlaceOrders(boolean placeOrders) {
        this.placeOrders = placeOrders;
    }

    public boolean isGenerateShippingReference() {
        return generateShippingReference;
    }

    public void setGenerateShippingReference(boolean generateShippingReference) {
        this.generateShippingReference = generateShippingReference;
    }

    public boolean isHasItems() {
        return hasItems;
    }

    public void setHasItems(boolean hasItems) {
        this.hasItems = hasItems;
    }

    public boolean isHasInvoice() {
        return hasInvoice;
    }

    public void setHasInvoice(boolean hasInvoice) {
        this.hasInvoice = hasInvoice;
    }

    public int getDaysFinance() {
        return daysFinance;
    }

    public void setDaysFinance(int daysFinance) {
        this.daysFinance = daysFinance;
    }

    public boolean isImportUnit() {
        return importUnit;
    }

    public void setImportUnit(boolean importUnit) {
        this.importUnit = importUnit;
    }

    public boolean isExportUnit() {
        return exportUnit;
    }

    public void setExportUnit(boolean exportUnit) {
        this.exportUnit = exportUnit;
    }

    public Address getPhysicalAddress() {
        return physicalAddress;
    }

    public void setPhysicalAddress(Address physicalAddress) {
        this.physicalAddress = physicalAddress;
    }

    public Address getPostalAddress() {
        return postalAddress;
    }

    public void setPostalAddress(Address postalAddress) {
        this.postalAddress = postalAddress;
    }

    public Percentage getSpotRateMargin() {

        return spotRateMargin;
    }

    public void setSpotRateMargin(Percentage spotRateMargin) {
        this.spotRateMargin = spotRateMargin;
    }

    public void setForwardRateMargin(Percentage forwardRateMargin) {
        this.forwardRateMargin = forwardRateMargin;
    }

    public Percentage getForwardRateMargin() {
        return forwardRateMargin;
    }

    public boolean mustApplyFinanceCharge() {
        return daysFinance > 0;
    }

//    // todo refactor this...currently building on existing functionality...
//    public RateSourceType getRateSource(String forexGroupName) {
//        Rule rule = getRuleWithCode(FOREX_GROUP_RATE_SOURCE_RULE_CODE);
//        if (rule != null) {
//            RuleAttribute attribute = rule.getAttributeWithCode("forex_group_" + forexGroupName.replaceAll(" ", "_"));
//            if (attribute != null && attribute.getValue() != null && !attribute.getValue().isEmpty()) {
//                return RateSourceType.valueOf(attribute.getValue());
//            }
//        }
//        return null;
//    }

    public String getStateAsXML() {
        StringBuilder builder = new StringBuilder();
        builder.append("<division>");
        builder.append("<id>");
        builder.append(getId());
        builder.append("</id>");
        builder.append("<code>");
        builder.append(code);
        builder.append("</code>");
        builder.append("<name>");
        builder.append(getName());
        builder.append("</name>");
        builder.append("</division>");
        return builder.toString();
    }

    public RateSourceType getRatesSource() {
        return ratesSource;
    }

    public void setRatesSource(RateSourceType ratesSource) {
        this.ratesSource = ratesSource;
    }

    public static OrganisationalUnit valueOf(String code, String name, int daysFinance, RateSourceType ratesSource,
                                             Percentage spot, Percentage forward) {
        OrganisationalUnit orgUnit = new OrganisationalUnit(code, name, null);
        orgUnit.setSpotRateMargin(spot);
        orgUnit.setForwardRateMargin(forward);
        orgUnit.setRatesSource(ratesSource);
        orgUnit.setDaysFinance(daysFinance);
        return orgUnit;
    }

    public void addChild(OrganisationalUnit child) {
        child.setParent(this);
        getChildren().add(child);
    }

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

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!HibernateUtils.proxyClassEquals(this, obj)) {
            return false;
        }
        OrganisationalUnit other = (OrganisationalUnit) obj;
        return new EqualsBuilder().append(code, other.getCode()).append(name, other.getName()).isEquals();
    }

    @Override
    public int compareTo(OrganisationalUnit o) {
        /*
         * if (name != null && o.name != null) { return name.compareTo(o.name); } else
         */
        if (code != null && o.code != null) {
            return code.compareTo(o.code);
        }
        return 0;
    }

    public boolean isLegalEntity() {
        return isLegalEntity;
    }

    public void setLegalEntity(boolean legalEntity) {
        isLegalEntity = legalEntity;
    }

    public boolean isCustomsValueRequired() {
        return isCustomsValueRequired;
    }

    public void setCustomsValueRequired(boolean customsValueRequired) {
        isCustomsValueRequired = customsValueRequired;
    }

    public Set<OrganisationalUnitSupplier> getSuppliers() {
        return organisationalUnitSuppliers;
    }

    public void setOrganisationalUnitSuppliers(Set<OrganisationalUnitSupplier> suppliers) {
        this.organisationalUnitSuppliers = suppliers;
    }

    public Set<ServiceProvider> getServiceProviders() {
        return serviceProviders;
    }

    public void setServiceProviders(Set<ServiceProvider> serviceProviders) {
        this.serviceProviders = serviceProviders;
    }

    public Set<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(Set<Employee> employees) {
        this.employees = employees;
    }

    public Set<OrganisationalUnitAgent> getAgents() {
        return organisationalUnitAgents;
    }

    public void setOrganisationalUnitAgents(Set<OrganisationalUnitAgent> agents) {
        this.organisationalUnitAgents = agents;
    }

    @JsonIgnore
    public OrganisationalUnit getRootNode() {
        return getParent() != null ? getParent().getRootNode() : this;
    }

    /**
     * Add this org unit to the set of matching org units and also all it's children
     * (recursively).
     *
     * @param matching
     */
    @JsonIgnore
    public void getAllOrgUnitsDown(Set<OrganisationalUnit> matching) {

        // Add this if it's an active org unit
        if (getActive() && !matching.equals(this)) {
            matching.add(this);
        }

        // Now add all children and their childrens childrens children
        // (infinity)
        for (OrganisationalUnit organisationalUnit : getChildren()) {
            organisationalUnit.getAllOrgUnitsDown(matching);
        }
    }

    public OrganisationalUnitTier getTier() {
        return tier;
    }

    public void setTier(OrganisationalUnitTier tier) {
        this.tier = tier;
    }

    public boolean isLetterOfCreditApplicant() {
        return letterOfCreditApplicant;
    }

    public void setLetterOfCreditApplicant(boolean letterOfCreditApplicant) {
        this.letterOfCreditApplicant = letterOfCreditApplicant;
    }

    @Override
    public String sortByString() {
        return getCode();
    }

    /**
     * Add this org unit to the set of matching org units and also all it's children
     * (recursively).
     *
     * @param matching
     */
    @JsonIgnore
    public void getAllOrgUnitsUp(List<OrganisationalUnit> matching) {

        // Add this if it's an active org unit
        if (getActive()) {
            matching.add(this);
        }

        // Now add all children and their childrens childrens children
        // (infinity)
        if (getParent() != null) {
            getParent().getAllOrgUnitsUp(matching);
        }
    }

    public String getCodeForShippingReference() {
        return codeForShippingReference;
    }

    public void setCodeForShippingReference(String codeForShippingReference) {
        this.codeForShippingReference = codeForShippingReference;
    }

    public Integer getNextOrderShippingRefCounterValue() {
        if (orderShippingRefAtomicCounter == null) {
            if (orderShippingRefCounter == null || orderShippingRefCounter == 0) {
                orderShippingRefAtomicCounter = new AtomicInteger(0);
            } else {
                orderShippingRefAtomicCounter = new AtomicInteger(orderShippingRefCounter);
            }
        }
        orderShippingRefCounter = orderShippingRefAtomicCounter.incrementAndGet();
        return orderShippingRefCounter;
    }

    public SwiftCompliantAddress getSwiftCompliantAddress() {
        return swiftCompliantAddress;
    }

    public void setSwiftCompliantAddress(SwiftCompliantAddress swiftCompliantAddress) {
        this.swiftCompliantAddress = swiftCompliantAddress;
    }

    public String getCustomsCode() {
        return customsCode;
    }

    public void setCustomsCode(String customsCode) {
        this.customsCode = customsCode;
    }

    public String getSalesTaxRegistrationNumber() {
        return salesTaxRegistrationNumber;
    }

    public void setSalesTaxRegistrationNumber(String salesTaxRegistrationNumber) {
        this.salesTaxRegistrationNumber = salesTaxRegistrationNumber;
    }

    public String getVatRegistrationNumber() {
        return vatRegistrationNumber;
    }

    public void setVatRegistrationNumber(String vatRegistrationNumber) {
        this.vatRegistrationNumber = vatRegistrationNumber;
    }

    public String getCompanyRegistrationNumber() {
        return companyRegistrationNumber;
    }

    public void setCompanyRegistrationNumber(String companyRegistrationNumber) {
        this.companyRegistrationNumber = companyRegistrationNumber;
    }

    public Logo getLogoImage() {
        return logoImage;
    }

    public void setLogoImage(Logo logoImage) {
        this.logoImage = logoImage;
    }

    public byte[] getImage() {
        return (logoImage != null) ? logoImage.getImage() : null;
    }

    public Long getLogoImageId() {
        if (logoImage instanceof HibernateProxy) {
            LazyInitializer lazyInitializer = ((HibernateProxy) logoImage).getHibernateLazyInitializer();
            if (lazyInitializer.isUninitialized()) {
                return (Long) lazyInitializer.getIdentifier();
            }
        }
        return logoImage.getId();
    }

    public boolean isAllowsSuppliers() {
        return allowsSuppliers;
    }

    public void setAllowsSuppliers(boolean allowsSuppliers) {
        this.allowsSuppliers = allowsSuppliers;
    }

    public boolean isAllowsAgents() {
        return allowsAgents;
    }

    public void setAllowsAgents(boolean allowsAgents) {
        this.allowsAgents = allowsAgents;
    }

    public boolean isAllowsServiceProviders() {
        return allowsServiceProviders;
    }

    public void setAllowsServiceProviders(boolean allowsServiceProviders) {
        this.allowsServiceProviders = allowsServiceProviders;
    }

    @Override
    public Class getInstanceClass() {
        return OrganisationalUnit.class;
    }

    public boolean isAllowSampleAndSparePart() {
        return allowSampleAndSparePart;
    }

    public void setAllowSampleAndSparePart(boolean allowSampleAndSparePart) {
        this.allowSampleAndSparePart = allowSampleAndSparePart;
    }

    public boolean isSabsEnabled() {
        return sabsEnabled;
    }

    public void setSabsEnabled(boolean sabsEnabled) {
        this.sabsEnabled = sabsEnabled;
    }

    public List<ServiceFee> getServiceFeeList() {
        return serviceFeeList;
    }

    public void setServiceFeeList(List<ServiceFee> serviceFeeList) {
        this.serviceFeeList = serviceFeeList;
    }

    public List<MarginPercentage> getMarginPercentageList() {
        return marginPercentageList;
    }

    public void setMarginPercentageList(List<MarginPercentage> marginPercentageList) {
        this.marginPercentageList = marginPercentageList;
    }

    public List<PrimeInterestRate> getPrimeInterestRateList() {
        return primeInterestRateList;
    }

    public void setPrimeInterestRateList(List<PrimeInterestRate> primeInterestRateList) {
        this.primeInterestRateList = primeInterestRateList;
    }

    public int getCreditTerm() {
        return creditTerm;
    }

    public void setCreditTerm(int creditTerm) {
        this.creditTerm = creditTerm;
    }

    public Set<PaymentBasisKeyValue> getPaymentBasisKeyValues() {
        return paymentBasisKeyValues;
    }

    public void setPaymentBasisKeyValues(Set<PaymentBasisKeyValue> paymentBasisKeyValues) {
        this.paymentBasisKeyValues = paymentBasisKeyValues;
    }

    public BigDecimal getContainerUtilization() {
        return containerUtilization;
    }

    public void setContainerUtilization(BigDecimal containerUtilization) {
        this.containerUtilization = containerUtilization;
    }

    public Type getType() {
        return type;
    }

    public void setType(Type type) {
        this.type = type;
    }

    public List<Contact> getContacts() {
        return contacts;
    }

    public void setContacts(List<Contact> contacts) {
        this.contacts = contacts;
    }

    public boolean isFullType() {
        return this.type == OrganisationalUnit.Type.FULL;
    }

    public ExternalApiConfiguration getExternalApiConfiguration() {
        return externalApiConfiguration;
    }

    public void setExternalApiConfiguration(ExternalApiConfiguration externalApiConfiguration) {
        this.externalApiConfiguration = externalApiConfiguration;
    }

    public String getAccountNumber() {
        return accountNumber;
    }

    public void setAccountNumber(String accountNumber) {
        this.accountNumber = accountNumber;
    }

    public CustomsClearanceDeclarationLevel getCustomsClearanceDeclarationLevel() {
        return customsClearanceDeclarationLevel;
    }

    public void setCustomsClearanceDeclarationLevel(CustomsClearanceDeclarationLevel customsClearanceDeclarationLevel) {
        this.customsClearanceDeclarationLevel = customsClearanceDeclarationLevel;
    }

    public boolean isConsignee() {
        return consignee;
    }

    public void setConsignee(boolean consignee) {
        this.consignee = consignee;
    }

    @Deprecated
    public boolean isUniqueLineNumber() {
        return uniqueLineNumber;
    }

    public void setUniqueLineNumber(boolean uniqueLineNumber) {
        this.uniqueLineNumber = uniqueLineNumber;
    }

    public List<CustomsAccount> getCustomsAccounts() {
        return customsAccounts;
    }

    public void setCustomsAccounts(List<CustomsAccount> customsAccounts) {
        this.customsAccounts = customsAccounts;
    }

    public String getBulkOrderNumber() {
        return bulkOrderNumber;
    }

    public void setBulkOrderNumber(String bulkOrderNumber) {
        this.bulkOrderNumber = bulkOrderNumber;
    }

    public String getInsurancePolicyNumber() {
        return insurancePolicyNumber;
    }

    public void setInsurancePolicyNumber(String insurancePolicyNumber) {
        this.insurancePolicyNumber = insurancePolicyNumber;
    }

    public String getInsurer() {
        return insurer;
    }

    public void setInsurer(String insurer) {
        this.insurer = insurer;
    }

    public String getLogoFileName() {
        if (logoImage != null)
            return logoImage.getFileName();
        return null;
    }

    public boolean isUseOnIntegrationEvents() {
        return useOnIntegrationEvents;
    }

    public void setUseOnIntegrationEvents(boolean useOnIntegrationEvents) {
        this.useOnIntegrationEvents = useOnIntegrationEvents;
    }

    public boolean isStockLevel() {
        return stockLevel;
    }

    public void setStockLevel(boolean stockLevel) {
        this.stockLevel = stockLevel;
    }

    public static String getRuleAttribute(ForexGroup forexGroup) {
        return "forex_group_" + forexGroup.getName().replaceAll(" ", "_");
    }
}