2 * Copyright (C) 2016, 2017 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.text.MessageFormat;
20 import java.util.Date;
21 import java.util.Objects;
22 import javax.persistence.Basic;
23 import javax.persistence.CascadeType;
24 import javax.persistence.Column;
25 import javax.persistence.Entity;
26 import javax.persistence.EnumType;
27 import javax.persistence.Enumerated;
28 import javax.persistence.GeneratedValue;
29 import javax.persistence.GenerationType;
30 import javax.persistence.Id;
31 import javax.persistence.Index;
32 import javax.persistence.JoinColumn;
33 import javax.persistence.NamedQueries;
34 import javax.persistence.NamedQuery;
35 import javax.persistence.OneToOne;
36 import javax.persistence.Table;
37 import javax.persistence.Temporal;
38 import javax.persistence.TemporalType;
39 import javax.persistence.Transient;
40 import org.mxchange.jcontactsbusiness.model.basicdata.BasicData;
41 import org.mxchange.jcontactsbusiness.model.basicdata.BusinessBasicData;
42 import org.mxchange.jproduct.model.category.Category;
43 import org.mxchange.jproduct.model.category.ProductCategory;
44 import org.mxchange.jproduct.model.product.agegroup.AgeGroup;
47 * Generic product class
49 * @author Roland Häder<roland@mxchange.org>
50 * TODO: Find a better name
52 @Entity (name = "generic_products")
54 name = "generic_products",
57 name = "idx_i18n_age_size",
58 columnList = "product_i18n_key,product_age_group,product_size",
65 @NamedQuery (name = "AllProducts", query = "SELECT p FROM generic_products AS p ORDER BY p.productId ASC"),
66 @NamedQuery (name = "AllAvailableProducts", query = "SELECT p FROM generic_products AS p WHERE p.productAvailability=TRUE ORDER BY p.productId ASC")
69 @SuppressWarnings ("PersistenceUnitPresent")
70 public class GenericProduct implements Product {
76 private static final long serialVersionUID = 54_578_571_769_283L;
79 * Product's age group (if any)
81 @Column (name = "product_age_group")
82 @Enumerated (EnumType.STRING)
83 private AgeGroup productAgeGroup;
86 * Availability of product
88 @Basic (optional = false)
89 @Column (name = "product_availability", nullable = false)
90 private Boolean productAvailability;
93 * Product productCategory
95 @JoinColumn (name = "product_category_id", referencedColumnName = "category_id", nullable = false, updatable = false)
96 @OneToOne (targetEntity = ProductCategory.class, cascade = CascadeType.REFRESH, optional = false)
97 private Category productCategory;
100 * When this product has been created
102 @Basic (optional = false)
103 @Column (name = "product_created", nullable = false, updatable = false)
104 @Temporal (TemporalType.TIMESTAMP)
105 private Date productCreated;
108 * Currency code for both prices, like EUR or USD
110 @Basic (optional = false)
111 @Column (name = "product_currency_code", nullable = false, length = 3)
112 private String productCurrencyCode;
115 * Gross price of product
117 @Basic (optional = false)
118 @Column (name = "product_gross_price", nullable = false)
119 private Float productGrossPrice;
122 * I18n key of product
124 @Basic (optional = false)
125 @Column (name = "product_i18n_key", length = 100, nullable = false)
126 private String productI18nKey;
129 * Id number of product
132 @GeneratedValue (strategy = GenerationType.IDENTITY)
133 @Column (name = "product_id", nullable = false, updatable = false)
134 private Long productId;
137 * The company that has manufactured/produced this product
139 @JoinColumn (name = "product_manufacturer_id", referencedColumnName = "company_data_id")
140 @OneToOne (targetEntity = BusinessBasicData.class, cascade = CascadeType.REFRESH)
141 private BasicData productManufacturer;
144 * Net price of product
146 @Column (name = "product_net_price")
147 private Float productNetPrice;
152 @Column (name = "product_number")
153 private Long productNumber;
156 * Product size (like for shoes, clothing)
158 @Column (name = "product_size", length = 10)
159 private String productSize;
162 * Tax rate (0-1, by 1=100%)
164 @Column (name = "product_tax_rate")
165 private Float productTaxRate;
168 * Amount of this product (for example 1 for 1 liter)
170 @Basic (optional = false)
171 @Column (name = "product_unit_amount", nullable = false)
172 private Float productUnitAmount;
175 * Unit type (for example liter)
177 @Basic (optional = false)
178 @Column (name = "product_unit_i18n_key", nullable = false)
179 private String productUnitI18nKey;
182 * Default constructor
184 public GenericProduct () {
188 * Constructor will all required data
190 * @param productI18nKey I18n key of product
191 * @param productGrossPrice Product's gross price
192 * @param productCurrencyCode Currency code for both prices
193 * @param productCategory Category instance
194 * @param productAvailability Availability (selectable by customer)
195 * @param productUnitAmount Unit amount
196 * @param productUnitI18nKey Unit's i18n key
198 * @throws NullPointerException If a parameter is null
199 * @throws IllegalArgumentException If a parameter is empty (string) or out
202 public GenericProduct (final String productI18nKey, final Float productGrossPrice, final String productCurrencyCode, final Category productCategory, final Boolean productAvailability, final Float productUnitAmount, final String productUnitI18nKey) {
203 // Call other constructor first
206 // Validate all parameters
207 if (null == productAvailability) {
209 throw new NullPointerException("productAvailability is null"); //NOI18N
210 } else if (null == productCategory) {
212 throw new NullPointerException("productCategory is null"); //NOI18N
213 } else if (productCategory.getCategoryId() == null) {
215 throw new NullPointerException("productCategory.categoryId is null"); //NOI18N
216 } else if (productCategory.getCategoryId() < 1) {
218 throw new IllegalArgumentException(MessageFormat.format("productCategory.categoryId={0} is invalid", productCategory.getCategoryId())); //NOI18N
219 } else if (null == productCurrencyCode) {
221 throw new NullPointerException("productCurrencyCode is null"); //NOI18N
222 } else if (productCurrencyCode.isEmpty()) {
224 throw new IllegalArgumentException("productCurrencyCode is empty"); //NOI18N
225 } else if (null == productGrossPrice) {
227 throw new NullPointerException("productGrossPrice is null"); //NOI18N
228 } else if (productGrossPrice < 0) {
230 throw new IllegalArgumentException(MessageFormat.format("productGrossPrice={0} is invalid. Do not enter discounts as products.", productGrossPrice)); //NOI18N
231 } else if (null == productI18nKey) {
233 throw new NullPointerException("productI18nKey is null"); //NOI18N
234 } else if (productI18nKey.isEmpty()) {
236 throw new IllegalArgumentException("productI18nKey is empty"); //NOI18N
237 } else if (null == productUnitAmount) {
239 throw new NullPointerException("productUnitAmount is null"); //NOI18N
240 } else if (productUnitAmount < 0) {
242 throw new IllegalArgumentException(MessageFormat.format("productUnitAmount={0} is invalid. Do not enter discounts as products.", productUnitAmount)); //NOI18N
243 } else if (null == productUnitI18nKey) {
245 throw new NullPointerException("productUnitI18nKey is null"); //NOI18N
246 } else if (productUnitI18nKey.isEmpty()) {
248 throw new IllegalArgumentException("productUnitI18nKey is empty"); //NOI18N
252 this.productI18nKey = productI18nKey;
253 this.productGrossPrice = productGrossPrice;
254 this.productCurrencyCode = productCurrencyCode.toUpperCase();
255 this.productCategory = productCategory;
256 this.productAvailability = productAvailability;
257 this.productUnitAmount = productUnitAmount;
258 this.productUnitI18nKey = productUnitI18nKey;
262 public boolean equals (final Object object) {
263 if (this == object) {
265 } else if (null == object) {
267 } else if (this.getClass() != object.getClass()) {
271 final Product product = (Product) object;
273 if (!Objects.equals(this.getProductId(), product.getProductId())) {
275 } else if (!Objects.equals(this.getProductI18nKey(), product.getProductI18nKey())) {
277 } else if (!Objects.equals(this.getProductAgeGroup(), product.getProductAgeGroup())) {
279 } else if (!Objects.equals(this.getProductSize(), product.getProductSize())) {
287 public AgeGroup getProductAgeGroup () {
288 return this.productAgeGroup;
292 public void setProductAgeGroup (final AgeGroup productAgeGroup) {
293 this.productAgeGroup = productAgeGroup;
297 public Boolean getProductAvailability () {
298 return this.productAvailability;
302 public void setProductAvailability (final Boolean productAvailability) {
303 this.productAvailability = productAvailability;
307 public Category getProductCategory () {
308 return this.productCategory;
312 public void setProductCategory (final Category productCategory) {
313 this.productCategory = productCategory;
317 @SuppressWarnings ("ReturnOfDateField")
318 public Date getProductCreated () {
319 return this.productCreated;
323 @SuppressWarnings ("AssignmentToDateFieldFromParameter")
324 public void setProductCreated (final Date productCreated) {
325 this.productCreated = productCreated;
329 public String getProductCurrencyCode () {
330 return this.productCurrencyCode;
334 public void setProductCurrencyCode (final String productCurrencyCode) {
335 this.productCurrencyCode = productCurrencyCode;
339 public Float getProductGrossPrice () {
340 return this.productGrossPrice;
344 public void setProductGrossPrice (final Float productGrossPrice) {
345 this.productGrossPrice = productGrossPrice;
349 public String getProductI18nKey () {
350 return this.productI18nKey;
354 public void setProductI18nKey (final String productI18nKey) {
355 this.productI18nKey = productI18nKey;
359 public Long getProductId () {
360 return this.productId;
364 public void setProductId (final Long productId) {
365 this.productId = productId;
369 public BasicData getProductManufacturer () {
370 return this.productManufacturer;
374 public void setProductManufacturer (final BasicData productManufacturer) {
375 this.productManufacturer = productManufacturer;
379 public Float getProductNetPrice () {
380 return this.productNetPrice;
384 public void setProductNetPrice (final Float productNetPrice) {
385 this.productNetPrice = productNetPrice;
389 public Long getProductNumber () {
390 return this.productNumber;
394 public void setProductNumber (final Long productNumber) {
395 this.productNumber = productNumber;
399 public String getProductSize () {
400 return this.productSize;
404 public void setProductSize (final String productSize) {
405 this.productSize = productSize;
409 public Float getProductTaxRate () {
410 return this.productTaxRate;
414 public void setProductTaxRate (final Float productTaxRate) {
415 this.productTaxRate = productTaxRate;
419 public Float getProductUnitAmount () {
420 return this.productUnitAmount;
424 public void setProductUnitAmount (final Float productUnitAmount) {
425 this.productUnitAmount = productUnitAmount;
429 public String getProductUnitI18nKey () {
430 return this.productUnitI18nKey;
434 public void setProductUnitI18nKey (final String productUnitI18nKey) {
435 this.productUnitI18nKey = productUnitI18nKey;
439 public int hashCode () {
442 hash = 23 * hash + Objects.hashCode(this.getProductId());
443 hash = 23 * hash + Objects.hashCode(this.getProductI18nKey());
444 hash = 23 * hash + Objects.hashCode(this.getProductAgeGroup());
445 hash = 23 * hash + Objects.hashCode(this.getProductSize());