refactor: reports module (#1227)

Fixes: #1196
This commit is contained in:
Karan Takalkar
2020-08-26 01:53:10 +05:30
committed by GitHub
parent efdd779aa9
commit 0f83739080
19 changed files with 206 additions and 200 deletions
@@ -30,7 +30,7 @@ export class LoansTransactionRecieptResolver implements Resolve<Object> {
'output-type': 'PDF', 'output-type': 'PDF',
R_transactionId: transactionId R_transactionId: transactionId
}; };
return this.reportsService.getPentahoRunReportData({name: 'Loan Transaction Receipt'}, data, 'default', 'en', 'dd MMMM yyyy'); return this.reportsService.getPentahoRunReportData('Loan Transaction Receipt', data, 'default', 'en', 'dd MMMM yyyy');
} }
} }
@@ -74,7 +74,7 @@ export class ExportTransactionsComponent implements OnInit {
R_endDate: this.datePipe.transform(this.transactionsReportForm.value.toDate, 'yyyy-MM-dd'), R_endDate: this.datePipe.transform(this.transactionsReportForm.value.toDate, 'yyyy-MM-dd'),
R_selectLoan: this.loansAccountId R_selectLoan: this.loansAccountId
}; };
this.reportsService.getPentahoRunReportData({ name: 'Client Loan Account Schedule'}, data, 'default', 'en', 'dd MMMM yyyy') this.reportsService.getPentahoRunReportData('Client Loan Account Schedule', data, 'default', 'en', 'dd MMMM yyyy')
.subscribe( (res: any) => { .subscribe( (res: any) => {
const contentType = res.headers.get('Content-Type'); const contentType = res.headers.get('Content-Type');
const file = new Blob([res.body], {type: contentType}); const file = new Blob([res.body], {type: contentType});
@@ -83,32 +83,34 @@ export class EditBusinessRuleParametersComponent implements OnChanges {
} else { // Child Parameter } else { // Child Parameter
const parent: ReportParameter = this.paramData const parent: ReportParameter = this.paramData
.find((entry: any) => entry.name === param.parentParameterName); .find((entry: any) => entry.name === param.parentParameterName);
// TODO: Refactor once Report Parameter Model is updated for multi-child support. parent.childParameters.push(param);
if (parent.childParameter instanceof Array) { this.updateParentParameters(parent);
parent.childParameter.push(param);
} else {
parent.childParameter = [];
parent.childParameter.push(param);
}
const parentNames = this.parentParameters.map(parameter => parameter.name);
if (!parentNames.includes(parent.name)) {
this.parentParameters.push(parent);
} else {
const index = parentNames.indexOf(parent.name);
this.parentParameters[index] = parent;
}
} }
}); });
this.setChildControls(); this.setChildControls();
} }
/**
* Updates the array of parent parameters.
* @param {ReportParameter} parent Parent report parameter
*/
updateParentParameters(parent: ReportParameter) {
const parentNames = this.parentParameters.map(parameter => parameter.name);
if (!parentNames.includes(parent.name)) { // Parent's first child.
this.parentParameters.push(parent);
} else { // Parent already has a child
const index = parentNames.indexOf(parent.name);
this.parentParameters[index] = parent;
}
}
/** /**
* Subscribes to changes in parent parameters value, builds child parameter vis-a-vis parent's value. * Subscribes to changes in parent parameters value, builds child parameter vis-a-vis parent's value.
*/ */
setChildControls() { setChildControls() {
this.parentParameters.forEach((param: ReportParameter) => { this.parentParameters.forEach((param: ReportParameter) => {
this.ReportForm.get(param.name).valueChanges.subscribe((option: any) => { this.ReportForm.get(param.name).valueChanges.subscribe((option: any) => {
param.childParameter.forEach((child: ReportParameter) => { param.childParameters.forEach((child: ReportParameter) => {
if (child.displayType === 'none') { if (child.displayType === 'none') {
this.ReportForm.addControl(child.name, new FormControl(child.defaultVal)); this.ReportForm.addControl(child.name, new FormControl(child.defaultVal));
} else { } else {
@@ -183,10 +185,10 @@ export class EditBusinessRuleParametersComponent implements OnChanges {
* TODO: Replace report object with report name once reports service is refactored. * TODO: Replace report object with report name once reports service is refactored.
*/ */
getResponseHeaders() { getResponseHeaders() {
const report = { name: this.paramValue.reportName }; const reportName = this.paramValue.reportName;
delete this.paramValue.reportName; delete this.paramValue.reportName;
const formattedResponse = this.formatUserResponse(this.paramValue, true); const formattedResponse = this.formatUserResponse(this.paramValue, true);
this.reportsService.getRunReportData(report, formattedResponse).subscribe( this.reportsService.getRunReportData(reportName, formattedResponse).subscribe(
(response: any) => { (response: any) => {
this.templateParameters.emit(response.columnHeaders); this.templateParameters.emit(response.columnHeaders);
}, },
@@ -69,7 +69,7 @@ export class BusinessRuleParametersComponent implements OnChanges {
createRunReportForm() { createRunReportForm() {
this.paramData.forEach( this.paramData.forEach(
(param: any) => { (param: any) => {
if (!param.parentParameterName) { // Non Child Parameter if (!param.parentParameterName) { // Non-Child Parameter
this.ReportForm.addControl(param.name, new FormControl('', Validators.required)); this.ReportForm.addControl(param.name, new FormControl('', Validators.required));
if (param.displayType === 'select') { if (param.displayType === 'select') {
this.fetchSelectOptions(param, param.name); this.fetchSelectOptions(param, param.name);
@@ -77,32 +77,34 @@ export class BusinessRuleParametersComponent implements OnChanges {
} else { // Child Parameter } else { // Child Parameter
const parent: ReportParameter = this.paramData const parent: ReportParameter = this.paramData
.find((entry: any) => entry.name === param.parentParameterName); .find((entry: any) => entry.name === param.parentParameterName);
// TODO: Refactor once Report Parameter Model is updated for multi-child support. parent.childParameters.push(param);
if (parent.childParameter instanceof Array) { this.updateParentParameters(parent);
parent.childParameter.push(param);
} else {
parent.childParameter = [];
parent.childParameter.push(param);
}
const parentNames = this.parentParameters.map(parameter => parameter.name);
if (!parentNames.includes(parent.name)) {
this.parentParameters.push(parent);
} else {
const index = parentNames.indexOf(parent.name);
this.parentParameters[index] = parent;
}
} }
}); });
this.setChildControls(); this.setChildControls();
} }
/**
* Updates the array of parent parameters.
* @param {ReportParameter} parent Parent report parameter
*/
updateParentParameters(parent: ReportParameter) {
const parentNames = this.parentParameters.map(parameter => parameter.name);
if (!parentNames.includes(parent.name)) { // Parent's first child.
this.parentParameters.push(parent);
} else { // Parent already has a child
const index = parentNames.indexOf(parent.name);
this.parentParameters[index] = parent;
}
}
/** /**
* Subscribes to changes in parent parameters value, builds child parameter vis-a-vis parent's value. * Subscribes to changes in parent parameters value, builds child parameter vis-a-vis parent's value.
*/ */
setChildControls() { setChildControls() {
this.parentParameters.forEach((param: ReportParameter) => { this.parentParameters.forEach((param: ReportParameter) => {
this.ReportForm.get(param.name).valueChanges.subscribe((option: any) => { this.ReportForm.get(param.name).valueChanges.subscribe((option: any) => {
param.childParameter.forEach((child: ReportParameter) => { param.childParameters.forEach((child: ReportParameter) => {
if (child.displayType === 'none') { if (child.displayType === 'none') {
this.ReportForm.addControl(child.name, new FormControl(child.defaultVal)); this.ReportForm.addControl(child.name, new FormControl(child.defaultVal));
} else { } else {
@@ -168,7 +170,7 @@ export class BusinessRuleParametersComponent implements OnChanges {
*/ */
getResponseHeaders() { getResponseHeaders() {
const formattedresponse = this.formatUserResponse(this.ReportForm.value, true); const formattedresponse = this.formatUserResponse(this.ReportForm.value, true);
this.reportsService.getRunReportData({ name: this.reportName }, formattedresponse).subscribe( this.reportsService.getRunReportData(this.reportName, formattedresponse).subscribe(
(response: any) => { (response: any) => {
this.templateParameters.emit(response.columnHeaders); this.templateParameters.emit(response.columnHeaders);
}, },
+5 -4
View File
@@ -12,11 +12,12 @@ export class UrlToStringPipe implements PipeTransform {
transform(url: string): any { transform(url: string): any {
url = decodeURIComponent(url); url = decodeURIComponent(url);
if (url.includes('search?query')) {
const query = url.substring(url.indexOf('=') + 1, url.indexOf('&'));
return 'Search ' + query;
}
const urlSubstrings: string[] = url.slice(1).split('/'); const urlSubstrings: string[] = url.slice(1).split('/');
if (url.includes('?')) { // Query params URL.
const query = urlSubstrings.pop();
const prefix = query.slice(0, query.indexOf('?'));
urlSubstrings.push(prefix);
}
const stringRepresentation = const stringRepresentation =
urlSubstrings urlSubstrings
.map((path: string) => { .map((path: string) => {
@@ -12,7 +12,7 @@ export class ReportParameter {
parentParameterName: string; parentParameterName: string;
inputName: string; inputName: string;
selectOptions: any[] = []; selectOptions: any[] = [];
childParameter: any; childParameters: any[] = [];
pentahoName: any; pentahoName: any;
constructor(options: any[]) { constructor(options: any[]) {
@@ -20,11 +20,11 @@ export class RunReportResolver implements Resolve<Object> {
constructor(private reportsService: ReportsService) {} constructor(private reportsService: ReportsService) {}
/** /**
* Returns the reports data. * Returns the report parameters data.
* @returns {Observable<any>} * @returns {Observable<any>}
*/ */
resolve(route: ActivatedRouteSnapshot): Observable<any> { resolve(route: ActivatedRouteSnapshot): Observable<any> {
return this.reportsService.getReportParams(route.params['report-name']); return this.reportsService.getReportParams(route.params['name']);
} }
} }
+8 -23
View File
@@ -33,35 +33,20 @@ const routes: Routes = [
children: [ children: [
{ {
path: '', path: '',
component: ReportsComponent, component: ReportsComponent
}, },
{ {
path: ':filter', path: ':filter',
data: { routeParamBreadcrumb: 'filter' }, data: { routeParamBreadcrumb: 'filter' },
component: ReportsComponent, component: ReportsComponent
}
]
},
{
path: 'run-report',
data: { title: extract('Reports'), breadcrumb: 'Reports' },
children: [
{
path: '',
redirectTo: '/reports', pathMatch: 'full'
}, },
{ {
path: ':report-name/:report-type/:report-id', path: 'run/:name',
data: { title: extract('Run Report'), routeParamBreadcrumb: 'report-name' }, data: { title: extract('Reports'), routeParamBreadcrumb: 'name' },
children: [ component: RunReportComponent,
{ resolve: {
path: '', reportParameters: RunReportResolver
component: RunReportComponent, }
resolve: {
params: RunReportResolver
}
}
]
} }
] ]
}, },
+1 -1
View File
@@ -28,7 +28,7 @@
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;" class="select-row" [routerLink]="['/run-report', row.reportName, row.reportType, row.id]"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;" class="select-row" [routerLink]="['/reports','run', row.reportName]" [queryParams]="{ type: row.reportType, id: row.id }"></tr>
</table> </table>
+10 -10
View File
@@ -57,7 +57,7 @@ export class ReportsService {
* @param {any} dates start date and end date * @param {any} dates start date and end date
* @returns {Observable<any>} Mix Report * @returns {Observable<any>} Mix Report
*/ */
getMixReport(dates: any) { getMixReport(dates: any): Observable<any> {
const httpParams = new HttpParams() const httpParams = new HttpParams()
.set('startDate', dates.startDate) .set('startDate', dates.startDate)
.set('endDate', dates.endDate); .set('endDate', dates.endDate);
@@ -98,40 +98,40 @@ export class ReportsService {
/** /**
* Run Report Data for Table and SMS. * Run Report Data for Table and SMS.
* @param {any} report report object containing 'id', 'name' & 'type' attributes. * @param {any} reportName report name
* @param {object} formData Form Data. * @param {object} formData Form Data.
* @returns {Observable<any>} * @returns {Observable<any>}
*/ */
getRunReportData(report: any, formData: object): Observable<any> { getRunReportData(reportName: string, formData: object): Observable<any> {
let httpParams = new HttpParams(); let httpParams = new HttpParams();
for (const [key, value] of Object.entries(formData)) { for (const [key, value] of Object.entries(formData)) {
httpParams = httpParams.set(key, value); httpParams = httpParams.set(key, value);
} }
return this.http.get(`/runreports/${report.name}`, {params: httpParams}); return this.http.get(`/runreports/${reportName}`, {params: httpParams});
} }
/** /**
* Run Report Data for Charts. * Run Report Data for Charts.
* @param {any} report report object containing 'id', 'name' & 'type' attributes. * @param {any} reportName report name
* @param {object} formData Form Data. * @param {object} formData Form Data.
* @returns {Observable<ChartData>} * @returns {Observable<ChartData>}
*/ */
getChartRunReportData(report: any, formData: object): Observable<ChartData> { getChartRunReportData(reportName: string, formData: object): Observable<ChartData> {
let httpParams = new HttpParams(); let httpParams = new HttpParams();
for (const [key, value] of Object.entries(formData)) { for (const [key, value] of Object.entries(formData)) {
httpParams = httpParams.set(key, value); httpParams = httpParams.set(key, value);
} }
return this.http.get(`/runreports/${report.name}`, {params: httpParams}) return this.http.get(`/runreports/${reportName}`, {params: httpParams})
.pipe(map((response: any) => new ChartData(response))); .pipe(map((response: any) => new ChartData(response)));
} }
/** /**
* Run Report Data for Pentaho. * Run Report Data for Pentaho.
* @param {any} report report object containing 'id', 'name' & 'type' attributes. * @param {any} reportName report name
* @param {object} formData Form Data. * @param {object} formData Form Data.
* @returns {Observable<any>} * @returns {Observable<any>}
*/ */
getPentahoRunReportData(report: any, formData: object, tenantIdentifier: string, locale: string, dateFormat: string): Observable<any> { getPentahoRunReportData(reportName: string, formData: object, tenantIdentifier: string, locale: string, dateFormat: string): Observable<any> {
let httpParams = new HttpParams() let httpParams = new HttpParams()
.set('tenantIdentifier', tenantIdentifier) .set('tenantIdentifier', tenantIdentifier)
.set('locale', locale) .set('locale', locale)
@@ -139,7 +139,7 @@ export class ReportsService {
for (const [key, value] of Object.entries(formData)) { for (const [key, value] of Object.entries(formData)) {
httpParams = httpParams.set(key, value); httpParams = httpParams.set(key, value);
} }
return this.http.get(`/runreports/${report.name}`, {responseType: 'arraybuffer', observe: 'response', params: httpParams}); return this.http.get(`/runreports/${reportName}`, {responseType: 'arraybuffer', observe: 'response', params: httpParams});
} }
} }
@@ -43,7 +43,7 @@ export class ChartComponent implements OnChanges {
} }
getRunReportData() { getRunReportData() {
this.reportsService.getChartRunReportData(this.dataObject.reportData, this.dataObject.formData) this.reportsService.getChartRunReportData(this.dataObject.report.name, this.dataObject.formData)
.subscribe((response: ChartData) => { .subscribe((response: ChartData) => {
this.inputData = response; this.inputData = response;
this.setPieChart(this.inputData); this.setPieChart(this.inputData);
@@ -39,7 +39,7 @@ export class PentahoComponent implements OnChanges {
} }
getRunReportData() { getRunReportData() {
this.reportsService.getPentahoRunReportData(this.dataObject.reportData, this.dataObject.formData, 'default', 'en', 'dd MMMM yyyy') this.reportsService.getPentahoRunReportData(this.dataObject.report.name, this.dataObject.formData, 'default', 'en', 'dd MMMM yyyy')
.subscribe( (res: any) => { .subscribe( (res: any) => {
const contentType = res.headers.get('Content-Type'); const contentType = res.headers.get('Content-Type');
const file = new Blob([res.body], {type: contentType}); const file = new Blob([res.body], {type: contentType});
@@ -2,85 +2,76 @@
<mat-card *ngIf="!isCollapsed"> <mat-card *ngIf="!isCollapsed">
<form [formGroup]="ReportForm" (ngSubmit)="run()"> <form [formGroup]="reportForm" (ngSubmit)="run()">
<mat-card-content> <mat-card-content fxLayout="column">
<div fxLayout="column" *ngFor="let param of paramData">
<div [ngSwitch]="param.displayType"> <ng-container *ngFor="let param of paramData" [ngSwitch]="param.displayType">
<div *ngIf="ReportForm.contains(param.name)"> <ng-container *ngIf="reportForm.contains(param.name)">
<mat-form-field fxFlex="100%" *ngSwitchCase="'text'">
<mat-label>{{param.label}}</mat-label> <mat-form-field fxFlex *ngSwitchCase="'text'">
<input matInput required [formControlName]="param.name"> <mat-label>{{param.label}}</mat-label>
<mat-error *ngIf="ReportForm.controls[param.name].hasError('required')"> <input matInput required [formControlName]="param.name">
{{param.label}} is <strong>required</strong> <mat-error *ngIf="reportForm.controls[param.name].hasError('required')">
</mat-error> {{param.label}} is <strong>required</strong>
</mat-form-field> </mat-error>
</div> </mat-form-field>
<div *ngIf="ReportForm.contains(param.name)"> <mat-form-field fxFlex *ngSwitchCase="'date'">
<mat-form-field fxFlex="100%" *ngSwitchCase="'date'"> <mat-label>{{param.label}}</mat-label>
<mat-label>{{param.label}}</mat-label> <input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="runReportDatePicker" required
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="runReportDatePicker" required [formControlName]="param.name"> [formControlName]="param.name">
<mat-datepicker-toggle matSuffix [for]="runReportDatePicker"></mat-datepicker-toggle> <mat-datepicker-toggle matSuffix [for]="runReportDatePicker"></mat-datepicker-toggle>
<mat-datepicker #runReportDatePicker></mat-datepicker> <mat-datepicker #runReportDatePicker></mat-datepicker>
<mat-error *ngIf="ReportForm.controls[param.name].hasError('required')"> <mat-error *ngIf="reportForm.controls[param.name].hasError('required')">
{{param.label}} is <strong>required</strong> {{param.label}} is <strong>required</strong>
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
</div>
<mat-form-field fxFlex *ngSwitchCase="'select'">
<div *ngIf="ReportForm.contains(param.name) "> <mat-label>{{param.label}}</mat-label>
<mat-form-field fxFlex="100%" *ngSwitchCase="'select'" > <mat-select required [formControlName]="param.name">
<mat-label>{{param.label}}</mat-label> <mat-option *ngFor="let option of param.selectOptions" [value]="option">
<mat-select required [formControlName]="param.name">
<mat-option *ngFor="let option of param.selectOptions" [value]="option" >
{{option.name}} {{option.name}}
</mat-option> </mat-option>
</mat-select> </mat-select>
<mat-error *ngIf="ReportForm.controls[param.name].hasError('required')"> <mat-error *ngIf="reportForm.controls[param.name].hasError('required')">
{{param.label}} is <strong>required</strong> {{param.label}} is <strong>required</strong>
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
</div>
</ng-container>
</div>
</ng-container>
</div>
<mat-form-field fxFlex>
<div> <mat-label>Decimal Places</mat-label>
<mat-form-field fxFlex="100%"> <mat-select [formControl]="decimalChoice">
<mat-label>Decimal Places</mat-label> <mat-option value="0">0</mat-option>
<mat-select [formControl]="decimalChoice"> <mat-option value="1">1</mat-option>
<mat-option value="0">0</mat-option> <mat-option value="2">2</mat-option>
<mat-option value="1">1</mat-option> <mat-option value="3">3</mat-option>
<mat-option value="2">2</mat-option> <mat-option value="4">4</mat-option>
<mat-option value="3">3</mat-option> </mat-select>
<mat-option value="4">4</mat-option> </mat-form-field>
</mat-select>
</mat-form-field> <mat-form-field fxFlex *ngIf="report.type === 'Pentaho' && reportForm.contains('outputType')">
</div> <mat-label>Output Type</mat-label>
<mat-select formControlName="outputType" value="HTML">
<div *ngIf="report.type === 'Pentaho' && ReportForm.contains('outputType')"> <mat-option value="HTML">Normal format</mat-option>
<mat-form-field fxFlex="100%"> <mat-option value="XLS">Excel format</mat-option>
<mat-label>Output Type</mat-label> <mat-option value="XLSX">Excel 2007 format</mat-option>
<mat-select formControlName="outputType" value="HTML"> <mat-option value="CSV">CSV format</mat-option>
<mat-option value="HTML">Normal format</mat-option> <mat-option value="PDF">PDF format</mat-option>
<mat-option value="XLS">Excel format</mat-option> </mat-select>
<mat-option value="XLSX">Excel 2007 format</mat-option> </mat-form-field>
<mat-option value="CSV">CSV format</mat-option>
<mat-option value="PDF">PDF format</mat-option>
</mat-select>
</mat-form-field>
</div>
</mat-card-content> </mat-card-content>
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px"> <mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px">
<button type="button" mat-raised-button [routerLink]="['/reports']">Cancel</button> <button type="button" mat-raised-button [routerLink]="['/reports']">Cancel</button>
<button mat-raised-button color="primary" [disabled]="!ReportForm.valid" id="runReport"> <button mat-raised-button color="primary" [disabled]="!reportForm.valid" id="runReport">
<fa-icon icon="cogs"></fa-icon> <fa-icon icon="cogs"></fa-icon>
&nbsp; Run Report &nbsp; Run Report
</button> </button>
@@ -25,20 +25,23 @@ export class RunReportComponent implements OnInit {
minDate = new Date(2000, 0, 1); minDate = new Date(2000, 0, 1);
/** Maximum date allowed. */ /** Maximum date allowed. */
maxDate = new Date(); maxDate = new Date();
/** Contains report specifications i.e: name, type and id */ /** Contains report specifications i.e: name, type and id */
report: any = {}; report: any = {};
/** Formatted data post labeling of report parameters fetched from API */ /** Formatted data post labeling of report parameters fetched from API */
paramData: any = []; paramData: ReportParameter[] = [];
/** Array of all parent parameters */ /** Array of all parent parameters */
parentParameters: any[] = []; parentParameters: any[] = [];
/** Parameter data to configure pentaho output */ /** Parameter data to configure pentaho output */
pentahoReportParameters: any[] = []; pentahoReportParameters: any[] = [];
/** Data to be passed on to component selectors */ /** Data to be passed on to component selectors */
dataObject: any; dataObject: any;
/** Initializes new form group 'ReportForm */
ReportForm = new FormGroup({}); /** Initializes new form group eportForm */
reportForm = new FormGroup({});
/** Static Form control for decimal places in output */ /** Static Form control for decimal places in output */
decimalChoice = new FormControl(); decimalChoice = new FormControl();
/** Toggles Report form */ /** Toggles Report form */
isCollapsed = false; isCollapsed = false;
/** Toggles Table output. */ /** Toggles Table output. */
@@ -51,18 +54,19 @@ export class RunReportComponent implements OnInit {
/** /**
* Fetches report specifications from route params and retrieves report parameters data from `resolve`. * Fetches report specifications from route params and retrieves report parameters data from `resolve`.
* @param {ActivatedRoute} route ActivatedRoute. * @param {ActivatedRoute} route ActivatedRoute.
* @param {DomSanitizer} sanitizer DomSanitizer.
* @param {ReportsService} reportsService ReportsService * @param {ReportsService} reportsService ReportsService
* @param {DatePipe} datePipe Date Pipe * @param {DatePipe} datePipe Date Pipe
*/ */
constructor(private route: ActivatedRoute, constructor(private route: ActivatedRoute,
private reportsService: ReportsService, private reportsService: ReportsService,
private datePipe: DatePipe) { private datePipe: DatePipe) {
this.report.name = this.route.snapshot.params['report-name']; this.report.name = this.route.snapshot.params['name'];
this.report.type = this.route.snapshot.params['report-type']; this.route.queryParams.subscribe((queryParams: { type: any, id: any }) => {
this.report.id = this.route.snapshot.params['report-id']; this.report.type = queryParams.type;
this.route.data.subscribe((data: any) => { this.report.id = queryParams.id;
this.paramData = data.params; });
this.route.data.subscribe((data: { reportParameters: ReportParameter[] }) => {
this.paramData = data.reportParameters;
}); });
} }
@@ -79,39 +83,39 @@ export class RunReportComponent implements OnInit {
*/ */
createRunReportForm() { createRunReportForm() {
this.paramData.forEach( this.paramData.forEach(
(param: any) => { (param: ReportParameter) => {
if (!param.parentParameterName) { if (!param.parentParameterName) { // Non Child Parameter
this.ReportForm.addControl(param.name, new FormControl('', Validators.required)); this.reportForm.addControl(param.name, new FormControl('', Validators.required));
if (param.displayType === 'select') { if (param.displayType === 'select') {
this.fetchSelectOptions(param, param.name); this.fetchSelectOptions(param, param.name);
} }
} else { } else { // Child Parameter
const parent: ReportParameter = this.paramData const parent: ReportParameter = this.paramData
.find((entry: any) => entry.name === param.parentParameterName); .find((entry: any) => entry.name === param.parentParameterName);
parent.childParameter = param; parent.childParameters.push(param);
this.parentParameters.push(parent); this.updateParentParameters(parent);
} }
}); });
if (this.report.type === 'Pentaho') { if (this.report.type === 'Pentaho') {
this.ReportForm.addControl('outputType', new FormControl('')); this.reportForm.addControl('outputType', new FormControl(''));
this.mapPentahoParams(); this.mapPentahoParams();
} }
this.decimalChoice.patchValue('0'); this.decimalChoice.patchValue('0');
this.setChildControls(); this.setChildControls();
} }
/** /**
* Fetches Select Dropdown options for param type "Select". * Updates the array of parent parameters.
* @param {ReportParameter} param Parameter for which dropdown options are required. * @param {ReportParameter} parent Parent report parameter
* @param {string} inputstring url substring for API call. */
*/ updateParentParameters(parent: ReportParameter) {
fetchSelectOptions(param: ReportParameter, inputstring: string) { const parentNames = this.parentParameters.map(parameter => parameter.name);
this.reportsService.getSelectOptions(inputstring).subscribe((options: SelectOption[]) => { if (!parentNames.includes(parent.name)) { // Parent's first child.
param.selectOptions = options; this.parentParameters.push(parent);
if (param.selectAll === 'Y') { } else { // Parent already has a child
param.selectOptions.push({id: '-1', name: 'All'}); const index = parentNames.indexOf(parent.name);
} this.parentParameters[index] = parent;
}); }
} }
/** /**
@@ -132,16 +136,36 @@ export class RunReportComponent implements OnInit {
*/ */
setChildControls() { setChildControls() {
this.parentParameters.forEach((param: ReportParameter) => { this.parentParameters.forEach((param: ReportParameter) => {
this.ReportForm.get(param.name).valueChanges.subscribe((option: any) => { this.reportForm.get(param.name).valueChanges.subscribe((option: any) => {
this.ReportForm.addControl(param.childParameter.name, new FormControl('', Validators.required)); param.childParameters.forEach((child: ReportParameter) => {
if (param.childParameter.displayType === 'select') { if (child.displayType === 'none') {
const inputstring = `${param.childParameter.name}?${param.inputName}=${option.id}`; this.reportForm.addControl(child.name, new FormControl(child.defaultVal));
this.fetchSelectOptions(param.childParameter, inputstring); } else {
} this.reportForm.addControl(child.name, new FormControl('', Validators.required));
}
if (child.displayType === 'select') {
const inputstring = `${child.name}?${param.inputName}=${option.id}`;
this.fetchSelectOptions(child, inputstring);
}
});
}); });
}); });
} }
/**
* Fetches Select Dropdown options for param type "Select".
* @param {ReportParameter} param Parameter for which dropdown options are required.
* @param {string} inputstring url substring for API call.
*/
fetchSelectOptions(param: ReportParameter, inputstring: string) {
this.reportsService.getSelectOptions(inputstring).subscribe((options: SelectOption[]) => {
param.selectOptions = options;
if (param.selectAll === 'Y') {
param.selectOptions.push({id: '-1', name: 'All'});
}
});
}
/** /**
* Formats user response and readies it for utilization by run report function. * Formats user response and readies it for utilization by run report function.
* @param {any} response Object containing formcontrol values. * @param {any} response Object containing formcontrol values.
@@ -168,6 +192,9 @@ export class RunReportComponent implements OnInit {
const dateFormat = 'yyyy-MM-dd'; const dateFormat = 'yyyy-MM-dd';
formattedResponse[newKey] = this.datePipe.transform(value, dateFormat); formattedResponse[newKey] = this.datePipe.transform(value, dateFormat);
break; break;
case 'none':
formattedResponse[newKey] = value;
break;
} }
} }
return formattedResponse; return formattedResponse;
@@ -178,10 +205,10 @@ export class RunReportComponent implements OnInit {
*/ */
run() { run() {
this.isCollapsed = true; this.isCollapsed = true;
const userResponse = this.formatUserResponse(this.ReportForm.value); const userResponse = this.formatUserResponse(this.reportForm.value);
this.dataObject = { this.dataObject = {
formData: userResponse, formData: userResponse,
reportData: this.report, report: this.report,
decimalChoice: this.decimalChoice.value decimalChoice: this.decimalChoice.value
}; };
switch (this.report.type) { switch (this.report.type) {
@@ -1,6 +1,6 @@
<div *ngIf = "!hideOutput"> <div *ngIf = "!hideOutput">
<div class="m-b-10" *ngIf = "dataObject.reportData.type === 'Table'" fxLayoutAlign="end"> <div class="m-b-10" *ngIf = "dataObject.report.type === 'Table'" fxLayoutAlign="end">
<button mat-raised-button color="primary" (click)="downloadCSV()" > <button mat-raised-button color="primary" (click)="downloadCSV()" >
Export CSV Export CSV
</button> </button>
@@ -52,7 +52,7 @@ export class TableAndSmsComponent implements OnChanges {
} }
getRunReportData() { getRunReportData() {
this.reportsService.getRunReportData(this.dataObject.reportData, this.dataObject.formData) this.reportsService.getRunReportData(this.dataObject.report.name, this.dataObject.formData)
.subscribe( (res: any) => { .subscribe( (res: any) => {
this.csvData = res.data; this.csvData = res.data;
this.setOutputTable(res.data); this.setOutputTable(res.data);
@@ -85,7 +85,7 @@ export class TableAndSmsComponent implements OnChanges {
csv = csv.join('\r\n'); csv = csv.join('\r\n');
const link = document.createElement('a'); const link = document.createElement('a');
link.setAttribute('href', encodeURI(csv)); link.setAttribute('href', encodeURI(csv));
link.setAttribute('download', `${this.dataObject.reportData.name}.csv`); link.setAttribute('download', `${this.dataObject.report.name}.csv`);
document.body.appendChild(link); document.body.appendChild(link);
link.click(); link.click();
document.body.removeChild(link); document.body.removeChild(link);
+7 -9
View File
@@ -44,7 +44,7 @@ export class XBRLComponent implements OnInit, AfterViewInit {
private reportService: ReportsService) { private reportService: ReportsService) {
this.route.data.subscribe(( data: { mixtaxonomy: any, mixmapping: any, glAccounts: any }) => { this.route.data.subscribe(( data: { mixtaxonomy: any, mixmapping: any, glAccounts: any }) => {
this.mixtaxonomyArray = data.mixtaxonomy; this.mixtaxonomyArray = data.mixtaxonomy;
this.mixMappingJson = data.mixmapping.config; this.mixMappingJson = data.mixmapping.config || JSON.stringify({});
this.glAccounts = data.glAccounts; this.glAccounts = data.glAccounts;
}); });
} }
@@ -67,7 +67,7 @@ export class XBRLComponent implements OnInit, AfterViewInit {
* Subscribe to taxonomy's value changes and filters options accordingly. * Subscribe to taxonomy's value changes and filters options accordingly.
*/ */
ngAfterViewInit() { ngAfterViewInit() {
this.mixtaxonomyArray.forEach( (taxonomy: any) => { this.mixtaxonomyArray.forEach((taxonomy: any) => {
taxonomy.mapping?.valueChanges.subscribe( (value: string) => { taxonomy.mapping?.valueChanges.subscribe( (value: string) => {
this.filteredGlAccounts = this.applyFilter(value); this.filteredGlAccounts = this.applyFilter(value);
}); });
@@ -78,13 +78,11 @@ export class XBRLComponent implements OnInit, AfterViewInit {
* Maps Taxonomy to it's value and add's formcontrol. * Maps Taxonomy to it's value and add's formcontrol.
*/ */
createMappings() { createMappings() {
if (this.mixMappingJson !== undefined && this.mixMappingJson.length > 0) { this.mixtaxonomyArray.forEach((taxonomy: any) => {
this.mixtaxonomyArray.forEach( (taxonomy: any) => { const mapping = JSON.parse(this.mixMappingJson)[taxonomy.id];
const mapping = JSON.parse(this.mixMappingJson)[taxonomy.id]; taxonomy.mapping = new FormControl('');
taxonomy.mapping = new FormControl(''); taxonomy.mapping.value = mapping || '';
taxonomy.mapping.value = mapping; });
});
}
} }
/** /**
@@ -30,7 +30,7 @@ export class SavingsTransactionRecieptResolver implements Resolve<Object> {
'output-type': 'PDF', 'output-type': 'PDF',
R_transactionId: transactionId R_transactionId: transactionId
}; };
return this.reportsService.getPentahoRunReportData({name: 'Savings Transaction Receipt'}, data, 'default', 'en', 'dd MMMM yyyy'); return this.reportsService.getPentahoRunReportData('Savings Transaction Receipt', data, 'default', 'en', 'dd MMMM yyyy');
} }
} }
@@ -74,7 +74,7 @@ export class ExportTransactionsComponent implements OnInit {
R_endDate: this.datePipe.transform(this.transactionsReportForm.value.toDate, 'yyyy-MM-dd'), R_endDate: this.datePipe.transform(this.transactionsReportForm.value.toDate, 'yyyy-MM-dd'),
R_savingsAccountId: this.savingsAccountId R_savingsAccountId: this.savingsAccountId
}; };
this.reportsService.getPentahoRunReportData({name: 'Client Saving Transactions'}, data, 'default', 'en', 'dd MMMM yyyy') this.reportsService.getPentahoRunReportData('Client Saving Transactions', data, 'default', 'en', 'dd MMMM yyyy')
.subscribe( (res: any) => { .subscribe( (res: any) => {
const contentType = res.headers.get('Content-Type'); const contentType = res.headers.get('Content-Type');
const file = new Blob([res.body], {type: contentType}); const file = new Blob([res.body], {type: contentType});