2 * Copyright (C) 2016 - 2022 Free Software Foundation
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.list;
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.event.Observes;
30 import javax.faces.view.ViewScoped;
31 import javax.inject.Inject;
32 import javax.inject.Named;
33 import org.mxchange.jfinancials.beans.BaseFinancialsBean;
34 import org.mxchange.jfinancials.beans.user.login.FinancialsUserLoginWebSessionController;
35 import org.mxchange.jfinancials.events.receipt_item.added.ObservableAdminReceiptItemAddedEvent;
36 import org.mxchange.jfinancials.events.receipt_item.updated.ObservableAdminReceiptItemUpdatedEvent;
37 import org.mxchange.jfinancials.exceptions.receipt_item.ReceiptItemNotFoundException;
38 import org.mxchange.jfinancials.model.receipt_item.BillableReceiptItem;
39 import org.mxchange.jfinancials.model.receipt_item.FinancialReceiptItemSessionBeanRemote;
40 import org.mxchange.jfinancials.model.utils.ReceiptItemUtils;
41 import org.mxchange.jproduct.events.product.updated.ObservableProductUpdatedEvent;
42 import org.mxchange.juserlogincore.events.login.ObservableUserLoggedInEvent;
45 * A list financial receipt item bean (controller)
47 * @author Roland Häder<roland@mxchange.org>
49 @Named ("receiptItemListController")
51 public class FinancialsReceiptItemListWebViewBean extends BaseFinancialsBean implements FinancialsReceiptItemListWebViewController {
56 private static final long serialVersionUID = 56_189_028_928_472L;
59 * All receipt items list
61 private final List<BillableReceiptItem> allReceiptItems;
64 * Filtered receipt items list
66 private List<BillableReceiptItem> filteredReceiptItems;
69 * EJB for general financial receipt purposes
71 @EJB (lookup = "java:global/jfinancials-ejb/financialReceiptItem!org.mxchange.jfinancials.model.receipt_item.FinancialReceiptItemSessionBeanRemote")
72 private FinancialReceiptItemSessionBeanRemote receiptItemBean;
75 * A list of all branch offices (globally)
78 @NamedCache (cacheName = "receiptItemCache")
79 private transient Cache<Long, BillableReceiptItem> receiptItemCache;
82 * Selected receipt item
84 private BillableReceiptItem selectedReceiptItem;
90 private FinancialsUserLoginWebSessionController userLoginController;
93 * User's receipt items
95 private final List<BillableReceiptItem> userReceiptItems;
100 @SuppressWarnings ("CollectionWithoutInitialCapacity")
101 public FinancialsReceiptItemListWebViewBean () {
102 // Call super constructor
106 this.allReceiptItems = new LinkedList<>();
107 this.userReceiptItems = new LinkedList<>();
111 * Observes events being fired when an administrator has added a new receipt
114 * @param event Event being fired
116 public void afterAdminAddedReceiptItemEvent (@Observes final ObservableAdminReceiptItemAddedEvent event) {
117 // Validate parameter
120 throw new NullPointerException("event is null"); //NOI18N
121 } else if (event.getAddedReceiptItem() == null) {
123 throw new NullPointerException("event.addedReceiptItem is null"); //NOI18N
124 } else if (event.getAddedReceiptItem().getItemId() == null) {
126 throw new NullPointerException("event.addedReceiptItem.itemId is null"); //NOI18N
127 } else if (event.getAddedReceiptItem().getItemId() < 1) {
129 throw new IllegalArgumentException(MessageFormat.format("event.addedReceiptItem.itemId={0} is not valid", event.getAddedReceiptItem().getItemId())); //NOI18N
132 // Uniquely add to cache
133 this.uniqueAddReceiptItem(event.getAddedReceiptItem());
137 * Observes events being fired when an administrator has updated a receipt
140 * @param event Event being fired
142 public void afterAdminUpdatedReceiptItemEvent (final @Observes ObservableAdminReceiptItemUpdatedEvent event) {
143 // Validate parameter
146 throw new NullPointerException("event is null"); //NOI18N
147 } else if (event.getUpdatedReceiptItem() == null) {
149 throw new NullPointerException("event.updatedReceiptItem is null"); //NOI18N
150 } else if (event.getUpdatedReceiptItem().getItemId() == null) {
152 throw new NullPointerException("event.updatedReceiptItem.itemId is null"); //NOI18N
153 } else if (event.getUpdatedReceiptItem().getItemId() < 1) {
155 throw new IllegalArgumentException(MessageFormat.format("event.updatedReceiptItem.itemId={0} is not valid", event.getUpdatedReceiptItem().getItemId())); //NOI18N
158 // Uniquely update instance
159 this.uniqueAddReceiptItem(event.getUpdatedReceiptItem());
163 * Event observer for updated product data by administrators
165 * @param event Updated product data event
167 public void afterProductUpdatedEvent (@Observes final ObservableProductUpdatedEvent event) {
168 // Event and contained entity instance should not be null
171 throw new NullPointerException("event is null"); //NOI18N
172 } else if (event.getUpdatedProduct() == null) {
174 throw new NullPointerException("event.updatedProduct is null"); //NOI18N
175 } else if (event.getUpdatedProduct().getProductId() == null) {
177 throw new NullPointerException("event.updatedProduct.productId is null"); //NOI18N
178 } else if (event.getUpdatedProduct().getProductId() < 1) {
180 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUpdatedProduct(), event.getUpdatedProduct().getProductId())); //NOI18N
184 final Iterator<Cache.Entry<Long, BillableReceiptItem>> iterator = this.receiptItemCache.iterator();
187 while (iterator.hasNext()) {
189 final Cache.Entry<Long, BillableReceiptItem> current = iterator.next();
191 // Get current product
192 final BillableReceiptItem currentItem = current.getValue();
194 // Is the same product id set?
195 if (event.getUpdatedProduct().getProductId().equals(currentItem.getItemProduct().getProductId())) {
196 // Yes, found it, get key
197 final Long itemId = current.getKey();
200 currentItem.setItemProduct(event.getUpdatedProduct());
203 this.receiptItemCache.put(itemId, currentItem);
205 // Stop searching here
212 * Event observer for logged-in user
214 * @param event Event instance
216 public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
217 // Event and contained entity instance should not be null
220 throw new NullPointerException("event is null"); //NOI18N
221 } else if (event.getLoggedInUser() == null) {
223 throw new NullPointerException("event.loggedInUser is null"); //NOI18N
224 } else if (event.getLoggedInUser().getUserId() == null) {
226 throw new NullPointerException("event.loggedInUser.userId is null"); //NOI18N
227 } else if (event.getLoggedInUser().getUserId() < 1) {
229 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
232 // Fill cache with all found user's receipts
233 for (final BillableReceiptItem receiptItem : this.allReceiptItems) {
235 if (Objects.equals(receiptItem.getItemReceipt().getReceiptUser(), event.getLoggedInUser())) {
237 this.userReceiptItems.add(receiptItem);
243 public BillableReceiptItem findReceiptItemById (final Long receiptItemId) throws ReceiptItemNotFoundException {
244 // Validate parameter
245 if (null == receiptItemId) {
247 throw new NullPointerException("receiptItemId is null");
248 } else if (receiptItemId < 1) {
250 throw new IllegalArgumentException(MessageFormat.format("receiptItemId={0} is not valid.", receiptItemId));
254 BillableReceiptItem receiptItem = null;
256 // Iterate over whole list
257 for (final BillableReceiptItem currentReceiptItem : this.getAllReceiptItems()) {
258 // Is the primary key matching?
259 if (Objects.equals(currentReceiptItem.getItemId(), receiptItemId)) {
260 // Yes, then remember and exit iteration
261 receiptItem = currentReceiptItem;
267 if (null == receiptItem) {
269 throw new ReceiptItemNotFoundException(receiptItemId);
277 @SuppressWarnings ("ReturnOfCollectionOrArrayField")
278 public List<BillableReceiptItem> getAllReceiptItems () {
279 return this.allReceiptItems;
283 * Getter for filtered receipt items
285 * @return Filtered receipts
287 @SuppressWarnings ("ReturnOfCollectionOrArrayField")
288 public List<BillableReceiptItem> getFilteredReceiptItems () {
289 return this.filteredReceiptItems;
293 * Setter for filtered receipt items
295 * @param filteredReceiptItems Filtered receipt items
297 @SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
298 public void setFilteredReceiptItems (final List<BillableReceiptItem> filteredReceiptItems) {
299 this.filteredReceiptItems = filteredReceiptItems;
303 * Getter for selected receipt item
305 * @return Selected receipt item
307 public BillableReceiptItem getSelectedReceiptItem () {
308 return this.selectedReceiptItem;
312 * Setter for selected receipt item
314 * @param selectedReceiptItem Selected receipt item
316 public void setSelectedReceiptItem (final BillableReceiptItem selectedReceiptItem) {
317 this.selectedReceiptItem = selectedReceiptItem;
321 public void initCache () {
323 if (!this.receiptItemCache.iterator().hasNext()) {
325 for (final BillableReceiptItem receiptItem : this.receiptItemBean.fetchAllReceiptItems()) {
327 this.receiptItemCache.put(receiptItem.getItemId(), receiptItem);
331 // Is the list empty, but filled cache?
332 if (this.getAllReceiptItems().isEmpty() && this.receiptItemCache.iterator().hasNext()) {
334 for (final Cache.Entry<Long, BillableReceiptItem> currentEntry : this.receiptItemCache) {
336 this.getAllReceiptItems().add(currentEntry.getValue());
340 this.getAllReceiptItems().sort(new Comparator<BillableReceiptItem>() {
342 public int compare (final BillableReceiptItem receiptItem1, final BillableReceiptItem receiptItem2) {
343 return receiptItem1.getItemId() > receiptItem2.getItemId() ? 1 : receiptItem1.getItemId() < receiptItem2.getItemId() ? -1 : 0;
351 public boolean isReceiptItemAdded (final BillableReceiptItem receiptItem) {
352 // Does it contain the same object?
353 if (this.getAllReceiptItems().contains(receiptItem)) {
354 // Yes, skip below code
358 // Default is not the same
359 boolean alreadyAdded = false;
362 for (final BillableReceiptItem item : this.getAllReceiptItems()) {
364 if (ReceiptItemUtils.isSameReceiptItem(item, receiptItem)) {
376 * Uniquely add a receipt item instance.
378 * @param receiptItem To be added/updated receipt item instance
380 private void uniqueAddReceiptItem (final BillableReceiptItem receiptItem) {
381 // Add to cache and general list
382 this.receiptItemCache.put(receiptItem.getItemId(), receiptItem);
385 final Iterator<BillableReceiptItem> allIterator = this.getAllReceiptItems().iterator();
387 // Iterate over all entries
388 while (allIterator.hasNext()) {
390 final BillableReceiptItem currentReceiptItem = allIterator.next();
392 // It the id matching?
393 if (Objects.equals(receiptItem.getItemId(), currentReceiptItem.getItemId())) {
394 // Yes, then remove it and stop iterating
395 allIterator.remove();
401 this.getAllReceiptItems().add(receiptItem);
404 if (this.userLoginController.isUserLoggedIn() && Objects.equals(receiptItem.getItemReceipt().getReceiptUser(), this.userLoginController.getLoggedInUser())) {
406 final Iterator<BillableReceiptItem> userIterator = this.userReceiptItems.iterator();
408 // Iterate over all entries
409 while (userIterator.hasNext()) {
411 final BillableReceiptItem currentReceiptItem = userIterator.next();
413 // It the id matching?
414 if (Objects.equals(receiptItem.getItemId(), currentReceiptItem.getItemId())) {
415 // Yes, then remove it and stop iterating
416 userIterator.remove();
422 this.userReceiptItems.add(receiptItem);