Skip to content

Commit

Permalink
QBD Items (#889)
Browse files Browse the repository at this point in the history
* QBD Items

* lint

* fixed bugs

* final commit

* lint fix

* pr comments

* lint fixes

* pr comment

* pr comments

* lint fix
  • Loading branch information
anishfyle authored Aug 2, 2024
1 parent e4f91f4 commit 4288559
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@ export type QBDFieldMappingGet = {
updated_at: Date,
class_type: string | null,
project_type: string | null,
item_type: string | null,
custom_fields: string[],
workspace: number
}

export type QBDFieldMappingPost = {
class_type: string | null,
project_type: string | null,
item_type: string | null
}

export class FieldMappingModel {
static constructPayload(fieldMappingForm: FormGroup): QBDFieldMappingPost {
const fieldMappingPayload: QBDFieldMappingPost = {
class_type: fieldMappingForm.get('classType')?.value ? fieldMappingForm.get('classType')?.value : null,
project_type: fieldMappingForm.get('customerType')?.value ? fieldMappingForm.get('customerType')?.value : null
project_type: fieldMappingForm.get('customerType')?.value ? fieldMappingForm.get('customerType')?.value : null,
item_type: fieldMappingForm.get('itemType')?.value ? fieldMappingForm.get('itemType')?.value : null
};
return fieldMappingPayload;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Observable } from 'rxjs';
import { QBDFieldMappingGet, QBDFieldMappingPost } from 'src/app/core/models/qbd/qbd-configuration/qbd-field-mapping.model';
import { QbdWorkspaceService } from '../qbd-core/qbd-workspace.service';
import { ApiService } from '../../common/api.service';
import { QBDExportSettingFormOption } from 'src/app/core/models/qbd/qbd-configuration/qbd-export-setting.model';

@Injectable({
providedIn: 'root'
Expand All @@ -21,5 +22,4 @@ export class QbdFieldMappingService {
postQbdFieldMapping(fieldMappingPayload: QBDFieldMappingPost): Observable<QBDFieldMappingGet> {
return this.apiService.post(`/workspaces/${this.workspaceService.getWorkspaceId()}/field_mappings/`, fieldMappingPayload);
}

}
10 changes: 6 additions & 4 deletions src/app/core/services/qbd/qbd-mapping/qbd-mapping.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ export class QbdMappingService {
private workspaceService: QbdWorkspaceService
) { }

getMappings(limit: number, offset: number, sourceType: string, mappingState: MappingState): Observable<MappingResponse> {
getMappings(limit: number, offset: number, sourceType: string, mappingState: MappingState, itemType: string | null): Observable<MappingResponse> {
const params: any = {
limit,
offset,
attribute_type: sourceType.toUpperCase()
attribute_type: sourceType === 'item' ? itemType : sourceType.toUpperCase()
};

if (mappingState === MappingState.MAPPED){
Expand All @@ -38,8 +38,10 @@ export class QbdMappingService {
return this.apiService.post(`/workspaces/${this.workspaceService.getWorkspaceId()}/qbd_mappings/`, mappingPayload);
}

getMappingStats(sourceType: string): Observable<MappingStats> {
return this.apiService.get(`/workspaces/${this.workspaceService.getWorkspaceId()}/qbd_mappings/stats/`, { source_type: sourceType.toUpperCase() });
getMappingStats(sourceType: string, itemType?: string | null): Observable<MappingStats> {
return this.apiService.get(`/workspaces/${this.workspaceService.getWorkspaceId()}/qbd_mappings/stats/`, {
source_type: sourceType === 'item' ? itemType : sourceType.toUpperCase()
});
}

refreshMappingPages(): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@
</div>
<div *ngIf="!isLoading" class="tw-py-16-px" [ngClass]="{'tw-px-120-px': brandingConfig.brandId === 'fyle', 'tw-px-60-px': brandingConfig.brandId === 'co'}">
<div>
<app-mapping-header-section [sourceType]="'Corporate Card'" [mappingStats]="mappingStats"></app-mapping-header-section>
<app-mapping-header-section [sourceType]="sourceType" [mappingStats]="mappingStats"></app-mapping-header-section>
</div>

<div class="tw-shadow-app-card tw-rounded-8-px tw-bg-white tw-border-1-px tw-border-separator tw-mt-16-px">
<div class="tw-p-24-px">
<app-mapping-filter [appName]="AppName.QBD" [mappingFilter]="selectedMappingFilter" (mappingFilterChangeEvent)="mappingStateFilter($event)" (mappingSearchingEvent)="mappingSeachingFilter($event)" [isAlphabetFilterHidden]="true"></app-mapping-filter>
</div>
<div *ngIf="totalCount > 0" >
<app-mapping-table [mappings]="filteredMappings" [destinationFieldType]="destinationFieldType.TEXT" [fyleHeaderName]="'Corporate Card in ' + brandingConfig.brandName + ''" [destinationHeaderName]="'QuickBooks Desktop Credit Card Account'" [operatingSystem]="operationgSystem" (postMapping)="postMapping($event)"></app-mapping-table>
<app-mapping-table [mappings]="filteredMappings" [destinationFieldType]="destinationFieldType.TEXT" [fyleHeaderName]="sourceType + ' in ' + brandingConfig.brandName + ''" [destinationHeaderName]="destinationHeaderName" [operatingSystem]="operationgSystem" (postMapping)="postMapping($event)"></app-mapping-table>
</div>
<div class="tw-p-24-px tw-border tw-border-t-separator" *ngIf="totalCount > 0" >
<app-paginator [totalCount]="totalCount" [pageType]="PaginatorPage.MAPPING" [page]="currentPage" [dropDownValue]="limit" (pageSizeChangeEvent)="pageSizeChanges($event)" (pageOffsetChangeEvent)="pageOffsetChanges($event)"></app-paginator>
</div>
<div *ngIf="totalCount === 0">
<app-zero-state-with-illustration [mainText]="'No corporate card to show yet!'" [subText]="'Add corporate cards to ' + brandingConfig.brandName + ' to map them to individual credit card account in QuickBooks Desktop'"></app-zero-state-with-illustration>
<app-zero-state-with-illustration [mainText]="'No ' + sourceType + ' to show yet!'" [subText]="'Add ' + sourceType + ' to ' + brandingConfig.brandName + ' to map them to individual credit card account in QuickBooks Desktop'"></app-zero-state-with-illustration>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import { forkJoin } from 'rxjs';
import { brandingConfig } from 'src/app/branding/branding-config';
import { AppName, FieldType, MappingState, PaginatorPage, ToastSeverity } from 'src/app/core/models/enum/enum.model';
import { Mapping, MappingPost, MappingResponse, MappingStats } from 'src/app/core/models/qbd/db/qbd-mapping.model';
import { QBDFieldMappingGet } from 'src/app/core/models/qbd/qbd-configuration/qbd-field-mapping.model';
import { IntegrationsToastService } from 'src/app/core/services/common/integrations-toast.service';
import { WindowService } from 'src/app/core/services/common/window.service';
import { QbdFieldMappingService } from 'src/app/core/services/qbd/qbd-configuration/qbd-field-mapping.service';
import { QbdMappingService } from 'src/app/core/services/qbd/qbd-mapping/qbd-mapping.service';

@Component({
Expand Down Expand Up @@ -43,19 +45,24 @@ export class QbdGenericMappingComponent implements OnInit {

operationgSystem: string;

destinationHeaderName: string;

fieldMapping: QBDFieldMappingGet;

readonly brandingConfig = brandingConfig;

readonly AppName = AppName;

constructor(
private mappingService: QbdMappingService,
private fieldMappingService: QbdFieldMappingService,
private route: ActivatedRoute,
private toastService: IntegrationsToastService,
private window: WindowService
) { }

private getFilteredMappings(): void {
this.mappingService.getMappings(this.limit, this.pageNo, this.sourceType, this.selectedMappingFilter).subscribe((qbdMappingResult: MappingResponse) => {
this.mappingService.getMappings(this.limit, this.pageNo, this.sourceType, this.selectedMappingFilter, this.fieldMapping?.item_type).subscribe((qbdMappingResult: MappingResponse) => {
this.filteredMappings = qbdMappingResult.results.concat();
this.totalCount = qbdMappingResult.count;
this.isLoading = false;
Expand All @@ -80,7 +87,7 @@ export class QbdGenericMappingComponent implements OnInit {

postMapping(mappingPayload: MappingPost): void {
this.mappingService.postMappings(mappingPayload).subscribe(() => {
this.mappingService.getMappingStats(this.sourceType).subscribe((mappingStat: MappingStats) => {
this.mappingService.getMappingStats(this.sourceType, this.fieldMapping?.item_type).subscribe((mappingStat: MappingStats) => {
this.mappingStats = mappingStat;
this.toastService.displayToastMessage(ToastSeverity.SUCCESS, 'Changes saved successfully');
});
Expand Down Expand Up @@ -116,12 +123,15 @@ export class QbdGenericMappingComponent implements OnInit {
private setupPage(): void {
this.isLoading = true;
this.sourceType = decodeURIComponent(decodeURIComponent(this.route.snapshot.params.source_field));
this.destinationHeaderName = this.sourceType === 'item' ? 'Account in QuickBooks Desktop' : 'QuickBooks Desktop Credit Card Account';
forkJoin([
this.mappingService.getMappingStats(this.sourceType),
this.mappingService.getMappings(this.limit, this.pageNo, this.sourceType, MappingState.ALL)
this.mappingService.getMappingStats(this.sourceType, this.fieldMapping?.item_type),
this.mappingService.getMappings(this.limit, this.pageNo, this.sourceType, MappingState.ALL, this.fieldMapping?.item_type),
this.fieldMappingService.getQbdFieldMapping()
]).subscribe((response) => {
this.mappingStats = response[0];
this.mappings = response[1];
this.fieldMapping = response[2];
this.filteredMappings = this.mappings.results.concat();
this.totalCount = this.mappings.count;
this.getOperatingSystem();
Expand All @@ -130,7 +140,10 @@ export class QbdGenericMappingComponent implements OnInit {
}

ngOnInit(): void {
this.setupPage();
this.route.params.subscribe(() => {
this.isLoading = true;
this.setupPage();
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import { brandingFeatureConfig } from 'src/app/branding/branding-config';
export class QbdMappingComponent implements OnInit {

mappingPages: MenuItem[] = [
{label: 'Corporate Card', routerLink: '/integrations/qbd/main/mapping/corporate_card'}
{label: 'Corporate Card', routerLink: '/integrations/qbd/main/mapping/corporate_card'},
{label: 'Item', routerLink: '/integrations/qbd/main/mapping/item'}
];

activeModule: MenuItem;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
[form]="fieldMappingForm"
[label]="'How to map CUSTOMER: JOB in QuickBooks Desktop to ' + brandingConfig.brandName + ''"
[subLabel]="'Select the field in ' + brandingConfig.brandName + ' that needs to be mapped to the \'Customers\' field in QuickBooks Desktops'"
[options]="mappingFieldFormOptionsFunction('classType')"
[options]="mappingFieldFormOptionsFunction('classType', 'itemType')"
[iconPath]="'user-two'"
[placeholder]="'Select representation'"
[formControllerName]="'customerType'"></app-configuration-select-field>
Expand All @@ -27,11 +27,21 @@
[form]="fieldMappingForm"
[label]="'How to map CLASS in QuickBooks Desktop to ' + brandingConfig.brandName + ''"
[subLabel]="'Select the field in ' + brandingConfig.brandName + ' that needs to be mapped to the \'Class\' field in QuickBooks Desktops'"
[options]="mappingFieldFormOptionsFunction('customerType')"
[options]="mappingFieldFormOptionsFunction('customerType', 'itemType')"
[iconPath]="'list'"
[placeholder]="'Select representation'"
[formControllerName]="'classType'"></app-configuration-select-field>
</div>
<div class="tw-mt-12-px tw-bg-white tw-border tw-border-solid tw-border-separator tw-rounded-12-px">
<app-configuration-select-field
[form]="fieldMappingForm"
[label]="'How to map ITEMS in QuickBooks Desktop to ' + brandingConfig.brandName + ''"
[subLabel]="'Select the field in ' + brandingConfig.brandName + ' that needs to be mapped to the \'Items\' field in QuickBooks Desktops'"
[options]="mappingFieldFormOptionsFunction('customerType', 'classType')"
[iconPath]="'list'"
[placeholder]="'Select representation'"
[formControllerName]="'itemType'"></app-configuration-select-field>
</div>
</div>
</div>
<app-configuration-step-footer [ctaText]="!saveInProgress ? (isOnboarding ? ConfigurationCtaText.SAVE_AND_CONTINUE : ConfigurationCtaText.SAVE) : ConfigurationCtaText.SAVING" [isButtonDisabled]="!fieldMappingForm.valid || saveInProgress" (save)="save()"></app-configuration-step-footer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { QbdFieldMappingService } from 'src/app/core/services/qbd/qbd-configurat
import { IntegrationsToastService } from 'src/app/core/services/common/integrations-toast.service';
import { QbdWorkspaceService } from 'src/app/core/services/qbd/qbd-core/qbd-workspace.service';
import { brandingConfig, brandingKbArticles } from 'src/app/branding/branding-config';
import { forkJoin } from 'rxjs';

@Component({
selector: 'app-qbd-field-mapping',
Expand Down Expand Up @@ -40,6 +41,8 @@ export class QbdFieldMappingComponent implements OnInit {
}
];

additionalOptionsItemType: QBDExportSettingFormOption[] = [];

private sessionStartTime = new Date();

fieldMapping: QBDFieldMappingGet;
Expand All @@ -55,10 +58,17 @@ export class QbdFieldMappingComponent implements OnInit {
private trackingService: TrackingService
) { }

mappingFieldFormOptionsFunction(formControllerName: string): QBDExportSettingFormOption[] {
return this.representationOption.filter(option => {
return option.value !== this.fieldMappingForm.value[formControllerName];
mappingFieldFormOptionsFunction(formControllerName1: string, formControllerName2: string): QBDExportSettingFormOption[] {
const filteredOptions = this.representationOption.filter(option => {
return option.value !== this.fieldMappingForm.value[formControllerName1] &&
option.value !== this.fieldMappingForm.value[formControllerName2];
});

if (formControllerName1==='customerType' && formControllerName2==='classType'){
filteredOptions.push(...this.additionalOptionsItemType);
}

return filteredOptions;
}

private getPhase(): ProgressPhase {
Expand Down Expand Up @@ -103,20 +113,33 @@ export class QbdFieldMappingComponent implements OnInit {
}
}


buildCustomFieldOptions(options: string[]): QBDExportSettingFormOption[] {
return options.map((label) => {
return {
label,
value: label
};
});
}

private getSettingsAndSetupForm(): void {
this.isLoading = true;
this.isOnboarding = this.router.url.includes('onboarding');
this.fieldMappingService.getQbdFieldMapping().subscribe((fieldMappingResponse : QBDFieldMappingGet) => {
this.fieldMapping = fieldMappingResponse;
this.additionalOptionsItemType = this.buildCustomFieldOptions(fieldMappingResponse.custom_fields);
this.fieldMappingForm = this.formBuilder.group({
classType: [this.fieldMapping?.class_type ? this.fieldMapping?.class_type : null],
customerType: [this.fieldMapping?.project_type ? this.fieldMapping?.project_type : null]
customerType: [this.fieldMapping?.project_type ? this.fieldMapping?.project_type : null],
itemType: [this.fieldMapping?.item_type ? this.fieldMapping?.item_type : null]
});
this.isLoading = false;
}, () => {
this.fieldMappingForm = this.formBuilder.group({
classType: [null],
customerType: [null]
customerType: [null],
itemType: [null]
});
this.isLoading = false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<p-table [value]="mappings" [tableStyle]="{ 'min-width': '50rem' }" [sortField]="'source_value'" [sortOrder]="1">
<ng-template pTemplate="header">
<tr>
<th class="tw-flex tw-justify-start tw-items-center">{{ fyleHeaderName }} <i class="tw-ml-6-px pi pi-sort-amount-down"></i></th>
<th class="tw-flex tw-justify-start tw-items-center">{{ fyleHeaderName | snakeCaseToSpaceCase | titlecase }} <i class="tw-ml-6-px pi pi-sort-amount-down"></i></th>
<th>{{ destinationHeaderName }}</th>
<th>Status</th>
</tr>
Expand Down

0 comments on commit 4288559

Please sign in to comment.