From 27f9a5f3f3a472cbb1ac81e77384b8b463fefb43 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 31 Dec 2019 00:58:06 -0700 Subject: [PATCH] Update giving reports --- Client/package-lock.json | 40 ++++++++- Client/package.json | 2 + .../contributor-all-reports.component.ts | 8 +- .../contributor-yearly-report.component.css | 18 +++- .../contributor-yearly-report.component.html | 35 ++++---- .../contributor-yearly-report.component.ts | 88 +++++++++++++++++-- 6 files changed, 160 insertions(+), 31 deletions(-) diff --git a/Client/package-lock.json b/Client/package-lock.json index bf148a0..a77a625 100644 --- a/Client/package-lock.json +++ b/Client/package-lock.json @@ -2236,6 +2236,37 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "chart.js": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.3.tgz", + "integrity": "sha512-+2jlOobSk52c1VU6fzkh3UwqHMdSlgH1xFv9FKMqHiNCpXsGPQa/+81AFa+i3jZ253Mq9aAycPwDjnn1XbRNNw==", + "requires": { + "chartjs-color": "^2.1.0", + "moment": "^2.10.2" + } + }, + "chartjs-color": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz", + "integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==", + "requires": { + "chartjs-color-string": "^0.6.0", + "color-convert": "^1.9.3" + } + }, + "chartjs-color-string": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz", + "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==", + "requires": { + "color-name": "^1.0.0" + } + }, + "chartjs-plugin-datalabels": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chartjs-plugin-datalabels/-/chartjs-plugin-datalabels-0.7.0.tgz", + "integrity": "sha512-PKVUX14nYhH0wcdCpgOoC39Gbzvn6cZ7O9n+bwc02yKD9FTnJ7/TSrBcfebmolFZp1Rcicr9xbT0a5HUbigS7g==" + }, "chokidar": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", @@ -2432,7 +2463,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -2440,8 +2470,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "colors": { "version": "1.1.2", @@ -6392,6 +6421,11 @@ "minimist": "0.0.8" } }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", diff --git a/Client/package.json b/Client/package.json index 62674f3..e6266d5 100644 --- a/Client/package.json +++ b/Client/package.json @@ -21,6 +21,8 @@ "@angular/platform-browser": "~7.2.0", "@angular/platform-browser-dynamic": "~7.2.0", "@angular/router": "~7.2.0", + "chart.js": "^2.9.3", + "chartjs-plugin-datalabels": "^0.7.0", "core-js": "^2.5.4", "hammerjs": "^2.0.8", "rxjs": "~6.3.3", diff --git a/Client/src/app/components/contributor-all-reports/contributor-all-reports.component.ts b/Client/src/app/components/contributor-all-reports/contributor-all-reports.component.ts index 26e973a..3a1b16d 100644 --- a/Client/src/app/components/contributor-all-reports/contributor-all-reports.component.ts +++ b/Client/src/app/components/contributor-all-reports/contributor-all-reports.component.ts @@ -16,17 +16,18 @@ export class ContributorAllReportsComponent implements OnInit { constructor(private printService: PrintService, private userService: UserService, private transactionService: TransactionService) { } ngOnInit() { - const query = forkJoin([this.userService.getAll(), this.transactionService.getByYear(2019)]); + const query = forkJoin([this.userService.getAll(), this.transactionService.getByYear(2019), this.transactionService.getByYear(2018)]); - query.subscribe(res => this.setup(res[0], res[1])); + query.subscribe(res => this.setup(res[0], res[1], res[2])); this.printService.setPrinting(true); } - private setup(contributorResult, transactionResult) { + private setup(contributorResult, transactionResult, priorYearTransactionResult) { const contributors = contributorResult.users; const transactions = transactionResult.transactions; + const priorYearTransactions = priorYearTransactionResult.transactions; const contrib = {}; transactions.forEach(t => { if (contrib.hasOwnProperty(t.contributorId)) { @@ -35,6 +36,7 @@ export class ContributorAllReportsComponent implements OnInit { const con = contributors.find(c => c.id === t.contributorId); if (con) { contrib[con.id] = {contributor: con, transactions: [t]}; + contrib[con.id].priorYearTransactions = priorYearTransactions.filter(t => t.contributorId === con.id); this.contributors.push(contrib[con.id]); } else { console.error('coould not find contributor for', t); diff --git a/Client/src/app/components/contributor-yearly-report/contributor-yearly-report.component.css b/Client/src/app/components/contributor-yearly-report/contributor-yearly-report.component.css index 3474234..4be74c1 100644 --- a/Client/src/app/components/contributor-yearly-report/contributor-yearly-report.component.css +++ b/Client/src/app/components/contributor-yearly-report/contributor-yearly-report.component.css @@ -29,12 +29,28 @@ display: flex; } + .flex-direction-column { + flex-direction: column; + } + .flex-align-center { align-items: center; } + .flex-justify-space-between { + justify-content: space-between; + } + + .flex-align-space-between { + align-content: space-between; + } + .flex-align-top { - align-items: baseline; + align-items: start; + } + + .flex-align-stretch { + align-items: stretch; } .flex-justify-center { diff --git a/Client/src/app/components/contributor-yearly-report/contributor-yearly-report.component.html b/Client/src/app/components/contributor-yearly-report/contributor-yearly-report.component.html index 9f42d85..d3aee19 100644 --- a/Client/src/app/components/contributor-yearly-report/contributor-yearly-report.component.html +++ b/Client/src/app/components/contributor-yearly-report/contributor-yearly-report.component.html @@ -3,13 +3,13 @@

- Old Fashion Baptist Church Contribution Report {{taxYear}} {{index}} + Old Fashion Baptist Church Contribution Report {{taxYear}}

{{contributorName}}

-

{{contributorStreet}}

-

{{contributorCity}} {{contributorState}}, {{contributorZip}}

+

{{contributorStreet}}

+

{{contributorCity}} {{contributorState}}, {{contributorZip}}

@@ -28,14 +28,13 @@

Old Fashion Baptist Church Giving Statement {{taxYear}}


-
-
-

Name: {{contributorName}}

-

Tax Year: {{taxYear}}

-

Registration Code: {{registrationCode}}

-
-
- +
+
+
+

Name: {{contributorName}}

+

Tax Year: {{taxYear}}

+
+
@@ -57,16 +56,18 @@
{{taxYear}} Giving Summary
+
+ +
-
+
Thank you for your contribution. The information provided in this statement reflects - your contributions on record for tax year {{taxYear}}. The chart below provides current and - historical data (if available) for informational purposes only. The data on the following - pages includes a detail listing of contributions for {{taxYear}}. + your contributions on record for tax year {{taxYear}}. + No goods or services were provided in exchange for your contribution.
- +
@@ -79,7 +80,7 @@ - + diff --git a/Client/src/app/components/contributor-yearly-report/contributor-yearly-report.component.ts b/Client/src/app/components/contributor-yearly-report/contributor-yearly-report.component.ts index 06d3013..08bd118 100644 --- a/Client/src/app/components/contributor-yearly-report/contributor-yearly-report.component.ts +++ b/Client/src/app/components/contributor-yearly-report/contributor-yearly-report.component.ts @@ -1,6 +1,8 @@ -import { Component, OnInit, Input } from '@angular/core'; +import { Component, OnInit, Input, ViewChild, ElementRef } from '@angular/core'; import { PrintService } from '../../services/print-service'; import { Transaction } from '../add-transaction-page/transaction'; +import Chart from 'chart.js'; +import ChartDataLabels from 'chartjs-plugin-datalabels'; @Component({ selector: 'app-contributor-yearly-report', @@ -9,20 +11,34 @@ import { Transaction } from '../add-transaction-page/transaction'; }) export class ContributorYearlyReportComponent implements OnInit { + @ViewChild('chart') chartElement:ElementRef; @Input() index: number; - @Input() contributorTransactions: {contributor: {}, transactions: {}}; + @Input() contributorTransactions: {contributor: {}, transactions: {}, priorYearTransactions: {}}; public transactions: Transaction[] = []; - public contributorName: string = 'Bob and Jill Handerson'; + public priorTransactions: Transaction[] = []; + public get contributorName(): string { + const first = (this.contributorTransactions.contributor).firstName; + const last = (this.contributorTransactions.contributor).lastName; + if (last && first) { + return last + ', ' + first; + } else if (last) { + return last; + } else if (first) { + return first; + } else { + return ''; + } + } public contributorStreet: string = '7878 Washington St'; public contributorCity: string = 'Butte'; public contributorState: string = 'MT'; public contributorZip: string = '59701'; public taxYear: number = 2019; - public registrationCode: string = 'HDIJDHDFD*#*@'; + public rowsFirstPage: number = 13; public rowsPerPage: number = 32; public get pages(): number { - return Math.ceil(this.transactions.length / this.rowsPerPage) + 2; + return Math.ceil((this.transactions.length - this.rowsFirstPage) / this.rowsPerPage) + 2; } public get pagesOdd(): boolean { return !(this.pages % 2 == 0) @@ -32,12 +48,12 @@ export class ContributorYearlyReportComponent implements OnInit { ngOnInit() { this.contributorCity = (this.contributorTransactions.contributor).city; - this.contributorName = (this.contributorTransactions.contributor).display; this.contributorState = (this.contributorTransactions.contributor).state; this.contributorStreet = (this.contributorTransactions.contributor).street; this.contributorZip = (this.contributorTransactions.contributor).zip; this.transactions = this.contributorTransactions.transactions; - + this.priorTransactions = this.contributorTransactions.priorYearTransactions; + this.renderChart(); } public totalGeneral() { @@ -46,10 +62,68 @@ export class ContributorYearlyReportComponent implements OnInit { return sum; } + public priorGeneral() { + let sum = 0; + this.priorTransactions.filter(t => t.fundId === 1).forEach(t => sum += t.amount); + return sum; + } + public totalMissions() { let sum = 0; this.transactions.filter(t => t.fundId === 2).forEach(t => sum += t.amount); return sum; } + public priorMissions() { + let sum = 0; + this.priorTransactions.filter(t => t.fundId === 2).forEach(t => sum += t.amount); + return sum; + } + + private renderChart() { + var myChart = new Chart(this.chartElement.nativeElement, { + plugins: [ChartDataLabels], + type: 'bar', + data: { + labels: ['2018', '2019'], + datasets: [{ + label: 'General', + data: [this.priorGeneral(), this.totalGeneral()], + backgroundColor: 'rgba(54, 245, 162, 0.2)', + borderColor: 'rgba(54, 245, 162, 1)', + borderWidth: 1 + }, { + label: 'Missions', + data: [this.priorMissions(), this.totalMissions()], + backgroundColor: 'rgba(54, 162, 235, 0.2)', + borderColor: 'rgba(54, 162, 235, 1)', + borderWidth: 1 + }] + }, + options:{ + scales: { + xAxes: [{ + stacked: true + }], + yAxes: [{ + stacked: true + }] + }, + plugins:{ + datalabels:{ + font:{ + weight: 'bold' + }, + formatter: function(value, context){ + if (value === 0) { + return ''; + } + return '$' + value.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'); + } + } + } + } + }); + } + }
Date
{{t.date | date:'shortDate'}}{{t.date | date:'MM-dd-yyyy'}} {{t.type === 0 ? 'Cash' : 'Check'}} {{t.checkNumber}} {{t.fund === 0 ? 'General' : 'Missions'}}