]> git.mxchange.org Git - jfinancials-war.git/blob
46a90a6dab0591a0a40c6549800ea435a50402a1
[jfinancials-war.git] /
1 /*
2  * Copyright (C) 2016, 2017 Roland Häder
3  *
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.
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 Affero General Public License for more details.
13  *
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/>.
16  */
17 package org.mxchange.jfinancials.beans.financial.model.receipt;
18
19 import fish.payara.cdi.jsr107.impl.NamedCache;
20 import java.text.MessageFormat;
21 import java.util.Comparator;
22 import java.util.Date;
23 import java.util.Iterator;
24 import java.util.LinkedList;
25 import java.util.List;
26 import java.util.Objects;
27 import javax.annotation.PostConstruct;
28 import javax.cache.Cache;
29 import javax.ejb.EJB;
30 import javax.enterprise.context.RequestScoped;
31 import javax.enterprise.event.Event;
32 import javax.enterprise.event.Observes;
33 import javax.enterprise.inject.Any;
34 import javax.faces.view.facelets.FaceletException;
35 import javax.inject.Inject;
36 import javax.inject.Named;
37 import org.mxchange.jcontactsbusiness.model.branchoffice.BranchOffice;
38 import org.mxchange.jcontactsbusiness.model.employee.Employee;
39 import org.mxchange.jfinancials.beans.BaseFinancialsBean;
40 import org.mxchange.jfinancials.beans.user.login.FinancialsUserLoginWebSessionController;
41 import org.mxchange.jfinancials.events.receipt.added.ObservableReceiptAddedEvent;
42 import org.mxchange.jfinancials.events.receipt.added.ReceiptAddedEvent;
43 import org.mxchange.jfinancials.exceptions.ReceiptAlreadyAddedException;
44 import org.mxchange.jfinancials.model.receipt.BillableReceipt;
45 import org.mxchange.jfinancials.model.receipt.FinancialReceipt;
46 import org.mxchange.jfinancials.model.receipt.FinancialReceiptSessionBeanRemote;
47 import org.mxchange.jproduct.model.payment.PaymentType;
48 import org.mxchange.juserlogincore.events.login.ObservableUserLoggedInEvent;
49
50 /**
51  * An administrative financial receipt bean (controller)
52  * <p>
53  * @author Roland Häder<roland@mxchange.org>
54  */
55 @Named ("receiptController")
56 @RequestScoped
57 public class FinancialsReceiptWebRequestBean extends BaseFinancialsBean implements FinancialsReceiptWebRequestController {
58
59         /**
60          * Serial number
61          */
62         private static final long serialVersionUID = 56_189_028_928_371L;
63
64         /**
65          * Event being fired when user has added a new receipt
66          */
67         @Inject
68         @Any
69         private Event<ObservableReceiptAddedEvent> addedReceiptEvent;
70
71         /**
72          * All receipts list
73          */
74         private final List<BillableReceipt> allReceipts;
75
76         /**
77          * Filtered receipts list
78          */
79         private List<BillableReceipt> filteredReceipts;
80
81         /**
82          * Bar-code number
83          */
84         private Long receiptBarCodeNumber;
85
86         /**
87          * EJB for general financial receipt purposes
88          */
89         @EJB (lookup = "java:global/jfinancials-ejb/financialReceipt!org.mxchange.jfinancials.model.receipt.FinancialReceiptSessionBeanRemote")
90         private FinancialReceiptSessionBeanRemote receiptBean;
91
92         /**
93          * Recipient issuing company (for example where the user went shopping to)
94          */
95         private BranchOffice receiptBranchOffice;
96
97         /**
98          * A list of all branch offices (globally)
99          */
100         @Inject
101         @NamedCache (cacheName = "receiptCache")
102         private Cache<Long, BillableReceipt> receiptCache;
103
104         /**
105          * Date/time the receipt has been issued
106          */
107         private Date receiptIssued;
108
109         /**
110          * Receipt number (only numbers)
111          */
112         private Long receiptNumber;
113
114         /**
115          * Payment type being used for this receipt
116          */
117         private PaymentType receiptPaymentType;
118
119         /**
120          * Register number
121          */
122         private Long receiptRegisterNumber;
123
124         /**
125          * Selling employee
126          */
127         private Employee receiptSellerEmployee;
128
129         /**
130          * User instance
131          */
132         @Inject
133         private FinancialsUserLoginWebSessionController userLoginController;
134
135         /**
136          * User's receipts
137          */
138         private final List<BillableReceipt> userReceipts;
139
140         /**
141          * Constructor
142          */
143         @SuppressWarnings ("CollectionWithoutInitialCapacity")
144         public FinancialsReceiptWebRequestBean () {
145                 // Call super constructor
146                 super();
147
148                 // Init lists
149                 this.allReceipts = new LinkedList<>();
150                 this.userReceipts = new LinkedList<>();
151         }
152
153         /**
154          * Adds the completed receipt to database by calling an EJB business method.
155          * If not all required fields are set, a proper exception is being thrown.
156          * <p>
157          * @return Link outcome
158          */
159         public String addReceipt () {
160                 // Are all required fields set?
161                 if (!this.userLoginController.isUserLoggedIn()) {
162                         // Not logged-in
163                         throw new IllegalStateException("User is not logged-in"); //NOI18N
164                 } else if (this.getReceiptBranchOffice() == null) {
165                         // Is not set
166                         throw new NullPointerException("this.receiptBranchOffice is not set."); //NOI18N
167                 } else if (this.getReceiptBranchOffice().getBranchId() == null) {
168                         // It must be an already peristed instance
169                         throw new NullPointerException("this.receiptBranchOffice.businessContactId is not set."); //NOI18N
170                 } else if (this.getReceiptBranchOffice().getBranchId() < 1) {
171                         // It must be an already peristed instance
172                         throw new IllegalArgumentException(MessageFormat.format("this.receiptBranchOffice.businessContactId={0} is not valid.", this.getReceiptBranchOffice().getBranchId())); //NOI18N
173                 } else if (this.getReceiptPaymentType() == null) {
174                         // Is not set
175                         throw new NullPointerException("this.receiptPaymentType is not set."); //NOI18N
176                 } else if (this.getReceiptIssued() == null) {
177                         // Is not set
178                         throw new NullPointerException("this.receiptIssued is not set."); //NOI18N
179                 }
180
181                 // Prepare receipt instance
182                 final BillableReceipt receipt = this.createReceiptInstance();
183
184                 // Is the receipt already there?
185                 if (this.isReceiptAdded(receipt)) {
186                         // Receipt has already been added
187                         throw new FaceletException(MessageFormat.format("Receipt for receiptBranchOffice={0},receiptIssued={1},receiptNumber={2} has already been added.", this.getReceiptBranchOffice().getBranchId(), this.getReceiptIssued().toString(), this.getReceiptNumber())); //NOI18N
188                 }
189
190                 // Init variable
191                 final BillableReceipt updatedReceipt;
192
193                 // All is set, then try to call EJB
194                 try {
195                         // Add it
196                         updatedReceipt = this.receiptBean.addReceipt(receipt);
197                 } catch (final ReceiptAlreadyAddedException ex) {
198                         // Throw it again
199                         throw new FaceletException(ex);
200                 }
201
202                 // Fire event with updated instance
203                 this.addedReceiptEvent.fire(new ReceiptAddedEvent(updatedReceipt));
204
205                 // Return redirect outcome
206                 return "add_receipt_item?faces-redirect=true"; //NOI18N
207         }
208
209         /**
210          * Observes events being fired when a new receipt has been added
211          * <p>
212          * @param event Event being fired
213          */
214         public void afterAddedReceiptEvent (@Observes final ObservableReceiptAddedEvent event) {
215                 // Validate parameter
216                 if (null == event) {
217                         // Throw NPE
218                         throw new NullPointerException("event is null"); //NOI18N
219                 } else if (event.getReceipt() == null) {
220                         // Throw NPE again
221                         throw new NullPointerException("event.receipt is null"); //NOI18N
222                 } else if (event.getReceipt().getReceiptId() == null) {
223                         // Throw it again
224                         throw new NullPointerException("event.receipt.receiptId is null"); //NOI18N
225                 } else if (event.getReceipt().getReceiptId() < 1) {
226                         // Throw IAE
227                         throw new IllegalArgumentException(MessageFormat.format("event.receipt.receiptId={0} is invalid", event.getReceipt().getReceiptId())); //NOI18N
228                 }
229
230                 // Add to cache and general list
231                 this.receiptCache.put(event.getReceipt().getReceiptId(), event.getReceipt());
232                 this.allReceipts.add(event.getReceipt());
233
234                 // Is same user?
235                 if (this.userLoginController.isUserLoggedIn() && Objects.equals(event.getReceipt().getReceiptUser(), this.userLoginController.getLoggedInUser())) {
236                         // Same user, then add it
237                         this.userReceipts.add(event.getReceipt());
238                 }
239         }
240
241         /**
242          * Event observer for logged-in user
243          * <p>
244          * @param event Event instance
245          */
246         public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
247                 // event should not be null
248                 if (null == event) {
249                         // Throw NPE
250                         throw new NullPointerException("event is null"); //NOI18N
251                 } else if (event.getLoggedInUser() == null) {
252                         // Throw NPE again
253                         throw new NullPointerException("event.loggedInUser is null"); //NOI18N
254                 } else if (event.getLoggedInUser().getUserId() == null) {
255                         // userId is null
256                         throw new NullPointerException("event.loggedInUser.userId is null"); //NOI18N
257                 } else if (event.getLoggedInUser().getUserId() < 1) {
258                         // Not avalid id
259                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
260                 }
261
262                 // Fill cache with all found user's receipts
263                 for (final BillableReceipt receipt : this.allReceipts) {
264                         // Is same user?
265                         if (Objects.equals(receipt.getReceiptUser(), event.getLoggedInUser())) {
266                                 // Yes, then add it
267                                 this.userReceipts.add(receipt);
268                         }
269                 }
270         }
271
272         /**
273          * Returns all receipts
274          * <p>
275          * @return All receipts
276          */
277         @SuppressWarnings ("ReturnOfCollectionOrArrayField")
278         public List<BillableReceipt> allReceipts () {
279                 return this.allReceipts;
280         }
281
282         /**
283          * Getter for filtered receipts
284          * <p>
285          * @return Filtered receipts
286          */
287         @SuppressWarnings ("ReturnOfCollectionOrArrayField")
288         public List<BillableReceipt> getFilteredReceipts () {
289                 return this.filteredReceipts;
290         }
291
292         /**
293          * Setter for filtered receipts
294          * <p>
295          * @param filteredReceipts Filtered receipts
296          */
297         @SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
298         public void setFilteredReceipts (final List<BillableReceipt> filteredReceipts) {
299                 this.filteredReceipts = filteredReceipts;
300         }
301
302         /**
303          * Getter for receipt's bar-code number
304          * <p>
305          * @return Receipt's bar-code number
306          */
307         public Long getReceiptBarCodeNumber () {
308                 return this.receiptBarCodeNumber;
309         }
310
311         /**
312          * Setter for receipt's bar-code number
313          * <p>
314          * @param receiptBarCodeNumber Receipt's bar-code number
315          */
316         public void setReceiptBarCodeNumber (final Long receiptBarCodeNumber) {
317                 this.receiptBarCodeNumber = receiptBarCodeNumber;
318         }
319
320         /**
321          * Getter for receipt issuing branch office
322          * <p>
323          * @return Receipt issuing branch office
324          */
325         public BranchOffice getReceiptBranchOffice () {
326                 return this.receiptBranchOffice;
327         }
328
329         /**
330          * Setter for receipt issuing branch office
331          * <p>
332          * @param receiptBranchOffice Receipt issuing branch office
333          */
334         public void setReceiptBranchOffice (final BranchOffice receiptBranchOffice) {
335                 this.receiptBranchOffice = receiptBranchOffice;
336         }
337
338         /**
339          * Getter for receipt issue date and time
340          * <p>
341          * @return Receipt issue date and time
342          */
343         @SuppressWarnings ("ReturnOfDateField")
344         public Date getReceiptIssued () {
345                 return this.receiptIssued;
346         }
347
348         /**
349          * Setter for receipt issue date and time
350          * <p>
351          * @param receiptIssued Receipt issue date and time
352          */
353         @SuppressWarnings ("AssignmentToDateFieldFromParameter")
354         public void setReceiptIssued (final Date receiptIssued) {
355                 this.receiptIssued = receiptIssued;
356         }
357
358         /**
359          * Getter for receipt number
360          * <p>
361          * @return Receipt number
362          */
363         public Long getReceiptNumber () {
364                 return this.receiptNumber;
365         }
366
367         /**
368          * Setter for receipt number
369          * <p>
370          * @param receiptNumber Receipt number
371          */
372         public void setReceiptNumber (final Long receiptNumber) {
373                 this.receiptNumber = receiptNumber;
374         }
375
376         /**
377          * Getter for payment type
378          * <p>
379          * @return Payment type
380          */
381         public PaymentType getReceiptPaymentType () {
382                 return this.receiptPaymentType;
383         }
384
385         /**
386          * Setter for payment type
387          * <p>
388          * @param receiptPaymentType Payment type
389          */
390         public void setReceiptPaymentType (final PaymentType receiptPaymentType) {
391                 this.receiptPaymentType = receiptPaymentType;
392         }
393
394         /**
395          * Getter for receipt register's number
396          * <p>
397          * @return Receipt register's number
398          */
399         public Long getReceiptRegisterNumber () {
400                 return this.receiptRegisterNumber;
401         }
402
403         /**
404          * Setter for receipt register's number
405          * <p>
406          * @param receiptRegisterNumber Receipt register's number
407          */
408         public void setReceiptRegisterNumber (final Long receiptRegisterNumber) {
409                 this.receiptRegisterNumber = receiptRegisterNumber;
410         }
411
412         /**
413          * Getter for receipt seller employee
414          * <p>
415          * @return Receipt seller employee
416          */
417         public Employee getReceiptSellerEmployee () {
418                 return this.receiptSellerEmployee;
419         }
420
421         /**
422          * Setter for receipt seller employee
423          * <p>
424          * @param receiptSellerEmployee Receipt seller employee
425          */
426         public void setReceiptSellerEmployee (final Employee receiptSellerEmployee) {
427                 this.receiptSellerEmployee = receiptSellerEmployee;
428         }
429
430         @PostConstruct
431         public void initCache () {
432                 // Is cache there?
433                 if (!this.receiptCache.iterator().hasNext()) {
434                         // Get whole list
435                         final List<BillableReceipt> list = this.receiptBean.allReceipts();
436
437                         // Add all
438                         for (final Iterator<BillableReceipt> iterator = list.iterator(); iterator.hasNext();) {
439                                 // Get next element
440                                 final BillableReceipt next = iterator.next();
441
442                                 // Add it to cache
443                                 this.receiptCache.put(next.getReceiptId(), next);
444                         }
445                 }
446
447                 // Is the list empty, but filled cache?
448                 if (this.allReceipts.isEmpty() && this.receiptCache.iterator().hasNext()) {
449                         // Get iterator
450                         final Iterator<Cache.Entry<Long, BillableReceipt>> iterator = this.receiptCache.iterator();
451
452                         // Build up list
453                         while (iterator.hasNext()) {
454                                 // GEt next element
455                                 final Cache.Entry<Long, BillableReceipt> next = iterator.next();
456
457                                 // Add to list
458                                 this.allReceipts.add(next.getValue());
459                         }
460
461                         // Sort list
462                         this.allReceipts.sort(new Comparator<BillableReceipt>() {
463                                 @Override
464                                 public int compare (final BillableReceipt o1, final BillableReceipt o2) {
465                                         return o1.getReceiptId() > o2.getReceiptId() ? 1 : o1.getReceiptId() < o2.getReceiptId() ? -1 : 0;
466                                 }
467                         }
468                         );
469                 }
470         }
471
472         @Override
473         public boolean isReceiptAdded (final BillableReceipt receipt) {
474                 // Always trust the cache
475                 return this.allReceipts.contains(receipt);
476         }
477
478         /**
479          * Returns a fully created receipt instance (except primary key, of course)
480          * <p>
481          * @return Receipt instance
482          */
483         private BillableReceipt createReceiptInstance () {
484                 // Init receipt instance
485                 final BillableReceipt receipt = new FinancialReceipt(this.getReceiptPaymentType(), this.getReceiptBranchOffice(), this.userLoginController.getLoggedInUser(), this.getReceiptIssued());
486
487                 // Set optional fields
488                 receipt.setReceiptNumber(this.getReceiptNumber());
489                 receipt.setReceiptBarCodeNumber(this.getReceiptBarCodeNumber());
490                 receipt.setReceiptRegisterNumber(this.getReceiptRegisterNumber());
491                 receipt.setReceiptSellerEmployee(this.getReceiptSellerEmployee());
492
493                 // Return it
494                 return receipt;
495         }
496 }