-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqbd-direct-dashboard.component.ts
181 lines (140 loc) · 8.51 KB
/
qbd-direct-dashboard.component.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { RouterModule } from '@angular/router';
import { Observable, interval, switchMap, from, takeWhile, forkJoin, catchError, of } from 'rxjs';
import { brandingFeatureConfig } from 'src/app/branding/branding-config';
import { brandingConfig } from 'src/app/branding/c1-contents-config';
import { AccountingExportSummary, AccountingExportSummaryModel } from 'src/app/core/models/db/accounting-export-summary.model';
import { DestinationFieldMap, DashboardModel } from 'src/app/core/models/db/dashboard.model';
import { AccountingGroupedErrors, AccountingGroupedErrorStat, Error, ErrorResponse } from 'src/app/core/models/db/error.model';
import { AppName, AccountingErrorType, QbdDirectTaskLogType, ReimbursableImportState, CCCImportState, AppUrl, TaskLogState } from 'src/app/core/models/enum/enum.model';
import { QbdDirectTaskResponse, QbdDirectTaskLog } from 'src/app/core/models/qbd-direct/db/qbd-direct-task-log.model';
import { AccountingExportService } from 'src/app/core/services/common/accounting-export.service';
import { DashboardService } from 'src/app/core/services/common/dashboard.service';
import { WorkspaceService } from 'src/app/core/services/common/workspace.service';
import { QbdDirectExportSettingsService } from 'src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-export-settings.service';
import { QbdDirectImportSettingsService } from 'src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-import-settings.service';
import { SharedModule } from 'src/app/shared/shared.module';
@Component({
selector: 'app-qbd-direct-dashboard',
standalone: true,
imports: [RouterModule, CommonModule, SharedModule],
templateUrl: './qbd-direct-dashboard.component.html',
styleUrl: './qbd-direct-dashboard.component.scss'
})
export class QbdDirectDashboardComponent implements OnInit {
isLoading: boolean = true;
appName: AppName = AppName.QBD_DIRECT;
isImportInProgress: boolean = true;
isExportInProgress: boolean = false;
exportableAccountingExportIds: number[] = [];
failedExpenseGroupCount: number = 0;
exportProgressPercentage: number = 0;
accountingExportSummary: AccountingExportSummary | null;
processedCount: number = 0;
errors: AccountingGroupedErrors;
destinationFieldMap : DestinationFieldMap;
groupedErrorStat: AccountingGroupedErrorStat = {
[AccountingErrorType.EMPLOYEE_MAPPING]: null,
[AccountingErrorType.CATEGORY_MAPPING]: null
};
getExportErrors$: Observable<ErrorResponse> = this.dashboardService.getExportErrors(AppName.QBD_DIRECT);
getAccountingExportSummary$: Observable<AccountingExportSummary> = this.accountingExportService.getAccountingExportSummary(AppName.QBD_DIRECT);
accountingExportType: QbdDirectTaskLogType[] = [QbdDirectTaskLogType.BILL, QbdDirectTaskLogType.CREDIT_CARD_PURCHASE, QbdDirectTaskLogType.JOURNAL_ENTRY];
exportLogProcessingStates: TaskLogState[] = [TaskLogState.IN_PROGRESS, TaskLogState.ENQUEUED, TaskLogState.EXPORT_PROCESSED];
isImportItemsEnabled: boolean;
reimbursableImportState: ReimbursableImportState | null;
private readonly reimbursableExpenseImportStateMap = DashboardModel.getReimbursableExpenseImportStateMap();
cccImportState: CCCImportState | null;
private readonly cccExpenseImportStateMap = DashboardModel.getCCCExpenseImportStateMap();
AppUrl = AppUrl;
readonly isGradientAllowed: boolean = brandingFeatureConfig.isGradientAllowed;
readonly brandingConfig = brandingConfig;
importCodeFields: any;
constructor(
private accountingExportService: AccountingExportService,
private dashboardService: DashboardService,
private QbdDirectExportSettingsService: QbdDirectExportSettingsService,
private workspaceService: WorkspaceService,
private importSettingService: QbdDirectImportSettingsService
) { }
export() {
this.isExportInProgress = true;
this.dashboardService.triggerAccountingExport('v1').subscribe(() => {
this.pollExportStatus(this.exportableAccountingExportIds);
});
}
private pollExportStatus(exportableAccountingExportIds: number[] = []): void {
interval(3000).pipe(
switchMap(() => from(this.dashboardService.getAllTasks([], exportableAccountingExportIds, this.accountingExportType, AppName.QBD_DIRECT))),
takeWhile((response: QbdDirectTaskResponse) =>
response.results.filter(task =>
(this.exportLogProcessingStates.includes(task.status))
).length > 0, true
)
).subscribe((res: QbdDirectTaskResponse) => {
this.processedCount = res.results.filter((task: { status: TaskLogState; }) => (task.status !== TaskLogState.IN_PROGRESS && task.status !== TaskLogState.ENQUEUED)).length;
this.exportProgressPercentage = Math.round((this.processedCount / this.exportableAccountingExportIds.length) * 100);
if (res.results.filter((task: { status: TaskLogState; }) => (this.exportLogProcessingStates.includes(task.status))).length === 0) {
forkJoin([
this.getExportErrors$,
this.getAccountingExportSummary$
]).subscribe(responses => {
this.errors = DashboardModel.parseAPIResponseToGroupedError(responses[0].results);
this.groupedErrorStat = {
EMPLOYEE_MAPPING: null,
CATEGORY_MAPPING: null
};
this.accountingExportSummary = AccountingExportSummaryModel.parseAPIResponseToAccountingSummaryForQbdDirect(responses[1]);
this.failedExpenseGroupCount = res.results.filter(task => task.status === TaskLogState.FAILED || task.status === TaskLogState.FATAL).length;
this.exportableAccountingExportIds = res.results.filter(task => task.status === TaskLogState.FAILED || task.status === TaskLogState.FATAL).map(taskLog => taskLog.expense_group);
this.isExportInProgress = false;
this.exportProgressPercentage = 0;
this.processedCount = 0;
});
}
});
}
private setupPage(): void {
forkJoin([
this.getExportErrors$,
this.getAccountingExportSummary$.pipe(catchError(() => of(null))),
this.dashboardService.getAllTasks(this.exportLogProcessingStates.concat(TaskLogState.ERROR), undefined, this.accountingExportType, AppName.QBD_DIRECT),
this.dashboardService.getExportableAccountingExportIds('v2'),
this.QbdDirectExportSettingsService.getQbdExportSettings(),
this.importSettingService.getImportSettings()
]).subscribe((responses) => {
this.errors = DashboardModel.parseAPIResponseToGroupedError(responses[0].results);
this.isImportItemsEnabled = responses[3].import_items;
if (responses[1]) {
this.accountingExportSummary = AccountingExportSummaryModel.parseAPIResponseToAccountingSummaryForQbdDirect(responses[1]);
}
this.destinationFieldMap = {
EMPLOYEE: responses[4].employee_field_mapping,
CATEGORY: 'ACCOUNT'
};
this.isLoading = false;
this.importCodeFields = responses[5].import_settings?.import_code_fields;
const queuedTasks: QbdDirectTaskLog[] = responses[2].results.filter((task: QbdDirectTaskLog) => this.exportLogProcessingStates.includes(task.status));
this.failedExpenseGroupCount = responses[2].results.filter((task: QbdDirectTaskLog) => task.status === TaskLogState.FAILED || task.status === TaskLogState.FATAL).length;
this.exportableAccountingExportIds = responses[3].exportable_export_log_ids?.length ? responses[3].exportable_export_log_ids : [];
this.reimbursableImportState = responses[4]?.reimbursable_expense_export_type && responses[4].reimbursable_expense_state ? this.reimbursableExpenseImportStateMap[responses[4].reimbursable_expense_state] : null;
this.cccImportState = responses[4].credit_card_expense_export_type && responses[4].credit_card_expense_state ? this.cccExpenseImportStateMap[responses[4].credit_card_expense_state] : null;
if (queuedTasks.length) {
this.isImportInProgress = false;
this.isExportInProgress = true;
this.pollExportStatus(this.exportableAccountingExportIds);
} else {
this.accountingExportService.importExpensesFromFyle('v2').subscribe(() => {
this.dashboardService.getExportableAccountingExportIds('v2').subscribe((exportableAccountingExportIds) => {
this.exportableAccountingExportIds = exportableAccountingExportIds.exportable_export_log_ids?.length ? exportableAccountingExportIds.exportable_export_log_ids : [];
this.isImportInProgress = false;
});
});
}
});
}
ngOnInit(): void {
this.setupPage();
}
}