AbstractItem.java
package com.tradecloud.domain.item;
import com.tradecloud.common.base.HibernateUtils;
import com.tradecloud.common.base.PersistenceBase;
import com.tradecloud.domain.common.Currency;
import com.tradecloud.domain.configuration.clearing.za.PenaltyType;
import com.tradecloud.domain.configuration.clearing.za.TypeOfGoods;
import com.tradecloud.domain.duties.*;
import com.tradecloud.domain.model.organisationalunit.Brand;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.domain.place.Country;
import com.tradecloud.domain.place.NamedPlace;
import com.tradecloud.domain.sabs.SABSTariff;
import com.tradecloud.domain.supplier.OrganisationalUnitSupplier;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.hibernate.annotations.ForeignKey;
import org.springframework.util.DigestUtils;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* Commonality for all items.
* These fields provide the uniqueness of an item:
* 1. {@link #code} 2. {@link #supplier} 3. {@link #organisationalUnit} 4.
* {@link #countryOfOrigin}
*
* @see Product
* @see LineItem
*/
@XmlAccessorType(XmlAccessType.FIELD)
@MappedSuperclass
public abstract class AbstractItem extends PersistenceBase implements ItemInterface {
private static final long serialVersionUID = 1L;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "supplier_id")
@ForeignKey(name = "fk_supplier")
@XmlElement(name = "Supplier", required = true)
protected OrganisationalUnitSupplier supplier;
@XmlAttribute
protected String supplierReference;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "organisationalunit_id")
@ForeignKey(name = "fk_organisationalunit")
@XmlElement(name = "OrganisationalUnit", required = true)
@NotNull(message = "Organisational unit is a required field")
protected OrganisationalUnit organisationalUnit;
/**
* Country of Origin is needed at item level for tariffing:
* 1. It needs to have a drop down list of countries. 2. If the COO is
* populated at order level, all items should get that value as a default,
* BUT a user should be able to edit any item's COO and change it 3. The
* country of origin can sometimes be received from the ERP system. This is
* at an item level 4. If you change the COO on order level it should change
* all items COO
* Country of origin at the order level is stored inside
* {@link com.tradecloud.domain.model.ordermanagement.Order#getShippingInformation()}.
*/
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "countryoforigin_code")
@ForeignKey(name = "fk_countryoforigin")
@XmlElement(name = "CountryOfOrigin", required = true)
protected Country countryOfOrigin;
@ManyToOne
@JoinColumn(name = "currency_code")
@ForeignKey(name = "fk_currency")
@XmlElement(name = "Currency", required = true)
protected Currency currency;
@ManyToOne
@JoinColumn(name = "supply_currency_code")
@ForeignKey(name = "fk_currency")
@XmlElement(name = "Currency", required = true)
protected Currency supplyCurrency;
@ManyToOne
@JoinColumn(name = "sale_currency_code")
@ForeignKey(name = "fk_currency")
@XmlElement(name = "Currency", required = true)
protected Currency saleCurrency;
@ManyToOne
@JoinColumn(name = "weightuom_code")
@ForeignKey(name = "fk_weightuom")
@XmlElement(name = "WeightUnitOfMeasure")
protected WeightUnitOfMeasure weightUOM;
@ManyToOne
@JoinColumn(name = "volumeuom_code")
@ForeignKey(name = "fk_volumeuom")
@XmlElement(name = "VolumeUnitOfMeasure")
protected VolumeUnitOfMeasure volumeUOM;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@ForeignKey(name = "fk_schedule1Part1A")
@XmlElement(name = "Schedule1Part1A")
protected Schedule1Part1A schedule1Part1A;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@ForeignKey(name = "fk_schedule1Part2A")
@XmlElement(name = "Schedule1Part2A")
protected Schedule1Part2A schedule1Part2A;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@ForeignKey(name = "fk_schedule1Part2B")
@XmlElement(name = "Schedule1Part2B")
protected Schedule1Part2B schedule1Part2B;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@ForeignKey(name = "fk_schedule2Part1")
@XmlElement(name = "Schedule2Part1")
protected Schedule2Part1 schedule2Part1;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@ForeignKey(name = "fk_schedule2Part2")
@XmlElement(name = "Schedule2Part2")
protected Schedule2Part2 schedule2Part2;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@ForeignKey(name = "fk_schedule1Part3E")
@XmlElement(name = "Schedule1Part3E")
protected Schedule1Part3E schedule1Part3E;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@ForeignKey(name = "fk_schedule1Part7")
@XmlElement(name = "Schedule1Part7")
protected Schedule1Part7 schedule1Part7;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@ForeignKey(name = "fk_schedule3Part1")
@XmlElement(name = "Schedule3Part1")
protected Schedule3Part1 schedule3Part1;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@ForeignKey(name = "fk_schedule4Part1")
@XmlElement(name = "Schedule4Part1")
protected Schedule4Part1 schedule4Part1;
@NotNull(message = "Item reference code is required")
@Size(max = 255, message = "item reference cannot exceed 255 characters")
@XmlAttribute(required = true)
@XmlID
protected String code;
@NotNull(message = "Item description is required")
@XmlAttribute(required = true)
protected String description;
@XmlAttribute
protected String barcode;
@XmlAttribute
@Column(precision = 27, scale = 10)
protected BigDecimal unitWeight;
@XmlAttribute
@Column(precision = 27, scale = 10)
protected BigDecimal unitVolume;
@XmlAttribute
@Column(precision = 27, scale = 10)
protected BigDecimal unitPrice;
@XmlElement
@Column(precision = 19, scale = 4)
protected BigDecimal unitsPerPackage;
@XmlTransient
@Column(precision = 27, scale = 10)
protected BigDecimal packageVolume;
@XmlAttribute
@Column(precision = 6, scale = 2)
protected BigDecimal packageHeight;
@XmlAttribute
@Column(precision = 6, scale = 2)
protected BigDecimal packageWidth;
@XmlAttribute
@Column(precision = 6, scale = 2)
protected BigDecimal packageLength;
@XmlAttribute
@Column(precision = 19, scale = 4)
protected BigDecimal packageWeight;
@ManyToOne
@ForeignKey(name = "fk_sabstariff")
@XmlElement(name = "SABSTariff")
protected SABSTariff sabsTariff;
@ManyToOne
@ForeignKey(name = "fk_sabstariff2")
@XmlElement(name = "SABSTariff2")
protected SABSTariff sabsTariff2;
@XmlAttribute
protected String styleReference;
@XmlAttribute
protected String styleDescription;
@XmlAttribute
protected String elcReference;
private boolean dangerousGoods;
protected BigDecimal unitWidth;
protected BigDecimal unitHeight;
protected BigDecimal unitLength;
@ManyToOne
@XmlElement(name = "baseCategory")
private ItemCategory itemCategory;
private String tariffDeterminationNumber;
private String hashTariff;
private BigDecimal containerUtilization;
private String sarsTariffUpdateReason;
private Long templateId;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "valuedeterminationnumber_id")
@XmlTransient
protected ValueDeterminationNumber valueDeterminationNumber = new ValueDeterminationNumber();
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "itacPermit_id")
@XmlTransient
protected ItacPermit itacPermit = new ItacPermit();
@ManyToOne
protected NamedPlace factory;
@Enumerated(EnumType.STRING)
protected TypeOfGoods typeOfGoods = TypeOfGoods.NEW_GOODS;
@Enumerated(EnumType.STRING)
protected PenaltyType penaltyType;
@ManyToOne
protected Brand brand;
public AbstractItem() {
}
public OrganisationalUnitSupplier getSupplier() {
return supplier;
}
public void setSupplier(OrganisationalUnitSupplier supplier) {
this.supplier = supplier;
}
public String getSupplierReference() {
return supplierReference;
}
public void setSupplierReference(String supplierReference) {
this.supplierReference = supplierReference;
}
public OrganisationalUnit getOrganisationalUnit() {
return organisationalUnit;
}
public void setOrganisationalUnit(OrganisationalUnit organisationalUnit) {
this.organisationalUnit = organisationalUnit;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getBarcode() {
return barcode;
}
public void setBarcode(String barcode) {
this.barcode = barcode;
}
public BigDecimal getUnitWeight() {
return unitWeight;
}
public void setUnitWeight(BigDecimal unitWeight) {
this.unitWeight = unitWeight;
}
public BigDecimal getUnitVolume() {
// if (unitVolume != null && !MathUtils.isZero(unitVolume)) {
// return unitVolume;
// }
// if (unitHeight != null && unitWidth != null && unitLength != null && !MathUtils.isZero(unitLength) && !MathUtils.isZero(unitHeight)
// && !MathUtils.isZero(unitWidth)) {
// return MathUtils.setScale(unitHeight.multiply(unitLength).multiply(unitWidth), MathUtils.SCALE_VERY_ACCURATE);
// }
// return (packageVolume != null && unitsPerPackage != null && !MathUtils.isZero(unitsPerPackage) && !MathUtils.isZero(packageVolume))
// ? packageVolume.divide(unitsPerPackage, MathUtils.SCALE, MathUtils.ROUNDING_MODE)
// : (unitVolume != null ? unitVolume : BigDecimal.ZERO);
// ItemProductUtil.calculateAndSetVolume(this, this.packageVolume, this.unitVolume);
return this.unitVolume;
}
public void setUnitVolume(BigDecimal unitVolume) {
this.unitVolume = unitVolume;
}
public BigDecimal getUnitPrice() {
return unitPrice != null ? unitPrice : BigDecimal.ZERO;
}
public void setUnitPrice(BigDecimal unitPrice) {
this.unitPrice = unitPrice;
}
public BigDecimal getUnitsPerPackage() {
return unitsPerPackage;
}
public void setUnitsPerPackage(BigDecimal unitsPerPackage) {
this.unitsPerPackage = unitsPerPackage;
}
public WeightUnitOfMeasure getWeightUOM() {
return weightUOM;
}
public void setWeightUOM(WeightUnitOfMeasure weightUOM) {
this.weightUOM = weightUOM;
}
public Country getCountryOfOrigin() {
return countryOfOrigin;
}
public void setCountryOfOrigin(Country countryOfOrigin) {
this.countryOfOrigin = countryOfOrigin;
}
public VolumeUnitOfMeasure getVolumeUOM() {
return volumeUOM;
}
public void setVolumeUOM(VolumeUnitOfMeasure volumeUOM) {
this.volumeUOM = volumeUOM;
}
public Currency getCurrency() {
return currency;
}
public void setCurrency(Currency currency) {
this.currency = currency;
}
public Schedule1Part1A getSchedule1Part1A() {
return schedule1Part1A;
}
public void setSchedule1Part1A(Schedule1Part1A schedule1Part1A) {
this.schedule1Part1A = schedule1Part1A;
}
public Schedule1Part2A getSchedule1Part2A() {
return schedule1Part2A;
}
public void setSchedule1Part2A(Schedule1Part2A schedule1Part2A) {
this.schedule1Part2A = schedule1Part2A;
}
public Schedule1Part2B getSchedule1Part2B() {
return schedule1Part2B;
}
public void setSchedule1Part2B(Schedule1Part2B schedule1Part2B) {
this.schedule1Part2B = schedule1Part2B;
}
public Schedule2Part1 getSchedule2Part1() {
return schedule2Part1;
}
public void setSchedule2Part1(Schedule2Part1 schedule2Part1) {
this.schedule2Part1 = schedule2Part1;
}
public Schedule2Part2 getSchedule2Part2() {
return schedule2Part2;
}
public void setSchedule2Part2(Schedule2Part2 schedule2Part2) {
this.schedule2Part2 = schedule2Part2;
}
public Schedule1Part3E getSchedule1Part3E() {
if (schedule1Part3E == null) {
schedule1Part3E = new Schedule1Part3E();
}
return schedule1Part3E;
}
public void setSchedule1Part3E(Schedule1Part3E schedule1Part3E) {
this.schedule1Part3E = schedule1Part3E;
}
public void setSchedule1Part7(Schedule1Part7 schedule1Part7) {
this.schedule1Part7 = schedule1Part7;
}
public Schedule1Part7 getSchedule1Part7() {
if (schedule1Part7 == null) {
schedule1Part7 = new Schedule1Part7();
}
return schedule1Part7;
}
public Schedule3Part1 getSchedule3Part1() {
if (schedule3Part1 == null) {
schedule3Part1 = new Schedule3Part1();
}
return schedule3Part1;
}
public void setSchedule3Part1(Schedule3Part1 schedule3Part1) {
this.schedule3Part1 = schedule3Part1;
}
public Schedule4Part1 getSchedule4Part1() {
if (schedule4Part1 == null) {
schedule4Part1 = new Schedule4Part1();
}
return schedule4Part1;
}
public void setSchedule4Part1(Schedule4Part1 schedule4Part1) {
this.schedule4Part1 = schedule4Part1;
}
public SABSTariff getSabsTariff() {
return sabsTariff;
}
public void setSabsTariff(SABSTariff sabsTariff) {
this.sabsTariff = sabsTariff;
}
public SABSTariff getSabsTariff2() {
return sabsTariff2;
}
public void setSabsTariff2(SABSTariff sabsTariff2) {
this.sabsTariff2 = sabsTariff2;
}
// Hack. Kind of. Overkill to store them in an array.
public SABSTariff findSABSTariff(int index) {
return index == 1 ? sabsTariff : sabsTariff2;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this == obj) {
return true;
}
AbstractItem other = (AbstractItem) obj;
return new EqualsBuilder()
.append(countryOfOrigin, other.getCountryOfOrigin())
.append(code, other.getCode())
.append(organisationalUnit, other.getOrganisationalUnit())
.append(currency, other.getCurrency())
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder()
.append(countryOfOrigin)
.append(code)
.append(organisationalUnit != null ? organisationalUnit.hashCode() : null)
.append(currency)
// .append(unitPrice)
// .append(description)
// .append(supplierReference)
.toHashCode();
}
@Override
public String toString() {
return new StringBuilder().append(code).append(" ").append(description).append(" ").append(supplier.getName()).append(" ")
.append(countryOfOrigin.getCode()).append(" ").append(currency.getCode()).append(" ").append(unitPrice).append(" ")
.append(supplierReference).append(" ").toString();
}
public String getStyleReference() {
return styleReference;
}
public void setStyleReference(String styleReference) {
this.styleReference = styleReference;
}
public String getStyleDescription() {
return styleDescription;
}
public void setStyleDescription(String styleDescription) {
this.styleDescription = styleDescription;
}
public Currency getSupplyCurrency() {
return supplyCurrency;
}
public void setSupplyCurrency(Currency supplyCurrency) {
this.supplyCurrency = supplyCurrency;
}
public Currency getSaleCurrency() {
return saleCurrency;
}
public void setSaleCurrency(Currency saleCurrency) {
this.saleCurrency = saleCurrency;
}
public BigDecimal getPackageVolume() {
return packageVolume != null ? packageVolume : BigDecimal.ZERO;
}
public void setPackageVolume(BigDecimal packageVolume) {
this.packageVolume = packageVolume;
}
public BigDecimal getPackageHeight() {
return packageHeight != null ? packageHeight : BigDecimal.ZERO;
}
public void setPackageHeight(BigDecimal packageHeight) {
this.packageHeight = packageHeight;
}
public BigDecimal getPackageWidth() {
return packageWidth != null ? packageWidth : BigDecimal.ZERO;
}
public void setPackageWidth(BigDecimal packageWidth) {
this.packageWidth = packageWidth;
}
public BigDecimal getPackageLength() {
return packageLength != null ? packageLength : BigDecimal.ZERO;
}
public void setPackageLength(BigDecimal packageLength) {
this.packageLength = packageLength;
}
public BigDecimal getPackageWeight() {
return packageWeight != null ? packageWeight : BigDecimal.ZERO;
}
public void setPackageWeight(BigDecimal packageWeight) {
this.packageWeight = packageWeight;
}
public boolean isDangerousGoods() {
return dangerousGoods;
}
public void setDangerousGoods(boolean dangerousGoods) {
this.dangerousGoods = dangerousGoods;
}
public BigDecimal getUnitWidth() {
return unitWidth;
}
public BigDecimal getUnitHeight() {
return unitHeight;
}
public BigDecimal getUnitLength() {
return unitLength;
}
public void setUnitWidth(BigDecimal unitWidth) {
this.unitWidth = unitWidth;
}
public void setUnitHeight(BigDecimal unitHeight) {
this.unitHeight = unitHeight;
}
public void setUnitLength(BigDecimal unitLength) {
this.unitLength = unitLength;
}
public ItemCategory getItemCategory() {
return itemCategory;
}
public void setItemCategory(ItemCategory itemCategory) {
this.itemCategory = itemCategory;
}
public String getElcReference() {
return elcReference;
}
public void setElcReference(String elcReference) {
this.elcReference = elcReference;
}
public String getTariffDeterminationNumber() {
return tariffDeterminationNumber;
}
public void setTariffDeterminationNumber(String tariffDeterminationNumber) {
this.tariffDeterminationNumber = tariffDeterminationNumber;
}
public String getHashTariff() {
return hashTariff;
}
public void setHashTariff(String hashTariff) {
this.hashTariff = hashTariff;
}
public String generateTariffHash() {
StringBuilder sb = new StringBuilder();
if (schedule1Part1A.getTariffHeading() != null) {
sb.append(schedule1Part1A.getTariffHeading().getTariffHeading());
}
if (schedule1Part1A.getTradeAgreement() != null) {
sb.append(schedule1Part1A.getTradeAgreement());
}
if (schedule1Part1A.getDutyRate() != null) {
if (schedule1Part1A.getDutyRate().getValue() != null) {
sb.append(schedule1Part1A.getDutyRate().getValue().setScale(2, RoundingMode.UP));
}
if (schedule1Part1A.getDutyRate().getPercentage() != null) {
sb.append(schedule1Part1A.getDutyRate().getPercentage().setScale(2, RoundingMode.UP));
}
}
if (schedule1Part1A.getDutyRate().getOtherDuty1() != null) {
if (schedule1Part1A.getDutyRate().getOtherDuty1().getValue() != null) {
sb.append(schedule1Part1A.getDutyRate().getOtherDuty1().getValue().setScale(2, RoundingMode.UP));
}
if (schedule1Part1A.getDutyRate().getOtherDuty1().getProof() != null) {
sb.append(schedule1Part1A.getDutyRate().getOtherDuty1().getProof().setScale(2, RoundingMode.UP));
}
}
return DigestUtils.md5DigestAsHex(sb.toString().getBytes());
}
public BigDecimal getContainerUtilization() {
return containerUtilization;
}
public void setContainerUtilization(BigDecimal containerUtilization) {
this.containerUtilization = containerUtilization;
}
public abstract void setPackageType(PackageType packageType);
public abstract PackageType getPackageType();
public abstract void setUnitType(UnitType unitType);
public abstract UnitType getUnitType();
public abstract BigDecimal getUnitQuantity();
public abstract void setUnitQuantity(BigDecimal unitQuantity);
@Override
public boolean isLineItem() {
return false;
}
@Override
public void setSarsTariffUpdateReason(String sarsTariffUpdateReason) {
this.sarsTariffUpdateReason = sarsTariffUpdateReason;
}
@Override
public String getSarsTariffUpdateReason() {
return sarsTariffUpdateReason;
}
@Override
public String getOrganisationalUnitCode() {
return organisationalUnit.getCode();
}
@Override
public ValueDeterminationNumber getValueDeterminationNumber() {
return valueDeterminationNumber;
}
@Override
public void setValueDeterminationNumber(ValueDeterminationNumber valueDeterminationNumber) {
this.valueDeterminationNumber = valueDeterminationNumber;
}
@Override
public ItacPermit getItacPermit() {
if (itacPermit == null) {
itacPermit = new ItacPermit();
}
return itacPermit;
}
@Override
public void setItacPermit(ItacPermit itacPermit) {
this.itacPermit = itacPermit;
}
@Override
public TypeOfGoods getTypeOfGoods() {
return typeOfGoods;
}
@Override
public void setTypeOfGoods(TypeOfGoods typeOfGoods) {
this.typeOfGoods = typeOfGoods;
if (typeOfGoods != null && !typeOfGoods.equals(TypeOfGoods.NEW_GOODS)) {
getItacPermit().setItacPermit(ItacPermitOptions.YES);
}
}
@Override
public PenaltyType getPenaltyType() {
return penaltyType;
}
@Override
public void setPenaltyType(PenaltyType penaltyType) {
this.penaltyType = penaltyType;
}
public Long getTemplateId() {
return templateId;
}
public void setTemplateId(Long templateId) {
this.templateId = templateId;
}
public NamedPlace getFactory() {
return factory;
}
public void setFactory(NamedPlace factory) {
this.factory = factory;
}
public Brand getBrand() {
return brand;
}
public void setBrand(Brand brand) {
this.brand = brand;
}
@Override
public PersistenceBase initialize() {
if (getSchedule1Part1A() != null)
setSchedule1Part1A(HibernateUtils.initializeAndUnproxy(getSchedule1Part1A()));
if (getSchedule1Part2B() != null)
setSchedule1Part2B(HibernateUtils.initializeAndUnproxy(getSchedule1Part2B()));
if (getSchedule1Part2A() != null)
setSchedule1Part2A(HibernateUtils.initializeAndUnproxy(getSchedule1Part2A()));
if (getSchedule2Part1() != null)
setSchedule2Part1(HibernateUtils.initializeAndUnproxy(getSchedule2Part1()));
if (getSchedule2Part2() != null)
setSchedule2Part2(HibernateUtils.initializeAndUnproxy(getSchedule2Part2()));
if (getSchedule1Part3E() != null)
setSchedule1Part3E(HibernateUtils.initializeAndUnproxy(getSchedule1Part3E()));
if (getSchedule1Part7() != null)
setSchedule1Part7(HibernateUtils.initializeAndUnproxy(getSchedule1Part7()));
if (getSchedule3Part1() != null)
setSchedule3Part1(HibernateUtils.initializeAndUnproxy(getSchedule3Part1()));
if (getSchedule4Part1() != null)
setSchedule4Part1(HibernateUtils.initializeAndUnproxy(getSchedule4Part1()));
return super.initialize();
}
}