1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package Controllers;
21
22 import Launchers.Reports;
23 import Utilities.*;
24 import Workers.ReportsWorker;
25 import Workers.orderHistoryReportWorker;
26 import javafx.event.ActionEvent;
27 import javafx.fxml.FXML;
28 import javafx.scene.control.*;
29 import javafx.scene.control.Button;
30 import javafx.scene.control.TextField;
31 import javafx.scene.layout.HBox;
32 import javafx.stage.FileChooser;
33 import javafx.stage.Stage;
34 import net.sf.saxon.s9api.SaxonApiException;
35
36 import javax.swing.filechooser.FileSystemView;
37 import javax.xml.parsers.ParserConfigurationException;
38 import java.awt.*;
39 import java.io.File;
40 import java.io.FileNotFoundException;
41 import java.io.IOException;
42 import java.nio.file.FileSystemException;
43 import java.sql.SQLException;
44 import java.util.ArrayList;
45 import java.util.HashMap;
46 import java.util.Objects;
47 import java.util.concurrent.CancellationException;
48
49
50
51
52
53
54
55
56
57
58
59
60 @SuppressWarnings("WeakerAccess")
61
62 public class ReportsController {
63
64 @FXML
65 private ComboBox<Object> cmbxReportType;
66 @FXML
67 private ComboBox<TreeItemPair<String, String>> cmbxUser;
68 @FXML
69 private TextField scoutName;
70 @FXML
71 private TextField scoutStAddr;
72 @FXML
73 private TextField scoutZip;
74 @FXML
75 private TextField scoutTown;
76 @FXML
77 private TextField scoutState;
78 @FXML
79 private TextField scoutPhone;
80 @FXML
81 private TextField scoutRank;
82 @FXML
83 private TextField logoLoc;
84 @FXML
85 private TextField pdfLoc;
86 @FXML
87 private ComboBox<Object> cmbxYears;
88 @FXML
89 private ComboBox<TreeItemPair<String, ArrayList<Customer>>> cmbxCustomers;
90
91 @FXML
92 private TabPane reportTabPane;
93
94 @FXML
95 private Button nextButton;
96 @FXML
97 private Button okButton;
98 @FXML
99 private Button cancelButton;
100 @FXML
101 private HBox categoryPane;
102 @FXML
103 private HBox customerPane;
104 @FXML
105 private HBox yearPane;
106 @FXML
107 private HBox userPanel;
108
109 @FXML
110 private ComboBox<Object> cmbxCategory;
111 @FXML
112 private CheckBox includeHeader;
113
114 private Reports reports;
115
116
117
118 private String Splitting = "";
119 private String repTitle = "";
120
121
122
123
124
125
126 @FXML
127 private void reportTypeChange(ActionEvent actionEvent) {
128 ComboBox comboBox = (ComboBox) actionEvent.getSource();
129
130 Object selected = comboBox.getSelectionModel().getSelectedItem();
131 reportTabPane.getTabs().get(1).setDisable(true);
132 okButton.setDisable(true);
133 if (selected != null) {
134 nextButton.setDisable(false);
135
136 }
137 }
138
139 @FXML
140 private void selectedYearChanged(ActionEvent actionEvent) {
141
142
143 if (cmbxReportType.getSelectionModel().getSelectedIndex() != 3) {
144 userPanel.setDisable(false);
145 String selected = cmbxYears.getSelectionModel().getSelectedItem().toString();
146 User curUser = DbInt.getUser(selected);
147 Iterable<String> uManage = curUser.getuManage();
148 cmbxUser.getItems().clear();
149 cmbxUser.getItems().addAll(new TreeItemPair<String, String>("All"), new TreeItemPair<String, String>("Yourself", curUser.getUserName()));
150 for (String user : uManage) {
151 cmbxUser.getItems().add(new TreeItemPair<String, String>(user, user));
152 }
153 cmbxUser.getSelectionModel().select(1);
154 }
155 }
156
157 @FXML
158 private void selectedUserChanged(ActionEvent actionEvent) {
159
160 switch (cmbxReportType.getSelectionModel().getSelectedItem().toString()) {
161
162 case "Year Totals":
163 okButton.setDisable(cmbxUser.getSelectionModel().getSelectedItem() == null);
164 break;
165 case "Year Totals; Spilt by Customer":
166 okButton.setDisable(cmbxUser.getSelectionModel().getSelectedItem() == null);
167 break;
168 case "Customer Year Totals":
169 okButton.setDisable(true);
170 break;
171 case "Customer All-Time Totals":
172 okButton.setDisable(true);
173 break;
174 }
175 if (cmbxReportType.getSelectionModel().getSelectedIndex() != 3) {
176
177 String selectedYear = cmbxYears.getSelectionModel().getSelectedItem().toString();
178 String selectedUser = cmbxUser.getSelectionModel().getSelectedItem().getValue();
179 cmbxCustomers.getItems().clear();
180
181 if (cmbxReportType.getSelectionModel().getSelectedIndex() == 2) {
182 if (!Objects.equals(selectedYear, "")) {
183 Year year;
184 if (Objects.equals(selectedUser, "")) {
185 year = new Year(selectedYear);
186 } else {
187 year = new Year(selectedYear, selectedUser);
188
189 }
190 Iterable<Customer> customersY = year.getCustomers();
191 cmbxCustomers.getItems().removeAll();
192 customersY.forEach(customer -> {
193 ArrayList custList = new ArrayList();
194 custList.add(customer);
195 cmbxCustomers.getItems().add(new TreeItemPair<String, ArrayList<Customer>>(customer.getName(), custList));
196 });
197 cmbxCustomers.setDisable(false);
198 }
199 }
200 if (!Objects.equals(selectedYear, "")) {
201 Year year;
202 if (Objects.equals(selectedUser, "")) {
203 year = new Year(selectedYear);
204 } else {
205 year = new Year(selectedYear, selectedUser);
206
207 }
208 cmbxCategory.getItems().clear();
209 cmbxCategory.getItems().add("All");
210 year.getCategories().forEach(category -> cmbxCategory.getItems().add(category.catName));
211 cmbxCategory.getSelectionModel().selectFirst();
212 }
213 }
214 }
215
216 @FXML
217 private void selectedCustomerChanged(ActionEvent actionEvent) {
218 switch (cmbxReportType.getSelectionModel().getSelectedItem().toString()) {
219
220 case "Year Totals":
221 okButton.setDisable(true);
222 break;
223 case "Year Totals; Spilt by Customer":
224 okButton.setDisable(true);
225 break;
226 case "Customer Year Totals":
227 okButton.setDisable(cmbxCustomers.getSelectionModel().getSelectedItem() == null);
228 break;
229 case "Customer All-Time Totals":
230 okButton.setDisable(cmbxCustomers.getSelectionModel().getSelectedItem() == null);
231 break;
232 }
233 }
234 @FXML
235 private void selectedCategoryChanged(ActionEvent actionEvent) {
236 if (!cmbxCategory.getSelectionModel().isEmpty()) {
237 includeHeader.setDisable(cmbxReportType.getSelectionModel().getSelectedIndex() == 4 || cmbxReportType.getSelectionModel().getSelectedIndex() == 0 || cmbxCategory.getSelectionModel().getSelectedItem().equals("All"));
238 }
239 }
240
241 @FXML
242 public void promptLogo(ActionEvent event) {
243
244 FileChooser chooser = new FileChooser();
245 FileChooser.ExtensionFilter filter = new FileChooser.ExtensionFilter("Image files", "*.jpg", "*.gif", "*.png", "*.bmp");
246 chooser.getExtensionFilters().add(filter);
247
248 chooser.setSelectedExtensionFilter(filter);
249
250 File image = chooser.showOpenDialog(reports);
251 if (image != null) {
252 String path = image.getAbsolutePath();
253 logoLoc.setText(path);
254 }
255 }
256
257 @FXML
258 public void promptPDF(ActionEvent event) {
259
260 FileChooser.ExtensionFilter filter;
261 String ending;
262 if (cmbxReportType.getSelectionModel().getSelectedIndex() == 4) {
263 filter = new FileChooser.ExtensionFilter("CSV files", "*.csv", "*.CSV");
264 ending = ".csv";
265
266 } else {
267 filter = new FileChooser.ExtensionFilter("Portable Document files", "*.pdf", "*.PDF");
268 ending = ".pdf";
269
270 }
271 FileChooser chooser = new FileChooser();
272 chooser.getExtensionFilters().add(filter);
273 chooser.setSelectedExtensionFilter(filter);
274 chooser.setInitialDirectory(FileSystemView.getFileSystemView().getDefaultDirectory());
275 File pdf = chooser.showSaveDialog(reports);
276 if (pdf != null) {
277 String path = pdf.getAbsolutePath();
278 if (!path.toLowerCase().endsWith(ending)) {
279 path += ending;
280 }
281 pdfLoc.setText(path);
282 }
283 }
284
285 @FXML
286 public void cancel(ActionEvent event) {
287 close();
288 }
289
290 @FXML
291 public void next(ActionEvent event) {
292 updateCombos();
293 nextButton.setDisable(true);
294
295 reportTabPane.getSelectionModel().select(reportTabPane.getSelectionModel().getSelectedIndex() + 1);
296 reportTabPane.getTabs().get(1).setDisable(false);
297 }
298
299 @FXML
300 public void submit(ActionEvent actionEvent) {
301 String addrFormat = scoutTown.getText() + ' ' + scoutState.getText() + ", " + scoutZip.getText();
302 switch (cmbxReportType.getSelectionModel().getSelectedIndex()) {
303 case 0:
304 repTitle = "Year of " + cmbxYears.getSelectionModel().getSelectedItem();
305 Splitting = "";
306
307 break;
308 case 1:
309 repTitle = "";
310 Splitting = "";
311
312 break;
313 case 2:
314 repTitle = cmbxCustomers.getSelectionModel().getSelectedItem() + " " + cmbxYears.getSelectionModel().getSelectedItem() + " Order";
315 Splitting = "";
316
317 break;
318 case 3:
319 repTitle = "All orders of " + cmbxCustomers.getSelectionModel().getSelectedItem();
320 Splitting = "Year:";
321
322 break;
323 case 4:
324 ProgressForm progDial = new ProgressForm();
325 orderHistoryReportWorker reportsWorker = new orderHistoryReportWorker(pdfLoc.getText());
326
327 progDial.activateProgressBar(reportsWorker);
328
329 reportsWorker.setOnSucceeded(event -> {
330 progDial.getDialogStage().close();
331
332 Alert alert = new Alert(Alert.AlertType.INFORMATION, "Saved");
333 alert.setHeaderText("CSV saved");
334 alert.show();
335 close();
336 });
337
338 reportsWorker.setOnFailed(event -> {
339 progDial.getDialogStage().close();
340 Throwable e = reportsWorker.getException();
341
342
343 if (e instanceof SQLException) {
344 LogToFile.log((SQLException) e, Severity.SEVERE, CommonErrors.returnSqlMessage(((SQLException) reportsWorker.getException())));
345
346 }
347 if (e instanceof InterruptedException) {
348 if (reportsWorker.isCancelled()) {
349 LogToFile.log((InterruptedException) e, Severity.FINE, "Report generation process canceled.");
350
351 }
352 }
353 if (e instanceof Exception) {
354 LogToFile.log((Exception) e, Severity.WARNING, reportsWorker.getMessage());
355 }
356 if (e instanceof FileNotFoundException) {
357 LogToFile.log((FileNotFoundException) e, Severity.WARNING, "Error accessing CSV file. Please check if it is open in any other programs and close it.");
358 }
359 if (e instanceof FileSystemException) {
360 LogToFile.log((FileSystemException) e, Severity.WARNING, "Error opening file for writing. Ensure path is correct.");
361 }
362 if (e instanceof IOException) {
363 LogToFile.log((IOException) e, Severity.WARNING, reportsWorker.getMessage());
364 }
365
366 });
367 progDial.getDialogStage().show();
368 new Thread(reportsWorker).start();
369 return;
370
371
372 }
373 ProgressForm progDial = new ProgressForm();
374 String selectedYear = (cmbxYears.getSelectionModel().getSelectedItem() != null) ? cmbxYears.getSelectionModel().getSelectedItem().toString() : "";
375 String selectedUser = (cmbxUser.getSelectionModel().getSelectedItem() != null) ? cmbxUser.getSelectionModel().getSelectedItem().getValue() : "";
376 selectedUser = (Objects.equals(selectedUser, "All")) ? "" : selectedUser;
377 String selectedCategory = (cmbxCategory.getSelectionModel().getSelectedItem() != null) ? cmbxCategory.getSelectionModel().getSelectedItem().toString() : "";
378 ArrayList<Customer> selectedCustomers = (cmbxCustomers.getSelectionModel().getSelectedItem() != null) ? cmbxCustomers.getSelectionModel().getSelectedItem().getValue() : new ArrayList<Customer>();
379
380 ReportsWorker reportsWorker = new ReportsWorker(cmbxReportType.getSelectionModel().getSelectedItem().toString(), selectedYear, scoutName.getText(), scoutStAddr.getText(), addrFormat, scoutRank.getText(), scoutPhone.getText(), logoLoc.getText(), selectedCategory, selectedUser, selectedCustomers, repTitle, Splitting, includeHeader.isSelected(), pdfLoc.getText());
381
382 progDial.activateProgressBar(reportsWorker);
383
384 reportsWorker.setOnSucceeded(event -> {
385 progDial.getDialogStage().close();
386
387 try {
388 if (Desktop.isDesktopSupported()) {
389 new Thread(() -> {
390 try {
391 File myFile = new File(pdfLoc.getText());
392 Desktop.getDesktop().open(myFile);
393 } catch (IOException ex) {
394 LogToFile.log(ex, Severity.SEVERE, "Error writing pdf file. Please try again or contacting support.");
395 }
396 }).start();
397
398 }
399 } catch (CancellationException e1) {
400 LogToFile.log(e1, Severity.INFO, "The process was cancelled.");
401
402 } catch (Exception e1) {
403 LogToFile.log(e1, Severity.SEVERE, "The process failed.");
404
405 }
406 close();
407 });
408
409 reportsWorker.setOnFailed(event -> {
410 progDial.getDialogStage().close();
411 Throwable e = reportsWorker.getException();
412
413 if (e instanceof ParserConfigurationException) {
414 LogToFile.log((ParserConfigurationException) e, Severity.WARNING, "Error configuring parser. Please reinstall or contact support.");
415
416 }
417 if (e instanceof SQLException) {
418 LogToFile.log((SQLException) e, Severity.SEVERE, CommonErrors.returnSqlMessage(((SQLException) reportsWorker.getException())));
419
420 }
421 if (e instanceof InterruptedException) {
422 if (reportsWorker.isCancelled()) {
423 LogToFile.log((InterruptedException) e, Severity.FINE, "Report Generation process canceled.");
424
425 }
426 }
427 if (e instanceof Exception) {
428 LogToFile.log((Exception) e, Severity.WARNING, reportsWorker.getMessage());
429 }
430 if (e instanceof FileNotFoundException) {
431 LogToFile.log((FileNotFoundException) e, Severity.WARNING, "Error accessing PDF file. Please check if it is open in any other programs and close it.");
432 }
433 if (e instanceof IOException) {
434 LogToFile.log((IOException) e, Severity.WARNING, reportsWorker.getMessage());
435 }
436 if (e instanceof SaxonApiException) {
437 LogToFile.log((SaxonApiException) e, Severity.SEVERE, "Error converting temporary XML to pdf. Try again or contact support.");
438 }
439 });
440 progDial.getDialogStage().show();
441 new Thread(reportsWorker).start();
442
443
444 }
445
446 private void close() {
447 Stage stage = (Stage) pdfLoc.getScene().getWindow();
448
449 stage.close();
450 }
451
452
453 public void initUI(Reports reps) {
454 reports = reps;
455
456 cmbxReportType.getSelectionModel().select(Config.getProp("ReportType"));
457
458
459 scoutName.setText(Config.getProp("ScoutName"));
460 scoutStAddr.setText(Config.getProp("ScoutAddress"));
461 scoutZip.setText(Config.getProp("ScoutZip"));
462 scoutTown.setText(Config.getProp("ScoutTown"));
463 scoutState.setText(Config.getProp("ScoutState"));
464 scoutPhone.setText(Config.getProp("ScoutPhone"));
465 scoutRank.setText(Config.getProp("ScoutRank"));
466 logoLoc.setText(Config.getProp("logoLoc"));
467 pdfLoc.setText(Config.getProp("pdfLoc"));
468
469 scoutZip.setOnKeyTyped(keyEvent -> {
470 if (scoutZip.getCharacters().length() >= 4) {
471 String zip = scoutZip.getText() + keyEvent.getCharacter();
472
473 String cityAndState;
474 try {
475 cityAndState = Geolocation.getCityState(zip);
476 String[] StateTown = cityAndState.split("&");
477 String state = StateTown[1];
478 String town = StateTown[0];
479 scoutTown.setText(town);
480 scoutState.setText(state);
481 } catch (IOException e1) {
482 LogToFile.log(e1, Severity.WARNING, "Couldn't contact geolocation service. Please try again or enter the adress manually and contact suport.");
483 }
484
485 }
486 });
487
488
489 }
490
491 private void updateCombos() {
492 Iterable<String> years = DbInt.getUserYears();
493 cmbxCategory.getItems().clear();
494 cmbxUser.getItems().clear();
495 cmbxCustomers.getItems().clear();
496 cmbxYears.getItems().clear();
497 switch (cmbxReportType.getSelectionModel().getSelectedItem().toString()) {
498
499 case "Year Totals":
500 userPanel.setDisable(false);
501 yearPane.setDisable(false);
502 customerPane.setDisable(true);
503 cmbxYears.getItems().clear();
504
505 categoryPane.setDisable(false);
506 includeHeader.setDisable(true);
507 years.forEach(cmbxYears.getItems()::add);
508
509
510
511 break;
512 case "Year Totals; Spilt by Customer":
513 userPanel.setDisable(false);
514
515 yearPane.setDisable(false);
516 customerPane.setDisable(true);
517 cmbxYears.getItems().clear();
518
519 years.forEach(cmbxYears.getItems()::add);
520 categoryPane.setDisable(false);
521 includeHeader.setDisable(false);
522
523
524 break;
525 case "Customer Year Totals":
526 userPanel.setDisable(false);
527
528 yearPane.setDisable(false);
529 customerPane.setDisable(false);
530 cmbxYears.getItems().removeAll();
531 years.forEach(cmbxYears.getItems()::add);
532
533 cmbxCustomers.setDisable(false);
534 categoryPane.setDisable(false);
535 includeHeader.setDisable(false);
536
537
538 break;
539 case "Customer All-Time Totals":
540 userPanel.setDisable(true);
541 categoryPane.setDisable(true);
542 cmbxUser.getItems().add(new TreeItemPair<String, String>("Yourself", DbInt.getUserName()));
543 cmbxUser.getSelectionModel().selectFirst();
544 yearPane.setDisable(true);
545 customerPane.setDisable(false);
546 cmbxCustomers.getItems().removeAll();
547 Iterable<Customer> customers = DbInt.getAllCustomers();
548
549 HashMap<String, ArrayList<Customer>> curCustomers = new HashMap<>();
550 customers.forEach(customer -> {
551 if (curCustomers.containsKey(customer.getName())) {
552 curCustomers.get(customer.getName()).add(customer);
553 } else {
554 ArrayList<Customer> customerArrayList = new ArrayList<>();
555 customerArrayList.add(customer);
556 curCustomers.put(customer.getName(), customerArrayList);
557 }
558 });
559 curCustomers.forEach((name, customersList) -> {
560 cmbxCustomers.getItems().add(new TreeItemPair<String, ArrayList<Customer>>(name, customersList));
561
562 });
563 includeHeader.setDisable(true);
564
565
566 break;
567 case "Address Order History":
568 userPanel.setDisable(true);
569 categoryPane.setDisable(true);
570 yearPane.setDisable(true);
571 customerPane.setDisable(true);
572 includeHeader.setDisable(true);
573 okButton.setDisable(false);
574 if (!pdfLoc.getText().toLowerCase().endsWith(".csv")) {
575 pdfLoc.setText("");
576 }
577
578 break;
579 }
580 }
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613 }