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 Affero General Public License as
6 * published by the Free Software Foundation, either version 3 of the
7 * License, or (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 Affero General Public License for more details.
14 * You should have received a copy of the GNU Affero General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 package org.mxchange.jfinancials.beans.financial.model.receipt_item;
19 import fish.payara.cdi.jsr107.impl.NamedCache;
20 import java.text.MessageFormat;
21 import java.util.Comparator;
22 import java.util.Iterator;
23 import java.util.LinkedList;
24 import java.util.List;
25 import java.util.Objects;
26 import javax.annotation.PostConstruct;
27 import javax.cache.Cache;
29 import javax.enterprise.context.RequestScoped;
30 import javax.enterprise.event.Event;
31 import javax.enterprise.event.Observes;
32 import javax.enterprise.inject.Any;
33 import javax.faces.view.facelets.FaceletException;
34 import javax.inject.Inject;
35 import javax.inject.Named;
36 import org.mxchange.jfinancials.beans.BaseFinancialsBean;
37 import org.mxchange.jfinancials.beans.user.login.FinancialsUserLoginWebSessionController;
38 import org.mxchange.jfinancials.events.receipt_item.added.ObservableReceiptItemAddedEvent;
39 import org.mxchange.jfinancials.events.receipt_item.added.ReceiptItemAddedEvent;
40 import org.mxchange.jfinancials.exceptions.receipt_item.ReceiptItemAlreadyAddedException;
41 import org.mxchange.jfinancials.model.receipt.item.BillableReceiptItem;
42 import org.mxchange.jfinancials.model.receipt.item.FinancialReceiptItem;
43 import org.mxchange.jfinancials.model.receipt_item.FinancialReceiptItemSessionBeanRemote;
44 import org.mxchange.juserlogincore.events.login.ObservableUserLoggedInEvent;
47 * A general financial receipt item bean (controller)
49 * @author Roland Häder<roland@mxchange.org>
51 @Named ("receiptItemController")
53 public class FinancialsReceiptItemWebRequestBean extends BaseFinancialsBean implements FinancialsReceiptItemWebRequestController {
58 private static final long serialVersionUID = 56_189_028_928_372L;
61 * Event being fired when user has added a new receipt
65 private Event<ObservableReceiptItemAddedEvent> addedReceiptItemEvent;
68 * All receipt items list
70 private final List<BillableReceiptItem> allReceiptItems;
73 * Filtered receipt items list
75 private List<BillableReceiptItem> filteredReceiptItems;
78 * EJB for general financial receipt purposes
80 @EJB (lookup = "java:global/jfinancials-ejb/financialReceiptItem!org.mxchange.jfinancials.model.receipt.item.FinancialReceiptItemSessionBeanRemote")
81 private FinancialReceiptItemSessionBeanRemote receiptItemBean;
84 * A list of all branch offices (globally)
87 @NamedCache (cacheName = "receiptItemCache")
88 private Cache<Long, BillableReceiptItem> receiptItemCache;
94 private FinancialsUserLoginWebSessionController userLoginController;
97 * User's receipt items
99 private final List<BillableReceiptItem> userReceiptItems;
104 @SuppressWarnings ("CollectionWithoutInitialCapacity")
105 public FinancialsReceiptItemWebRequestBean () {
106 // Call super constructor
110 this.allReceiptItems = new LinkedList<>();
111 this.userReceiptItems = new LinkedList<>();
115 * Adds the completed receipt item to database by calling an EJB business method.
116 * If not all required fields are set, a proper exception is being thrown.
118 * @return Link outcome
120 public String addReceiptItem () {
121 // Are all required fields set?
122 if (!this.userLoginController.isUserLoggedIn()) {
124 throw new IllegalStateException("User is not logged-in"); //NOI18N
127 // Prepare receipt instance
128 final BillableReceiptItem receiptItem = this.createReceiptInstance();
130 // Is the receipt already there?
131 if (this.isReceiptItemAdded(receiptItem)) {
132 // Receipt has already been added
133 throw new FaceletException(MessageFormat.format("Receipt for itemReceipt.receiptId={0},itemProduct.productId={1},itemProductQuantity={2} has already been added.", receiptItem.getItemReceipt().getReceiptId(), receiptItem.getItemProduct().getProductId(), receiptItem.getItemProductQuantity())); //NOI18N
137 final BillableReceiptItem updatedReceiptItem;
139 // All is set, then try to call EJB
142 updatedReceiptItem = this.receiptItemBean.addReceiptItem(receiptItem);
143 } catch (final ReceiptItemAlreadyAddedException ex) {
145 throw new FaceletException(ex);
148 // Fire event with updated instance
149 this.addedReceiptItemEvent.fire(new ReceiptItemAddedEvent(updatedReceiptItem));
154 // Return redirect outcome
155 return "add_receipt_item?faces-redirect=true"; //NOI18N
159 * Observes events being fired when a new receipt item has been added
161 * @param event Event being fired
163 public void afterAddedReceiptItemEvent (@Observes final ObservableReceiptItemAddedEvent event) {
164 // Validate parameter
167 throw new NullPointerException("event is null"); //NOI18N
170 // Add to cache and general list
171 this.receiptItemCache.put(event.getReceiptItem().getItemId(), event.getReceiptItem());
172 this.allReceiptItems.add(event.getReceiptItem());
175 if (this.userLoginController.isUserLoggedIn() && Objects.equals(event.getReceiptItem().getItemReceipt().getReceiptUser(), this.userLoginController.getLoggedInUser())) {
176 // Same user, then add it
177 this.userReceiptItems.add(event.getReceiptItem());
182 * Event observer for logged-in user
184 * @param event Event instance
186 public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
187 // event should not be null
190 throw new NullPointerException("event is null"); //NOI18N
191 } else if (event.getLoggedInUser() == null) {
193 throw new NullPointerException("event.loggedInUser is null"); //NOI18N
194 } else if (event.getLoggedInUser().getUserId() == null) {
196 throw new NullPointerException("event.loggedInUser.userId is null"); //NOI18N
197 } else if (event.getLoggedInUser().getUserId() < 1) {
199 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
202 // Fill cache with all found user's receipts
203 for (final BillableReceiptItem receiptItem : this.allReceiptItems) {
205 if (Objects.equals(receiptItem.getItemReceipt().getReceiptUser(), event.getLoggedInUser())) {
207 this.userReceiptItems.add(receiptItem);
213 * Returns all receipt items
215 * @return All receipt items
217 @SuppressWarnings ("ReturnOfCollectionOrArrayField")
218 public List<BillableReceiptItem> allReceiptItems () {
219 return this.allReceiptItems;
223 * Getter for filtered receipt items
225 * @return Filtered receipts
227 @SuppressWarnings ("ReturnOfCollectionOrArrayField")
228 public List<BillableReceiptItem> getFilteredReceiptItems () {
229 return this.filteredReceiptItems;
233 * Setter for filtered receipt items
235 * @param filteredReceiptItems Filtered receipt items
237 @SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
238 public void setFilteredReceipts (final List<BillableReceiptItem> filteredReceiptItems) {
239 this.filteredReceiptItems = filteredReceiptItems;
243 public void initCache () {
245 if (!this.receiptItemCache.iterator().hasNext()) {
247 final List<BillableReceiptItem> receiptItems = this.receiptItemBean.allReceiptItems();
250 for (final BillableReceiptItem receiptItem : receiptItems) {
252 this.receiptItemCache.put(receiptItem.getItemId(), receiptItem);
256 // Is the list empty, but filled cache?
257 if (this.allReceiptItems.isEmpty() && this.receiptItemCache.iterator().hasNext()) {
259 final Iterator<Cache.Entry<Long, BillableReceiptItem>> iterator = this.receiptItemCache.iterator();
262 while (iterator.hasNext()) {
264 final Cache.Entry<Long, BillableReceiptItem> next = iterator.next();
267 this.allReceiptItems.add(next.getValue());
271 this.allReceiptItems.sort(new Comparator<BillableReceiptItem>() {
273 public int compare (final BillableReceiptItem o1, final BillableReceiptItem o2) {
274 return o1.getItemId() > o2.getItemId() ? 1 : o1.getItemId() < o2.getItemId() ? -1 : 0;
282 public boolean isReceiptItemAdded (final BillableReceiptItem receiptItem) {
283 // Always trust the cache
284 return this.allReceiptItems.contains(receiptItem);
290 private void clear () {
295 * Returns a fully created receipt item instance (except primary key, of course)
297 * @return Receipt item instance
299 private BillableReceiptItem createReceiptInstance () {
300 // Init receipt instance
301 final BillableReceiptItem receiptItem = new FinancialReceiptItem();
303 // Set optional fields