2 * Copyright (C) 2016 - 2018 Free Software Foundation
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 package org.mxchange.jproduct.model.product;
19 import java.math.BigDecimal;
20 import java.text.MessageFormat;
21 import java.util.Date;
22 import java.util.Objects;
23 import javax.persistence.Basic;
24 import javax.persistence.CascadeType;
25 import javax.persistence.Column;
26 import javax.persistence.Entity;
27 import javax.persistence.EnumType;
28 import javax.persistence.Enumerated;
29 import javax.persistence.GeneratedValue;
30 import javax.persistence.GenerationType;
31 import javax.persistence.Id;
32 import javax.persistence.Index;
33 import javax.persistence.JoinColumn;
34 import javax.persistence.NamedQueries;
35 import javax.persistence.NamedQuery;
36 import javax.persistence.OneToOne;
37 import javax.persistence.Table;
38 import javax.persistence.Temporal;
39 import javax.persistence.TemporalType;
40 import javax.persistence.Transient;
41 import org.mxchange.jcontactsbusiness.model.basicdata.BasicData;
42 import org.mxchange.jcontactsbusiness.model.basicdata.BusinessBasicData;
43 import org.mxchange.jproduct.model.category.Category;
44 import org.mxchange.jproduct.model.category.ProductCategory;
45 import org.mxchange.jproduct.model.product.agegroup.AgeGroup;
48 * Generic product class
50 * @author Roland Häder<roland@mxchange.org>
51 * TODO: Find a better name
53 @Entity (name = "generic_products")
55 name = "generic_products",
58 name = "idx_i18n_age_size",
59 columnList = "product_i18n_key,product_age_group,product_size",
66 @NamedQuery (name = "AllProducts", query = "SELECT p FROM generic_products AS p ORDER BY p.productId ASC"),
67 @NamedQuery (name = "AllAvailableProducts", query = "SELECT p FROM generic_products AS p WHERE p.productAvailability=TRUE ORDER BY p.productId ASC")
70 @SuppressWarnings ("PersistenceUnitPresent")
71 public class GenericProduct implements Product {
77 private static final long serialVersionUID = 54_578_571_769_283L;
80 * Product's age group (if any)
82 @Column (name = "product_age_group")
83 @Enumerated (EnumType.STRING)
84 private AgeGroup productAgeGroup;
87 * Availability of product
89 @Basic (optional = false)
90 @Column (name = "product_availability", nullable = false)
91 private Boolean productAvailability;
94 * Product productCategory
96 @JoinColumn (name = "product_category_id", referencedColumnName = "category_id", nullable = false, updatable = false)
97 @OneToOne (targetEntity = ProductCategory.class, cascade = CascadeType.REFRESH, optional = false)
98 private Category productCategory;
101 * When this product has been created
103 @Basic (optional = false)
104 @Column (name = "product_created", nullable = false, updatable = false)
105 @Temporal (TemporalType.TIMESTAMP)
106 private Date productCreated;
109 * Currency code for both prices, like EUR or USD
111 @Basic (optional = false)
112 @Column (name = "product_currency_code", nullable = false, length = 3)
113 private String productCurrencyCode;
116 * Gross price of product
118 @Basic (optional = false)
119 @Column (name = "product_gross_price", nullable = false, precision = 10, scale = 4)
120 private BigDecimal productGrossPrice;
123 * I18n key of product
125 @Basic (optional = false)
126 @Column (name = "product_i18n_key", length = 100, nullable = false)
127 private String productI18nKey;
130 * Id number of product
133 @GeneratedValue (strategy = GenerationType.IDENTITY)
134 @Column (name = "product_id", nullable = false, updatable = false)
135 private Long productId;
138 * The company that has manufactured/produced this product
140 @JoinColumn (name = "product_manufacturer_id", referencedColumnName = "company_data_id")
141 @OneToOne (targetEntity = BusinessBasicData.class, cascade = CascadeType.REFRESH)
142 private BasicData productManufacturer;
145 * Net price of product
147 @Column (name = "product_net_price", precision = 10, scale = 4)
148 private BigDecimal productNetPrice;
153 @Column (name = "product_number")
154 private Long productNumber;
157 * Product size (like for shoes, clothing)
159 @Column (name = "product_size", length = 10)
160 private String productSize;
163 * Tax rate (0-1, by 1=100%)
165 @Column (name = "product_tax_rate", precision = 3, scale = 1)
166 private BigDecimal productTaxRate;
169 * Amount of this product (for example 1 for 1 liter)
171 @Basic (optional = false)
172 @Column (name = "product_unit_amount", nullable = false, precision = 10, scale = 2)
173 private BigDecimal productUnitAmount;
176 * Unit type (for example liter)
178 @Basic (optional = false)
179 @Column (name = "product_unit_i18n_key", nullable = false)
180 private String productUnitI18nKey;
183 * Default constructor
185 public GenericProduct () {
189 * Constructor will all required data
191 * @param productI18nKey I18n key of product
192 * @param productGrossPrice Product's gross price
193 * @param productCurrencyCode Currency code for both prices
194 * @param productCategory Category instance
195 * @param productAvailability Availability (selectable by customer)
196 * @param productUnitAmount Unit amount
197 * @param productUnitI18nKey Unit's i18n key
199 * @throws NullPointerException If a parameter is null
200 * @throws IllegalArgumentException If a parameter is empty (string) or out
203 public GenericProduct (final String productI18nKey, final BigDecimal productGrossPrice, final String productCurrencyCode, final Category productCategory, final Boolean productAvailability, final BigDecimal productUnitAmount , final String productUnitI18nKey) {
204 // Call other constructor first
207 // Validate all parameters
208 if (null == productAvailability) {
210 throw new NullPointerException("productAvailability is null"); //NOI18N
211 } else if (null == productCategory) {
213 throw new NullPointerException("productCategory is null"); //NOI18N
214 } else if (productCategory.getCategoryId() == null) {
216 throw new NullPointerException("productCategory.categoryId is null"); //NOI18N
217 } else if (productCategory.getCategoryId() < 1) {
219 throw new IllegalArgumentException(MessageFormat.format("productCategory.categoryId={0} is invalid", productCategory.getCategoryId())); //NOI18N
220 } else if (null == productCurrencyCode) {
222 throw new NullPointerException("productCurrencyCode is null"); //NOI18N
223 } else if (productCurrencyCode.isEmpty()) {
225 throw new IllegalArgumentException("productCurrencyCode is empty"); //NOI18N
226 } else if (null == productGrossPrice) {
228 throw new NullPointerException("productGrossPrice is null"); //NOI18N
229 } else if (productGrossPrice.longValue() < 0) {
231 throw new IllegalArgumentException(MessageFormat.format("productGrossPrice={0} is invalid. Do not enter discounts as products.", productGrossPrice)); //NOI18N
232 } else if (null == productI18nKey) {
234 throw new NullPointerException("productI18nKey is null"); //NOI18N
235 } else if (productI18nKey.isEmpty()) {
237 throw new IllegalArgumentException("productI18nKey is empty"); //NOI18N
238 } else if (null == productUnitAmount) {
240 throw new NullPointerException("productUnitAmount is null"); //NOI18N
241 } else if (productUnitAmount.longValue() < 0) {
243 throw new IllegalArgumentException(MessageFormat.format("productUnitAmount={0} is invalid. Do not enter discounts as products.", productUnitAmount)); //NOI18N
244 } else if (null == productUnitI18nKey) {
246 throw new NullPointerException("productUnitI18nKey is null"); //NOI18N
247 } else if (productUnitI18nKey.isEmpty()) {
249 throw new IllegalArgumentException("productUnitI18nKey is empty"); //NOI18N
253 this.productI18nKey = productI18nKey;
254 this.productGrossPrice = productGrossPrice;
255 this.productCurrencyCode = productCurrencyCode.toUpperCase();
256 this.productCategory = productCategory;
257 this.productAvailability = productAvailability;
258 this.productUnitAmount = productUnitAmount;
259 this.productUnitI18nKey = productUnitI18nKey;
263 public boolean equals (final Object object) {
264 if (this == object) {
266 } else if (null == object) {
268 } else if (this.getClass() != object.getClass()) {
272 final Product product = (Product) object;
274 if (!Objects.equals(this.getProductGrossPrice(), product.getProductGrossPrice())) {
276 } else if (!Objects.equals(this.getProductId(), product.getProductId())) {
278 } else if (!Objects.equals(this.getProductI18nKey(), product.getProductI18nKey())) {
280 } else if (!Objects.equals(this.getProductAgeGroup(), product.getProductAgeGroup())) {
282 } else if (!Objects.equals(this.getProductSize(), product.getProductSize())) {
290 public AgeGroup getProductAgeGroup () {
291 return this.productAgeGroup;
295 public void setProductAgeGroup (final AgeGroup productAgeGroup) {
296 this.productAgeGroup = productAgeGroup;
300 public Boolean getProductAvailability () {
301 return this.productAvailability;
305 public void setProductAvailability (final Boolean productAvailability) {
306 this.productAvailability = productAvailability;
310 public Category getProductCategory () {
311 return this.productCategory;
315 public void setProductCategory (final Category productCategory) {
316 this.productCategory = productCategory;
320 @SuppressWarnings ("ReturnOfDateField")
321 public Date getProductCreated () {
322 return this.productCreated;
326 @SuppressWarnings ("AssignmentToDateFieldFromParameter")
327 public void setProductCreated (final Date productCreated) {
328 this.productCreated = productCreated;
332 public String getProductCurrencyCode () {
333 return this.productCurrencyCode;
337 public void setProductCurrencyCode (final String productCurrencyCode) {
338 this.productCurrencyCode = productCurrencyCode;
342 public BigDecimal getProductGrossPrice () {
343 return this.productGrossPrice;
347 public void setProductGrossPrice (final BigDecimal productGrossPrice) {
348 this.productGrossPrice = productGrossPrice;
352 public String getProductI18nKey () {
353 return this.productI18nKey;
357 public void setProductI18nKey (final String productI18nKey) {
358 this.productI18nKey = productI18nKey;
362 public Long getProductId () {
363 return this.productId;
367 public void setProductId (final Long productId) {
368 this.productId = productId;
372 public BasicData getProductManufacturer () {
373 return this.productManufacturer;
377 public void setProductManufacturer (final BasicData productManufacturer) {
378 this.productManufacturer = productManufacturer;
382 public BigDecimal getProductNetPrice () {
383 return this.productNetPrice;
387 public void setProductNetPrice (final BigDecimal productNetPrice) {
388 this.productNetPrice = productNetPrice;
392 public Long getProductNumber () {
393 return this.productNumber;
397 public void setProductNumber (final Long productNumber) {
398 this.productNumber = productNumber;
402 public String getProductSize () {
403 return this.productSize;
407 public void setProductSize (final String productSize) {
408 this.productSize = productSize;
412 public BigDecimal getProductTaxRate () {
413 return this.productTaxRate;
417 public void setProductTaxRate (final BigDecimal productTaxRate) {
418 this.productTaxRate = productTaxRate;
422 public BigDecimal getProductUnitAmount () {
423 return this.productUnitAmount;
427 public void setProductUnitAmount (final BigDecimal productUnitAmount) {
428 this.productUnitAmount = productUnitAmount;
432 public String getProductUnitI18nKey () {
433 return this.productUnitI18nKey;
437 public void setProductUnitI18nKey (final String productUnitI18nKey) {
438 this.productUnitI18nKey = productUnitI18nKey;
442 public int hashCode () {
445 hash = 23 * hash + Objects.hashCode(this.getProductGrossPrice());
446 hash = 23 * hash + Objects.hashCode(this.getProductId());
447 hash = 23 * hash + Objects.hashCode(this.getProductI18nKey());
448 hash = 23 * hash + Objects.hashCode(this.getProductAgeGroup());
449 hash = 23 * hash + Objects.hashCode(this.getProductSize());