import { Component, Input, OnChanges } from '@angular/core'; import { CurrencyService } from '@core/services/currency.service'; import { PaymentStatusStat } from '@core/typings/program.typing'; import { PaymentStatus } from '@core/typings/status.typing'; import { ClientSettingsService } from '@features/client-settings/client-settings.service'; import { ProgramService } from '@features/programs/program.service'; import { AutoTableRepository, AutoTableRepositoryFactory, ChartService, DashboardTableData, ValueComparisonService } from '@yourcause/common'; import { I18nService } from '@yourcause/common/i18n'; import { NotifierService } from '@yourcause/common/notifier'; import { ChartData, ChartOptions, ChartType, TooltipItem } from 'chart.js'; @Component({ selector: 'gc-payment-status-block', templateUrl: './payment-status-block.component.html', styleUrls: ['./payment-status-block.component.scss'] }) export class PaymentStatusBlockComponent implements OnChanges { @Input() cycleIds: number[]; baseChart: ChartOptions = { responsive: true, plugins: { legend: { display: false } } }; branding = this.clientSettingsService.get('clientBranding'); colors = [ this.branding.brandPrimary, this.branding.brandSecondary, this.branding.brandUtility ]; defaultCurrency = this.clientSettingsService.defaultCurrency; numberOfPayments: number; stats: PaymentStatusStat[] = []; statusRepo: AutoTableRepository; statusLabels: string[] = []; statusData: number[] = []; statusColors: string[] = []; statusTableData: DashboardTableData[]; statusChartOptions = { ...this.baseChart, tooltips: { callbacks: { label: (tooltipItem: TooltipItem) => { const numberOfPayments = this.stats[tooltipItem.dataIndex].numberOfPayments; return this.i18n.translate( 'common:hdrPayments' ) + ': ' + numberOfPayments + ` (${this.chartService.getPercent(numberOfPayments, this.numberOfPayments)})`; }, beforeLabel: (tooltipItem: TooltipItem, data: ChartData) => { return this.chartService.getLabelForTooltip( tooltipItem, data ); }, afterLabel: (tooltipItem: TooltipItem) => { const totalAmount = this.stats[tooltipItem.dataIndex].paymentsTotal; return this.currencyService.formatMoney( totalAmount ); } } } } as ChartOptions; constructor ( private i18n: I18nService, private chartService: ChartService, private programService: ProgramService, private autoTableFactory: AutoTableRepositoryFactory, private notifierService: NotifierService, private valueComparisonService: ValueComparisonService, private clientSettingsService: ClientSettingsService, private currencyService: CurrencyService ) { } async ngOnChanges () { this.stats = await this.programService.getPaymentStatusStatsByCycle( this.cycleIds ); this.setupStatusStats(); } setupStatusStats () { if (!this.statusRepo) { this.statusRepo = this.autoTableFactory.create({ key: 'PROGRAM_STATUS_STATS', columns: [], notifier: this.notifierService, rowsPerPage: 1000, valueComparisonService: this.valueComparisonService, rows: this.stats }); } else { this.statusRepo.rows = this.stats; this.statusRepo.reset(); } this.statusLabels = this.stats.map((item) => { return item.statusName; }); this.statusData = this.stats.map((item) => { return item.numberOfPayments; }); this.statusColors = this.chartService.getFixedAmountOfColors( this.stats.length, this.colors ); this.numberOfPayments = this.stats.reduce((acc, item) => { if (item.statusId !== PaymentStatus.Voided) { return acc + (item.numberOfPayments || 0); } return acc; }, 0); this.statusTableData = [{ columnName: this.i18n.translate( 'common:hdrStatus' ), isNumber: false, isMoney: false, getRouterLink: null, isLegendRef: true, key: 'statusName' }, { columnName: this.i18n.translate( 'GLOBAL:hdrActivePayments' ), isNumber: true, isMoney: false, getRouterLink: null, isLegendRef: false, key: 'numberOfPayments', total: this.numberOfPayments }, { columnName: this.i18n.translate( 'GLOBAL:textTotal' ), isNumber: false, isMoney: false, isMixedVal: true, getRouterLink: null, isLegendRef: false, key: 'paymentsTotal', getRowValue: (row) => { return this.currencyService.formatMoney( row.paymentsTotal ); }, total: this.currencyService.formatMoney( (this.stats.reduce((acc, item) => { if (item.statusId !== PaymentStatus.Voided) { return acc + item.paymentsTotal; } return acc; }, 0)) ) }]; } }