]> git.mxchange.org Git - jfinancials-war.git/blob
9ff56943943aaa982d5b0e99501ed0304147be6a
[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.receipt.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  * A general 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                 // Clear bean
206                 this.clear();
207
208                 // Return redirect outcome
209                 return "add_receipt_item?faces-redirect=true"; //NOI18N
210         }
211
212         /**
213          * Observes events being fired when a new receipt has been added
214          * <p>
215          * @param event Event being fired
216          */
217         public void afterAddedReceiptEvent (@Observes final ObservableReceiptAddedEvent event) {
218                 // Validate parameter
219                 if (null == event) {
220                         // Throw NPE
221                         throw new NullPointerException("event is null"); //NOI18N
222                 } else if (event.getReceipt() == null) {
223                         // Throw NPE again
224                         throw new NullPointerException("event.receipt is null"); //NOI18N
225                 } else if (event.getReceipt().getReceiptId() == null) {
226                         // Throw it again
227                         throw new NullPointerException("event.receipt.receiptId is null"); //NOI18N
228                 } else if (event.getReceipt().getReceiptId() < 1) {
229                         // Throw IAE
230                         throw new IllegalArgumentException(MessageFormat.format("event.receipt.receiptId={0} is invalid", event.getReceipt().getReceiptId())); //NOI18N
231                 }
232
233                 // Add to cache and general list
234                 this.receiptCache.put(event.getReceipt().getReceiptId(), event.getReceipt());
235                 this.allReceipts.add(event.getReceipt());
236
237                 // Is same user?
238                 if (this.userLoginController.isUserLoggedIn() && Objects.equals(event.getReceipt().getReceiptUser(), this.userLoginController.getLoggedInUser())) {
239                         // Same user, then add it
240                         this.userReceipts.add(event.getReceipt());
241                 }
242         }
243
244         /**
245          * Event observer for logged-in user
246          * <p>
247          * @param event Event instance
248          */
249         public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
250                 // event should not be null
251                 if (null == event) {
252                         // Throw NPE
253                         throw new NullPointerException("event is null"); //NOI18N
254                 } else if (event.getLoggedInUser() == null) {
255                         // Throw NPE again
256                         throw new NullPointerException("event.loggedInUser is null"); //NOI18N
257                 } else if (event.getLoggedInUser().getUserId() == null) {
258                         // userId is null
259                         throw new NullPointerException("event.loggedInUser.userId is null"); //NOI18N
260                 } else if (event.getLoggedInUser().getUserId() < 1) {
261                         // Not avalid id
262                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
263                 }
264
265                 // Fill cache with all found user's receipts
266                 for (final BillableReceipt receipt : this.allReceipts) {
267                         // Is same user?
268                         if (Objects.equals(receipt.getReceiptUser(), event.getLoggedInUser())) {
269                                 // Yes, then add it
270                                 this.userReceipts.add(receipt);
271                         }
272                 }
273         }
274
275         /**
276          * Returns all receipts
277          * <p>
278          * @return All receipts
279          */
280         @SuppressWarnings ("ReturnOfCollectionOrArrayField")
281         public List<BillableReceipt> allReceipts () {
282                 return this.allReceipts;
283         }
284
285         /**
286          * Getter for filtered receipts
287          * <p>
288          * @return Filtered receipts
289          */
290         @SuppressWarnings ("ReturnOfCollectionOrArrayField")
291         public List<BillableReceipt> getFilteredReceipts () {
292                 return this.filteredReceipts;
293         }
294
295         /**
296          * Setter for filtered receipts
297          * <p>
298          * @param filteredReceipts Filtered receipts
299          */
300         @SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
301         public void setFilteredReceipts (final List<BillableReceipt> filteredReceipts) {
302                 this.filteredReceipts = filteredReceipts;
303         }
304
305         /**
306          * Getter for receipt's bar-code number
307          * <p>
308          * @return Receipt's bar-code number
309          */
310         public Long getReceiptBarCodeNumber () {
311                 return this.receiptBarCodeNumber;
312         }
313
314         /**
315          * Setter for receipt's bar-code number
316          * <p>
317          * @param receiptBarCodeNumber Receipt's bar-code number
318          */
319         public void setReceiptBarCodeNumber (final Long receiptBarCodeNumber) {
320                 this.receiptBarCodeNumber = receiptBarCodeNumber;
321         }
322
323         /**
324          * Getter for receipt issuing branch office
325          * <p>
326          * @return Receipt issuing branch office
327          */
328         public BranchOffice getReceiptBranchOffice () {
329                 return this.receiptBranchOffice;
330         }
331
332         /**
333          * Setter for receipt issuing branch office
334          * <p>
335          * @param receiptBranchOffice Receipt issuing branch office
336          */
337         public void setReceiptBranchOffice (final BranchOffice receiptBranchOffice) {
338                 this.receiptBranchOffice = receiptBranchOffice;
339         }
340
341         /**
342          * Getter for receipt issue date and time
343          * <p>
344          * @return Receipt issue date and time
345          */
346         @SuppressWarnings ("ReturnOfDateField")
347         public Date getReceiptIssued () {
348                 return this.receiptIssued;
349         }
350
351         /**
352          * Setter for receipt issue date and time
353          * <p>
354          * @param receiptIssued Receipt issue date and time
355          */
356         @SuppressWarnings ("AssignmentToDateFieldFromParameter")
357         public void setReceiptIssued (final Date receiptIssued) {
358                 this.receiptIssued = receiptIssued;
359         }
360
361         /**
362          * Getter for receipt number
363          * <p>
364          * @return Receipt number
365          */
366         public Long getReceiptNumber () {
367                 return this.receiptNumber;
368         }
369
370         /**
371          * Setter for receipt number
372          * <p>
373          * @param receiptNumber Receipt number
374          */
375         public void setReceiptNumber (final Long receiptNumber) {
376                 this.receiptNumber = receiptNumber;
377         }
378
379         /**
380          * Getter for payment type
381          * <p>
382          * @return Payment type
383          */
384         public PaymentType getReceiptPaymentType () {
385                 return this.receiptPaymentType;
386         }
387
388         /**
389          * Setter for payment type
390          * <p>
391          * @param receiptPaymentType Payment type
392          */
393         public void setReceiptPaymentType (final PaymentType receiptPaymentType) {
394                 this.receiptPaymentType = receiptPaymentType;
395         }
396
397         /**
398          * Getter for receipt register's number
399          * <p>
400          * @return Receipt register's number
401          */
402         public Long getReceiptRegisterNumber () {
403                 return this.receiptRegisterNumber;
404         }
405
406         /**
407          * Setter for receipt register's number
408          * <p>
409          * @param receiptRegisterNumber Receipt register's number
410          */
411         public void setReceiptRegisterNumber (final Long receiptRegisterNumber) {
412                 this.receiptRegisterNumber = receiptRegisterNumber;
413         }
414
415         /**
416          * Getter for receipt seller employee
417          * <p>
418          * @return Receipt seller employee
419          */
420         public Employee getReceiptSellerEmployee () {
421                 return this.receiptSellerEmployee;
422         }
423
424         /**
425          * Setter for receipt seller employee
426          * <p>
427          * @param receiptSellerEmployee Receipt seller employee
428          */
429         public void setReceiptSellerEmployee (final Employee receiptSellerEmployee) {
430                 this.receiptSellerEmployee = receiptSellerEmployee;
431         }
432
433         @PostConstruct
434         public void initCache () {
435                 // Is cache there?
436                 if (!this.receiptCache.iterator().hasNext()) {
437                         // Get whole list
438                         final List<BillableReceipt> receipts = this.receiptBean.allReceipts();
439
440                         // Add all
441                         for (final BillableReceipt receipt : receipts) {
442                                 // Add it to cache
443                                 this.receiptCache.put(receipt.getReceiptId(), receipt);
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          * Clears this bean
480          */
481         private void clear () {
482                 // Clear all fields
483                 this.setReceiptBarCodeNumber(null);
484                 this.setReceiptBranchOffice(null);
485                 this.setReceiptIssued(null);
486                 this.setReceiptNumber(null);
487                 this.setReceiptPaymentType(null);
488                 this.setReceiptRegisterNumber(null);
489                 this.setReceiptSellerEmployee(null);
490         }
491
492         /**
493          * Returns a fully created receipt instance (except primary key, of course)
494          * <p>
495          * @return Receipt instance
496          */
497         private BillableReceipt createReceiptInstance () {
498                 // Init receipt instance
499                 final BillableReceipt receipt = new FinancialReceipt(this.getReceiptPaymentType(), this.getReceiptBranchOffice(), this.userLoginController.getLoggedInUser(), this.getReceiptIssued());
500
501                 // Set optional fields
502                 receipt.setReceiptNumber(this.getReceiptNumber());
503                 receipt.setReceiptBarCodeNumber(this.getReceiptBarCodeNumber());
504                 receipt.setReceiptRegisterNumber(this.getReceiptRegisterNumber());
505                 receipt.setReceiptSellerEmployee(this.getReceiptSellerEmployee());
506
507                 // Return it
508                 return receipt;
509         }
510 }