2 * Copyright (C) 2016, 2017 Roland Häder
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.GeneratedValue;
27 import javax.persistence.GenerationType;
28 import javax.persistence.Id;
29 import javax.persistence.JoinColumn;
30 import javax.persistence.NamedQueries;
31 import javax.persistence.NamedQuery;
32 import javax.persistence.OneToOne;
33 import javax.persistence.Table;
34 import javax.persistence.Temporal;
35 import javax.persistence.TemporalType;
36 import javax.persistence.Transient;
37 import org.mxchange.jcontactsbusiness.model.basicdata.BasicData;
38 import org.mxchange.jcontactsbusiness.model.basicdata.BusinessBasicData;
39 import org.mxchange.jproduct.model.category.Category;
40 import org.mxchange.jproduct.model.category.ProductCategory;
43 * Generic product class
45 * @author Roland Häder<roland@mxchange.org>
46 * TODO: Find a better name
48 @Entity (name = "generic_products")
49 @Table (name = "generic_products")
52 @NamedQuery (name = "AllProducts", query = "SELECT p FROM generic_products AS p ORDER BY p.productId ASC"),
53 @NamedQuery (name = "AllAvailableProducts", query = "SELECT p FROM generic_products AS p WHERE p.productAvailability=TRUE ORDER BY p.productId ASC")
56 @SuppressWarnings ("PersistenceUnitPresent")
57 public class GenericProduct implements Product {
63 private static final long serialVersionUID = 54_578_571_769_283L;
66 * Availability of product
68 @Basic (optional = false)
69 @Column (name = "product_availability", nullable = false)
70 private Boolean productAvailability;
73 * Product productCategory
75 @JoinColumn (name = "product_category_id", referencedColumnName = "category_id", nullable = false, updatable = false)
76 @OneToOne (targetEntity = ProductCategory.class, cascade = CascadeType.REFRESH, optional = false)
77 private Category productCategory;
80 * When this product has been created
82 @Basic (optional = false)
83 @Column (name = "product_created", nullable = false, updatable = false)
84 @Temporal (TemporalType.TIMESTAMP)
85 private Date productCreated;
88 * Currency code for both prices, like EUR or USD
90 @Basic (optional = false)
91 @Column (name = "product_currency_code", nullable = false, length = 3)
92 private String productCurrencyCode;
95 * Gross price of product
97 @Basic (optional = false)
98 @Column (name = "product_gross_price", nullable = false)
99 private Float productGrossPrice;
102 * I18n key of product
104 @Basic (optional = false)
105 @Column (name = "product_i18n_key", length = 100, nullable = false, unique = true)
106 private String productI18nKey;
109 * Id number of product
112 @GeneratedValue (strategy = GenerationType.IDENTITY)
113 @Column (name = "product_id", nullable = false, updatable = false)
114 private Long productId;
117 * The company that has manufactured/produced this product
119 @JoinColumn (name = "product_manufacturer_id", referencedColumnName = "company_data_id")
120 @OneToOne (targetEntity = BusinessBasicData.class, cascade = CascadeType.REFRESH)
121 private BasicData productManufacturer;
124 * Net price of product
126 @Column (name = "product_net_price")
127 private Float productNetPrice;
130 * Tax rate (0-1, by 1=100%)
132 @Column (name = "product_tax_rate")
133 private Float productTaxRate;
136 * Amount of this product (for example 1 for 1 liter)
138 @Column (name = "product_unit_amount")
139 private Float productUnitAmount;
142 * Unit type (for example liter)
144 @Column (name = "product_unit_type")
145 private String productUnitType;
148 * Default constructor
150 public GenericProduct () {
154 * Constructor will all required data
156 * @param productI18nKey I18n key of product
157 * @param productGrossPrice Product's gross price
158 * @param productCurrencyCode Currency code for both prices
159 * @param productCategory Category instance
160 * @param productAvailability Availability (selectable by customer)
161 * @throws NullPointerException If a parameter is null
162 * @throws IllegalArgumentException If a parameter is empty (string) or out of bounds
164 public GenericProduct (final String productI18nKey, final Float productGrossPrice, final String productCurrencyCode, final Category productCategory, final Boolean productAvailability) {
165 // Call other constructor first
168 // Validate all parameters
169 if (null == productAvailability) {
171 throw new NullPointerException("productAvailability is null"); //NOI18N
172 } else if (null == productCategory) {
174 throw new NullPointerException("productCategory is null"); //NOI18N
175 } else if (productCategory.getCategoryId() == null) {
177 throw new NullPointerException("productCategory.categoryId is null"); //NOI18N
178 } else if (productCategory.getCategoryId() < 1) {
180 throw new IllegalArgumentException(MessageFormat.format("productCategory.categoryId={0} is invalid", productCategory.getCategoryId())); //NOI18N
181 } else if (null == productCurrencyCode) {
183 throw new NullPointerException("productCurrencyCode is null"); //NOI18N
184 } else if (productCurrencyCode.isEmpty()) {
186 throw new IllegalArgumentException("productCurrencyCode is empty"); //NOI18N
187 } else if (null == productGrossPrice) {
189 throw new NullPointerException("productGrossPrice is null"); //NOI18N
190 } else if (productGrossPrice < 0) {
192 throw new IllegalArgumentException(MessageFormat.format("productGrossPrice={0} is invalid. Do not enter discounts as products.", productGrossPrice)); //NOI18N
193 } else if (null == productI18nKey) {
195 throw new NullPointerException("productI18nKey is null"); //NOI18N
196 } else if (productI18nKey.isEmpty()) {
198 throw new IllegalArgumentException("productI18nKey is empty"); //NOI18N
202 this.productI18nKey = productI18nKey;
203 this.productGrossPrice = productGrossPrice;
204 this.productCurrencyCode = productCurrencyCode.toUpperCase();
205 this.productCategory = productCategory;
206 this.productAvailability = productAvailability;
210 public boolean equals (final Object object) {
211 if (this == object) {
213 } else if (null == object) {
215 } else if (this.getClass() != object.getClass()) {
219 final Product product = (Product) object;
221 if (!Objects.equals(this.getProductId(), product.getProductId())) {
223 } else if (!Objects.equals(this.getProductI18nKey(), product.getProductI18nKey())) {
231 public Boolean getProductAvailability () {
232 return this.productAvailability;
236 public void setProductAvailability (final Boolean productAvailability) {
237 this.productAvailability = productAvailability;
241 public Category getProductCategory () {
242 return this.productCategory;
246 public void setProductCategory (final Category productCategory) {
247 this.productCategory = productCategory;
251 @SuppressWarnings ("ReturnOfDateField")
252 public Date getProductCreated () {
253 return this.productCreated;
257 @SuppressWarnings ("AssignmentToDateFieldFromParameter")
258 public void setProductCreated (final Date productCreated) {
259 this.productCreated = productCreated;
263 public String getProductCurrencyCode () {
264 return this.productCurrencyCode;
268 public void setProductCurrencyCode (final String productCurrencyCode) {
269 this.productCurrencyCode = productCurrencyCode;
273 public Float getProductGrossPrice () {
274 return this.productGrossPrice;
278 public void setProductGrossPrice (final Float productGrossPrice) {
279 this.productGrossPrice = productGrossPrice;
283 public String getProductI18nKey () {
284 return this.productI18nKey;
288 public void setProductI18nKey (final String productI18nKey) {
289 this.productI18nKey = productI18nKey;
293 public Long getProductId () {
294 return this.productId;
298 public void setProductId (final Long productId) {
299 this.productId = productId;
303 public BasicData getProductManufacturer () {
304 return this.productManufacturer;
308 public void setProductManufacturer (final BasicData productManufacturer) {
309 this.productManufacturer = productManufacturer;
313 public Float getProductNetPrice () {
314 return this.productNetPrice;
318 public void setProductNetPrice (final Float productNetPrice) {
319 this.productNetPrice = productNetPrice;
323 public Float getProductTaxRate () {
324 return this.productTaxRate;
328 public void setProductTaxRate (final Float productTaxRate) {
329 this.productTaxRate = productTaxRate;
333 public Float getProductUnitAmount () {
334 return this.productUnitAmount;
338 public void setProductUnitAmount (final Float productUnitAmount) {
339 this.productUnitAmount = productUnitAmount;
343 public String getProductUnitType () {
344 return this.productUnitType;
348 public void setProductUnitType (final String productUnitType) {
349 this.productUnitType = productUnitType;
353 public int hashCode () {
356 hash = 23 * hash + Objects.hashCode(this.getProductId());
357 hash = 23 * hash + Objects.hashCode(this.getProductI18nKey());