]> git.mxchange.org Git - jproduct-core.git/blob - src/org/mxchange/jproduct/model/product/GenericProduct.java
Continued:
[jproduct-core.git] / src / org / mxchange / jproduct / model / product / GenericProduct.java
1 /*
2  * Copyright (C) 2016 - 2018 Free Software Foundation
3  *
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.
8  *
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.
13  *
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/>.
16  */
17 package org.mxchange.jproduct.model.product;
18
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.apache.commons.lang3.StringUtils;
42 import org.mxchange.jcontactsbusiness.model.basicdata.BasicData;
43 import org.mxchange.jcontactsbusiness.model.basicdata.BasicDataUtils;
44 import org.mxchange.jcontactsbusiness.model.basicdata.BusinessBasicData;
45 import org.mxchange.jcoreutils.Comparables;
46 import org.mxchange.jcoreutils.SafeNumberUtils;
47 import org.mxchange.jproduct.model.category.Categories;
48 import org.mxchange.jproduct.model.category.Category;
49 import org.mxchange.jproduct.model.category.ProductCategory;
50 import org.mxchange.jproduct.model.product.agegroup.AgeGroup;
51
52 /**
53  * Generic product POJO (entity)
54  * <p>
55  * @author Roland Häder<roland@mxchange.org>
56  */
57 @Entity (name = "generic_products")
58 @Table (
59                 name = "generic_products",
60                 indexes = {
61                         @Index (
62                                         name = "idx_i18n_age_size",
63                                         columnList = "product_i18n_key,product_age_group,product_size",
64                                         unique = true
65                         )
66                 }
67 )
68 @NamedQueries (
69                 {
70                         @NamedQuery (name = "AllProducts", query = "SELECT p FROM generic_products AS p ORDER BY p.productId ASC"),
71                         @NamedQuery (name = "AllAvailableProducts", query = "SELECT p FROM generic_products AS p WHERE p.productAvailability=TRUE ORDER BY p.productId ASC")
72                 }
73 )
74 @SuppressWarnings ("PersistenceUnitPresent")
75 public class GenericProduct implements Product {
76
77         /**
78          * Serial number
79          */
80         @Transient
81         private static final long serialVersionUID = 54_578_571_769_283L;
82
83         /**
84          * Product's age group (if any)
85          */
86         @Column (name = "product_age_group")
87         @Enumerated (EnumType.STRING)
88         private AgeGroup productAgeGroup;
89
90         /**
91          * Availability of product
92          */
93         @Basic (optional = false)
94         @Column (name = "product_availability", nullable = false)
95         private Boolean productAvailability;
96
97         /**
98          * Product productCategory
99          */
100         @JoinColumn (name = "product_category_id", referencedColumnName = "category_id", nullable = false, updatable = false)
101         @OneToOne (targetEntity = ProductCategory.class, cascade = CascadeType.REFRESH, optional = false)
102         private Category productCategory;
103
104         /**
105          * When this product has been created
106          */
107         @Basic (optional = false)
108         @Column (name = "product_created", nullable = false, updatable = false)
109         @Temporal (TemporalType.TIMESTAMP)
110         private Date productCreated;
111
112         /**
113          * Currency code for both prices, like EUR or USD
114          */
115         @Basic (optional = false)
116         @Column (name = "product_currency_code", nullable = false, length = 3)
117         private String productCurrencyCode;
118
119         /**
120          * Gross price of product
121          */
122         @Basic (optional = false)
123         @Column (name = "product_gross_price", nullable = false, precision = 10, scale = 4)
124         private BigDecimal productGrossPrice;
125
126         /**
127          * I18n key of product
128          */
129         @Basic (optional = false)
130         @Column (name = "product_i18n_key", length = 100, nullable = false)
131         private String productI18nKey;
132
133         /**
134          * Id number of product
135          */
136         @Id
137         @GeneratedValue (strategy = GenerationType.IDENTITY)
138         @Column (name = "product_id", nullable = false, updatable = false)
139         private Long productId;
140
141         /**
142          * The company that has manufactured/produced this product
143          */
144         @JoinColumn (name = "product_manufacturer_id", referencedColumnName = "company_data_id")
145         @OneToOne (targetEntity = BusinessBasicData.class, cascade = CascadeType.REFRESH)
146         private BasicData productManufacturer;
147
148         /**
149          * Net price of product
150          */
151         @Column (name = "product_net_price", precision = 10, scale = 4)
152         private BigDecimal productNetPrice;
153
154         /**
155          * Number of product
156          */
157         @Column (name = "product_number")
158         private Long productNumber;
159
160         /**
161          * Product size (like for shoes, clothing)
162          */
163         @Column (name = "product_size", length = 10)
164         private String productSize;
165
166         /**
167          * Tax rate (0-1, by 1=100%)
168          */
169         @Column (name = "product_tax_rate", precision = 3, scale = 1)
170         private BigDecimal productTaxRate;
171
172         /**
173          * Amount of this product (for example 1 for 1 liter)
174          */
175         @Basic (optional = false)
176         @Column (name = "product_unit_amount", nullable = false, precision = 10, scale = 2)
177         private BigDecimal productUnitAmount;
178
179         /**
180          * Unit type (for example liter)
181          */
182         @Basic (optional = false)
183         @Column (name = "product_unit_i18n_key", nullable = false)
184         private String productUnitI18nKey;
185
186         /**
187          * Default constructor
188          */
189         public GenericProduct () {
190         }
191
192         /**
193          * Constructor will all required data
194          * <p>
195          * @param productI18nKey      I18n key of product
196          * @param productGrossPrice   Product's gross price
197          * @param productCurrencyCode Currency code for both prices
198          * @param productCategory     Category instance
199          * @param productAvailability Availability (selectable by customer)
200          * @param productUnitAmount   Unit amount
201          * @param productUnitI18nKey  Unit's i18n key
202          * <p>
203          * @throws NullPointerException If a parameter is null
204          * @throws IllegalArgumentException If a parameter is empty (string) or out
205          * of bounds
206          */
207         public GenericProduct (final String productI18nKey, final BigDecimal productGrossPrice, final String productCurrencyCode, final Category productCategory, final Boolean productAvailability, final BigDecimal productUnitAmount, final String productUnitI18nKey) {
208                 // Call other constructor first
209                 this();
210
211                 // Validate all parameters
212                 if (null == productAvailability) {
213                         // Throw NPE
214                         throw new NullPointerException("productAvailability is null"); //NOI18N
215                 } else if (null == productCategory) {
216                         // Throw it again
217                         throw new NullPointerException("productCategory is null"); //NOI18N
218                 } else if (productCategory.getCategoryId() == null) {
219                         // Throw it again
220                         throw new NullPointerException("productCategory.categoryId is null"); //NOI18N
221                 } else if (productCategory.getCategoryId() < 1) {
222                         // Throw IAE
223                         throw new IllegalArgumentException(MessageFormat.format("productCategory.categoryId={0} is invalid", productCategory.getCategoryId())); //NOI18N
224                 } else if (null == productCurrencyCode) {
225                         // Throw it again
226                         throw new NullPointerException("productCurrencyCode is null"); //NOI18N
227                 } else if (productCurrencyCode.isEmpty()) {
228                         // Throw IAE
229                         throw new IllegalArgumentException("productCurrencyCode is empty"); //NOI18N
230                 } else if (null == productGrossPrice) {
231                         // Throw it again
232                         throw new NullPointerException("productGrossPrice is null"); //NOI18N
233                 } else if (productGrossPrice.longValue() < 0) {
234                         // Throw IAE
235                         throw new IllegalArgumentException(MessageFormat.format("productGrossPrice={0} is invalid. Do not enter discounts as products.", productGrossPrice)); //NOI18N
236                 } else if (null == productI18nKey) {
237                         // Throw NPE
238                         throw new NullPointerException("productI18nKey is null"); //NOI18N
239                 } else if (productI18nKey.isEmpty()) {
240                         // Throw IAE
241                         throw new IllegalArgumentException("productI18nKey is empty"); //NOI18N
242                 } else if (null == productUnitAmount) {
243                         // Throw it again
244                         throw new NullPointerException("productUnitAmount is null"); //NOI18N
245                 } else if (productUnitAmount.longValue() < 0) {
246                         // Throw IAE
247                         throw new IllegalArgumentException(MessageFormat.format("productUnitAmount={0} is invalid. Do not enter discounts as products.", productUnitAmount)); //NOI18N
248                 } else if (null == productUnitI18nKey) {
249                         // Throw NPE
250                         throw new NullPointerException("productUnitI18nKey is null"); //NOI18N
251                 } else if (productUnitI18nKey.isEmpty()) {
252                         // Throw IAE
253                         throw new IllegalArgumentException("productUnitI18nKey is empty"); //NOI18N
254                 }
255
256                 // Set all here
257                 this.productI18nKey = productI18nKey;
258                 this.productGrossPrice = productGrossPrice;
259                 this.productCurrencyCode = productCurrencyCode.toUpperCase();
260                 this.productCategory = productCategory;
261                 this.productAvailability = productAvailability;
262                 this.productUnitAmount = productUnitAmount;
263                 this.productUnitI18nKey = productUnitI18nKey;
264         }
265
266         @Override
267         public int compareTo (final Product product) {
268                 // Check parameter on null-reference and equality to this
269                 if (null == product) {
270                         // Should not happen
271                         throw new NullPointerException("product is null"); //NOI18N
272                 } else if (product.equals(this)) {
273                         // Same object
274                         return 0;
275                 }
276
277                 // Init comparators
278                 final int comparators[] = {
279                         // First check product number
280                         SafeNumberUtils.compare(this.getProductNumber(), product.getProductNumber()),
281                         // ... size
282                         StringUtils.compare(this.getProductSize(), product.getProductSize()),
283                         // ... then i18n key
284                         this.getProductI18nKey().compareTo(product.getProductI18nKey()),
285                         // ... gross price
286                         this.getProductGrossPrice().compareTo(product.getProductGrossPrice()),
287                         // ... net price
288                         SafeNumberUtils.compare(this.getProductNetPrice(), product.getProductNetPrice()),
289                         // ... tax rate
290                         SafeNumberUtils.compare(this.getProductTaxRate(), product.getProductTaxRate()),
291                         // ... unit amount
292                         this.getProductUnitAmount().compareTo(product.getProductUnitAmount()),
293                         // ... currency code
294                         this.getProductCurrencyCode().compareTo(product.getProductCurrencyCode()),
295                         // ... manufacturer
296                         BasicDataUtils.compare(this.getProductManufacturer(), product.getProductManufacturer()),
297                         // ... category
298                         Categories.compare(this.getProductCategory(), product.getProductCategory())
299                 };
300
301                 // Check all values
302                 final int comparison = Comparables.checkAll(comparators);
303
304                 // Return value
305                 return comparison;
306         }
307
308         @Override
309         public boolean equals (final Object object) {
310                 if (this == object) {
311                         return true;
312                 } else if (null == object) {
313                         return false;
314                 } else if (this.getClass() != object.getClass()) {
315                         return false;
316                 }
317
318                 final Product product = (Product) object;
319
320                 if (!Objects.equals(this.getProductGrossPrice(), product.getProductGrossPrice())) {
321                         return false;
322                 } else if (!Objects.equals(this.getProductId(), product.getProductId())) {
323                         return false;
324                 } else if (!Objects.equals(this.getProductI18nKey(), product.getProductI18nKey())) {
325                         return false;
326                 } else if (!Objects.equals(this.getProductAgeGroup(), product.getProductAgeGroup())) {
327                         return false;
328                 } else if (!Objects.equals(this.getProductSize(), product.getProductSize())) {
329                         return false;
330                 }
331
332                 return true;
333         }
334
335         @Override
336         public AgeGroup getProductAgeGroup () {
337                 return this.productAgeGroup;
338         }
339
340         @Override
341         public void setProductAgeGroup (final AgeGroup productAgeGroup) {
342                 this.productAgeGroup = productAgeGroup;
343         }
344
345         @Override
346         public Boolean getProductAvailability () {
347                 return this.productAvailability;
348         }
349
350         @Override
351         public void setProductAvailability (final Boolean productAvailability) {
352                 this.productAvailability = productAvailability;
353         }
354
355         @Override
356         public Category getProductCategory () {
357                 return this.productCategory;
358         }
359
360         @Override
361         public void setProductCategory (final Category productCategory) {
362                 this.productCategory = productCategory;
363         }
364
365         @Override
366         @SuppressWarnings ("ReturnOfDateField")
367         public Date getProductCreated () {
368                 return this.productCreated;
369         }
370
371         @Override
372         @SuppressWarnings ("AssignmentToDateFieldFromParameter")
373         public void setProductCreated (final Date productCreated) {
374                 this.productCreated = productCreated;
375         }
376
377         @Override
378         public String getProductCurrencyCode () {
379                 return this.productCurrencyCode;
380         }
381
382         @Override
383         public void setProductCurrencyCode (final String productCurrencyCode) {
384                 this.productCurrencyCode = productCurrencyCode;
385         }
386
387         @Override
388         public BigDecimal getProductGrossPrice () {
389                 return this.productGrossPrice;
390         }
391
392         @Override
393         public void setProductGrossPrice (final BigDecimal productGrossPrice) {
394                 this.productGrossPrice = productGrossPrice;
395         }
396
397         @Override
398         public String getProductI18nKey () {
399                 return this.productI18nKey;
400         }
401
402         @Override
403         public void setProductI18nKey (final String productI18nKey) {
404                 this.productI18nKey = productI18nKey;
405         }
406
407         @Override
408         public Long getProductId () {
409                 return this.productId;
410         }
411
412         @Override
413         public void setProductId (final Long productId) {
414                 this.productId = productId;
415         }
416
417         @Override
418         public BasicData getProductManufacturer () {
419                 return this.productManufacturer;
420         }
421
422         @Override
423         public void setProductManufacturer (final BasicData productManufacturer) {
424                 this.productManufacturer = productManufacturer;
425         }
426
427         @Override
428         public BigDecimal getProductNetPrice () {
429                 return this.productNetPrice;
430         }
431
432         @Override
433         public void setProductNetPrice (final BigDecimal productNetPrice) {
434                 this.productNetPrice = productNetPrice;
435         }
436
437         @Override
438         public Long getProductNumber () {
439                 return this.productNumber;
440         }
441
442         @Override
443         public void setProductNumber (final Long productNumber) {
444                 this.productNumber = productNumber;
445         }
446
447         @Override
448         public String getProductSize () {
449                 return this.productSize;
450         }
451
452         @Override
453         public void setProductSize (final String productSize) {
454                 this.productSize = productSize;
455         }
456
457         @Override
458         public BigDecimal getProductTaxRate () {
459                 return this.productTaxRate;
460         }
461
462         @Override
463         public void setProductTaxRate (final BigDecimal productTaxRate) {
464                 this.productTaxRate = productTaxRate;
465         }
466
467         @Override
468         public BigDecimal getProductUnitAmount () {
469                 return this.productUnitAmount;
470         }
471
472         @Override
473         public void setProductUnitAmount (final BigDecimal productUnitAmount) {
474                 this.productUnitAmount = productUnitAmount;
475         }
476
477         @Override
478         public String getProductUnitI18nKey () {
479                 return this.productUnitI18nKey;
480         }
481
482         @Override
483         public void setProductUnitI18nKey (final String productUnitI18nKey) {
484                 this.productUnitI18nKey = productUnitI18nKey;
485         }
486
487         @Override
488         public int hashCode () {
489                 int hash = 7;
490
491                 hash = 23 * hash + Objects.hashCode(this.getProductGrossPrice());
492                 hash = 23 * hash + Objects.hashCode(this.getProductId());
493                 hash = 23 * hash + Objects.hashCode(this.getProductI18nKey());
494                 hash = 23 * hash + Objects.hashCode(this.getProductAgeGroup());
495                 hash = 23 * hash + Objects.hashCode(this.getProductSize());
496
497                 return hash;
498         }
499
500 }