From e0b3b43c06f4b55b295225b6ccb0fd98e811f546 Mon Sep 17 00:00:00 2001
From: Akash Shah <akash.shah@nist.gov>
Date: Sat, 26 Jan 2019 21:41:01 -0500
Subject: [PATCH] Invoice Printing!!

---
 .../app/invoice-gen/invoice-gen.component.css |  11 +-
 .../invoice-gen/invoice-gen.component.html    | 121 +++---
 .../app/invoice-gen/invoice-gen.component.ts  | 367 ++++++++++++++----
 3 files changed, 359 insertions(+), 140 deletions(-)

diff --git a/AstuteClient2/src/app/invoice-gen/invoice-gen.component.css b/AstuteClient2/src/app/invoice-gen/invoice-gen.component.css
index dedc174..4864a90 100644
--- a/AstuteClient2/src/app/invoice-gen/invoice-gen.component.css
+++ b/AstuteClient2/src/app/invoice-gen/invoice-gen.component.css
@@ -9,16 +9,21 @@
 /*-moz-box-sizing: border-box;*/
 /*}*/
 .page {
-    width: 21cm;
-    min-height: 29.7cm;
+    width: 215.9mm;
+    height: 279.4mm;
     padding: 2cm;
     margin: 1cm auto;
     border: 1px #D3D3D3 solid;
-    border-radius: 5px;
+    border-radius: 2px;
     background: white;
     box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
     font-size: 11pt;
 }
+
+@media print {
+    * { display:none; }
+    .page * { display:block; }
+}
 /*.subpage {*/
 /*padding: 1cm;*/
 /*border: 5px red solid;*/
diff --git a/AstuteClient2/src/app/invoice-gen/invoice-gen.component.html b/AstuteClient2/src/app/invoice-gen/invoice-gen.component.html
index 51e76a3..d0477c8 100644
--- a/AstuteClient2/src/app/invoice-gen/invoice-gen.component.html
+++ b/AstuteClient2/src/app/invoice-gen/invoice-gen.component.html
@@ -1,57 +1,65 @@
+<app-nav-bar></app-nav-bar>
 <div class="page" #doc>
   <div class="container-fluid">
-    <div class="row">
-      <div class="col-6">
-        <img src="AstuteLogo.gif" align="left" alt="Astute Engineering" height="75">
-      </div>
-      <div class="col-6">
-        <p class="h1 text-right align-bottom">INVOICE</p>
-      </div>
-    </div>
+    <table>
+      <tr>
+        <td width="100%"><img src="assets/img/AstuteLogo.gif" align="left" alt="Astute Engineering" height="75"></td>
+        <td width="100%"><p class="h1 text-right align-bottom">INVOICE</p></td>
+      </tr>
+    </table>
+    <!--<div class="row">-->
+      <!--<div class="col-6">-->
+        <!--<img src="AstuteLogo.gif" align="left" alt="Astute Engineering" height="75">-->
+      <!--</div>-->
+      <!--<div class="col-6">-->
+        <!--<p class="h1 text-right align-bottom">INVOICE</p>-->
+      <!--</div>-->
+    <!--</div>-->
     <br/>
-    <div class="row">
-      <div class="col-4">
-        <p>To,</p>
-        <p>{{name}}</p>
-        <p>{{email}}</p>
-        <p>{{address}}</p>
-      </div>
-      <div class="col-5 text-right">
-        <p>Purchase Order No.:</p>
-        <p>Contract No.:</p>
-        <p>Invoice No.:</p>
-        <p>Invoice Date:</p>
-      </div>
-      <div class="col text-left">
-        <p>{{poNum}}</p>
-        <p>{{coNum}}</p>
-        <p>{{inNum}}</p>
-        <p>{{inDate}}</p>
-      </div>
-    </div>
+
+    <table>
+      <tr>
+        <td width="30%">
+          <p>To,</p>
+          <p>{{name}}</p>
+          <p>{{email}}</p>
+          <p>{{address}}</p>
+        </td>
+        <td class="text-right" width="40%">
+          <p>Purchase Order No.:</p>
+          <p>Contract No.:</p>
+          <p>Invoice No.:</p>
+          <p>Invoice Date:</p>
+        </td>
+        <td class="text-left" width="100%">
+          <p>{{poNum}}</p>
+          <p>{{coNum}}</p>
+          <p>{{inNum}}</p>
+          <p>{{inDate}}</p>
+        </td>
+      </tr>
+    </table>
     <br/>
-    <div class="row">
-      <table class="table table-sm table-bordered table-light">
-        <thead class="thead-light">
-        <tr>
-          <th scope="col" style="text-align: center;">No.</th>
-          <th scope="col">Description</th>
-          <th scope="col" style="text-align: center;">Hourly Rate</th>
-          <th scope="col" style="text-align: center;">Hours Expended</th>
-          <th scope="col" style="text-align: center;">Invoice Amount</th>
-        </tr>
-        </thead>
-        <tbody>
-        <tr *ngFor="let inDet of inDetails">
-          <th scope="row" style="text-align: center;">{{inDet.lineItemNum}}</th>
-          <td>{{inDet.desc}}</td>
-          <td style="text-align: right;">${{inDet.anount}}.00</td>
-          <td style="text-align: center;">-</td>
-          <td style="text-align: right;">${{inDet.anount}}.00</td>
-        </tr>
-        </tbody>
-      </table>
-    </div>
+    <table class="table table-sm table-bordered table-light">
+      <thead class="thead-light">
+      <tr>
+        <th scope="col" style="text-align: center;">No.</th>
+        <th scope="col" style="text-align: center;">Description</th>
+        <th scope="col" style="text-align: center;">Fee</th>
+        <th scope="col" style="text-align: center;">Quantity</th>
+        <th scope="col" style="text-align: center;">Amount</th>
+      </tr>
+      </thead>
+      <tbody>
+      <tr *ngFor="let inDet of inDetails">
+        <th scope="row" style="text-align: center;">{{inDet.lineItemNum}}</th>
+        <td>{{inDet.desc}}</td>
+        <td style="text-align: right;">${{inDet.fee}}{{(inDet.feeTypeId == 2) ? ' /hr' : ''}}</td>
+        <td style="text-align: right;">{{inDet.qty}}</td>
+        <td style="text-align: right;">${{inDet.qty * inDet.fee}}.00</td>
+      </tr>
+      </tbody>
+    </table>
     <br/>
     <div class="row">
       <table>
@@ -80,12 +88,6 @@
           <td style="width: 305px; text-align: right; height: 18px;">&nbsp;</td>
           <td style="background-color: lightgray; border-color: black; width: 153px; height: 18px;">&nbsp;</td>
         </tr>
-        <tr style="height: 18px;">
-          <td style="width: 251.5px; text-align: right; height: 18px;">Amount This Invoice</td>
-          <td style="background-color: lightgray; border-color: black; width: 137.5px; height: 18px;">{{inAmt}}</td>
-          <td style="width: 305px; text-align: right; height: 18px;">&nbsp;</td>
-          <td style="background-color: lightgray; border-color: black; width: 153px; height: 18px;">&nbsp;</td>
-        </tr>
         <tr style="height: 18px;">
           <td style="width: 251.5px; text-align: right; height: 18px;">Balance to be Billed</td>
           <td style="background-color: lightgray; border-color: black; width: 137.5px; height: 18px;">{{balToBeBill}}</td>
@@ -111,12 +113,13 @@
     </div>
   </div>
 </div>
-<div id="editor"></div>
-<div class="container-fluid">
+<div class="container-fluid skip">
   <div class="row">
     <div class="col">
       <div class="text-center">
-        <button class="btn btn-lg btn-outline-primary"(click)="moreTestJsPDF()">Download PDF</button>
+        <button class="btn btn-lg btn-outline-primary" (click)="downloadPDF()">Download Image PDF</button>
+        <button class="btn btn-lg btn-outline-primary" (click)="testjsPDF()">Build PDF</button>
+        <button class="btn btn-lg btn-outline-primary" (click)="printGrid(null)">Print Grid</button>
       </div>
     </div>
   </div>
diff --git a/AstuteClient2/src/app/invoice-gen/invoice-gen.component.ts b/AstuteClient2/src/app/invoice-gen/invoice-gen.component.ts
index 06b8ab8..9d141d9 100644
--- a/AstuteClient2/src/app/invoice-gen/invoice-gen.component.ts
+++ b/AstuteClient2/src/app/invoice-gen/invoice-gen.component.ts
@@ -1,10 +1,11 @@
 import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
 import {AstuteClientService} from '../services/astute-client-service';
+import {formatCurrency} from '@angular/common';
 
 declare var html2pdf: any;
 declare var html2canvas: any;
 declare var jsPDF: any;
-declare var $: any
+declare var $: any;
 
 @Component({
     selector: 'app-invoice-gen',
@@ -17,9 +18,9 @@ export class InvoiceGenComponent implements OnInit {
     gridX = []; // these are the layout grid STARTING
     gridY = []; // from the 1 inch border (x: 25; y:23)
 
-    name;
-    email;
-    address;
+    name: string;
+    email: string;
+    address: string;
 
     poNum;
     coNum;
@@ -48,19 +49,17 @@ export class InvoiceGenComponent implements OnInit {
     }
 
     ngOnInit() {
-        let x = 25;
-        let y = 23;
-        for (let i = 0; i < 17; i++) {
+        let x = 28.5;
+        let y = 25;
+        for (let i = 0; i < 17; i++) { //
             this.gridX[i] = x;
             x += 10;
         }
-        for (let j = 0; j < 26; j++) {
+        for (let j = 0; j < 24; j++) {
             this.gridY[j] = y;
             y += 10;
         }
-        console.log('Layout Grid X: ' + this.gridX);
-        console.log('Layout Grid Y: ' + this.gridY);
-        this.astuteClientService.getInvoiceGen('VDO-02_0108_3').then((data) => {
+        this.astuteClientService.getInvoiceGen('MDO-01_DRAFT_720').then((data) => {
             this.name = data.customer.customerName;
             this.email = data.customer.email;
             this.address = data.customer.add1 + ' ' + data.customer.add2 + ' ' +
@@ -76,15 +75,10 @@ export class InvoiceGenComponent implements OnInit {
 
             this.ogCoAmt = data.po.contractAmt;
             this.netChanges = 0;
-            this.totCoAmt = 0;
-            this.prevBill = data.previouslyPaidAmt;
-            this.inAmt = data.invoice.billAmt;
+            this.totCoAmt = data.po.contractAmt;
+            this.prevBill = data.po.previouslyBilledAmount;
             this.balToBeBill = data.balanceToBeBilled;
-            this.subTotal = this.inAmt;
-            this.milage = 0;
-            this.otherExp = 0;
-            this.outOf = 0;
-            this.finTot = this.inAmt;
+            this.finTot = data.invoice.billAmt;
 
             this.notes = data.invoice.specialNotes;
             this.cert = data.invoice.certification;
@@ -94,32 +88,34 @@ export class InvoiceGenComponent implements OnInit {
     downloadPDF() {
         // new html2pdf(document.getElementById('doc'));
 
-        const A4_width = 210;//425; // pixels
-        const A4_height = 297;//550; // pixels
-        const ratio = 2;
+        // const A4_width = 210;// pixels
+        // const A4_height = 297;// pixels
+        const letter_width = 215.9;
+        const letter_height = 279.4;
+        const ratio = 5;
         // //
         const oldCanvas = document.createElement('canvas');
-        oldCanvas.width = A4_width;
-        oldCanvas.height = A4_height;
+        oldCanvas.width = letter_width;
+        oldCanvas.height = letter_height;
         const oldContext = oldCanvas.getContext('2d');
         const oldImg = new Image();
         oldImg.src = oldCanvas.toDataURL();
-        oldContext.drawImage(oldImg, 0, 0, A4_width, A4_height);
+        oldContext.drawImage(oldImg, 0, 0, letter_width, letter_height);
 
         const newImg = new Image();
         newImg.onload = () => {
             html2canvas(this.invoiceHTML.nativeElement).then((newCanvas) => {
                     console.log(this.invoiceHTML.nativeElement);
-                    // newCanvas.width = A4_width / 50;
-                    // newCanvas.height = A4_height / 50;
+                    // newCanvas.width = letter_width / 5;
+                    // newCanvas.height = letter_height / 5;
                     const newContext = newCanvas.getContext('2d');
                     // Scale and draw the source image to the canvas
-                    newContext.drawImage(newImg, 0, 0, A4_width * ratio, A4_height * ratio);
+                    newContext.drawImage(newImg, 0, 0, letter_width * ratio, letter_height * ratio);
                     newImg.src = newCanvas.toDataURL();
                     const pdfDoc = new jsPDF({
                         unit: 'mm'
                     });
-                    pdfDoc.addImage(newImg, 'png', 0, 0, 210, 297); // imageData, format, x, y, w, h
+                    pdfDoc.addImage(newImg, 'pdf', 0, 0, letter_width, letter_height); // imageData, format, x, y, w, h
                     //pdfDoc.addHTML(this.invoiceHTML.nativeElement);
                     pdfDoc.save(this.inNum + '.pdf'); // save file
                     newImg.onload = undefined; // kill the func
@@ -139,60 +135,275 @@ export class InvoiceGenComponent implements OnInit {
     }
 
     testjsPDF() {
-        const doc = jsPDF();
-        doc.text('INVOICE', this.gridX[13], this.gridY[0]);
-        doc.text('ASTUTE', this.gridX[0], this.gridY[0]);
-
-        // No. Column (header and rows)
-        doc.rect(this.gridX[0], this.gridY[5], 10, 10);
-        for (let i = 6; i < 15; i += 2) {
-            doc.rect(this.gridX[0], this.gridY[i], 10, 20);
+        const doc = jsPDF('p', 'mm', 'letter');
+        console.log(doc.getFontList());
+        // this.printGrid(doc);
+        this.printHeader(doc);
+        let len = this.inDetails.length;
+        if (len <= 6) {
+            this.printTable(doc, 7, 13, this.inDetails);
+        } else if (len > 6 && len <= 28) {
+            this.printTable(doc, 7, 22, this.inDetails.slice(0, 15));
+            doc.addPage('letter', 'p');
+            this.printTable(doc, 0, 13, this.inDetails.slice(15, 28));
+        } else {
+            this.printTable(doc, 7, 22, this.inDetails.slice(0, 15));
+            len -= 15;
+            let i = 0;
+            while (len > 13) {
+                doc.addPage('letter', 'p');
+                this.printTable(doc, 0, 22, this.inDetails.slice(15 + (22 * i), 37 + (22 * i)));
+                i++;
+            }
+            doc.addPage('letter', 'p');
+            this.printTable(doc, 0, 13, this.inDetails.slice(37 + (22 * (i - 1))));
         }
-
-        // Description Column (header and rows)
-        doc.rect(this.gridX[1], this.gridY[5], 70, 10);
-        for (let i = 6; i < 15; i += 2) {
-            doc.rect(this.gridX[1], this.gridY[i], 70, 20);
-        }
-
-        // Hourly Rate Column (header and rows)
-        doc.rect(this.gridX[8], this.gridY[5], 30, 10);
-        for (let i = 6; i < 15; i += 2) {
-            doc.rect(this.gridX[8], this.gridY[i], 30, 20);
-        }
-
-        // Hours Column (header and rows)
-        doc.rect(this.gridX[11], this.gridY[5], 20, 10);
-        for (let i = 6; i < 15; i += 2) {
-            doc.rect(this.gridX[11], this.gridY[i], 20, 20);
-        }
-
-        // Amount Column (header and rows)
-        doc.rect(this.gridX[13], this.gridY[5], 30, 10);
-        for (let i = 6; i < 15; i += 2) {
-            doc.rect(this.gridX[13], this.gridY[i], 30, 20);
-        }
-        doc.addPage()
-        doc.addPage()
-        doc.text('I am on page 3', 10, 10)
-        doc.setPage(1)
+        this.printFooter(doc);
         doc.save('a4.pdf');
     }
 
+    printHeader (doc) {
+        if (!doc) {
+            doc = jsPDF('p', 'mm', 'letter');
+        }
+        ///////////////////// Header //////////
+        // Logo and INVOICE
+        doc.setFontSize(35);
+        doc.text('INVOICE', this.gridX[10] + 5, this.gridY[2] - 5);
+        doc.addImage('assets/img/AstuteLogo.png', 'png', this.gridX[0], this.gridY[0], 50, 22.04);
+
+        // To, customer
+        doc.setFontSize(12);
+        doc.text('To,', this.gridX[0], this.gridY[3]);
+        const nameSplit = doc.splitTextToSize(this.name, 65);
+        nameSplit.forEach((text, i) => {
+            doc.text(text, this.gridX[0] + 5, this.gridY[3] + (5 * (i + 1)));
+        });
+        doc.setTextColor(66, 144, 255);
+        const emailSplit = doc.splitTextToSize(this.email, 65);
+        emailSplit.forEach((text, i) => {
+            doc.text(text, this.gridX[0] + 5, this.gridY[4] + (5 * (i + 1)));
+        });
+        doc.setTextColor(0);
+        const addressSplit = doc.splitTextToSize(this.address, 65);
+        addressSplit.forEach((text, i) => {
+            doc.text(text, this.gridX[0] + 5, this.gridY[5] + (5 * (i + 1)));
+        });
+
+        // Invoice Information
+        doc.text('Purchase Order #:', this.gridX[11], this.gridY[3], {'align': 'right'});
+        const poNumSplit = doc.splitTextToSize(' ' + this.poNum, 50);
+        poNumSplit.forEach((text, i) => {
+            doc.text(text, this.gridX[11], this.gridY[3] + (5 * i));
+        });
+
+        doc.text('Contract #:', this.gridX[11], this.gridY[4], {'align': 'right'});
+        const coNumSplit = doc.splitTextToSize(' ' + this.coNum, 50);
+        coNumSplit.forEach((text, i) => {
+            doc.text(text, this.gridX[11], this.gridY[4] + (5 * i));
+        });
+
+        doc.text('Invoice #:', this.gridX[11], this.gridY[5], {'align': 'right'});
+        const inNumSplit = doc.splitTextToSize(' ' + this.inNum, 50);
+        inNumSplit.forEach((text, i) => {
+            doc.text(text, this.gridX[11], this.gridY[5] + (5 * i));
+        });
+
+        doc.text('Invoice Date:', this.gridX[11], this.gridY[6], {'align': 'right'});
+        const inDateSplit = doc.splitTextToSize(' ' + this.inDate, 50);
+        inDateSplit.forEach((text, i) => {
+            doc.text(text, this.gridX[11], this.gridY[6] + (5 * i));
+        });
+        ///////////////////////////////////////
+        if (!doc) {
+            doc.autoPrint({variant: 'non-conform'});
+            doc.save('grid.pdf');
+        }
+    }
+
+    printTable (doc, start, end, details) {
+        if (!doc) {
+            doc = jsPDF('p', 'mm', 'letter');
+        }
+        ///////////////////// Table ///////////
+        doc.setLineWidth(.25);
+        doc.setDrawColor(170);
+
+        // Number Column (header and rows)
+        doc.setFillColor(225);
+        doc.rect(this.gridX[0], this.gridY[start], 10, 10, 'FD');
+        doc.text('#', this.gridX[0] + 5, this.gridY[start + 1] - 3.5, {'align': 'center'});
+        for (let i = start + 1; i <= end; i++) {
+            doc.rect(this.gridX[0], this.gridY[i], 10, 10);
+        }
+
+        // Description Column (header and rows)
+        doc.setFillColor(225);
+        doc.rect(this.gridX[1], this.gridY[start], 70, 10, 'FD');
+        doc.text('Description', this.gridX[4] + 5, this.gridY[start + 1] - 3.5, {'align': 'center'});
+        for (let i = start + 1; i <= end; i++) {
+            doc.rect(this.gridX[1], this.gridY[i], 70, 10);
+        }
+
+        // Fee Column (header and rows)
+        doc.setFillColor(225);
+        doc.rect(this.gridX[8], this.gridY[start], 30, 10, 'FD');
+        doc.text('Fee', this.gridX[9] + 5, this.gridY[start + 1] - 3.5, {'align': 'center'});
+        for (let i = start + 1; i <= end; i++) {
+            doc.rect(this.gridX[8], this.gridY[i], 30, 10);
+        }
+
+        // Quantity Column (header and rows)
+        doc.setFillColor(225);
+        doc.rect(this.gridX[11], this.gridY[start], 20, 10, 'FD');
+        doc.text('Qty.', this.gridX[12], this.gridY[start + 1] - 3.5, {'align': 'center'});
+        for (let i = start + 1; i <= end; i++) {
+            doc.rect(this.gridX[11], this.gridY[i], 20, 10);
+        }
+
+        // Amount Column (header and rows)
+        doc.setFillColor(225);
+        doc.rect(this.gridX[13], this.gridY[start], 30, 10, 'FD');
+        doc.text('Amount', this.gridX[14] + 5, this.gridY[start + 1] - 3.5, {'align': 'center'});
+        for (let i = start + 1; i <= end; i++) {
+            doc.rect(this.gridX[13], this.gridY[i], 30, 10);
+        }
+
+        // Filling Data
+        doc.setFontSize(12);
+        details.forEach((inDet, i) => {
+            doc.text(inDet.lineItemNum.toString(), this.gridX[0] + 5, this.gridY[start + 2 + i] - 3.5, {'align': 'center'});
+
+            doc.setFontSize(11);
+            const descSplit = doc.splitTextToSize(inDet.desc, 66);
+            descSplit.forEach((text, j) => {
+                doc.text(text, this.gridX[1] + 2, this.gridY[start + 1 + i] + (4 * (j + 1)));
+            });
+
+            doc.setFontSize(12);
+            const fee = formatCurrency(inDet.fee, 'en-US', '$', 'USD').split('.')[0] + ((inDet.feeTypeId === 2) ? '/hr' : '');
+            doc.text(fee, this.gridX[11] - 3.5, this.gridY[start + 2 + i] - 3.5, {'align': 'right'});
+
+            doc.text(inDet.qty.toString(), this.gridX[13] - 3.5, this.gridY[start + 2 + i] - 3.5, {'align': 'right'});
+
+            const amt = formatCurrency(inDet.fee * inDet.qty, 'en-US', '$', 'USD');
+            doc.text(amt, this.gridX[16] - 3.5, this.gridY[start + 2 + i] - 3.5, {'align': 'right'});
+        });
+        ///////////////////////////////////////
+        if (!doc) {
+            doc.autoPrint({variant: 'non-conform'});
+            doc.save('table.pdf');
+        }
+    }
+
+    printFooter (doc) {
+        if (!doc) {
+            doc = jsPDF('p', 'mm', 'letter');
+        }
+        ///////////////////// Footer //////////
+        doc.setFontSize(12);
+
+        // Invoice Bill Info Section
+        doc.setLineWidth(.25);
+        doc.setDrawColor(170);
+        doc.rect(this.gridX[0], this.gridY[15], 160, 50);
+        doc.text('Original Contract Amt.', this.gridX[5] - 3.5, this.gridY[16] - 3.5, {align: 'right'});
+        doc.text('Net Changes by CO\'s', this.gridX[5] - 3.5, this.gridY[17] - 3.5, {align: 'right'});
+        doc.text('Total Contract Amt.', this.gridX[5] - 3.5, this.gridY[18] - 3.5, {align: 'right'});
+        doc.text('Previously Billed', this.gridX[5] - 3.5, this.gridY[19] - 3.5, {align: 'right'});
+        doc.text('Balance to be Billed', this.gridX[5] - 3.5, this.gridY[20] - 3.5, {align: 'right'});
+        for (let i = 15; i <= 19; i++) {
+            doc.setFillColor(225);
+            doc.rect(this.gridX[5], this.gridY[i], 30, 10, 'FD');
+        }
+        doc.setFont('helvetica', 'bold');
+        doc.text('Total Due this Invoice', this.gridX[13] - 3.5, this.gridY[16] - 3.5, {align: 'right'});
+        doc.setFont('helvetica', 'normal');
+        doc.setFillColor(225);
+        doc.rect(this.gridX[13], this.gridY[15], 30, 10, 'FD');
+
+        // Fill Data
+        const ogCoAmt = formatCurrency(this.ogCoAmt, 'en-US', '$', 'USD');
+        doc.text(ogCoAmt, this.gridX[8] - 3.5, this.gridY[16] - 3.5, {align: 'right'});
+
+        const netChanges = formatCurrency(this.netChanges, 'en-US', '$', 'USD');
+        doc.text(netChanges, this.gridX[8] - 3.5, this.gridY[17] - 3.5, {align: 'right'});
+
+        const totCoAmt = formatCurrency(this.totCoAmt, 'en-US', '$', 'USD');
+        doc.text(totCoAmt, this.gridX[8] - 3.5, this.gridY[18] - 3.5, {align: 'right'});
+
+        const prevBill = formatCurrency(this.prevBill, 'en-US', '$', 'USD');
+        doc.text(prevBill, this.gridX[8] - 3.5, this.gridY[19] - 3.5, {align: 'right'});
+
+        const toBeBilled = formatCurrency(this.totCoAmt - this.prevBill - this.finTot, 'en-US', '$', 'USD');
+        doc.text(toBeBilled, this.gridX[8] - 3.5, this.gridY[20] - 3.5, {align: 'right'});
+
+        const finTot = formatCurrency(this.finTot, 'en-US', '$', 'USD');
+        doc.setFont('helvetica', 'bold');
+        doc.text(finTot, this.gridX[16] - 3.5, this.gridY[16] - 3.5, {align: 'right'});
+        doc.setFont('helvetica', 'normal');
+
+        // Notes and Certification
+        doc.text('Notes:', this.gridX[0], this.gridY[20] + 5);
+        const noteSplit = doc.splitTextToSize(this.notes, 145);
+        noteSplit.forEach((text, i) => {
+            doc.text(text, this.gridX[1] + 5, this.gridY[20] + (5 * (i + 1)));
+        });
+        const certSplit = doc.splitTextToSize(this.cert, 160);
+        certSplit.forEach((text, i) => {
+            doc.text(text, this.gridX[0], this.gridY[22] + (5 * i));
+        });
+        doc.line(this.gridX[11], this.gridY[23], this.gridX[16], this.gridY[23]);
+        ///////////////////////////////////////
+        if (!doc) {
+            doc.autoPrint({variant: 'non-conform'});
+            doc.save('footer.pdf');
+        }
+    }
+
+    printGrid (doc) {
+        if (!doc) {
+            doc = jsPDF('p', 'mm', 'letter');
+        } else {
+            doc.setDrawColor(225);
+        }
+        this.gridX.forEach((x) => {
+            doc.line(x, this.gridY[0], x, this.gridY[this.gridY.length - 1]);
+            // doc.text(x.toString(), x, this.gridY[0]);
+        });
+        this.gridY.forEach((y) => {
+            doc.line(this.gridX[0], y, this.gridX[this.gridX.length - 1], y);
+            // doc.text(y.toString(), this.gridX[0], y);
+        });
+        doc.setDrawColor(0);
+        if (!doc) {
+            doc.autoPrint({variant: 'non-conform'});
+            doc.save('grid.pdf');
+        }
+    }
+
     moreTestJsPDF() {
-        const doc = new jsPDF();
-        // const specialElementHandlers = {
-        //     '#editor': function (element, renderer) {
-        //         return true;
-        //     }
-        // };
-        // doc.fromHTML(this.invoiceHTML.nativeElement, 15, 15, {
-        //     'width': 170,
-        //     'elementHandlers': specialElementHandlers
-        // });
-        console.log (this.invoiceHTML);
-        doc.addHTML(this.invoiceHTML.nativeElement);
-        doc.save('sample-file.pdf');
+        const doc = jsPDF('p', 'mm', 'letter');
+        const specialElementHandlers = {
+            '#editor': function (element, renderer) {
+                return true;
+            }
+        };
+
+        // let content = invoiceHTML.nativeElement;
+        doc.fromHTML(this.invoiceHTML.nativeElement.innerHTML, 15, 15, {
+            'width': 1900,
+            'elementHandlers': specialElementHandlers
+        }, () => {
+            doc.save('sample-file.pdf');
+        });
+        // console.log (this.invoiceHTML);
+        // doc.addHTML(this.invoiceHTML.nativeElement);
+
+    }
+
+    jQueryTest() {
+        $('doc').printElement();
     }
 
     // html2pdf((<HTMLInputElement>document.getElementById('doc')));