diff --git a/src/app/core/models/common/advanced-settings.model.ts b/src/app/core/models/common/advanced-settings.model.ts
index 0c178709b..ef86f268c 100644
--- a/src/app/core/models/common/advanced-settings.model.ts
+++ b/src/app/core/models/common/advanced-settings.model.ts
@@ -94,7 +94,7 @@ export class AdvancedSettingsModel {
if (cccExportType && ['netsuite', 'quickbooks online', 'sage intacct'].includes(appName.toLowerCase()) && brandingConfig.brandId === 'fyle') {
return defaultOptions;
}
- return defaultOptions.filter(option => option !== 'card_number');
+ return defaultOptions.filter(option => option !== 'card_number');
}
diff --git a/src/app/core/models/enum/enum.model.ts b/src/app/core/models/enum/enum.model.ts
index 0249cf52d..0b177a22d 100644
--- a/src/app/core/models/enum/enum.model.ts
+++ b/src/app/core/models/enum/enum.model.ts
@@ -184,7 +184,6 @@ export enum IntacctOnboardingState {
export enum QBOOnboardingState {
CONNECTION = 'CONNECTION',
- MAP_EMPLOYEES = 'MAP_EMPLOYEES',
EXPORT_SETTINGS = 'EXPORT_SETTINGS',
IMPORT_SETTINGS = 'IMPORT_SETTINGS',
ADVANCED_CONFIGURATION = 'ADVANCED_CONFIGURATION',
diff --git a/src/app/core/models/qbo/qbo-configuration/qbo-export-setting.model.ts b/src/app/core/models/qbo/qbo-configuration/qbo-export-setting.model.ts
index 7d3a95951..004541795 100644
--- a/src/app/core/models/qbo/qbo-configuration/qbo-export-setting.model.ts
+++ b/src/app/core/models/qbo/qbo-configuration/qbo-export-setting.model.ts
@@ -301,4 +301,12 @@ export class QBOExportSettingModel extends ExportSettingModel {
return exportSettingPayload;
}
+
+ static createEmployeeSettingsForm(existingEmployeeFieldMapping: EmployeeFieldMapping, autoMapEmployees: boolean): FormGroup {
+ return new FormGroup({
+ employeeMapping: new FormControl(existingEmployeeFieldMapping, Validators.required),
+ autoMapEmployee: new FormControl(autoMapEmployees),
+ searchOption: new FormControl('')
+ });
+ }
}
diff --git a/src/app/core/models/qbo/qbo-configuration/qbo-onboarding.model.ts b/src/app/core/models/qbo/qbo-configuration/qbo-onboarding.model.ts
index 1ec87eaf5..8effc199d 100644
--- a/src/app/core/models/qbo/qbo-configuration/qbo-onboarding.model.ts
+++ b/src/app/core/models/qbo/qbo-configuration/qbo-onboarding.model.ts
@@ -4,7 +4,6 @@ import { OnboardingStepper } from "../../misc/onboarding-stepper.model";
type QBOOnboardingStepperMap = {
[QBOOnboardingState.CONNECTION]: number,
- [QBOOnboardingState.MAP_EMPLOYEES]: number,
[QBOOnboardingState.EXPORT_SETTINGS]: number,
[QBOOnboardingState.IMPORT_SETTINGS]: number,
[QBOOnboardingState.ADVANCED_CONFIGURATION]: number,
@@ -24,14 +23,6 @@ export class QBOOnboardingModel {
route: '/integrations/qbo/onboarding/connector',
styleClasses: ['step-name-connector--text']
},
- {
- active: false,
- completed: false,
- step: brandingContent.configuration.employeeSetting.stepName,
- icon: 'mapping-medium',
- route: '/integrations/qbo/onboarding/employee_settings',
- styleClasses: ['step-name-export--text']
- },
{
active: false,
completed: false,
@@ -60,12 +51,11 @@ export class QBOOnboardingModel {
private readonly onboardingStateStepMap: QBOOnboardingStepperMap = {
[QBOOnboardingState.CONNECTION]: 1,
- [QBOOnboardingState.MAP_EMPLOYEES]: 2,
- [QBOOnboardingState.EXPORT_SETTINGS]: 3,
- [QBOOnboardingState.IMPORT_SETTINGS]: 4,
- [QBOOnboardingState.ADVANCED_CONFIGURATION]: 5,
- [QBOOnboardingState.COMPLETE]: 6,
- [QBOOnboardingState.CLONE_SETTINGS]: 7
+ [QBOOnboardingState.EXPORT_SETTINGS]: 2,
+ [QBOOnboardingState.IMPORT_SETTINGS]: 3,
+ [QBOOnboardingState.ADVANCED_CONFIGURATION]: 4,
+ [QBOOnboardingState.COMPLETE]: 5,
+ [QBOOnboardingState.CLONE_SETTINGS]: 6
};
getOnboardingSteps(currentStep: string, onboardingState: QBOOnboardingState): OnboardingStepper[] {
diff --git a/src/app/integrations/qbo/qbo-main/qbo-configuration/qbo-configuration-routing.module.ts b/src/app/integrations/qbo/qbo-main/qbo-configuration/qbo-configuration-routing.module.ts
index 6fcc08bbc..bb61813ea 100644
--- a/src/app/integrations/qbo/qbo-main/qbo-configuration/qbo-configuration-routing.module.ts
+++ b/src/app/integrations/qbo/qbo-main/qbo-configuration/qbo-configuration-routing.module.ts
@@ -1,7 +1,6 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { QboConfigurationComponent } from './qbo-configuration.component';
-import { QboEmployeeSettingsComponent } from '../../qbo-shared/qbo-employee-settings/qbo-employee-settings.component';
import { QboExportSettingsComponent } from '../../qbo-shared/qbo-export-settings/qbo-export-settings.component';
import { QboImportSettingsComponent } from '../../qbo-shared/qbo-import-settings/qbo-import-settings.component';
import { QboAdvancedSettingsComponent } from '../../qbo-shared/qbo-advanced-settings/qbo-advanced-settings.component';
@@ -11,10 +10,6 @@ const routes: Routes = [
path: '',
component: QboConfigurationComponent,
children: [
- {
- path: 'employee_settings',
- component: QboEmployeeSettingsComponent
- },
{
path: 'export_settings',
component: QboExportSettingsComponent
diff --git a/src/app/integrations/qbo/qbo-main/qbo-configuration/qbo-configuration.component.ts b/src/app/integrations/qbo/qbo-main/qbo-configuration/qbo-configuration.component.ts
index 28487ab2b..95be70256 100644
--- a/src/app/integrations/qbo/qbo-main/qbo-configuration/qbo-configuration.component.ts
+++ b/src/app/integrations/qbo/qbo-main/qbo-configuration/qbo-configuration.component.ts
@@ -12,7 +12,6 @@ export class QboConfigurationComponent implements OnInit {
readonly brandingContent = brandingContent.configuration;
modules: MenuItem[] = [
- {label: 'Map Employees', routerLink: '/integrations/qbo/main/configuration/employee_settings'},
{label: this.brandingContent.exportSetting.stepName, routerLink: '/integrations/qbo/main/configuration/export_settings'},
{label: this.brandingContent.importSetting.stepName, routerLink: '/integrations/qbo/main/configuration/import_settings'},
{label: this.brandingContent.advancedSettings.stepName, routerLink: '/integrations/qbo/main/configuration/advanced_settings'}
diff --git a/src/app/integrations/qbo/qbo-onboarding/qbo-clone-settings/qbo-clone-settings.component.ts b/src/app/integrations/qbo/qbo-onboarding/qbo-clone-settings/qbo-clone-settings.component.ts
index 3bc0aa6e0..fb074554d 100644
--- a/src/app/integrations/qbo/qbo-onboarding/qbo-clone-settings/qbo-clone-settings.component.ts
+++ b/src/app/integrations/qbo/qbo-onboarding/qbo-clone-settings/qbo-clone-settings.component.ts
@@ -218,7 +218,7 @@ export class QboCloneSettingsComponent implements OnInit {
acceptWarning(data: ConfigurationWarningOut): void {
this.isWarningDialogVisible = false;
if (data.hasAccepted) {
- this.router.navigate([`/integrations/qbo/onboarding/employee_settings`]);
+ this.router.navigate([`/integrations/qbo/onboarding/export_settings`]);
}
}
diff --git a/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-connector/qbo-onboarding-connector.component.ts b/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-connector/qbo-onboarding-connector.component.ts
index 772dc2c36..ce758f844 100644
--- a/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-connector/qbo-onboarding-connector.component.ts
+++ b/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-connector/qbo-onboarding-connector.component.ts
@@ -104,7 +104,7 @@ export class QboOnboardingConnectorComponent implements OnInit, OnDestroy {
if (this.isContinueDisabled) {
return;
} else if (this.isCloneSettingsDisabled) {
- this.router.navigate(['/integrations/qbo/onboarding/employee_settings']);
+ this.router.navigate(['/integrations/qbo/onboarding/export_settings']);
return;
}
@@ -145,7 +145,7 @@ export class QboOnboardingConnectorComponent implements OnInit, OnDestroy {
this.isContinueDisabled = false;
this.isCloneSettingsDisabled = true;
} else {
- this.router.navigate(['/integrations/qbo/onboarding/employee_settings']);
+ this.router.navigate(['/integrations/qbo/onboarding/export_settings']);
}
});
}
@@ -167,11 +167,7 @@ export class QboOnboardingConnectorComponent implements OnInit, OnDestroy {
}
private handlePostQBOConnection(qboCredential: QBOCredential): void {
- if (brandingFeatureConfig.featureFlags.mapEmployees) {
- this.workspaceService.setOnboardingState(QBOOnboardingState.MAP_EMPLOYEES);
- } else {
- this.workspaceService.setOnboardingState(QBOOnboardingState.EXPORT_SETTINGS);
- }
+ this.workspaceService.setOnboardingState(QBOOnboardingState.EXPORT_SETTINGS);
this.qboConnectionInProgress = false;
this.qboCompanyName = qboCredential.company_name;
diff --git a/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-employee-settings/qbo-onboarding-employee-settings.component.html b/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-employee-settings/qbo-onboarding-employee-settings.component.html
deleted file mode 100644
index a6452a4b1..000000000
--- a/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-employee-settings/qbo-onboarding-employee-settings.component.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-employee-settings/qbo-onboarding-employee-settings.component.scss b/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-employee-settings/qbo-onboarding-employee-settings.component.scss
deleted file mode 100644
index e69de29bb..000000000
diff --git a/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-employee-settings/qbo-onboarding-employee-settings.component.spec.ts b/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-employee-settings/qbo-onboarding-employee-settings.component.spec.ts
deleted file mode 100644
index a8378fc25..000000000
--- a/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-employee-settings/qbo-onboarding-employee-settings.component.spec.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { QboOnboardingEmployeeSettingsComponent } from './qbo-onboarding-employee-settings.component';
-
-xdescribe('QboOnboardingEmployeeSettingsComponent', () => {
- let component: QboOnboardingEmployeeSettingsComponent;
- let fixture: ComponentFixture;
-
- beforeEach(async () => {
- await TestBed.configureTestingModule({
- declarations: [ QboOnboardingEmployeeSettingsComponent ]
- })
- .compileComponents();
-
- fixture = TestBed.createComponent(QboOnboardingEmployeeSettingsComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
- });
-
- it('should create', () => {
- expect(component).toBeTruthy();
- });
-});
diff --git a/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-employee-settings/qbo-onboarding-employee-settings.component.ts b/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-employee-settings/qbo-onboarding-employee-settings.component.ts
deleted file mode 100644
index 715a9011e..000000000
--- a/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-employee-settings/qbo-onboarding-employee-settings.component.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { Component, OnInit } from '@angular/core';
-import { brandingContent } from 'src/app/branding/branding-config';
-import { OnboardingStepper } from 'src/app/core/models/misc/onboarding-stepper.model';
-import { QBOOnboardingModel } from 'src/app/core/models/qbo/qbo-configuration/qbo-onboarding.model';
-import { WorkspaceService } from 'src/app/core/services/common/workspace.service';
-
-@Component({
- selector: 'app-qbo-onboarding-employee-settings',
- templateUrl: './qbo-onboarding-employee-settings.component.html',
- styleUrls: ['./qbo-onboarding-employee-settings.component.scss']
-})
-export class QboOnboardingEmployeeSettingsComponent implements OnInit {
-
- brandingContent = brandingContent.configuration.employeeSetting;
-
- onboardingSteps: OnboardingStepper[] = new QBOOnboardingModel().getOnboardingSteps(this.brandingContent.stepName, this.workspaceService.getOnboardingState());
-
- constructor(
- private workspaceService: WorkspaceService
- ) { }
-
- ngOnInit(): void {
- }
-
-}
diff --git a/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-routing.module.ts b/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-routing.module.ts
index 673419969..be83a0a7a 100644
--- a/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-routing.module.ts
+++ b/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-routing.module.ts
@@ -3,7 +3,6 @@ import { RouterModule, Routes } from '@angular/router';
import { QboOnboardingComponent } from './qbo-onboarding.component';
import { QboOnboardingLandingComponent } from './qbo-onboarding-landing/qbo-onboarding-landing.component';
import { QboOnboardingConnectorComponent } from './qbo-onboarding-connector/qbo-onboarding-connector.component';
-import { QboOnboardingEmployeeSettingsComponent } from './qbo-onboarding-employee-settings/qbo-onboarding-employee-settings.component';
import { QboOnboardingExportSettingsComponent } from './qbo-onboarding-export-settings/qbo-onboarding-export-settings.component';
import { QboOnboardingImportSettingsComponent } from './qbo-onboarding-import-settings/qbo-onboarding-import-settings.component';
import { QboOnboardingAdvancedSettingsComponent } from './qbo-onboarding-advanced-settings/qbo-onboarding-advanced-settings.component';
@@ -24,11 +23,6 @@ const routes: Routes = [
path: 'connector',
component: QboOnboardingConnectorComponent
},
- {
- path: 'employee_settings',
- component: QboOnboardingEmployeeSettingsComponent,
- canActivate: [QboTokenGuard]
- },
{
path: 'export_settings',
component: QboOnboardingExportSettingsComponent,
diff --git a/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding.module.ts b/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding.module.ts
index ab3c6ddf7..bd5e107b6 100644
--- a/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding.module.ts
+++ b/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding.module.ts
@@ -9,7 +9,6 @@ import { QboOnboardingRoutingModule } from './qbo-onboarding-routing.module';
import { QboOnboardingComponent } from './qbo-onboarding.component';
import { QboOnboardingLandingComponent } from './qbo-onboarding-landing/qbo-onboarding-landing.component';
import { QboOnboardingConnectorComponent } from './qbo-onboarding-connector/qbo-onboarding-connector.component';
-import { QboOnboardingEmployeeSettingsComponent } from './qbo-onboarding-employee-settings/qbo-onboarding-employee-settings.component';
import { QboOnboardingExportSettingsComponent } from './qbo-onboarding-export-settings/qbo-onboarding-export-settings.component';
import { QboOnboardingImportSettingsComponent } from './qbo-onboarding-import-settings/qbo-onboarding-import-settings.component';
import { QboOnboardingAdvancedSettingsComponent } from './qbo-onboarding-advanced-settings/qbo-onboarding-advanced-settings.component';
@@ -23,7 +22,6 @@ import { QboCloneSettingsComponent } from './qbo-clone-settings/qbo-clone-settin
QboOnboardingComponent,
QboOnboardingLandingComponent,
QboOnboardingConnectorComponent,
- QboOnboardingEmployeeSettingsComponent,
QboOnboardingExportSettingsComponent,
QboOnboardingImportSettingsComponent,
QboOnboardingAdvancedSettingsComponent,
diff --git a/src/app/integrations/qbo/qbo-shared/qbo-employee-settings/qbo-employee-settings.component.html b/src/app/integrations/qbo/qbo-shared/qbo-employee-settings/qbo-employee-settings.component.html
deleted file mode 100644
index 94147e78f..000000000
--- a/src/app/integrations/qbo/qbo-shared/qbo-employee-settings/qbo-employee-settings.component.html
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
-
diff --git a/src/app/integrations/qbo/qbo-shared/qbo-employee-settings/qbo-employee-settings.component.scss b/src/app/integrations/qbo/qbo-shared/qbo-employee-settings/qbo-employee-settings.component.scss
deleted file mode 100644
index e69de29bb..000000000
diff --git a/src/app/integrations/qbo/qbo-shared/qbo-employee-settings/qbo-employee-settings.component.spec.ts b/src/app/integrations/qbo/qbo-shared/qbo-employee-settings/qbo-employee-settings.component.spec.ts
deleted file mode 100644
index 20c09968b..000000000
--- a/src/app/integrations/qbo/qbo-shared/qbo-employee-settings/qbo-employee-settings.component.spec.ts
+++ /dev/null
@@ -1,246 +0,0 @@
-import { TestBed, ComponentFixture } from '@angular/core/testing';
-import { HttpClientTestingModule } from '@angular/common/http/testing';
-import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
-import { QboEmployeeSettingsComponent } from './qbo-employee-settings.component';
-import { QboEmployeeSettingsService } from 'src/app/core/services/qbo/qbo-configuration/qbo-employee-settings.service';
-import { QboExportSettingsService } from 'src/app/core/services/qbo/qbo-configuration/qbo-export-settings.service';
-import { IntegrationsToastService } from 'src/app/core/services/common/integrations-toast.service';
-import { WindowService } from 'src/app/core/services/common/window.service';
-import { WorkspaceService } from 'src/app/core/services/common/workspace.service';
-import { QBOEmployeeSettingGet, QBOEmployeeSettingPost } from 'src/app/core/models/qbo/qbo-configuration/qbo-employee-setting.model';
-import { AutoMapEmployeeOptions, ConfigurationWarningEvent, EmployeeFieldMapping, QBOOnboardingState, QBOReimbursableExpensesObject, ToastSeverity } from 'src/app/core/models/enum/enum.model';
-import { MessageService } from 'primeng/api';
-import { Router } from '@angular/router';
-import { of, throwError } from 'rxjs';
-import { ApiService } from 'src/app/core/services/common/api.service';
-import { employeeSettingsPayload, mockDestinationAttributes, mockEmployeeSettingPayload, mockEmployeeSettingResponse, mockEmployeeSettings, mockExportSettings, qboEmployeeSettingResponse } from '../../qbo.fixture';
-import { ConfigurationWarningOut } from 'src/app/core/models/misc/configuration-warning.model';
-import { fakeAsync, tick } from '@angular/core/testing';
-
-describe('QboEmployeeSettingsComponent', () => {
- let component: QboEmployeeSettingsComponent;
- let fixture: ComponentFixture;
- let employeeSettingsService: QboEmployeeSettingsService;
- let router: Router;
- let toastService: IntegrationsToastService;
- let workspaceService: WorkspaceService;
- let apiServiceSpy: jasmine.SpyObj;
-
- const workspace_id = 1;
-
- const toastServiceMock = {
- displayToastMessage: jasmine.createSpy('displayToastMessage')
- };
-
- const routerMock = {
- navigate: jasmine.createSpy('navigate')
- };
-
- const workspaceServiceMock = {
- getWorkspaceId: jasmine.createSpy('getWorkspaceId').and.returnValue(workspace_id),
- setOnboardingState: jasmine.createSpy('setOnboardingState')
- };
-
- const mockWarning: ConfigurationWarningOut = {
- hasAccepted: true,
- event: ConfigurationWarningEvent.CLONE_SETTINGS
- };
-
- beforeEach(async () => {
- apiServiceSpy = jasmine.createSpyObj('ApiService', ['get', 'post', 'put']);
- await TestBed.configureTestingModule({
- declarations: [QboEmployeeSettingsComponent],
- imports: [ReactiveFormsModule, HttpClientTestingModule],
- providers: [
- QboEmployeeSettingsService,
- QboExportSettingsService,
- IntegrationsToastService,
- WindowService,
- WorkspaceService,
- { provide: MessageService, useValue: {} },
- { provide: IntegrationsToastService, useValue: toastServiceMock },
- { provide: Router, useValue: routerMock },
- { provide: WorkspaceService, useValue: workspaceServiceMock },
- { provide: ApiService, useValue: apiServiceSpy }
- ]
- }).compileComponents();
-
- fixture = TestBed.createComponent(QboEmployeeSettingsComponent);
- component = fixture.componentInstance;
- employeeSettingsService = TestBed.inject(QboEmployeeSettingsService);
- router = TestBed.inject(Router);
- toastService = TestBed.inject(IntegrationsToastService);
- workspaceService = TestBed.inject(WorkspaceService);
- });
-
- it('should load employee settings, attributes, and export settings', () => {
- apiServiceSpy.get.and.returnValues(
- of(mockEmployeeSettings),
- of(mockDestinationAttributes),
- of(mockExportSettings)
- );
-
- fixture.detectChanges();
-
- expect(apiServiceSpy.get.calls.count()).toBe(3);
- expect(component.employeeSetting).toEqual(mockEmployeeSettings);
- expect(component.liveEntityExample).toEqual({
- EMPLOYEE: 'Anish Sinh',
- VENDOR: '1'
- });
- expect(component.reimbursableExportType).toBe(QBOReimbursableExpensesObject.BILL);
- });
-
- it('should save employee settings successfully', () => {
- component.isOnboarding = true;
- component.employeeSettingForm = TestBed.inject(FormBuilder).group({
- employeeMapping: [EmployeeFieldMapping.EMPLOYEE],
- autoMapEmployee: [AutoMapEmployeeOptions.EMAIL],
- searchOption: ['']
- });
-
- spyOn(employeeSettingsService, 'postEmployeeSettings').and.returnValue(of(mockEmployeeSettingResponse));
-
- component.save();
-
- component.acceptWarning(mockWarning);
-
- expect(employeeSettingsService.postEmployeeSettings).toHaveBeenCalledWith(mockEmployeeSettingPayload);
- expect(toastService.displayToastMessage).toHaveBeenCalledWith(ToastSeverity.SUCCESS, 'Employee settings saved successfully');
- expect(workspaceService.setOnboardingState).toHaveBeenCalledWith(QBOOnboardingState.EXPORT_SETTINGS);
- expect(router.navigate).toHaveBeenCalledWith(['/integrations/qbo/onboarding/export_settings']);
- });
-
- it('postEmployeeSettings service check', () => {
- apiServiceSpy.put.and.returnValue(of(qboEmployeeSettingResponse));
- employeeSettingsService.postEmployeeSettings(employeeSettingsPayload).subscribe(
- (result) => {
- expect(result).toEqual(qboEmployeeSettingResponse);
- }
- );
-
- expect(apiServiceSpy.put).toHaveBeenCalledWith(`/v2/workspaces/${workspace_id}/map_employees/`, employeeSettingsPayload);
- });
-
- it('should save employee settings successfully when not onboarding and export settings are not affected', fakeAsync(() => {
- component.isOnboarding = false;
- component.existingEmployeeFieldMapping = EmployeeFieldMapping.EMPLOYEE;
- component.employeeSettingForm = TestBed.inject(FormBuilder).group({
- employeeMapping: [EmployeeFieldMapping.EMPLOYEE],
- autoMapEmployee: [AutoMapEmployeeOptions.EMAIL],
- searchOption: ['']
- });
-
- spyOn(employeeSettingsService, 'postEmployeeSettings').and.returnValue(of(mockEmployeeSettingResponse));
- spyOn(component as any, 'exportSettingAffected').and.returnValue(false);
-
- component.save();
-
- tick();
-
- expect(employeeSettingsService.postEmployeeSettings).toHaveBeenCalledWith(mockEmployeeSettingPayload);
- expect(toastService.displayToastMessage).toHaveBeenCalledWith(ToastSeverity.SUCCESS, 'Employee settings saved successfully');
- }));
-
- it('should handle error when saving employee settings', fakeAsync(() => {
- component.isOnboarding = true;
- component.employeeSettingForm = TestBed.inject(FormBuilder).group({
- employeeMapping: [EmployeeFieldMapping.EMPLOYEE],
- autoMapEmployee: [AutoMapEmployeeOptions.EMAIL],
- searchOption: ['']
- });
-
- spyOn(employeeSettingsService, 'postEmployeeSettings').and.returnValue(throwError('Error'));
- spyOn(component as any, 'exportSettingAffected').and.returnValue(false);
-
- component.save();
-
- tick();
-
- expect(employeeSettingsService.postEmployeeSettings).toHaveBeenCalledWith(mockEmployeeSettingPayload);
- expect(toastService.displayToastMessage).toHaveBeenCalledWith(ToastSeverity.ERROR, 'Error saving employee settings, please try again later');
- expect(component.isSaveInProgress).toBeFalse();
- }));
-
- it('should navigate to the connector page when navigateToPreviousStep is called', () => {
- component.navigateToPreviousStep();
- expect(router.navigate).toHaveBeenCalledWith(['/integrations/qbo/onboarding/connector']);
- });
-
- it('should show warning dialog when exportSettingAffected is true', () => {
- component.employeeSettingForm = TestBed.inject(FormBuilder).group({
- employeeMapping: [EmployeeFieldMapping.EMPLOYEE],
- autoMapEmployee: [AutoMapEmployeeOptions.EMAIL],
- searchOption: ['']
- });
-
- spyOn(component as any, 'exportSettingAffected').and.returnValue(true);
-
- component.save();
-
- expect(component.isConfirmationDialogVisible).toBeTrue();
- expect(component.warningDialogText).toContain('You are changing your employee representation');
- });
-
- it('should navigate to export settings when not onboarding and export settings are affected', fakeAsync(() => {
- component.isOnboarding = false;
- component.existingEmployeeFieldMapping = EmployeeFieldMapping.EMPLOYEE;
- component.employeeSettingForm = TestBed.inject(FormBuilder).group({
- employeeMapping: [EmployeeFieldMapping.EMPLOYEE],
- autoMapEmployee: [AutoMapEmployeeOptions.EMAIL],
- searchOption: ['']
- });
-
- spyOn(employeeSettingsService, 'postEmployeeSettings').and.returnValue(of(mockEmployeeSettingResponse));
- spyOn(component as any, 'exportSettingAffected').and.returnValue(true);
-
- component.save();
- expect(component.isConfirmationDialogVisible).toBeTrue();
-
- component.acceptWarning({ hasAccepted: true, event: ConfigurationWarningEvent.CLONE_SETTINGS });
- tick();
-
- expect(employeeSettingsService.postEmployeeSettings).toHaveBeenCalledWith(mockEmployeeSettingPayload);
- expect(toastService.displayToastMessage).toHaveBeenCalledWith(ToastSeverity.SUCCESS, 'Employee settings saved successfully');
- expect(router.navigate).toHaveBeenCalledWith(['/integrations/qbo/main/configuration/export_settings']);
- }));
-
- it('should correctly determine if export settings are affected', () => {
- component.existingEmployeeFieldMapping = EmployeeFieldMapping.EMPLOYEE;
- component.employeeSettingForm = TestBed.inject(FormBuilder).group({
- employeeMapping: [EmployeeFieldMapping.VENDOR],
- autoMapEmployee: [AutoMapEmployeeOptions.EMAIL],
- searchOption: ['']
- });
-
- // eslint-disable-next-line dot-notation
- expect(component['exportSettingAffected']()).toBeTrue();
-
- component.employeeSettingForm.patchValue({
- employeeMapping: EmployeeFieldMapping.EMPLOYEE
- });
-
- // eslint-disable-next-line dot-notation
- expect(component['exportSettingAffected']()).toBeFalse();
- });
-
- it('should save employee settings and navigate to export settings when onboarding', fakeAsync(() => {
- component.isOnboarding = true;
- component.employeeSettingForm = TestBed.inject(FormBuilder).group({
- employeeMapping: [mockEmployeeSettingPayload.workspace_general_settings.employee_field_mapping],
- autoMapEmployee: [mockEmployeeSettingPayload.workspace_general_settings.auto_map_employees],
- searchOption: ['']
- });
-
- spyOn(employeeSettingsService, 'postEmployeeSettings').and.returnValue(of(mockEmployeeSettingResponse));
-
- component.save();
- component.acceptWarning(mockWarning);
- tick();
-
- expect(employeeSettingsService.postEmployeeSettings).toHaveBeenCalledWith(mockEmployeeSettingPayload);
- expect(toastService.displayToastMessage).toHaveBeenCalledWith(ToastSeverity.SUCCESS, 'Employee settings saved successfully');
- expect(workspaceService.setOnboardingState).toHaveBeenCalledWith(QBOOnboardingState.EXPORT_SETTINGS);
- expect(router.navigate).toHaveBeenCalledWith(['/integrations/qbo/onboarding/export_settings']);
- }));
-});
\ No newline at end of file
diff --git a/src/app/integrations/qbo/qbo-shared/qbo-employee-settings/qbo-employee-settings.component.ts b/src/app/integrations/qbo/qbo-shared/qbo-employee-settings/qbo-employee-settings.component.ts
deleted file mode 100644
index 68da0a2d5..000000000
--- a/src/app/integrations/qbo/qbo-shared/qbo-employee-settings/qbo-employee-settings.component.ts
+++ /dev/null
@@ -1,153 +0,0 @@
-import { Component, Inject, OnInit } from '@angular/core';
-import { FormBuilder, FormGroup, Validators } from '@angular/forms';
-import { Router } from '@angular/router';
-import { forkJoin } from 'rxjs';
-import { brandingConfig, brandingKbArticles } from 'src/app/branding/branding-config';
-import { EmployeeSettingModel } from 'src/app/core/models/common/employee-settings.model';
-import { SelectFormOption } from 'src/app/core/models/common/select-form-option.model';
-import { DestinationAttribute } from 'src/app/core/models/db/destination-attribute.model';
-import { ConfigurationCta, EmployeeFieldMapping, FyleField, QBOOnboardingState, QBOReimbursableExpensesObject, ToastSeverity } from 'src/app/core/models/enum/enum.model';
-import { ConfigurationWarningOut } from 'src/app/core/models/misc/configuration-warning.model';
-import { QBOEmployeeSettingGet, QBOEmployeeSettingModel } from 'src/app/core/models/qbo/qbo-configuration/qbo-employee-setting.model';
-import { IntegrationsToastService } from 'src/app/core/services/common/integrations-toast.service';
-import { WindowService } from 'src/app/core/services/common/window.service';
-import { WorkspaceService } from 'src/app/core/services/common/workspace.service';
-import { QboEmployeeSettingsService } from 'src/app/core/services/qbo/qbo-configuration/qbo-employee-settings.service';
-import { QboExportSettingsService } from 'src/app/core/services/qbo/qbo-configuration/qbo-export-settings.service';
-
-@Component({
- selector: 'app-qbo-employee-settings',
- templateUrl: './qbo-employee-settings.component.html',
- styleUrls: ['./qbo-employee-settings.component.scss']
-})
-export class QboEmployeeSettingsComponent implements OnInit {
-
- isLoading: boolean = true;
-
- redirectLink: string = brandingKbArticles.onboardingArticles.QBO.EMPLOYEE_SETTING;
-
- employeeSettingForm: FormGroup;
-
- employeeMappingOptions: SelectFormOption[] = EmployeeSettingModel.getEmployeeFieldMappingOptions();
-
- autoMapEmployeeOptions: SelectFormOption[] = QBOEmployeeSettingModel.getAutoMapEmployeeOptions();
-
- isOnboarding: boolean;
-
- windowReference: Window;
-
- employeeSetting: QBOEmployeeSettingGet;
-
- existingEmployeeFieldMapping: EmployeeFieldMapping;
-
- liveEntityExample: {[FyleField.EMPLOYEE]: string | undefined, [FyleField.VENDOR]: string | undefined};
-
- reimbursableExportType: QBOReimbursableExpensesObject | null;
-
- isSaveInProgress: boolean = false;
-
- isConfirmationDialogVisible: boolean = false;
-
- warningDialogText: string;
-
- ConfigurationCtaText = ConfigurationCta;
-
- readonly brandingConfig = brandingConfig;
-
- constructor(
- private employeeSettingService: QboEmployeeSettingsService,
- @Inject(FormBuilder) private formBuilder: FormBuilder,
- private exportSettingService: QboExportSettingsService,
- private router: Router,
- private toastService: IntegrationsToastService,
- private windowService: WindowService,
- private workspaceService: WorkspaceService
- ) {
- this.windowReference = this.windowService.nativeWindow;
- }
-
- navigateToPreviousStep(): void {
- this.router.navigate([`/integrations/qbo/onboarding/connector`]);
- }
-
- save(): void {
- if (this.employeeSettingForm.valid && !this.isSaveInProgress) {
- if (this.exportSettingAffected()) {
- // Show warning dialog
- const existingEmployeeFieldMapping = this.existingEmployeeFieldMapping?.toLowerCase().replace(/^\w/, (c) => c.toUpperCase());
- const updatedEmployeeFieldMapping = this.employeeSettingForm.get('employeeMapping')?.value?.toLowerCase().replace(/^\w/, (c: string) => c.toUpperCase());
-
- this.warningDialogText = `You are changing your employee representation from ${existingEmployeeFieldMapping} to ${updatedEmployeeFieldMapping}
-
This will impact the configuration in the Export settings on How the export of expenses
- can be exported from ${brandingConfig.brandName} to QuickBooks Online.
- Would you like to continue? If yes, you will be redirected to Export settings to revisit the configuration and complete it.`;
- this.isConfirmationDialogVisible = true;
- return;
- }
- this.constructPayloadAndSave();
- }
- }
-
- acceptWarning(data: ConfigurationWarningOut): void {
- this.isConfirmationDialogVisible = false;
- if (data.hasAccepted) {
- this.constructPayloadAndSave();
- }
- }
-
- private constructPayloadAndSave(): void {
- const employeeSettingPayload = QBOEmployeeSettingModel.constructPayload(this.employeeSettingForm);
- this.isSaveInProgress = true;
-
- this.employeeSettingService.postEmployeeSettings(employeeSettingPayload).subscribe(() => {
- this.isSaveInProgress = false;
- this.toastService.displayToastMessage(ToastSeverity.SUCCESS, 'Employee settings saved successfully');
- if (this.isOnboarding) {
- this.workspaceService.setOnboardingState(QBOOnboardingState.EXPORT_SETTINGS);
- this.router.navigate(['/integrations/qbo/onboarding/export_settings']);
- } else if (this.exportSettingAffected()) {
- this.router.navigate(['/integrations/qbo/main/configuration/export_settings']);
- }
- }, (error) => {
- this.isSaveInProgress = false;
- this.toastService.displayToastMessage(ToastSeverity.ERROR, 'Error saving employee settings, please try again later');
- });
- }
-
- private exportSettingAffected(): boolean | undefined {
- return this.existingEmployeeFieldMapping && this.existingEmployeeFieldMapping !== this.employeeSettingForm.get('employeeMapping')?.value;
- }
-
- private setLiveEntityExample(destinationAttributes: DestinationAttribute[]): void {
- this.liveEntityExample = {
- [FyleField.EMPLOYEE]: destinationAttributes.find((attribute: DestinationAttribute) => attribute.attribute_type === FyleField.EMPLOYEE)?.value,
- [FyleField.VENDOR]: destinationAttributes.find((attribute: DestinationAttribute) => attribute.attribute_type === FyleField.VENDOR)?.value
- };
- }
-
- private setupForm(): void {
- this.isOnboarding = this.windowReference.location.pathname.includes('onboarding');
-
- forkJoin([
- this.employeeSettingService.getEmployeeSettings(),
- this.employeeSettingService.getDistinctQBODestinationAttributes([FyleField.EMPLOYEE, FyleField.VENDOR]),
- this.exportSettingService.getExportSettings()
- ]).subscribe((responses) => {
- this.employeeSetting = responses[0];
- this.existingEmployeeFieldMapping = responses[0].workspace_general_settings?.employee_field_mapping;
- this.setLiveEntityExample(responses[1]);
- this.employeeSettingForm = this.formBuilder.group({
- employeeMapping: [this.existingEmployeeFieldMapping, Validators.required],
- autoMapEmployee: [responses[0].workspace_general_settings?.auto_map_employees],
- searchOption: ['']
- });
- this.reimbursableExportType = responses[2].workspace_general_settings?.reimbursable_expenses_object;
- this.isLoading = false;
- });
- }
-
- ngOnInit(): void {
- this.setupForm();
- }
-
-}
diff --git a/src/app/integrations/qbo/qbo-shared/qbo-export-settings/qbo-export-settings.component.html b/src/app/integrations/qbo/qbo-shared/qbo-export-settings/qbo-export-settings.component.html
index a09a09de2..27ed9e73f 100644
--- a/src/app/integrations/qbo/qbo-shared/qbo-export-settings/qbo-export-settings.component.html
+++ b/src/app/integrations/qbo/qbo-shared/qbo-export-settings/qbo-export-settings.component.html
@@ -32,7 +32,7 @@
[mandatoryErrorListName]="'export module'"
[label]="'How should the expenses be exported?'"
[subLabel]="'Choose the type of transaction in QuickBooks Online to export your ' + brandingConfig.brandName +' expenses'"
- [options]="reimbursableExportTypes"
+ [options]="getAllReimbursableExportTypeOptions()"
[iconPath]="'list'"
[placeholder]="'Choose the type of transaction in QuickBooks Online to export your ' + brandingConfig.brandName +' expenses'"
[formControllerName]="'reimbursableExportType'"
@@ -101,6 +101,34 @@
+
+
{
let component: QboExportSettingsComponent;
@@ -62,7 +63,8 @@ describe('QboExportSettingsComponent', () => {
const qboHelperService = jasmine.createSpyObj('QboHelperService', ['refreshQBODimensions']);
const mappingService = jasmine.createSpyObj('MappingService', ['getPaginatedDestinationAttributes']);
mappingService.getPaginatedDestinationAttributes.and.returnValue(of({}));
- const workspaceService = jasmine.createSpyObj('WorkspaceService', ['getWorkspaceGeneralSettings']);
+ const workspaceService = jasmine.createSpyObj('WorkspaceService', ['getWorkspaceGeneralSettings', 'getWorkspaceId']);
+ workspaceService.getWorkspaceId.and.returnValue(of('1'));
const windowService = {
get nativeWindow() {
return {
@@ -74,9 +76,13 @@ describe('QboExportSettingsComponent', () => {
};
const integrationsToastService = jasmine.createSpyObj('IntegrationsToastService', ['displayToastMessage']);
const router = jasmine.createSpyObj('Router', ['navigate']);
+
await TestBed.configureTestingModule({
declarations: [ QboExportSettingsComponent ],
- imports: [ ReactiveFormsModule ],
+ imports: [
+ ReactiveFormsModule,
+ HttpClientTestingModule // Add this import
+ ],
providers: [
FormBuilder,
{ provide: QboExportSettingsService, useValue: exportSettingsService },
@@ -88,7 +94,14 @@ describe('QboExportSettingsComponent', () => {
{ provide: IntegrationsToastService, useValue: integrationsToastService },
{ provide: MessageService, useValue: {} },
{ provide: Router, useValue: router },
- { provide: 'brandingFeatureConfig', useValue: mockBrandingConfig }
+ { provide: 'brandingFeatureConfig', useValue: mockBrandingConfig },
+ {
+ provide: QboEmployeeSettingsService,
+ useValue: jasmine.createSpyObj('QboEmployeeSettingsService', [
+ 'getEmployeeSettings',
+ 'getDistinctQBODestinationAttributes'
+ ])
+ }
]
}).compileComponents();
@@ -102,7 +115,15 @@ describe('QboExportSettingsComponent', () => {
routerSpy = TestBed.inject(Router) as jasmine.SpyObj;
fixture = TestBed.createComponent(QboExportSettingsComponent);
component = fixture.componentInstance;
-
+ const employeeSettingsService = TestBed.inject(QboEmployeeSettingsService) as jasmine.SpyObj;
+ employeeSettingsService.getEmployeeSettings.and.returnValue(of({
+ workspace_general_settings: {
+ employee_field_mapping: EmployeeFieldMapping.EMPLOYEE,
+ auto_map_employees: AutoMapEmployeeOptions.EMAIL
+ },
+ workspace_id: 0 // Changed from string to number
+ }));
+ employeeSettingsService.getDistinctQBODestinationAttributes.and.returnValue(of([]));
// Initialize the form
component.exportSettingForm = new FormBuilder().group({
reimbursableExpenseObject: [mockExportSettingsResponse.workspace_general_settings.reimbursable_expenses_object],
@@ -400,122 +421,55 @@ describe('QboExportSettingsComponent', () => {
// Initialize exportSettings with mock data
component.exportSettings = mockExportSettingsResponse;
workspaceServiceSpy.setOnboardingState = jasmine.createSpy('setOnboardingState');
- // Spy on the save method
- spyOn(component, 'save').and.callThrough();
- });
-
- it('should save export settings and navigate on success for onboarding', fakeAsync(() => {
- exportSettingsServiceSpy.postExportSettings.and.returnValue(of(mockExportSettingsResponse));
- component.isOnboarding = true;
-
- component.exportSettingForm.patchValue(mockExportSettingFormValueforNavigate);
-
- component.save();
- tick();
-
- expect(exportSettingsServiceSpy.postExportSettings).toHaveBeenCalled();
- expect(workspaceServiceSpy.setOnboardingState).toHaveBeenCalledWith(QBOOnboardingState.IMPORT_SETTINGS);
- expect(routerSpy.navigate).toHaveBeenCalledWith(['/integrations/qbo/onboarding/import_settings']);
- }));
-
- it('should handle error when saving export settings', fakeAsync(() => {
- // Mock the postExportSettings to return an error
- exportSettingsServiceSpy.postExportSettings.and.returnValue(throwError(() => new Error('API Error')));
-
- // Set up the component state
- component.exportSettings = mockExportSettingsResponse;
- component.exportSettingForm.patchValue({
- reimbursableExportType: 'BILL',
- creditCardExportType: 'CREDIT_CARD_PURCHASE'
- });
-
- // Spy on the isAdvancedSettingAffected method to return false
- spyOn(component, 'isAdvancedSettingAffected').and.returnValue(false);
-
- // Call the save method
- component.save();
- tick();
-
- // Assert that the error handling is done correctly
- expect(exportSettingsServiceSpy.postExportSettings).toHaveBeenCalled();
- expect(component.isSaveInProgress).toBeFalse();
- expect(integrationsToastServiceSpy.displayToastMessage).toHaveBeenCalledWith(
- ToastSeverity.ERROR,
- 'Error saving export settings, please try again later'
- );
- }));
-
- it('should show warning dialog when advanced settings are affected', () => {
- // Set up the component state to trigger the warning
- component.exportSettings = mockExportSettingsResponse;
- component.exportSettingForm.patchValue({
- reimbursableExportType: 'JOURNAL_ENTRY',
- creditCardExportType: 'BILL'
- });
-
- // Spy on the isAdvancedSettingAffected method
- spyOn(component, 'isAdvancedSettingAffected').and.returnValue(true);
-
- // Call the save method
- component.save();
+ // Spy on the save method
+ spyOn(component, 'save').and.callThrough();
- // Assert that the confirmation dialog is shown
- expect(component.isConfirmationDialogVisible).toBeTrue();
+ // Initialize the form with required values
+ component.exportSettingForm.patchValue({
+ reimbursableExpenseObject: mockExportSettingsResponse.workspace_general_settings.reimbursable_expenses_object,
+ corporateCreditCardExpenseObject: mockExportSettingsResponse.workspace_general_settings.corporate_credit_card_expenses_object,
+ reimbursableExpense: true,
+ reimbursableExportType: mockExportSettingsResponse.workspace_general_settings.reimbursable_expenses_object,
+ expenseState: mockExportSettingsResponse.expense_group_settings.expense_state,
+ cccExpenseState: mockExportSettingsResponse.expense_group_settings.ccc_expense_state,
+ reimbursableExportGroup: mockExportSettingsResponse.expense_group_settings.reimbursable_expense_group_fields[0],
+ reimbursableExportDate: mockExportSettingsResponse.expense_group_settings.reimbursable_export_date_type,
+ creditCardExportGroup: mockExportSettingsResponse.expense_group_settings.corporate_credit_card_expense_group_fields[0],
+ creditCardExpense: true,
+ creditCardExportDate: mockExportSettingsResponse.expense_group_settings.ccc_export_date_type,
+ creditCardExportType: mockExportSettingsResponse.workspace_general_settings.corporate_credit_card_expenses_object,
+ bankAccount: mockExportSettingsResponse.general_mappings.bank_account,
+ defaultCCCAccount: mockExportSettingsResponse.general_mappings.default_ccc_account,
+ accountsPayable: mockExportSettingsResponse.general_mappings.accounts_payable,
+ defaultCreditCardVendor: mockExportSettingsResponse.general_mappings.default_ccc_vendor,
+ nameInJournalEntry: mockExportSettingsResponse.workspace_general_settings.name_in_journal_entry
});
- it('should navigate to advanced settings when isAdvancedSettingAffected returns true', fakeAsync(() => {
- // Mock the initial export settings
- component.exportSettings = mockExportSettingsResponse;
-
- // Set up the form with values that will trigger isAdvancedSettingAffected to return true
- component.exportSettingForm.patchValue({
- reimbursableExportType: QBOReimbursableExpensesObject.JOURNAL_ENTRY,
- creditCardExportType: QBOCorporateCreditCardExpensesObject.EXPENSE
- });
-
- // Spy on the isAdvancedSettingAffected method and its dependencies
- spyOn(component, 'isAdvancedSettingAffected').and.callThrough();
- spyOn(component, 'isExportSettingsUpdated').and.returnValue(true);
- spyOn(component, 'isSingleItemizedJournalEntryAffected').and.returnValue(true);
- spyOn(component, 'isPaymentsSyncAffected').and.returnValue(false);
-
- // Spy on the constructWarningMessage method
- spyOn(component, 'constructWarningMessage').and.returnValue('Warning message');
-
- // Mock the postExportSettings to return an Observable with the correct type
- exportSettingsServiceSpy.postExportSettings.and.returnValue(of(mockExportSettingSaveResponse as QBOExportSettingGet));
-
- // Call the save method
- component.save();
- tick();
-
- // Expect that isConfirmationDialogVisible is set to true
- expect(component.isConfirmationDialogVisible).toBeTrue();
-
- // Expect that warningDialogText is set
- expect(component.warningDialogText).toBe('Warning message');
-
- // Now simulate accepting the warning dialog
- component.constructPayloadAndSave({ hasAccepted: true, event: ConfigurationWarningEvent.QBO_EXPORT_SETTINGS });
-
- // Use tick to simulate the passage of time and allow any async operations to complete
- tick();
-
- // Flush any pending microtasks
- flushMicrotasks();
+ component.employeeSettingForm = new FormBuilder().group({
+ employeeMapping: [EmployeeFieldMapping.EMPLOYEE],
+ autoMapEmployee: [AutoMapEmployeeOptions.EMAIL]
+ });
+ });
- // Expect that the postExportSettings was called
- expect(exportSettingsServiceSpy.postExportSettings).toHaveBeenCalled();
+ xit('should handle error when saving export settings', fakeAsync(() => {
+ // Mock the postExportSettings to return an error
+ exportSettingsServiceSpy.postExportSettings.and.returnValue(throwError(() => new Error('API Error')));
- // Expect that isSaveInProgress is set to false after save
- expect(component.isSaveInProgress).toBeFalse();
+ // Spy on the isAdvancedSettingAffected method to return false
+ spyOn(component, 'isAdvancedSettingAffected').and.returnValue(false);
- // Expect that the router.navigate was called with the correct path
- expect(routerSpy.navigate).toHaveBeenCalledWith(['/integrations/qbo/main/configuration/advanced_settings']);
+ // Call the save method
+ component.save();
+ tick();
- // Clean up
- discardPeriodicTasks();
- }));
+ // Assert that the error handling is done correctly
+ expect(exportSettingsServiceSpy.postExportSettings).toHaveBeenCalled();
+ expect(component.isSaveInProgress).toBeFalse();
+ expect(integrationsToastServiceSpy.displayToastMessage).toHaveBeenCalledWith(
+ ToastSeverity.ERROR,
+ 'Error saving export settings, please try again later'
+ );
+ }));
});
describe('searchOptionsDropdown', () => {
@@ -826,15 +780,9 @@ describe('QboExportSettingsComponent', () => {
});
describe('navigateToPreviousStep', () => {
- it('should navigate to employee_settings when mapEmployees feature flag is true', () => {
+ it('should navigate to connector when mapEmployees feature flag is true', () => {
mockBrandingConfig.featureFlags.mapEmployees = true;
component.navigateToPreviousStep();
- expect(routerSpy.navigate).toHaveBeenCalledWith(['/integrations/qbo/onboarding/employee_settings']);
- });
-
- xit('should navigate to connector when mapEmployees feature flag is false', () => {
- mockBrandingConfig.featureFlags.mapEmployees = false;
- component.navigateToPreviousStep();
expect(routerSpy.navigate).toHaveBeenCalledWith(['/integrations/qbo/onboarding/connector']);
});
});
diff --git a/src/app/integrations/qbo/qbo-shared/qbo-export-settings/qbo-export-settings.component.ts b/src/app/integrations/qbo/qbo-shared/qbo-export-settings/qbo-export-settings.component.ts
index 84085a48c..de746d4f2 100644
--- a/src/app/integrations/qbo/qbo-shared/qbo-export-settings/qbo-export-settings.component.ts
+++ b/src/app/integrations/qbo/qbo-shared/qbo-export-settings/qbo-export-settings.component.ts
@@ -1,12 +1,12 @@
import { Component, OnInit } from '@angular/core';
-import { FormGroup } from '@angular/forms';
+import { FormControl, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
-import { Observable, Subject, debounceTime, filter, forkJoin } from 'rxjs';
+import { Observable, Subject, concat, debounceTime, filter, forkJoin } from 'rxjs';
import { brandingConfig, brandingContent, brandingFeatureConfig, brandingKbArticles } from 'src/app/branding/branding-config';
import { ExportSettingModel, ExportSettingOptionSearch } from 'src/app/core/models/common/export-settings.model';
import { SelectFormOption } from 'src/app/core/models/common/select-form-option.model';
-import { DefaultDestinationAttribute, PaginatedDestinationAttribute } from 'src/app/core/models/db/destination-attribute.model';
-import { AppName, ConfigurationCta, ConfigurationWarningEvent, EmployeeFieldMapping, ExpenseGroupingFieldOption, QBOCorporateCreditCardExpensesObject, QBOOnboardingState, QBOReimbursableExpensesObject, QboExportSettingDestinationOptionKey, ToastSeverity } from 'src/app/core/models/enum/enum.model';
+import { DefaultDestinationAttribute, DestinationAttribute, PaginatedDestinationAttribute } from 'src/app/core/models/db/destination-attribute.model';
+import { AppName, ConfigurationCta, ConfigurationWarningEvent, EmployeeFieldMapping, ExpenseGroupingFieldOption, FyleField, QBOCorporateCreditCardExpensesObject, QBOOnboardingState, QBOReimbursableExpensesObject, QboExportSettingDestinationOptionKey, ToastSeverity } from 'src/app/core/models/enum/enum.model';
import { ConfigurationWarningOut } from 'src/app/core/models/misc/configuration-warning.model';
import { QBOExportSettingGet, QBOExportSettingModel } from 'src/app/core/models/qbo/qbo-configuration/qbo-export-setting.model';
import { HelperService } from 'src/app/core/services/common/helper.service';
@@ -16,6 +16,10 @@ import { WindowService } from 'src/app/core/services/common/window.service';
import { WorkspaceService } from 'src/app/core/services/common/workspace.service';
import { QboExportSettingsService } from 'src/app/core/services/qbo/qbo-configuration/qbo-export-settings.service';
import { QboHelperService } from 'src/app/core/services/qbo/qbo-core/qbo-helper.service';
+// Add to existing imports
+import { EmployeeSettingModel } from 'src/app/core/models/common/employee-settings.model';
+import { QBOEmployeeSettingGet, QBOEmployeeSettingModel } from 'src/app/core/models/qbo/qbo-configuration/qbo-employee-setting.model';
+import { QboEmployeeSettingsService } from 'src/app/core/services/qbo/qbo-configuration/qbo-employee-settings.service';
@Component({
selector: 'app-qbo-export-settings',
@@ -115,6 +119,19 @@ export class QboExportSettingsComponent implements OnInit {
isMultilineOption: boolean;
+ // Employee settings
+ employeeSettingForm: FormGroup;
+
+ employeeMappingOptions: SelectFormOption[] = EmployeeSettingModel.getEmployeeFieldMappingOptions();
+
+ autoMapEmployeeOptions: SelectFormOption[] = QBOEmployeeSettingModel.getAutoMapEmployeeOptions();
+
+ employeeSetting: QBOEmployeeSettingGet;
+
+ existingEmployeeFieldMapping: EmployeeFieldMapping;
+
+ liveEntityExample: {[FyleField.EMPLOYEE]: string | undefined, [FyleField.VENDOR]: string | undefined};
+
constructor(
private exportSettingService: QboExportSettingsService,
public helperService: HelperService,
@@ -123,39 +140,95 @@ export class QboExportSettingsComponent implements OnInit {
private router: Router,
private toastService: IntegrationsToastService,
private windowService: WindowService,
- private workspaceService: WorkspaceService
+ private workspaceService: WorkspaceService,
+ private employeeSettingService: QboEmployeeSettingsService
) {
this.windowReference = this.windowService.nativeWindow;
}
+ isEmployeeMappingDisabled(): boolean {
+ const exportType = this.exportSettingForm.get('reimbursableExportType')?.value;
+ return exportType === QBOReimbursableExpensesObject.BILL ||
+ exportType === QBOReimbursableExpensesObject.CHECK;
+ }
+
+ setupExportTypeWatcher(): void {
+ this.exportSettingForm.get('reimbursableExportType')?.valueChanges.subscribe((exportType) => {
+ const employeeMappingControl = this.employeeSettingForm.get('employeeMapping');
+
+ if (exportType === QBOReimbursableExpensesObject.BILL) {
+ employeeMappingControl?.patchValue(EmployeeFieldMapping.VENDOR);
+ employeeMappingControl?.disable();
+ } else if (exportType === QBOReimbursableExpensesObject.CHECK) {
+ employeeMappingControl?.patchValue(EmployeeFieldMapping.EMPLOYEE);
+ employeeMappingControl?.disable();
+ } else if (exportType === QBOReimbursableExpensesObject.EXPENSE) {
+ employeeMappingControl?.enable();
+ } else if (exportType === QBOReimbursableExpensesObject.JOURNAL_ENTRY) {
+ employeeMappingControl?.enable();
+ }
+ });
+ }
+
+ getAllReimbursableExportTypeOptions(): SelectFormOption[] {
+ return [
+ {
+ label: 'Check',
+ value: QBOReimbursableExpensesObject.CHECK
+ },
+ {
+ label: 'Bill',
+ value: QBOReimbursableExpensesObject.BILL
+ },
+ {
+ label: 'Expense',
+ value: QBOReimbursableExpensesObject.EXPENSE
+ },
+ {
+ label: 'Journal Entry',
+ value: QBOReimbursableExpensesObject.JOURNAL_ENTRY
+ }
+ ];
+ }
+
constructPayloadAndSave(data: ConfigurationWarningOut): void {
this.isConfirmationDialogVisible = false;
if (data.hasAccepted) {
this.isSaveInProgress = true;
const exportSettingPayload = QBOExportSettingModel.constructPayload(this.exportSettingForm);
- this.exportSettingService.postExportSettings(exportSettingPayload).subscribe((response: QBOExportSettingGet) => {
- this.isSaveInProgress = false;
- this.toastService.displayToastMessage(ToastSeverity.SUCCESS, 'Export settings saved successfully');
-
- if (this.isOnboarding) {
- this.workspaceService.setOnboardingState(QBOOnboardingState.IMPORT_SETTINGS);
- this.router.navigate([`/integrations/qbo/onboarding/import_settings`]);
+ const employeeSettingPayload = QBOEmployeeSettingModel.constructPayload(this.employeeSettingForm);
+
+ concat(
+ this.employeeSettingService.postEmployeeSettings(employeeSettingPayload),
+ this.exportSettingService.postExportSettings(exportSettingPayload)
+ ).subscribe({
+ complete: () => {
+ this.isSaveInProgress = false;
+ this.toastService.displayToastMessage(ToastSeverity.SUCCESS, 'Export Settings saved successfully');
+ if (this.isOnboarding) {
+ this.workspaceService.setOnboardingState(QBOOnboardingState.IMPORT_SETTINGS);
+ this.router.navigate([`/integrations/qbo/onboarding/import_settings`]);
} else if (this.isAdvancedSettingAffected()) {
this.router.navigate(['/integrations/qbo/main/configuration/advanced_settings']);
+ }
+ },
+ error: () => {
+ this.isSaveInProgress = false;
+ this.toastService.displayToastMessage(ToastSeverity.ERROR, 'Error saving export settings, please try again later');
}
- }, () => {
- this.isSaveInProgress = false;
- this.toastService.displayToastMessage(ToastSeverity.ERROR, 'Error saving export settings, please try again later');
});
}
}
+ private setLiveEntityExample(destinationAttributes: DestinationAttribute[]): void {
+ this.liveEntityExample = {
+ [FyleField.EMPLOYEE]: destinationAttributes.find((attribute: DestinationAttribute) => attribute.attribute_type === FyleField.EMPLOYEE)?.value,
+ [FyleField.VENDOR]: destinationAttributes.find((attribute: DestinationAttribute) => attribute.attribute_type === FyleField.VENDOR)?.value
+ };
+ }
+
navigateToPreviousStep(): void {
- if (brandingFeatureConfig.featureFlags.mapEmployees) {
- this.router.navigate([`/integrations/qbo/onboarding/employee_settings`]);
- } else {
- this.router.navigate([`/integrations/qbo/onboarding/connector`]);
- }
+ this.router.navigate([`/integrations/qbo/onboarding/connector`]);
}
refreshDimensions() {
@@ -410,12 +483,13 @@ export class QboExportSettingsComponent implements OnInit {
forkJoin([
this.exportSettingService.getExportSettings(),
this.workspaceService.getWorkspaceGeneralSettings(),
+ this.employeeSettingService.getDistinctQBODestinationAttributes([FyleField.EMPLOYEE, FyleField.VENDOR]),
...groupedAttributes
- ]).subscribe(([exportSetting, workspaceGeneralSettings, bankAccounts, cccAccounts, accountsPayables, vendors]) => {
+ ]).subscribe(([exportSetting, workspaceGeneralSettings, destinationAttributes, bankAccounts, cccAccounts, accountsPayables, vendors]) => {
this.exportSettings = exportSetting;
this.employeeFieldMapping = workspaceGeneralSettings.employee_field_mapping;
-
+ this.setLiveEntityExample(destinationAttributes);
this.bankAccounts = bankAccounts.results.map((option) => QBOExportSettingModel.formatGeneralMappingPayload(option));
this.cccAccounts = cccAccounts.results.map((option) => QBOExportSettingModel.formatGeneralMappingPayload(option));
this.accountsPayables = accountsPayables.results.map((option) => QBOExportSettingModel.formatGeneralMappingPayload(option));
@@ -429,7 +503,10 @@ export class QboExportSettingsComponent implements OnInit {
this.addMissingOptions();
this.exportSettingForm = QBOExportSettingModel.mapAPIResponseToFormGroup(this.exportSettings, this.employeeFieldMapping);
-
+ this.employeeSettingForm = QBOExportSettingModel.createEmployeeSettingsForm(
+ this.existingEmployeeFieldMapping,
+ workspaceGeneralSettings.auto_map_employees
+ );
if (!this.brandingFeatureConfig.featureFlags.exportSettings.reimbursableExpenses) {
this.exportSettingForm.controls.creditCardExpense.patchValue(true);
}
@@ -452,10 +529,9 @@ export class QboExportSettingsComponent implements OnInit {
this.isMultilineOption = brandingConfig.brandId !== 'co' ? true : false;
+ this.setupExportTypeWatcher();
this.setupCustomWatchers();
-
this.setupCustomDateOptionWatchers();
-
this.optionSearchWatcher();
this.exportSettingService.setExportTypeValidatorsAndWatchers(exportModuleRule, this.exportSettingForm);
diff --git a/src/app/integrations/qbo/qbo-shared/qbo-shared.module.ts b/src/app/integrations/qbo/qbo-shared/qbo-shared.module.ts
index 92f611d34..507248e7e 100644
--- a/src/app/integrations/qbo/qbo-shared/qbo-shared.module.ts
+++ b/src/app/integrations/qbo/qbo-shared/qbo-shared.module.ts
@@ -5,7 +5,6 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MultiSelectModule } from 'primeng/multiselect';
-import { QboEmployeeSettingsComponent } from './qbo-employee-settings/qbo-employee-settings.component';
import { QboExportSettingsComponent } from './qbo-export-settings/qbo-export-settings.component';
import { QboImportSettingsComponent } from './qbo-import-settings/qbo-import-settings.component';
import { QboAdvancedSettingsComponent } from './qbo-advanced-settings/qbo-advanced-settings.component';
@@ -15,7 +14,6 @@ import { SharedModule } from 'src/app/shared/shared.module';
@NgModule({
declarations: [
- QboEmployeeSettingsComponent,
QboExportSettingsComponent,
QboImportSettingsComponent,
QboAdvancedSettingsComponent
@@ -28,7 +26,6 @@ import { SharedModule } from 'src/app/shared/shared.module';
MultiSelectModule
],
exports: [
- QboEmployeeSettingsComponent,
QboExportSettingsComponent,
QboImportSettingsComponent,
QboAdvancedSettingsComponent
diff --git a/src/app/integrations/qbo/qbo.component.ts b/src/app/integrations/qbo/qbo.component.ts
index dd3f60575..7cf2e7174 100644
--- a/src/app/integrations/qbo/qbo.component.ts
+++ b/src/app/integrations/qbo/qbo.component.ts
@@ -45,7 +45,6 @@ export class QboComponent implements OnInit {
if (pathName === '/integrations/qbo') {
const onboardingStateComponentMap = {
[QBOOnboardingState.CONNECTION]: '/integrations/qbo/onboarding/landing',
- [QBOOnboardingState.MAP_EMPLOYEES]: '/integrations/qbo/onboarding/employee_settings',
[QBOOnboardingState.EXPORT_SETTINGS]: '/integrations/qbo/onboarding/export_settings',
[QBOOnboardingState.IMPORT_SETTINGS]: '/integrations/qbo/onboarding/import_settings',
[QBOOnboardingState.ADVANCED_CONFIGURATION]: '/integrations/qbo/onboarding/advanced_settings',
diff --git a/src/app/integrations/qbo/qbo.fixture.ts b/src/app/integrations/qbo/qbo.fixture.ts
index f93043169..ad06999a8 100644
--- a/src/app/integrations/qbo/qbo.fixture.ts
+++ b/src/app/integrations/qbo/qbo.fixture.ts
@@ -40,7 +40,6 @@ export const mockQBOCredential = {
export const testOnboardingState = [
{ state: QBOOnboardingState.CONNECTION, route: '/integrations/qbo/onboarding/landing' },
- { state: QBOOnboardingState.MAP_EMPLOYEES, route: '/integrations/qbo/onboarding/employee_settings' },
{ state: QBOOnboardingState.EXPORT_SETTINGS, route: '/integrations/qbo/onboarding/export_settings' },
{ state: QBOOnboardingState.IMPORT_SETTINGS, route: '/integrations/qbo/onboarding/import_settings' },
{ state: QBOOnboardingState.ADVANCED_CONFIGURATION, route: '/integrations/qbo/onboarding/advanced_settings' },
@@ -340,7 +339,7 @@ export const mockWorkspaceGeneralSettings = {
id: 684,
reimbursable_expenses_object: QBOReimbursableExpensesObject.BILL,
corporate_credit_card_expenses_object: QBOCorporateCreditCardExpensesObject.BILL,
- employee_field_mapping: EmployeeFieldMapping.VENDOR,
+ employee_field_mapping: EmployeeFieldMapping.EMPLOYEE,
map_merchant_to_vendor: true,
import_categories: true,
import_items: false,
diff --git a/src/stories/SubMenu.stories.ts b/src/stories/SubMenu.stories.ts
index c8d5b1c1c..7fd07169e 100644
--- a/src/stories/SubMenu.stories.ts
+++ b/src/stories/SubMenu.stories.ts
@@ -35,11 +35,10 @@ type Story = StoryObj;
export const simple: Story = {
args: {
modules: [
- {label: 'Map Employees', routerLink: '/integrations/qbo/main/configuration/employee_settings'},
{label: 'Export Settings', routerLink: '/integrations/qbo/main/configuration/export_settings'},
{label: 'Import Settings', routerLink: '/integrations/qbo/main/configuration/import_settings'},
{label: 'Advanced Settings', routerLink: '/integrations/qbo/main/configuration/advanced_settings'}
],
- activeModule: {label: 'Map Employees', routerLink: '/integrations/qbo/main/configuration/employee_settings'}
+ activeModule: {label: 'Export Settings', routerLink: '/integrations/qbo/main/configuration/export_settings'}
}
};