View Javadoc
1   /*
2    * Copyright (c) Patrick Magauran 2018.
3    *   Licensed under the AGPLv3. All conditions of said license apply.
4    *       This file is part of ABOS.
5    *
6    *       ABOS is free software: you can redistribute it and/or modify
7    *       it under the terms of the GNU Affero General Public License as published by
8    *       the Free Software Foundation, either version 3 of the License, or
9    *       (at your option) any later version.
10   *
11   *       ABOS is distributed in the hope that it will be useful,
12   *       but WITHOUT ANY WARRANTY; without even the implied warranty of
13   *       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   *       GNU Affero General Public License for more details.
15   *
16   *       You should have received a copy of the GNU Affero General Public License
17   *       along with ABOS.  If not, see <http://www.gnu.org/licenses/>.
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  //import javax.swing.*;
50  //import javax.swing.border.EmptyBorder;
51  //import javax.swing.filechooser.FileNameExtensionFilter;
52  //import java.awt.*;
53  //import java.awt.event.ActionEvent;
54  //import java.awt.event.ActionListener;
55  //import java.awt.event.ItemEvent;
56  
57  /**
58   * Created by patrick on 12/24/15.
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      //private Label includeHeaderL;
91      @FXML
92      private TabPane reportTabPane;
93      // --Commented out by Inspection (7/27/16 3:02 PM):private Object[][] rowDataF = new Object[0][];
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     // --Commented out by Inspection (7/27/16 3:02 PM):private double totL = 0.0;
117     // --Commented out by Inspection (7/27/16 3:02 PM):private double QuantL = 0.0;
118     private String Splitting = "";
119     private String repTitle = "";
120     // --Commented out by Inspection (7/27/16 3:02 PM):private File xmlTempFile = null;
121     // --Commented out by Inspection (7/27/16 3:02 PM):private File[] xmlTempFileA = null;
122     // private Workers.ReportsWorker reportsWorker = null;
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         //ComboBox comboBox = (ComboBox) actionEvent.getSource();
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         //ComboBox comboBox = (ComboBox) actionEvent.getSource();
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         //Creates a JFileChooser to select a directory to store the Databases
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 //        logoLoc.setText(chooser.showOpenDialog(settings).getAbsolutePath());
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         //Creates a JFileChooser to select save location of XML file
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         // okButton.setDisable(false);
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         // do what you have to do
449         stage.close();
450     }
451 
452     //SetBounds(X,Y,Width,Height)
453     public void initUI(Reports reps) {
454         reports = reps;
455 
456         cmbxReportType.getSelectionModel().select(Config.getProp("ReportType"));
457 
458         // includeHeaderL.setVisible(false);
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                 //cmbxYears.getItems().add("");
505                 categoryPane.setDisable(false);
506                 includeHeader.setDisable(true);
507                 years.forEach(cmbxYears.getItems()::add);
508 
509                 //cmbxYears.
510                 //cmbxYears.getSelectionModel().select(cmbxYears.getItems().size() - 1);
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                 //cmbxYears.getItems().addAll(years);
519                 years.forEach(cmbxYears.getItems()::add);
520                 categoryPane.setDisable(false);
521                 includeHeader.setDisable(false);
522 
523                 // cmbxYears.getSelectionModel().select(cmbxYears.getItems().size() - 1);
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                 //    cmbxYears.getSelectionModel().select(cmbxYears.getItems().size() - 1);
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                 //      cmbxYears.getSelectionModel().select(cmbxYears.getItems().size() - 1);
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                 //      cmbxYears.getSelectionModel().select(cmbxYears.getItems().size() - 1);
578                 break;
579         }
580     }
581 
582 
583 // --Commented out by Inspection START (7/27/16 3:02 PM):
584 //    private String getDate(String catName){
585 //        Date ret = null;
586 //        try (PreparedStatement prep = Utilities.DbInt.getPrep("set", "SELECT Date FROM Categories WHERE Name=?")) {
587 //
588 //
589 //            prep.setString(1, catName);
590 //
591 //            try (ResultSet rs = prep.executeQuery()) {
592 //
593 //                while (rs.next()) {
594 //
595 //                    ret = rs.getDate(1);
596 //
597 //                }
598 //            }
599 //            ////Utilities.DbInt.pCon.close();
600 //
601 //        } catch (SQLException e) {
602 //            e.printStackTrace();
603 //        }
604 //        String output;
605 //        SimpleDateFormat formatter;
606 //        formatter = new SimpleDateFormat("MM/dd/yyyy");
607 //        output = formatter.format(ret);
608 //        return output;
609 //    }
610 // --Commented out by Inspection STOP (7/27/16 3:02 PM)
611 
612 
613 }