]> git.mxchange.org Git - jproduct-core.git/blobdiff - src/org/mxchange/jproduct/model/product/GenericProduct.java
Continued:
[jproduct-core.git] / src / org / mxchange / jproduct / model / product / GenericProduct.java
index 1a6e51b7e5dd509e6dab0cf0af39cceb5e7ff6c0..1c04f3b20a5a17956016e673d48742fe1bf14774 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.OneToOne;
 import javax.persistence.Table;
+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 = "products")
-@Table (name = "products")
+@Entity (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"),
+                       @NamedQuery (name = "AllAvailableProducts", query = "SELECT p FROM generic_products AS p WHERE p.productAvailability=TRUE ORDER BY p.productId ASC")
+               }
+)
 @SuppressWarnings ("PersistenceUnitPresent")
 public class GenericProduct implements Product {
 
@@ -48,19 +80,56 @@ public class GenericProduct implements Product {
        @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
         */
+       @Basic (optional = false)
        @Column (name = "product_availability", nullable = false)
        private Boolean productAvailability;
 
        /**
         * Product productCategory
         */
-       @JoinColumn (name = "category_id", nullable = false, updatable = false)
+       @JoinColumn (name = "product_category_id", referencedColumnName = "category_id", nullable = false, updatable = false)
        @OneToOne (targetEntity = ProductCategory.class, cascade = CascadeType.REFRESH, optional = false)
        private Category productCategory;
 
+       /**
+        * When this product has been created
+        */
+       @Basic (optional = false)
+       @Column (name = "product_created", nullable = false, updatable = false)
+       @Temporal (TemporalType.TIMESTAMP)
+       private Date productCreated;
+
+       /**
+        * 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, 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
         */
@@ -70,18 +139,49 @@ public class GenericProduct implements Product {
        private Long productId;
 
        /**
-        * Price 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 productManufacturer;
+
+       /**
+        * Net price of product
+        */
+       @Column (name = "product_net_price", precision = 10, scale = 4)
+       private BigDecimal productNetPrice;
+
+       /**
+        * Number of product
+        */
+       @Column (name = "product_number")
+       private Long productNumber;
+
+       /**
+        * Product size (like for shoes, clothing)
+        */
+       @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)
         */
        @Basic (optional = false)
-       @Column (name = "product_price", nullable = false)
-       private Float productPrice;
+       @Column (name = "product_unit_amount", nullable = false, precision = 10, scale = 2)
+       private BigDecimal productUnitAmount;
 
        /**
-        * Title of product
+        * Unit type (for example liter)
         */
        @Basic (optional = false)
-       @Column (name = "product_title", length = 100, nullable = false)
-       private String productTitle;
+       @Column (name = "product_unit_i18n_key", nullable = false)
+       private String productUnitI18nKey;
 
        /**
         * Default constructor
@@ -92,28 +192,117 @@ public class GenericProduct implements Product {
        /**
         * Constructor will all required data
         * <p>
-        * @param productId           Id number of product
-        * @param productTitle        Name of product
-        * @param productPrice        Price
+        * @param productI18nKey      I18n key of product
+        * @param productGrossPrice   Product's gross price
+        * @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 Long productId, final String productTitle, final Float productPrice, 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.productId = productId;
-               this.productTitle = productTitle;
-               this.productPrice = productPrice;
+               this.productI18nKey = productI18nKey;
+               this.productGrossPrice = productGrossPrice;
+               this.productCurrencyCode = productCurrencyCode.toUpperCase();
                this.productCategory = productCategory;
                this.productAvailability = productAvailability;
+               this.productUnitAmount = productUnitAmount;
+               this.productUnitI18nKey = productUnitI18nKey;
        }
 
        @Override
-       public void copyAll (final Product product) {
-               // Copy all
-               this.setProductAvailability(product.getProductAvailability());
-               this.setProductCategory(product.getProductCategory());
-               this.setProductPrice(product.getProductPrice());
-               this.setProductTitle(product.getProductTitle());
+       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
@@ -126,21 +315,31 @@ public class GenericProduct implements Product {
                        return false;
                }
 
-               final Product other = (Product) object;
+               final Product product = (Product) object;
 
-               if (!Objects.equals(this.getProductTitle(), other.getProductTitle())) {
+               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.getProductSize(), product.getProductSize())) {
                        return false;
                }
 
-               return Objects.equals(this.getProductId(), other.getProductId());
+               return true;
        }
 
        @Override
-       public int hashCode () {
-               int hash = 7;
-               hash = 23 * hash + Objects.hashCode(this.getProductId());
-               hash = 23 * hash + Objects.hashCode(this.getProductTitle());
-               return hash;
+       public AgeGroup getProductAgeGroup () {
+               return this.productAgeGroup;
+       }
+
+       @Override
+       public void setProductAgeGroup (final AgeGroup productAgeGroup) {
+               this.productAgeGroup = productAgeGroup;
        }
 
        @Override
@@ -163,6 +362,48 @@ public class GenericProduct implements Product {
                this.productCategory = productCategory;
        }
 
+       @Override
+       @SuppressWarnings ("ReturnOfDateField")
+       public Date getProductCreated () {
+               return this.productCreated;
+       }
+
+       @Override
+       @SuppressWarnings ("AssignmentToDateFieldFromParameter")
+       public void setProductCreated (final Date productCreated) {
+               this.productCreated = productCreated;
+       }
+
+       @Override
+       public String getProductCurrencyCode () {
+               return this.productCurrencyCode;
+       }
+
+       @Override
+       public void setProductCurrencyCode (final String productCurrencyCode) {
+               this.productCurrencyCode = productCurrencyCode;
+       }
+
+       @Override
+       public BigDecimal getProductGrossPrice () {
+               return this.productGrossPrice;
+       }
+
+       @Override
+       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;
@@ -174,23 +415,86 @@ public class GenericProduct implements Product {
        }
 
        @Override
-       public Float getProductPrice () {
-               return this.productPrice;
+       public BasicData getProductManufacturer () {
+               return this.productManufacturer;
+       }
+
+       @Override
+       public void setProductManufacturer (final BasicData productManufacturer) {
+               this.productManufacturer = productManufacturer;
+       }
+
+       @Override
+       public BigDecimal getProductNetPrice () {
+               return this.productNetPrice;
+       }
+
+       @Override
+       public void setProductNetPrice (final BigDecimal productNetPrice) {
+               this.productNetPrice = productNetPrice;
        }
 
        @Override
-       public void setProductPrice (final Float productPrice) {
-               this.productPrice = productPrice;
+       public Long getProductNumber () {
+               return this.productNumber;
        }
 
        @Override
-       public String getProductTitle () {
-               return this.productTitle;
+       public void setProductNumber (final Long productNumber) {
+               this.productNumber = productNumber;
        }
 
        @Override
-       public void setProductTitle (final String productTitle) {
-               this.productTitle = productTitle;
+       public String getProductSize () {
+               return this.productSize;
+       }
+
+       @Override
+       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 BigDecimal getProductUnitAmount () {
+               return this.productUnitAmount;
+       }
+
+       @Override
+       public void setProductUnitAmount (final BigDecimal productUnitAmount) {
+               this.productUnitAmount = productUnitAmount;
+       }
+
+       @Override
+       public String getProductUnitI18nKey () {
+               return this.productUnitI18nKey;
+       }
+
+       @Override
+       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.getProductI18nKey());
+               hash = 23 * hash + Objects.hashCode(this.getProductAgeGroup());
+               hash = 23 * hash + Objects.hashCode(this.getProductSize());
+
+               return hash;
        }
 
 }