/*
- * Copyright (C) 2016, 2017 Roland Häder
+ * Copyright (C) 2016 - 2018 Free Software Foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*/
package org.mxchange.jproduct.model.product;
+import java.math.BigDecimal;
+import java.text.MessageFormat;
import java.util.Date;
import java.util.Objects;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
+import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
+import org.apache.commons.lang3.StringUtils;
import org.mxchange.jcontactsbusiness.model.basicdata.BasicData;
+import org.mxchange.jcontactsbusiness.model.basicdata.BasicDataUtils;
import org.mxchange.jcontactsbusiness.model.basicdata.BusinessBasicData;
+import org.mxchange.jcoreutils.Comparables;
+import org.mxchange.jcoreutils.SafeNumberUtils;
+import org.mxchange.jproduct.model.category.Categories;
import org.mxchange.jproduct.model.category.Category;
import org.mxchange.jproduct.model.category.ProductCategory;
+import org.mxchange.jproduct.model.product.agegroup.AgeGroup;
/**
- * Generic product class
+ * Generic product POJO (entity)
* <p>
* @author Roland Häder<roland@mxchange.org>
- * TODO: Find a better name
*/
@Entity (name = "generic_products")
-@Table (name = "generic_products")
+@Table (
+ name = "generic_products",
+ indexes = {
+ @Index (
+ name = "idx_i18n_age_size",
+ columnList = "product_i18n_key,product_age_group,product_size",
+ unique = true
+ )
+ }
+)
@NamedQueries (
{
@NamedQuery (name = "AllProducts", query = "SELECT p FROM generic_products AS p ORDER BY p.productId ASC"),
@Transient
private static final long serialVersionUID = 54_578_571_769_283L;
+ /**
+ * Product's age group (if any)
+ */
+ @Column (name = "product_age_group")
+ @Enumerated (EnumType.STRING)
+ private AgeGroup productAgeGroup;
+
/**
* Availability of product
*/
private Date productCreated;
/**
- * Currency code for both prices
+ * Currency code for both prices, like EUR or USD
*/
+ @Basic (optional = false)
+ @Column (name = "product_currency_code", nullable = false, length = 3)
private String productCurrencyCode;
/**
* Gross price of product
*/
@Basic (optional = false)
- @Column (name = "product_gross_price", nullable = false)
- private Float productGrossPrice;
+ @Column (name = "product_gross_price", nullable = false, precision = 10, scale = 4)
+ private BigDecimal productGrossPrice;
+
+ /**
+ * I18n key of product
+ */
+ @Basic (optional = false)
+ @Column (name = "product_i18n_key", length = 100, nullable = false)
+ private String productI18nKey;
/**
* Id number of product
/**
* The company that has manufactured/produced this product
*/
- @JoinColumn(name = "product_manufacturer_id", referencedColumnName = "company_data_id")
- @OneToOne(targetEntity = BusinessBasicData.class, cascade = CascadeType.REFRESH)
- private BasicData productManfacturer;
+ @JoinColumn (name = "product_manufacturer_id", referencedColumnName = "company_data_id")
+ @OneToOne (targetEntity = BusinessBasicData.class, cascade = CascadeType.REFRESH)
+ private BasicData productManufacturer;
/**
* Net price of product
*/
- @Column (name = "product_net_price")
- private Float productNetPrice;
+ @Column (name = "product_net_price", precision = 10, scale = 4)
+ private BigDecimal productNetPrice;
/**
- * Tax rate (0-1, by 1=100%)
+ * Number of product
*/
- @Column (name = "product_tax_rate")
- private Float productTaxRate;
+ @Column (name = "product_number")
+ private Long productNumber;
/**
- * Title of product
+ * Product size (like for shoes, clothing)
*/
- @Basic (optional = false)
- @Column (name = "product_title", length = 100, nullable = false, unique = true)
- private String productTitle;
+ @Column (name = "product_size", length = 10)
+ private String productSize;
+
+ /**
+ * Tax rate (0-1, by 1=100%)
+ */
+ @Column (name = "product_tax_rate", precision = 3, scale = 1)
+ private BigDecimal productTaxRate;
/**
* Amount of this product (for example 1 for 1 liter)
*/
- @Column (name = "product_unit_amount")
- private Float productUnitAmount;
+ @Basic (optional = false)
+ @Column (name = "product_unit_amount", nullable = false, precision = 10, scale = 2)
+ private BigDecimal productUnitAmount;
/**
* Unit type (for example liter)
*/
- @Column (name = "product_unit_type")
- private String productUnitType;
+ @Basic (optional = false)
+ @Column (name = "product_unit_i18n_key", nullable = false)
+ private String productUnitI18nKey;
/**
* Default constructor
/**
* Constructor will all required data
* <p>
- * @param productTitle Name of product
+ * @param productI18nKey I18n key of product
* @param productGrossPrice Product's gross price
- * @param productCurrencyCode code for both prices
+ * @param productCurrencyCode Currency code for both prices
* @param productCategory Category instance
* @param productAvailability Availability (selectable by customer)
+ * @param productUnitAmount Unit amount
+ * @param productUnitI18nKey Unit's i18n key
+ * <p>
+ * @throws NullPointerException If a parameter is null
+ * @throws IllegalArgumentException If a parameter is empty (string) or out
+ * of bounds
*/
- public GenericProduct (final String productTitle, final Float productGrossPrice, final String productCurrencyCode, final Category productCategory, final Boolean productAvailability) {
+ public GenericProduct (final String productI18nKey, final BigDecimal productGrossPrice, final String productCurrencyCode, final Category productCategory, final Boolean productAvailability, final BigDecimal productUnitAmount, final String productUnitI18nKey) {
+ // Call other constructor first
+ this();
+
+ // Validate all parameters
+ if (null == productAvailability) {
+ // Throw NPE
+ throw new NullPointerException("productAvailability is null"); //NOI18N
+ } else if (null == productCategory) {
+ // Throw it again
+ throw new NullPointerException("productCategory is null"); //NOI18N
+ } else if (productCategory.getCategoryId() == null) {
+ // Throw it again
+ throw new NullPointerException("productCategory.categoryId is null"); //NOI18N
+ } else if (productCategory.getCategoryId() < 1) {
+ // Throw IAE
+ throw new IllegalArgumentException(MessageFormat.format("productCategory.categoryId={0} is invalid", productCategory.getCategoryId())); //NOI18N
+ } else if (null == productCurrencyCode) {
+ // Throw it again
+ throw new NullPointerException("productCurrencyCode is null"); //NOI18N
+ } else if (productCurrencyCode.isEmpty()) {
+ // Throw IAE
+ throw new IllegalArgumentException("productCurrencyCode is empty"); //NOI18N
+ } else if (null == productGrossPrice) {
+ // Throw it again
+ throw new NullPointerException("productGrossPrice is null"); //NOI18N
+ } else if (productGrossPrice.longValue() < 0) {
+ // Throw IAE
+ throw new IllegalArgumentException(MessageFormat.format("productGrossPrice={0} is invalid. Do not enter discounts as products.", productGrossPrice)); //NOI18N
+ } else if (null == productI18nKey) {
+ // Throw NPE
+ throw new NullPointerException("productI18nKey is null"); //NOI18N
+ } else if (productI18nKey.isEmpty()) {
+ // Throw IAE
+ throw new IllegalArgumentException("productI18nKey is empty"); //NOI18N
+ } else if (null == productUnitAmount) {
+ // Throw it again
+ throw new NullPointerException("productUnitAmount is null"); //NOI18N
+ } else if (productUnitAmount.longValue() < 0) {
+ // Throw IAE
+ throw new IllegalArgumentException(MessageFormat.format("productUnitAmount={0} is invalid. Do not enter discounts as products.", productUnitAmount)); //NOI18N
+ } else if (null == productUnitI18nKey) {
+ // Throw NPE
+ throw new NullPointerException("productUnitI18nKey is null"); //NOI18N
+ } else if (productUnitI18nKey.isEmpty()) {
+ // Throw IAE
+ throw new IllegalArgumentException("productUnitI18nKey is empty"); //NOI18N
+ }
+
// Set all here
- this.productTitle = productTitle;
+ this.productI18nKey = productI18nKey;
this.productGrossPrice = productGrossPrice;
- this.productCurrencyCode = productCurrencyCode;
+ this.productCurrencyCode = productCurrencyCode.toUpperCase();
this.productCategory = productCategory;
this.productAvailability = productAvailability;
+ this.productUnitAmount = productUnitAmount;
+ this.productUnitI18nKey = productUnitI18nKey;
+ }
+
+ @Override
+ public int compareTo (final Product product) {
+ // Check parameter on null-reference and equality to this
+ if (null == product) {
+ // Should not happen
+ throw new NullPointerException("product is null"); //NOI18N
+ } else if (product.equals(this)) {
+ // Same object
+ return 0;
+ }
+
+ // Init comparators
+ final int comparators[] = {
+ // First check product number
+ SafeNumberUtils.compare(this.getProductNumber(), product.getProductNumber()),
+ // ... size
+ StringUtils.compare(this.getProductSize(), product.getProductSize()),
+ // ... then i18n key
+ this.getProductI18nKey().compareTo(product.getProductI18nKey()),
+ // ... gross price
+ this.getProductGrossPrice().compareTo(product.getProductGrossPrice()),
+ // ... net price
+ SafeNumberUtils.compare(this.getProductNetPrice(), product.getProductNetPrice()),
+ // ... tax rate
+ SafeNumberUtils.compare(this.getProductTaxRate(), product.getProductTaxRate()),
+ // ... unit amount
+ this.getProductUnitAmount().compareTo(product.getProductUnitAmount()),
+ // ... currency code
+ this.getProductCurrencyCode().compareTo(product.getProductCurrencyCode()),
+ // ... manufacturer
+ BasicDataUtils.compare(this.getProductManufacturer(), product.getProductManufacturer()),
+ // ... category
+ Categories.compare(this.getProductCategory(), product.getProductCategory())
+ };
+
+ // Check all values
+ final int comparison = Comparables.checkAll(comparators);
+
+ // Return value
+ return comparison;
}
@Override
final Product product = (Product) object;
- if (!Objects.equals(this.getProductId(), product.getProductId())) {
+ if (!Objects.equals(this.getProductGrossPrice(), product.getProductGrossPrice())) {
+ return false;
+ } else if (!Objects.equals(this.getProductId(), product.getProductId())) {
+ return false;
+ } else if (!Objects.equals(this.getProductI18nKey(), product.getProductI18nKey())) {
+ return false;
+ } else if (!Objects.equals(this.getProductAgeGroup(), product.getProductAgeGroup())) {
return false;
- } else if (!Objects.equals(this.getProductTitle(), product.getProductTitle())) {
+ } else if (!Objects.equals(this.getProductSize(), product.getProductSize())) {
return false;
}
return true;
}
+ @Override
+ public AgeGroup getProductAgeGroup () {
+ return this.productAgeGroup;
+ }
+
+ @Override
+ public void setProductAgeGroup (final AgeGroup productAgeGroup) {
+ this.productAgeGroup = productAgeGroup;
+ }
+
@Override
public Boolean getProductAvailability () {
return this.productAvailability;
}
@Override
- public Float getProductGrossPrice () {
+ public BigDecimal getProductGrossPrice () {
return this.productGrossPrice;
}
@Override
- public void setProductGrossPrice (final Float productGrossPrice) {
+ public void setProductGrossPrice (final BigDecimal productGrossPrice) {
this.productGrossPrice = productGrossPrice;
}
+ @Override
+ public String getProductI18nKey () {
+ return this.productI18nKey;
+ }
+
+ @Override
+ public void setProductI18nKey (final String productI18nKey) {
+ this.productI18nKey = productI18nKey;
+ }
+
@Override
public Long getProductId () {
return this.productId;
}
@Override
- public BasicData getProductManfacturer () {
- return this.productManfacturer;
+ public BasicData getProductManufacturer () {
+ return this.productManufacturer;
}
@Override
- public void setProductManfacturer (final BasicData productManfacturer) {
- this.productManfacturer = productManfacturer;
+ public void setProductManufacturer (final BasicData productManufacturer) {
+ this.productManufacturer = productManufacturer;
}
@Override
- public Float getProductNetPrice () {
+ public BigDecimal getProductNetPrice () {
return this.productNetPrice;
}
@Override
- public void setProductNetPrice (final Float productNetPrice) {
+ public void setProductNetPrice (final BigDecimal productNetPrice) {
this.productNetPrice = productNetPrice;
}
@Override
- public Float getProductTaxRate () {
- return this.productTaxRate;
+ public Long getProductNumber () {
+ return this.productNumber;
}
@Override
- public void setProductTaxRate (final Float productTaxRate) {
- this.productTaxRate = productTaxRate;
+ public void setProductNumber (final Long productNumber) {
+ this.productNumber = productNumber;
}
@Override
- public String getProductTitle () {
- return this.productTitle;
+ public String getProductSize () {
+ return this.productSize;
}
@Override
- public void setProductTitle (final String productTitle) {
- this.productTitle = productTitle;
+ public void setProductSize (final String productSize) {
+ this.productSize = productSize;
+ }
+
+ @Override
+ public BigDecimal getProductTaxRate () {
+ return this.productTaxRate;
+ }
+
+ @Override
+ public void setProductTaxRate (final BigDecimal productTaxRate) {
+ this.productTaxRate = productTaxRate;
}
@Override
- public Float getProductUnitAmount () {
+ public BigDecimal getProductUnitAmount () {
return this.productUnitAmount;
}
@Override
- public void setProductUnitAmount (final Float productUnitAmount) {
+ public void setProductUnitAmount (final BigDecimal productUnitAmount) {
this.productUnitAmount = productUnitAmount;
}
@Override
- public String getProductUnitType () {
- return this.productUnitType;
+ public String getProductUnitI18nKey () {
+ return this.productUnitI18nKey;
}
@Override
- public void setProductUnitType (final String productUnitType) {
- this.productUnitType = productUnitType;
+ public void setProductUnitI18nKey (final String productUnitI18nKey) {
+ this.productUnitI18nKey = productUnitI18nKey;
}
@Override
public int hashCode () {
int hash = 7;
+ hash = 23 * hash + Objects.hashCode(this.getProductGrossPrice());
hash = 23 * hash + Objects.hashCode(this.getProductId());
- hash = 23 * hash + Objects.hashCode(this.getProductTitle());
+ hash = 23 * hash + Objects.hashCode(this.getProductI18nKey());
+ hash = 23 * hash + Objects.hashCode(this.getProductAgeGroup());
+ hash = 23 * hash + Objects.hashCode(this.getProductSize());
return hash;
}