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 Workers;
21  
22  import Utilities.*;
23  import com.itextpdf.text.pdf.PdfWriter;
24  import com.itextpdf.tool.xml.XMLWorker;
25  import com.itextpdf.tool.xml.XMLWorkerHelper;
26  import com.itextpdf.tool.xml.css.CssFile;
27  import com.itextpdf.tool.xml.html.Tags;
28  import com.itextpdf.tool.xml.parser.XMLParser;
29  import com.itextpdf.tool.xml.pipeline.css.CSSResolver;
30  import com.itextpdf.tool.xml.pipeline.css.CssResolverPipeline;
31  import com.itextpdf.tool.xml.pipeline.end.PdfWriterPipeline;
32  import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;
33  import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;
34  import javafx.concurrent.Task;
35  import net.sf.saxon.s9api.*;
36  import org.w3c.dom.Document;
37  import org.w3c.dom.Element;
38  import org.w3c.tidy.Tidy;
39  
40  import javax.xml.parsers.DocumentBuilder;
41  import javax.xml.parsers.DocumentBuilderFactory;
42  import javax.xml.transform.*;
43  import javax.xml.transform.dom.DOMSource;
44  import javax.xml.transform.stream.StreamResult;
45  import javax.xml.transform.stream.StreamSource;
46  import java.io.*;
47  import java.math.BigDecimal;
48  import java.text.SimpleDateFormat;
49  import java.util.ArrayList;
50  import java.util.Calendar;
51  import java.util.Collection;
52  import java.util.Objects;
53  
54  //import javax.swing.*;
55  
56  //import com.itextpdf.text.Document;
57  
58  /**
59   * Searches the text files under the given directory and counts the number of instances a given word is found
60   * in these file.
61   *
62   * @author Albert Attard
63   */
64  public class ReportsWorker extends Task<Integer> {
65  
66      private final String reportType;
67      private final String selectedYear;
68      private final String scoutName;
69      private final String scoutStAddr;
70      private final String addrFormat;
71      private final String scoutRank;
72      private final String scoutPhone;
73      private final String logoLoc;
74      private final String category;
75      private final String user;
76      private final ArrayList<Customer> customers;
77      private final String repTitle;
78      private final String Splitting;
79      private final Boolean includeHeader;
80      private final String pdfLoc;
81  
82      private Document doc = null;
83      private File xmlTempFile = null;
84      private Double prog = 0.0;
85      // --Commented out by Inspection (7/27/16 3:02 PM):private File[] xmlTempFileA = null;
86  
87      /**
88       * Creates an instance of the worker
89       * @param reportType    the type of report
90       * @param selectedYear  the selected year
91       * @param scoutName     name of the scout to put in header
92       * @param scoutStAddr   address  of the scout to put in header
93       * @param addrFormat    formatted address
94       * @param scoutRank     rank  of the scout to put in header
95       * @param scoutPhone    phone #  of the scout to put in header
96       * @param logoLoc       Location on disk of the logo
97       * @param category      Category to generate report for
98       * @param user          Utilities.User to create Report as
99       * @param customers  Name of the customer
100      * @param repTitle      Title of the report
101      * @param splitting     Split the report in any way?
102      * @param includeHeader Include a header?
103      * @param pdfLoc1       Location to save the pdf
104      */
105     public ReportsWorker(String reportType, String selectedYear, String scoutName, String scoutStAddr, String addrFormat, String scoutRank, String scoutPhone, String logoLoc, String category, String user, ArrayList<Customer> customers, String repTitle, String splitting, Boolean includeHeader, String pdfLoc1) {
106 
107         this.reportType = reportType;
108         this.selectedYear = selectedYear;
109         this.scoutName = scoutName;
110         this.scoutStAddr = scoutStAddr;
111         this.addrFormat = addrFormat;
112         this.scoutRank = scoutRank;
113         this.scoutPhone = scoutPhone;
114         this.logoLoc = logoLoc;
115         this.category = category;
116         this.user = user;
117         this.customers = customers;
118         this.repTitle = repTitle;
119         Splitting = splitting;
120         this.includeHeader = includeHeader;
121         pdfLoc = pdfLoc1;
122     }
123 
124 // --Commented out by Inspection START (7/27/16 3:02 PM):
125 //    private static void failIfInterrupted() throws InterruptedException {
126 //        if (Thread.currentThread().isInterrupted()) {
127 //            throw new InterruptedException("Interrupted while searching files");
128 //        }
129 //    }
130 // --Commented out by Inspection STOP (7/27/16 3:02 PM)
131 
132     @Override
133     protected Integer call() throws Exception {
134         updateMessage("Generating Report");
135         if (Objects.equals(reportType, "Year Totals; Spilt by Customer")) {
136             Year year;
137             if (user == null) {
138                 year = new Year(selectedYear);
139             } else {
140                 year = new Year(selectedYear, user);
141 
142             }
143             Iterable<Customer> customers = year.getCustomers();
144             // String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime());
145             DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
146             DocumentBuilder domBuilder;
147             domBuilder = domFactory.newDocumentBuilder();
148 
149 
150             doc = domBuilder.newDocument();
151             Element rootElement = doc.createElement("LawnGardenReports");
152             doc.appendChild(rootElement);
153             //Info Elements
154             Element info = doc.createElement("info");
155             rootElement.appendChild(info);
156 
157             {
158                 // Scoutname elements
159                 {
160                     Element ScoutName = doc.createElement("name");
161                     ScoutName.appendChild(doc.createTextNode(scoutName));
162                     info.appendChild(ScoutName);
163                 }
164                 // StreetAddress elements
165                 {
166                     Element StreetAddress = doc.createElement("streetAddress");
167                     StreetAddress.appendChild(doc.createTextNode(scoutStAddr));
168                     info.appendChild(StreetAddress);
169                 }
170                 // City elements
171                 {
172                     Element city = doc.createElement("city");
173                     city.appendChild(doc.createTextNode(addrFormat));
174                     info.appendChild(city);
175                 }
176                 // Rank elements
177                 {
178                     Element rank = doc.createElement("rank");
179                     rank.appendChild(doc.createTextNode(scoutRank));
180                     info.appendChild(rank);
181                 }
182                 // phone elements
183                 {
184                     Element rank = doc.createElement("PhoneNumber");
185                     rank.appendChild(doc.createTextNode(scoutPhone));
186                     info.appendChild(rank);
187                 }
188                 // Logo elements
189                 {
190                     Element logo = doc.createElement("logo");
191                     logo.appendChild(doc.createTextNode("file:///" + logoLoc.replace("\\", "/")));
192                     info.appendChild(logo);
193                 }
194 
195 
196             }
197             //Column Elements
198             {
199                 Element columns = doc.createElement("columns");
200                 rootElement.appendChild(columns);
201                 String[] Columns = {"ID", "Name", "Unit Size", "Unit Cost", "Quantity", "Extended Price"};
202                 for (String Column : Columns) {
203                     //Column
204                     {
205                         Element columnName = doc.createElement("column");
206                         Element cName = doc.createElement("name");
207                         cName.appendChild(doc.createTextNode(Column));
208                         columnName.appendChild(cName);
209                         columns.appendChild(columnName);
210                     }
211                 }
212             }
213             setProgress(10);
214             int custProgressIncValue = 90 / ((customers instanceof Collection<?> && !((Collection) customers).isEmpty()) ? ((Collection<?>) customers).size() : 1);
215 
216             customers.forEach(cust -> {
217                 BigDecimal paid = cust.getPaid();
218                 int custId = cust.getId();
219                 String customer = cust.getName();
220                 // Root element
221                 Order.orderArray orderArray;
222                 if (Objects.equals(category, "All")) {
223                     orderArray = Order.createOrderArray(selectedYear, custId, true);
224 
225                 } else {
226                     orderArray = Order.createOrderArray(selectedYear, custId, true, category);
227                 }
228                 if (orderArray.totalQuantity > 0) {
229                     //Set Items
230                     {
231                         //Product Elements
232                         Element products = doc.createElement("customerYear");
233                         //YearTitle
234                         {
235                             Element custAddr = doc.createElement("custAddr");
236                             custAddr.appendChild(doc.createTextNode("true"));
237                             products.appendChild(custAddr);
238                         }
239                         // customername elements
240                         {
241                             Element custName = doc.createElement("name");
242                             custName.appendChild(doc.createTextNode(customer));
243                             products.appendChild(custName);
244                         }
245                         // StreetAddress elements
246                         {
247                             Element StreetAddress = doc.createElement("streetAddress");
248                             StreetAddress.appendChild(doc.createTextNode(cust.getAddr()));
249                             products.appendChild(StreetAddress);
250                         }
251                         // City elements
252                         {
253                             Element city = doc.createElement("city");
254                             String addr = cust.getTown() + ' ' + cust.getState() + ", " + cust.getZip();
255                             city.appendChild(doc.createTextNode(addr));
256                             products.appendChild(city);
257                         }
258 
259                         // phone elements
260                         {
261                             Element phone = doc.createElement("PhoneNumber");
262                             phone.appendChild(doc.createTextNode(cust.getPhone()));
263                             products.appendChild(phone);
264                         }
265                         {
266                             Element header = doc.createElement("header");
267                             header.appendChild(doc.createTextNode("true"));
268                             products.appendChild(header);
269                         }
270                         {
271                             Element title = doc.createElement("title");
272                             title.appendChild(doc.createTextNode(customer + ' ' + selectedYear + " Order"));
273                             products.appendChild(title);
274                         }
275                         {
276                             if (includeHeader && !Objects.equals(category, "All")) {
277                                 Element title = doc.createElement("specialInfo");
278                                 {
279                                     Element text = doc.createElement("text");
280                                     String notice = "*Notice: These products will be delivered to your house on " + DbInt.getCategoryDate(category, selectedYear) + (". Total paid to date: $" + paid.toPlainString());
281                                     text.appendChild(doc.createTextNode(notice));
282                                     title.appendChild(text);
283                                 }
284                                 products.appendChild(title);
285                             }
286                         }
287                         setProgress(getProg() + (custProgressIncValue / 10));
288                         BigDecimal tCost = BigDecimal.ZERO;
289 
290                         if (orderArray.totalQuantity > 0) {
291                             Element prodTable = doc.createElement("prodTable");
292                             prodTable.appendChild(doc.createTextNode("true"));
293                             products.appendChild(prodTable);
294                             int productProgressIncValue = ((custProgressIncValue / 10) * 9) / orderArray.orderData.length;
295                             //For each product ordered, enter info
296                             for (formattedProduct aRowDataF : orderArray.orderData) {
297                                 if (Objects.equals(aRowDataF.productCategory, category) || (Objects.equals(category, "All"))) {
298 
299                                     {
300                                         Element Product = doc.createElement("Product");
301                                         products.appendChild(Product);
302                                         //ID
303                                         {
304                                             Element ID = doc.createElement("ID");
305                                             ID.appendChild(doc.createTextNode(aRowDataF.productID));
306                                             Product.appendChild(ID);
307                                         }
308                                         //Name
309                                         {
310                                             Element Name = doc.createElement("Name");
311                                             Name.appendChild(doc.createTextNode(aRowDataF.productName));
312                                             Product.appendChild(Name);
313                                         }
314                                         //Size
315                                         {
316                                             Element Size = doc.createElement("Size");
317                                             Size.appendChild(doc.createTextNode(aRowDataF.productSize));
318                                             Product.appendChild(Size);
319                                         }
320                                         //UnitCost
321                                         {
322                                             Element UnitCost = doc.createElement("UnitCost");
323                                             UnitCost.appendChild(doc.createTextNode(aRowDataF.productUnitPrice.toPlainString()));
324                                             Product.appendChild(UnitCost);
325                                         }
326                                         //Quantity
327                                         {
328                                             Element Quantity = doc.createElement("Quantity");
329                                             Quantity.appendChild(doc.createTextNode(String.valueOf(aRowDataF.orderedQuantity)));
330                                             Product.appendChild(Quantity);
331                                         }
332                                         //TotalCost
333                                         {
334                                             Element TotalCost = doc.createElement("TotalCost");
335                                             TotalCost.appendChild(doc.createTextNode(String.valueOf(aRowDataF.extendedCost)));
336                                             tCost = tCost.add(aRowDataF.extendedCost);
337                                             Product.appendChild(TotalCost);
338                                         }
339                                     }
340                                 }
341                                 setProgress(getProg() + productProgressIncValue);
342 
343                             }
344                             //Total Cost for this Utilities.Year
345                             {
346                                 Element tCostE = doc.createElement("totalCost");
347                                 tCostE.appendChild(doc.createTextNode(String.valueOf(tCost)));
348                                 products.appendChild(tCostE);
349                             }
350 
351 
352                         }
353                         Year cYear;
354                         if (user == null) {
355                             cYear = new Year(selectedYear);
356                         } else {
357                             cYear = new Year(selectedYear, user);
358 
359                         }
360                         // OverallTotalCost elements
361                         {
362                             Element TotalCost = doc.createElement("TotalCost");
363                             TotalCost.appendChild(doc.createTextNode(cYear.getGTot().toPlainString()));
364                             info.appendChild(TotalCost);
365                         }
366                         // OverallTotalQuantity elements
367                         {
368                             Element TotalQuantity = doc.createElement("totalQuantity");
369                             TotalQuantity.appendChild(doc.createTextNode(Integer.toString(cYear.getQuant())));
370                             info.appendChild(TotalQuantity);
371                         }
372                         BigDecimal donationBD = cust.getDontation();
373 
374                         String donation = donationBD.toPlainString();
375                         if (!(donationBD.compareTo(BigDecimal.ZERO) <= 0)) {
376                             Element title = doc.createElement("DonationThanks");
377                             {
378                                 Element text = doc.createElement("text");
379                                 String notice = "Thank you for your $" + donation + " donation ";
380                                 text.appendChild(doc.createTextNode(notice));
381                                 title.appendChild(text);
382                             }
383                             products.appendChild(title);
384 
385                             {
386                                 Element prodTable = doc.createElement("includeDonation");
387                                 prodTable.appendChild(doc.createTextNode("true"));
388                                 products.appendChild(prodTable);
389                             }
390                             {
391                                 Element text = doc.createElement("Donation");
392                                 text.appendChild(doc.createTextNode(donation));
393                                 products.appendChild(text);
394                             }
395                             {
396                                 Element text = doc.createElement("GrandTotal");
397                                 text.appendChild(doc.createTextNode(tCost.add(new BigDecimal(donation)).toPlainString()));
398                                 products.appendChild(text);
399                             }
400 
401                         }
402                         rootElement.appendChild(products);
403 
404                     }
405                 }
406 
407             });
408         } else {
409 
410             DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
411             DocumentBuilder domBuilder;
412             domBuilder = domFactory.newDocumentBuilder();
413 
414 
415             doc = domBuilder.newDocument();
416             // Root element
417             Element rootElement = doc.createElement("LawnGardenReports");
418             doc.appendChild(rootElement);
419             //Info Elements
420             Element info = doc.createElement("info");
421             rootElement.appendChild(info);
422 
423             {
424                 // Scoutname elements
425                 {
426                     Element ScoutName = doc.createElement("name");
427                     ScoutName.appendChild(doc.createTextNode(scoutName));
428                     info.appendChild(ScoutName);
429                 }
430                 // StreetAddress elements
431                 {
432                     Element StreetAddress = doc.createElement("streetAddress");
433                     StreetAddress.appendChild(doc.createTextNode(scoutStAddr));
434                     info.appendChild(StreetAddress);
435                 }
436                 // City elements
437                 {
438                     Element city = doc.createElement("city");
439                     city.appendChild(doc.createTextNode(addrFormat));
440                     info.appendChild(city);
441                 }
442                 // Rank elements
443                 {
444                     Element rank = doc.createElement("rank");
445                     rank.appendChild(doc.createTextNode(scoutRank));
446                     info.appendChild(rank);
447                 }
448                 // phone elements
449                 {
450                     Element rank = doc.createElement("PhoneNumber");
451                     rank.appendChild(doc.createTextNode(scoutPhone));
452                     info.appendChild(rank);
453                 }
454                 // Logo elements
455                 {
456                     Element logo = doc.createElement("logo");
457                     logo.appendChild(doc.createTextNode("file:///" + logoLoc.replace("\\", "/")));
458                     info.appendChild(logo);
459                 }
460                 // ReportTitle elements
461                 {
462                     Element reportTitle = doc.createElement("reportTitle");
463                     reportTitle.appendChild(doc.createTextNode(repTitle));
464                     info.appendChild(reportTitle);
465                 }
466                 // Splitter elements
467                 {
468                     if (!Splitting.isEmpty()) {
469                         Element splitting = doc.createElement("splitting");
470 
471                         splitting.appendChild(doc.createTextNode(Splitting));
472                         info.appendChild(splitting);
473                     }
474                 }
475 
476 
477             }
478             //Column Elements
479             {
480                 Element columns = doc.createElement("columns");
481                 rootElement.appendChild(columns);
482                 String[] Columns = {"ID", "Name", "Unit Size", "Unit Cost", "Quantity", "Extended Price"};
483                 for (String Column : Columns) {
484                     //Column
485                     {
486                         Element columnName = doc.createElement("column");
487                         Element cName = doc.createElement("name");
488                         cName.appendChild(doc.createTextNode(Column));
489                         columnName.appendChild(cName);
490                         columns.appendChild(columnName);
491                     }
492                 }
493             }
494             setProgress(5);
495             switch (reportType) {
496 
497                 case "Year Totals": {
498                     Order.orderArray orderArray;
499                     if (user == null) {
500                         orderArray = Order.createOrderArray(selectedYear);
501                     } else {
502                         orderArray = Order.createOrderArray(selectedYear, user);
503 
504                     }
505                     //Products for year
506                     {
507                         //Product Elements
508                         Element products = doc.createElement("customerYear");
509                         rootElement.appendChild(products);
510                         {
511                             Element header = doc.createElement("header");
512                             header.appendChild(doc.createTextNode("true"));
513                             products.appendChild(header);
514                         }
515                         {
516                             Element prodTable = doc.createElement("prodTable");
517                             prodTable.appendChild(doc.createTextNode("true"));
518                             products.appendChild(prodTable);
519                         }
520 
521                         /*{
522                             if (includeHeader && !Objects.equals(category, "All")) {
523                                 Element title = doc.createElement("specialInfo");
524                                 {
525                                     Element text = doc.createElement("text");
526 
527                                     String notice = "*Notice: These products will be delivered to your house on " + Utilities.DbInt.getCategoryDate(category, selectedYear) + (paid ? "Please be available for delivery. Thank you for your advance payment." : ". Please Have the total payment listed below ready and be present on that date.");
528                                     text.appendChild(doc.createTextNode(notice));
529                                     title.appendChild(text);
530                                 }
531                                 info.appendChild(title);
532                             }
533 
534                         }*/
535                         setProgress(10);
536                         BigDecimal tCost = BigDecimal.ZERO;
537                         orderArray.totalCost = BigDecimal.ZERO;
538                         orderArray.totalQuantity = 0;
539                         int productIncValue = 90 / orderArray.orderData.length;
540                         for (formattedProduct aRowDataF : orderArray.orderData) {
541                             if (Objects.equals(aRowDataF.productCategory, category) || (Objects.equals(category, "All"))) {
542 
543                                 {
544                                     Element Product = doc.createElement("Product");
545                                     products.appendChild(Product);
546                                     //ID
547                                     {
548                                         Element ID = doc.createElement("ID");
549                                         ID.appendChild(doc.createTextNode(aRowDataF.productID));
550                                         Product.appendChild(ID);
551                                     }
552                                     //Name
553                                     {
554                                         Element Name = doc.createElement("Name");
555                                         Name.appendChild(doc.createTextNode(aRowDataF.productName));
556                                         Product.appendChild(Name);
557                                     }
558                                     //Size
559                                     {
560                                         Element Size = doc.createElement("Size");
561                                         Size.appendChild(doc.createTextNode(aRowDataF.productSize));
562                                         Product.appendChild(Size);
563                                     }
564                                     //UnitCost
565                                     {
566                                         Element UnitCost = doc.createElement("UnitCost");
567                                         UnitCost.appendChild(doc.createTextNode(aRowDataF.productUnitPrice.toPlainString()));
568                                         Product.appendChild(UnitCost);
569                                     }
570                                     //Quantity
571                                     {
572                                         Element Quantity = doc.createElement("Quantity");
573                                         orderArray.totalQuantity = orderArray.totalQuantity + aRowDataF.orderedQuantity;
574                                         Quantity.appendChild(doc.createTextNode(String.valueOf(aRowDataF.orderedQuantity)));
575                                         Product.appendChild(Quantity);
576                                     }
577                                     //TotalCost
578                                     {
579                                         Element TotalCost = doc.createElement("TotalCost");
580                                         orderArray.totalCost = orderArray.totalCost.add(aRowDataF.extendedCost);
581 
582                                         TotalCost.appendChild(doc.createTextNode(String.valueOf(aRowDataF.extendedCost)));
583                                         tCost = tCost.add(aRowDataF.extendedCost);
584                                         Product.appendChild(TotalCost);
585                                     }
586                                 }
587                             }
588                             setProgress(getProg() + productIncValue);
589                         }
590                         //Total Cost for list
591                         {
592                             Element tCostE = doc.createElement("totalCost");
593                             tCostE.appendChild(doc.createTextNode(String.valueOf(tCost)));
594                             products.appendChild(tCostE);
595                         }
596                         // OverallTotalCost elements
597                         {
598                             Element TotalCost = doc.createElement("TotalCost");
599                             TotalCost.appendChild(doc.createTextNode((orderArray.totalCost).toPlainString()));
600                             info.appendChild(TotalCost);
601                         }
602                         // OverallTotalQuantity elements
603                         {
604                             Element TotalQuantity = doc.createElement("totalQuantity");
605                             TotalQuantity.appendChild(doc.createTextNode(Integer.toString(orderArray.totalQuantity)));
606                             info.appendChild(TotalQuantity);
607                         }
608 
609                     }
610                     setProgress(100);
611                 }
612                 break;
613                 case "Customer Year Totals": {
614                     Order.orderArray orderArray = Order.createOrderArray(selectedYear, customers.get(0).getId(), true);
615                     Customer cust = new Customer(customers.get(0).getId(), selectedYear);
616                     //Set Items
617                     {
618                         Element products = doc.createElement("customerYear");
619 
620                         {
621                             Element custAddr = doc.createElement("custAddr");
622                             custAddr.appendChild(doc.createTextNode("true"));
623                             products.appendChild(custAddr);
624                         }
625                         // customername elements
626                         {
627                             Element custName = doc.createElement("name");
628                             custName.appendChild(doc.createTextNode(cust.getName()));
629                             products.appendChild(custName);
630                         }
631                         // StreetAddress elements
632                         {
633                             Element StreetAddress = doc.createElement("streetAddress");
634                             StreetAddress.appendChild(doc.createTextNode(cust.getAddr()));
635                             products.appendChild(StreetAddress);
636                         }
637                         // City elements
638                         {
639                             Element city = doc.createElement("city");
640                             String addr = cust.getTown() + ' ' + cust.getState() + ", " + cust.getZip();
641                             city.appendChild(doc.createTextNode(addr));
642                             products.appendChild(city);
643                         }
644 
645                         // phone elements
646                         {
647                             Element phone = doc.createElement("PhoneNumber");
648                             phone.appendChild(doc.createTextNode(cust.getPhone()));
649                             products.appendChild(phone);
650                         }
651                         {
652                             Element header = doc.createElement("header");
653                             header.appendChild(doc.createTextNode("true"));
654                             products.appendChild(header);
655                         }
656                         /*{
657                             Element title = doc.createElement("title");
658                             title.appendChild(doc.createTextNode(cust.getName() + ' ' + selectedYear + " Utilities.Order"));
659                             products.appendChild(title);
660                         }*/
661                         {
662                             if (includeHeader && !Objects.equals(category, "All")) {
663                                 Element title = doc.createElement("specialInfo");
664                                 {
665                                     Element text = doc.createElement("text");
666                                     String notice = "*Notice: These products will be delivered to your house on " + DbInt.getCategoryDate(category, selectedYear) + (". Total paid to date: $" + cust.getPaid().toPlainString());
667                                     text.appendChild(doc.createTextNode(notice));
668                                     title.appendChild(text);
669                                 }
670                                 products.appendChild(title);
671                             }
672                         }
673 
674 
675                         //Product Elements
676                         rootElement.appendChild(products);
677 
678                         {
679                             Element prodTable = doc.createElement("prodTable");
680                             prodTable.appendChild(doc.createTextNode("true"));
681                             products.appendChild(prodTable);
682                         }
683 
684                         setProgress(5);
685                         BigDecimal tCost = BigDecimal.ZERO;
686                         int productIncValue = 90 / orderArray.orderData.length;
687 
688                         //For each product ordered, enter info
689                         for (formattedProduct aRowDataF : orderArray.orderData) {
690                             if (Objects.equals(aRowDataF.productCategory, category) || (Objects.equals(category, "All"))) {
691 
692                                 {
693                                     Element Product = doc.createElement("Product");
694                                     products.appendChild(Product);
695                                     //ID
696                                     {
697                                         Element ID = doc.createElement("ID");
698                                         ID.appendChild(doc.createTextNode(aRowDataF.productID));
699                                         Product.appendChild(ID);
700                                     }
701                                     //Name
702                                     {
703                                         Element Name = doc.createElement("Name");
704                                         Name.appendChild(doc.createTextNode(aRowDataF.productName));
705                                         Product.appendChild(Name);
706                                     }
707                                     //Size
708                                     {
709                                         Element Size = doc.createElement("Size");
710                                         Size.appendChild(doc.createTextNode(aRowDataF.productSize));
711                                         Product.appendChild(Size);
712                                     }
713                                     //UnitCost
714                                     {
715                                         Element UnitCost = doc.createElement("UnitCost");
716                                         UnitCost.appendChild(doc.createTextNode(aRowDataF.productUnitPrice.toPlainString()));
717                                         Product.appendChild(UnitCost);
718                                     }
719                                     //Quantity
720                                     {
721                                         Element Quantity = doc.createElement("Quantity");
722                                         Quantity.appendChild(doc.createTextNode(String.valueOf(aRowDataF.orderedQuantity)));
723                                         Product.appendChild(Quantity);
724                                     }
725                                     //TotalCost
726                                     {
727                                         Element TotalCost = doc.createElement("TotalCost");
728                                         TotalCost.appendChild(doc.createTextNode(String.valueOf(aRowDataF.extendedCost)));
729                                         tCost = tCost.add(aRowDataF.extendedCost);
730                                         Product.appendChild(TotalCost);
731                                     }
732                                 }
733                             }
734                             setProgress(getProg() + productIncValue);
735                         }
736                         //Total Cost for this Utilities.Year
737                         {
738                             Element tCostE = doc.createElement("totalCost");
739                             tCostE.appendChild(doc.createTextNode(String.valueOf(tCost)));
740                             products.appendChild(tCostE);
741                         }
742                         // OverallTotalCost elements
743                         {
744                             Element TotalCost = doc.createElement("TotalCost");
745                             TotalCost.appendChild(doc.createTextNode(orderArray.totalCost.toPlainString()));
746                             info.appendChild(TotalCost);
747                         }
748                         // OverallTotalQuantity elements
749                         {
750                             Element TotalQuantity = doc.createElement("totalQuantity");
751                             TotalQuantity.appendChild(doc.createTextNode(Integer.toString(orderArray.totalQuantity)));
752                             info.appendChild(TotalQuantity);
753                         }
754                     }
755                     setProgress(100);
756                 }
757                 break;
758 
759                 case "Customer All-Time Totals": {
760                     // Collection<String> customerYears = new ArrayList<>();
761                     ArrayList<String> years = DbInt.getUserYears();
762                     if (years != null && !years.isEmpty()) {
763                         final String[] headerS = {"true"};
764                         final BigDecimal[] overallTotalCost = {BigDecimal.ZERO};
765                         final int[] overallTotalQuantity = {0};
766                         int yearProgressInc = 95 / (years.size());
767                         //For Each Utilities.Year
768                         customers.forEach(cust -> {
769 
770 
771                             //    customerYears.add(year);
772                             //Product Elements
773                             Element products = doc.createElement("customerYear");
774                             rootElement.appendChild(products);
775                             {
776                                 Element header = doc.createElement("header");
777                                 header.appendChild(doc.createTextNode(headerS[0]));
778                                 headerS[0] = "false";
779                                 products.appendChild(header);
780                             }
781                             {
782                                 Element prodTable = doc.createElement("prodTable");
783                                 prodTable.appendChild(doc.createTextNode("true"));
784                                 products.appendChild(prodTable);
785                             }
786                             {
787                                 Element custAddr = doc.createElement("custAddr");
788                                 custAddr.appendChild(doc.createTextNode("true"));
789                                 products.appendChild(custAddr);
790                             }
791                             // customername elements
792                             {
793                                 Element custName = doc.createElement("name");
794                                 custName.appendChild(doc.createTextNode(cust.getName()));
795                                 products.appendChild(custName);
796                             }
797                             // StreetAddress elements
798                             {
799                                 Element StreetAddress = doc.createElement("streetAddress");
800                                 StreetAddress.appendChild(doc.createTextNode(cust.getAddr()));
801                                 products.appendChild(StreetAddress);
802                             }
803                             // City elements
804                             {
805                                 Element city = doc.createElement("city");
806                                 String addr = cust.getTown() + ' ' + cust.getState() + ", " + cust.getZip();
807                                 city.appendChild(doc.createTextNode(addr));
808                                 products.appendChild(city);
809                             }
810 
811                             // phone elements
812                             {
813                                 Element phone = doc.createElement("PhoneNumber");
814                                 phone.appendChild(doc.createTextNode(cust.getPhone()));
815                                 products.appendChild(phone);
816                             }
817 
818                             //YearTitle
819                             {
820                                 Element title = doc.createElement("title");
821                                 title.appendChild(doc.createTextNode(cust.getYear()));
822                                 products.appendChild(title);
823                             }
824 
825                             Order.orderArray orderArray = Order.createOrderArray(cust.getYear(), cust.getId(), true);
826                             BigDecimal tCost = BigDecimal.ZERO;
827                             overallTotalCost[0] = orderArray.totalCost;
828                             overallTotalQuantity[0] = orderArray.totalQuantity;
829                             //For each product in the table set the data
830                             for (formattedProduct orderedProduct : orderArray.orderData) {
831                                 Element Product = doc.createElement("Product");
832                                 products.appendChild(Product);
833                                 //ID
834                                 {
835                                     Element ID = doc.createElement("ID");
836                                     ID.appendChild(doc.createTextNode(orderedProduct.productID));
837                                     Product.appendChild(ID);
838                                 }
839                                 //Name
840                                 {
841                                     Element Name = doc.createElement("Name");
842                                     Name.appendChild(doc.createTextNode(orderedProduct.productName));
843                                     Product.appendChild(Name);
844                                 }
845                                 //Size
846                                 {
847                                     Element Size = doc.createElement("Size");
848                                     Size.appendChild(doc.createTextNode(orderedProduct.productSize));
849                                     Product.appendChild(Size);
850                                 }
851                                 //UnitCost
852                                 {
853                                     Element UnitCost = doc.createElement("UnitCost");
854                                     UnitCost.appendChild(doc.createTextNode(orderedProduct.productUnitPrice.toPlainString()));
855                                     Product.appendChild(UnitCost);
856                                 }
857                                 //Quantity
858                                 {
859                                     Element Quantity = doc.createElement("Quantity");
860                                     Quantity.appendChild(doc.createTextNode(String.valueOf(orderedProduct.orderedQuantity)));
861                                     Product.appendChild(Quantity);
862                                 }
863                                 //TotalCost
864                                 {
865                                     Element TotalCost = doc.createElement("TotalCost");
866                                     TotalCost.appendChild(doc.createTextNode(String.valueOf(orderedProduct.extendedCost)));
867                                     tCost = tCost.add(orderedProduct.extendedCost);
868                                     Product.appendChild(TotalCost);
869                                 }
870                             }
871                             //Total for current customers
872                             {
873                                 Element tCostE = doc.createElement("totalCost");
874                                 tCostE.appendChild(doc.createTextNode(String.valueOf(tCost)));
875                                 products.appendChild(tCostE);
876                             }
877 
878 
879                             ////Utilities.DbInt.pCon.close();
880 
881 
882                             setProgress(getProg() + yearProgressInc);
883                         });
884 
885                         // OverallTotalCost elements
886                         {
887                             Element TotalCost = doc.createElement("TotalCost");
888                             TotalCost.appendChild(doc.createTextNode((overallTotalCost[0].toPlainString())));
889                             info.appendChild(TotalCost);
890                         }
891                         // OverallTotalQuantity elements
892                         {
893                             Element TotalQuantity = doc.createElement("totalQuantity");
894                             TotalQuantity.appendChild(doc.createTextNode(Integer.toString(overallTotalQuantity[0])));
895                             info.appendChild(TotalQuantity);
896                         }
897                     }
898                     setProgress(100);
899 
900                 }
901                 break;
902             }
903         }
904         OutputStreamWriter osw = null;
905 
906         try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
907             osw = new OutputStreamWriter(baos);
908 
909             TransformerFactory tranFactory = TransformerFactory.newInstance();
910             Transformer aTransformer = tranFactory.newTransformer();
911             aTransformer.setOutputProperty(OutputKeys.ENCODING, osw.getEncoding());
912             aTransformer.setOutputProperty(OutputKeys.INDENT, "yes");
913             aTransformer.setOutputProperty(OutputKeys.METHOD, "xml");
914             aTransformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
915 
916             Source src = new DOMSource(doc);
917             Result result = new StreamResult(osw);
918             aTransformer.transform(src, result);
919 
920             osw.flush();
921 
922             String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime());
923             String tmpDirectoryOp = System.getProperty("java.io.tmpdir");
924             File tmpDirectory = new File(tmpDirectoryOp);
925             xmlTempFile = File.createTempFile("LGReport" + timeStamp, ".xml", tmpDirectory);
926             xmlTempFile.deleteOnExit();
927 
928             try (OutputStream outStream = new FileOutputStream(xmlTempFile)) {// writing bytes in to byte output stream
929 
930                 baos.writeTo(outStream);
931                 //fstream.deleteOnExit();
932 
933             } catch (IOException e) {
934                 updateMessage("Error writing temporary XML. Please try again.");
935                 throw e;
936             }
937 
938 
939         } catch (Exception exp) {
940             updateMessage("Error while genertating tempory XML. Please try again or contact support.");
941             throw exp;
942         } finally {
943             try {
944                 if (osw != null) {
945                     osw.close();
946                 }
947             } catch (IOException | RuntimeException e) {
948                 LogToFile.log(e, Severity.FINE, "Error closing temporary XML file.");
949             }
950 
951         }
952         convertXSLToPDF();
953         updateMessage("Done");
954 
955 
956         // Return the number of matches found
957         return 1;
958     }
959 
960     private void convertXSLToPDF() throws Exception {
961         OutputStream os = new ByteArrayOutputStream();
962 
963         Processor proc = new Processor(false);
964         XsltCompiler comp = proc.newXsltCompiler();
965 
966         try (InputStream in = getClass().getResourceAsStream("/Report.xsl")) {
967 
968 
969             XsltExecutable exp = comp.compile(new StreamSource(in));
970             XdmNode source = proc.newDocumentBuilder().build(new StreamSource(xmlTempFile));
971             Serializer out = proc.newSerializer(os);
972             out.setOutputProperty(Serializer.Property.METHOD, "html");
973             out.setOutputProperty(Serializer.Property.INDENT, "yes");
974             XsltTransformer trans = exp.load();
975             trans.setInitialContextNode(source);
976             trans.setDestination(out);
977             trans.transform();
978             ByteArrayOutputStream baos;
979             baos = (ByteArrayOutputStream) os;
980 
981             InputStream is = new ByteArrayInputStream(baos.toByteArray());
982 
983             Tidy tidy = new Tidy(); // obtain a new Tidy instance
984             // set desired config options using tidy setters
985             OutputStream osT = new ByteArrayOutputStream();
986             tidy.setQuiet(true);
987             tidy.setIndentContent(true);
988             tidy.setDocType("loose");
989             tidy.setFixBackslash(true);
990             tidy.setFixUri(true);
991             tidy.setShowWarnings(false);
992             tidy.setEscapeCdata(true);
993             tidy.setXHTML(true);
994             tidy.setInputEncoding("utf8");
995             tidy.setOutputEncoding("utf8");
996 
997             File xhtml;
998             String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime());
999             String tmpDirectoryOp = System.getProperty("java.io.tmpdir");
1000             File tmpDirectory = new File(tmpDirectoryOp);
1001             xhtml = File.createTempFile("LGReportXhtml" + timeStamp, ".xhtml", tmpDirectory);
1002             xhtml.deleteOnExit();
1003             try (FileOutputStream fos = new FileOutputStream(pdfLoc);
1004                  FileOutputStream xhtmlfos = new FileOutputStream(xhtml)) {
1005 
1006 
1007                 tidy.parse(is, osT); // run tidy, providing an input and output streamp
1008                 ByteArrayOutputStream baosT;
1009                 baosT = (ByteArrayOutputStream) osT;
1010 
1011                 baosT.writeTo(xhtmlfos);
1012                 String cssText = "* {\n" +
1013                         "                margin-top: 0px;\n" +
1014                         "                margin-bottom: 0px;\n" +
1015                         "                } " +
1016                         " .LBordered {\n" +
1017                         "                border-left: 1px solid black;\n" +
1018                         "                border-bottom: 1px solid black;\n" +
1019 
1020                         "                border-collapse: collapse;\n" +
1021                         "                }\n" +
1022                         "                .Bordered {\n" +
1023                         "                border: 1px solid black;\n" +
1024                         "                border-collapse: collapse;\n" +
1025                         "                }\n" +
1026                         "                .UBordered {\n" +
1027                         "                border: 0px solid black;\n" +
1028                         "                border-collapse: collapse;\n" +
1029                         "                }\n" +
1030                         "                .splitTitle {display:inline;}\n" +
1031                         "                h4{\n" +
1032                         "                margin:1px;\n" +
1033                         "                padding:1px;\n" +
1034                         "                }\n" +
1035                         "                table {\n" +
1036                         "                width:100%;\n" +
1037                         "                margin-bottom: 0.4pt;\n" +
1038                         "                margin-top: 0;\n" +
1039                         "                margin-left: 0;\n" +
1040                         "                margin-right: 0;\n" +
1041                         "                text-indent: 0;\n" +
1042                         "                }\n" +
1043                         "                tr {\n" +
1044                         "                vertical-align: inherit;\n" +
1045                         "                }\n" +
1046                         "                table > tr {\n" +
1047                         "                vertical-align: middle;\n" +
1048                         "                }\n" +
1049                         "                table, td {\n" +
1050                         "                background-color:#FFF;\n" +
1051                         "                font-size:10pt;\n" +
1052                         "                padding: 50px;\n" +
1053                         "                border-spacing: 50px;\n" +
1054 
1055                         "                text-align: inherit;\n" +
1056                         "                vertical-align: inherit;\n" +
1057                         "                }\n" +
1058                         "                th {\n" +
1059                         "                background-color: #FFF;\n" +
1060                         "                font-size:10pt;\n" +
1061                         "                color:#000;\n" +
1062                         "                display: table-cell;\n" +
1063                         "                font-weight: bold;\n" +
1064                         "                padding: 1px;\n" +
1065                         "                vertical-align: inherit;\n" +
1066                         "                }";
1067                 //fstream.deleteOnExit();
1068                 com.itextpdf.text.Document document = new com.itextpdf.text.Document();
1069 
1070                 // step 2
1071                 PdfWriter writer = PdfWriter.getInstance(document, fos);
1072                 writer.setInitialLeading(12.5f);
1073                 writer.setTagged();
1074                 // step 3
1075                 document.open();
1076 
1077                 // step 4
1078 
1079                 // CSS
1080                 CSSResolver cssResolver = XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
1081                 CssFile cssFile = XMLWorkerHelper.getCSS(new ByteArrayInputStream(cssText.getBytes()));
1082                 cssResolver.addCss(cssFile);
1083                 // HTML
1084                 HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
1085                 htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
1086                 htmlContext.autoBookmark(false);
1087 
1088                 // Pipelines
1089                 PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
1090                 HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
1091                 CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
1092 
1093                 // XML Worker
1094                 XMLWorker worker = new XMLWorker(css, true);
1095                 XMLParser p = new XMLParser(worker);
1096                 p.parse(new FileInputStream(xhtml));
1097 
1098                 // step 5
1099                 document.close();
1100                 /*com.itextpdf.text.Document document = new com.itextpdf.text.Document();
1101                 // step 2
1102                 PdfWriter writer = PdfWriter.getInstance(document, fos);
1103                 // step 3
1104                 document.open();
1105                 // step 4
1106                 XMLWorkerHelper.getInstance().parseXHtml(writer, document,
1107                         new FileInputStream(xhtml));
1108                 // step 5
1109                 document.close();*/
1110 
1111 
1112             } catch (Exception e) {
1113                 updateMessage("Error ocurred while converting temporary XML to pdf. Try again or contact support.");
1114                 throw e;
1115             }
1116         } catch (IOException e) {
1117             updateMessage("Error writing PDF file. Please try again.");
1118             throw e;
1119         }
1120 
1121 
1122         /*
1123           Compile and execute a simple transformation that applies a stylesheet to an input file,
1124           and serializing the result to an output file
1125          */
1126 
1127 
1128     }
1129 
1130     private double getProg() {
1131         return prog;
1132     }
1133     private void setProgress(double progress) {
1134         prog += progress;
1135         updateProgress(progress, 100.0);
1136     }
1137 }