Skip to content

Commit 6dd0a7c

Browse files
JustARatherRidiculouslyLongUsernameashwin1111NileshPant1999DhaaraniCITanishfyle
authored
fix: business central beta bugfixes (#1122)
* fix: initialize chart of accounts multiselect when there is no api response (#1110) * fix: remove the posted at date option for ccc expenses grouped by report (#1105) * fix: update login error flow and fix redirect url (#1117) * fix: restrict JE modules to group by expense only (#1113) * fix: restrict JE modules to group by expense only * fix: add a default bank account field for CCC expenses (#1114) * fix: remove validation temporarily (#1111) * fix: add a default bank account field for CCC expenses * fix: add missing options to bank accounts on page init * fix: dynamic content for xero customize settings (#1112) * fix: update sublabel key to avoid build fail (#1116) * fix: Prod fixes of QBD direct (#1118) * fix bugs (#1119) * refactor: capitalization * fix: only ccc exports not being saved (#1121) --------- Co-authored-by: Ashwin Thanaraj <[email protected]> Co-authored-by: Nilesh Pant <[email protected]> Co-authored-by: Dhaarani <[email protected]> Co-authored-by: Anish Kr Singh <[email protected]> --------- Co-authored-by: Ashwin Thanaraj <[email protected]> Co-authored-by: Nilesh Pant <[email protected]> Co-authored-by: Dhaarani <[email protected]> Co-authored-by: Anish Kr Singh <[email protected]> --------- Co-authored-by: Ashwin Thanaraj <[email protected]> Co-authored-by: Nilesh Pant <[email protected]> Co-authored-by: Dhaarani <[email protected]> Co-authored-by: Anish Kr Singh <[email protected]>
1 parent d1d596e commit 6dd0a7c

File tree

8 files changed

+82
-40
lines changed

8 files changed

+82
-40
lines changed

src/app/core/models/business-central/business-central-configuration/business-central-export-setting.model.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ export type BusinessCentralExportSetting = {
1515
credit_card_expense_date: ExportDateType,
1616
default_bank_account_name: string,
1717
default_bank_account_id: string,
18+
default_ccc_bank_account_name: string,
19+
default_ccc_bank_account_id: string,
1820
name_in_journal_entry: string,
1921
employee_field_mapping: string,
2022
auto_map_employees: string,
@@ -184,6 +186,7 @@ export class BusinessCentralExportSettingModel {
184186
cccExportDate: new FormControl(exportSettings?.credit_card_expense_date ? exportSettings?.credit_card_expense_date.toLowerCase() : null),
185187
cccExportGroup: new FormControl(exportSettings?.credit_card_expense_grouped_by ? exportSettings?.credit_card_expense_grouped_by: null),
186188
defaultBankName: new FormControl(exportSettings?.default_bank_account_name ? findObjectByDestinationId(accounts, exportSettings?.default_bank_account_id) : null),
189+
cccDefaultBankName: new FormControl(exportSettings?.default_ccc_bank_account_name ? findObjectByDestinationId(accounts, exportSettings?.default_ccc_bank_account_id) : null),
187190
reimbursableEmployeeMapping: new FormControl(exportSettings?.employee_field_mapping ? exportSettings?.employee_field_mapping : null, Validators.required),
188191
journalEntryNamePreference: new FormControl(exportSettings?.name_in_journal_entry ? exportSettings?.name_in_journal_entry : null),
189192
autoMapEmployee: new FormControl(exportSettings?.auto_map_employees ? exportSettings?.auto_map_employees : null),
@@ -204,6 +207,8 @@ export class BusinessCentralExportSettingModel {
204207
credit_card_expense_date: exportSettingsForm.get('cccExportDate')?.value ? exportSettingsForm.get('cccExportDate')?.value.toUpperCase() : null,
205208
default_bank_account_name: exportSettingsForm.get('defaultBankName')?.value ? exportSettingsForm.get('defaultBankName')?.value.value : null,
206209
default_bank_account_id: exportSettingsForm.get('defaultBankName')?.value ? exportSettingsForm.get('defaultBankName')?.value.destination_id : null,
210+
default_ccc_bank_account_name: exportSettingsForm.get('cccDefaultBankName')?.value ? exportSettingsForm.get('cccDefaultBankName')?.value.value : null,
211+
default_ccc_bank_account_id: exportSettingsForm.get('cccDefaultBankName')?.value ? exportSettingsForm.get('cccDefaultBankName')?.value.destination_id : null,
207212
name_in_journal_entry: exportSettingsForm.get('journalEntryNamePreference')?.value ? exportSettingsForm.get('journalEntryNamePreference')?.value : null,
208213
employee_field_mapping: exportSettingsForm.get('reimbursableEmployeeMapping')?.value ? exportSettingsForm.get('reimbursableEmployeeMapping')?.value : null,
209214
auto_map_employees: exportSettingsForm.get('autoMapEmployee')?.value ? exportSettingsForm.get('autoMapEmployee')?.value : null,

src/app/core/models/business-central/business-central-configuration/business-central-import-settings.model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export class BusinessCentralImportSettingsModel extends ImportSettingsModel {
2626
const expenseFieldsArray = importSettings?.mapping_settings ? this.constructFormArray(importSettings.mapping_settings, businessCentralFields) : [] ;
2727
return new FormGroup({
2828
importCategories: new FormControl(importSettings?.import_settings?.import_categories ?? false),
29-
chartOfAccountTypes: new FormControl(importSettings?.import_settings.charts_of_accounts ? importSettings?.import_settings.charts_of_accounts : ['Expense']),
29+
chartOfAccountTypes: new FormControl(importSettings?.import_settings?.charts_of_accounts ? importSettings?.import_settings?.charts_of_accounts : ['Expense']),
3030
importVendorAsMerchant: new FormControl(importSettings?.import_settings?.import_vendors_as_merchants ?? false ),
3131
expenseFields: new FormArray(expenseFieldsArray)
3232
});

src/app/core/models/enum/enum.model.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -702,9 +702,8 @@ export enum Sage300ExportSettingDestinationOptionKey {
702702
}
703703

704704
export enum BCExportSettingDestinationOptionKey {
705-
ACCOUNT = 'ACCOUNT',
706705
VENDOR = 'VENDOR',
707-
REIMBURSABLE_BANK_ACCOUNT = 'REIMBURSABLE_BANK_ACCOUNT'
706+
BANK_ACCOUNT = 'BANK_ACCOUNT'
708707
}
709708

710709
export enum QbdDirectExportSettingDestinationOptionKey {

src/app/integrations/business-central/business-central-onboarding/business-central-onboarding-landing/business-central-onboarding-landing.component.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
<div *ngIf="!isIncorrectQBOConnectedDialogVisible">
1+
<div *ngIf="!isIncorrectBCConnectedDialogVisible">
22
<div>
33
<app-landing-page-header [logoWidth]="'65px'" [logoStyleClasses]="'tw-p-0'" [logoSectionStyleClasses]="''" [iconPath]="'assets/logos/BusinessCentral-logo.svg'" [appName]="'Dynamics 365 Business Central'" [appDescription]="'Import data from Dynamics 365 Business Central to ' + brandingConfig.brandName + ' and Export expenses from ' + brandingConfig.brandName + ' to Dynamics 365 Business Central. '" [isLoading]="false" [isIntegrationSetupInProgress]="businessCentralConnectionInProgress" [isIntegrationConnected]="isIntegrationConnected" [redirectLink]="redirectLink" [buttonText]="'Connect'" [postConnectionRoute]="'business_central/onboarding/connector'" (connectIntegration)="connectBusinessCentral()"></app-landing-page-header>
44
</div>
55
<div>
66
<app-landing-page-body [headlineText]="'Guide to setup your Integrations'" [headerText]="'A quick guide to help you set up the integration quick and easy.'" [svgPath]="'assets/flow-charts/ms-dynamics-flow-chart.svg'" [appName]="appName"></app-landing-page-body>
77
</div>
88
</div>
9-
<app-configuration-confirmation-dialog *ngIf="isIncorrectQBOConnectedDialogVisible"
9+
<app-configuration-confirmation-dialog *ngIf="isIncorrectBCConnectedDialogVisible"
1010
(warningAccepted)="acceptWarning($event)"
11-
[isWarningVisible]="isIncorrectQBOConnectedDialogVisible"
11+
[isWarningVisible]="isIncorrectBCConnectedDialogVisible"
1212
[headerText]="'Incorrect account selected'"
1313
[contextText]="'You had previously set up the integration with a different Dynamic 365 Business Central account. Please choose the same to restore the settings'"
1414
[confirmBtnText]="'Re connect'"

src/app/integrations/business-central/business-central-onboarding/business-central-onboarding-landing/business-central-onboarding-landing.component.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export class BusinessCentralOnboardingLandingComponent implements OnInit, OnDest
3333

3434
private oauthCallbackSubscription: Subscription;
3535

36-
isIncorrectQBOConnectedDialogVisible: boolean;
36+
isIncorrectBCConnectedDialogVisible: boolean;
3737

3838
constructor(
3939
private helperService: HelperService,
@@ -45,9 +45,9 @@ export class BusinessCentralOnboardingLandingComponent implements OnInit, OnDest
4545
) { }
4646

4747
acceptWarning(data: ConfigurationWarningOut): void {
48-
this.isIncorrectQBOConnectedDialogVisible = false;
48+
this.isIncorrectBCConnectedDialogVisible = false;
4949
if (data.hasAccepted) {
50-
this.router.navigate([`/integrations/qbo/onboarding/landing`]);
50+
this.router.navigate([`/integrations/business_central/onboarding/landing`]);
5151
}
5252
}
5353

@@ -72,7 +72,7 @@ export class BusinessCentralOnboardingLandingComponent implements OnInit, OnDest
7272
}, (error) => {
7373
const errorMessage = 'message' in error.error ? error.error.message : 'Failed to connect to Dynamic 365 Business Central. Please try again';
7474
if (errorMessage === 'Please choose the correct Dynamic 365 Business Central account') {
75-
this.isIncorrectQBOConnectedDialogVisible = false;
75+
this.isIncorrectBCConnectedDialogVisible = true;
7676
} else {
7777
this.toastService.displayToastMessage(ToastSeverity.ERROR, errorMessage);
7878
this.router.navigate([`/integrations/business_central/onboarding/landing`]);

src/app/integrations/business-central/business-central-shared/business-central-export-settings/business-central-export-settings.component.html

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@
9191
[mandatoryErrorListName]="'Default Bank Account Name'"
9292
[label]="'Set the Default Bank Account as?'"
9393
[subLabel]="'The integration will assign the Expenses that is exported as Journal Entry to the Bank Account selected here.'"
94-
[destinationAttributes]="reimbursableBankOptions"
95-
[destinationOptionKey]="BCExportSettingDestinationOptionKey.REIMBURSABLE_BANK_ACCOUNT"
94+
[destinationAttributes]="bankAccountOptions"
95+
[destinationOptionKey]="BCExportSettingDestinationOptionKey.BANK_ACCOUNT"
9696
[isOptionSearchInProgress]="isOptionSearchInProgress"
9797
[isAdvanceSearchEnabled]="true"
9898
(searchOptionsDropdown)="searchOptionsDropdown($event)"
@@ -113,7 +113,8 @@
113113
[iconPath]="'question-square-outline'"
114114
[placeholder]="'Select expense grouping'"
115115
[formControllerName]="'reimbursableExportGroup'"
116-
[appName]="appName">
116+
[appName]="appName"
117+
[isDisabled]="exportSettingForm.get('reimbursableExportType')?.value === BusinessCentralExportType.JOURNAL_ENTRY">
117118
</app-configuration-select-field>
118119
</div>
119120
<div *ngIf="exportSettingForm?.value.reimbursableExportType" class="tw-mt-16-px tw-bg-white tw-border tw-border-solid tw-border-separator tw-rounded-12-px">
@@ -172,21 +173,21 @@
172173
[exportTypeIconPathArray]="previewImagePaths">
173174
</app-configuration-select-field>
174175
</div>
175-
<div *ngIf="exportSettingForm.get('cccExportType')?.value && exportSettingForm.get('reimbursableExportType')?.value !== BusinessCentralExportType.JOURNAL_ENTRY" class="tw-mt-16-px tw-bg-white tw-border tw-border-solid tw-border-separator tw-rounded-12-px">
176+
<div *ngIf="exportSettingForm.get('cccExportType')?.value === BusinessCentralExportType.JOURNAL_ENTRY" class="tw-mt-16-px tw-bg-white tw-border tw-border-solid tw-border-separator tw-rounded-12-px">
176177
<app-configuration-select-field
177178
[form]="exportSettingForm"
178179
[isFieldMandatory]="true"
179180
[mandatoryErrorListName]="'Default Bank Account Name'"
180181
[label]="'Set the Default Bank Account as?'"
181182
[subLabel]="'The integration will assign the Expenses that is exported as Journal Entry to the Bank Account selected here.'"
182-
[destinationAttributes]="bankOptions"
183-
[destinationOptionKey]="BCExportSettingDestinationOptionKey.ACCOUNT"
183+
[destinationAttributes]="bankAccountOptions"
184+
[destinationOptionKey]="BCExportSettingDestinationOptionKey.BANK_ACCOUNT"
184185
[isOptionSearchInProgress]="isOptionSearchInProgress"
185186
[isAdvanceSearchEnabled]="true"
186187
(searchOptionsDropdown)="searchOptionsDropdown($event)"
187188
[iconPath]="'list'"
188189
[placeholder]="'Select default Bank Account'"
189-
[formControllerName]="'defaultBankName'">
190+
[formControllerName]="'cccDefaultBankName'">
190191
</app-configuration-select-field>
191192
</div>
192193
<div *ngIf="exportSettingForm.get('cccExportType')?.value" class="tw-mt-16-px tw-bg-white tw-border tw-border-solid tw-border-separator tw-rounded-12-px">
@@ -217,7 +218,8 @@
217218
[iconPath]="'question-square-outline'"
218219
[placeholder]="'Select expense grouping'"
219220
[formControllerName]="'cccExportGroup'"
220-
[appName]="appName">
221+
[appName]="appName"
222+
[isDisabled]="exportSettingForm.get('cccExportType')?.value === BusinessCentralExportType.JOURNAL_ENTRY">
221223
</app-configuration-select-field>
222224
</div>
223225
<div *ngIf="!exportSettingForm.get('reimbursableExpense')?.value" class="tw-mt-16-px tw-bg-white tw-border tw-border-solid tw-border-separator tw-rounded-12-px">

src/app/integrations/business-central/business-central-shared/business-central-export-settings/business-central-export-settings.component.ts

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,7 @@ export class BusinessCentralExportSettingsComponent implements OnInit {
2929

3030
exportSettingForm: FormGroup;
3131

32-
bankOptions: DestinationAttribute[];
33-
34-
reimbursableBankOptions: DestinationAttribute[];
32+
bankAccountOptions: DestinationAttribute[];
3533

3634
vendorOptions: DestinationAttribute[];
3735

@@ -142,13 +140,23 @@ export class BusinessCentralExportSettingsComponent implements OnInit {
142140
if (this.exportSettingForm.controls[formControllerName].value === ExpenseGroupedBy.EXPENSE) {
143141
return options.filter(option => option.value !== ExportDateType.LAST_SPENT_AT);
144142
}
145-
return options.filter(option => option.value !== ExportDateType.SPENT_AT);
143+
return options.filter(option => (option.value !== ExportDateType.SPENT_AT && option.value !== ExportDateType.POSTED_AT));
146144
}
147145

148146
refreshDimensions(isRefresh: boolean): void{
149147
this.businessCentralHelperService.importAttributes(isRefresh);
150148
}
151149

150+
updateExpenseGroupingValues() {
151+
if (this.exportSettingForm.get('cccExportType')?.value === BusinessCentralExportType.JOURNAL_ENTRY) {
152+
this.exportSettingForm.get('cccExportGroup')?.setValue(ExpenseGroupedBy.EXPENSE);
153+
}
154+
155+
if (this.exportSettingForm.get('reimbursableExportType')?.value === BusinessCentralExportType.JOURNAL_ENTRY) {
156+
this.exportSettingForm.get('reimbursableExportGroup')?.setValue(ExpenseGroupedBy.EXPENSE);
157+
}
158+
}
159+
152160
private setupCustomWatchers(): void {
153161
this.exportSettingForm.controls.reimbursableExportGroup.valueChanges.subscribe((reimbursableExportGroup) => {
154162
if (brandingConfig.brandId==='fyle') {
@@ -161,16 +169,25 @@ export class BusinessCentralExportSettingsComponent implements OnInit {
161169
if (brandingConfig.brandId==='fyle') {
162170
this.cccExpenseGroupingDateOptions = BusinessCentralExportSettingModel.getCCCExpenseGroupingDateOptions();
163171
this.cccExpenseGroupingDateOptions = ExportSettingModel.constructGroupingDateOptions(cccExportGroup, this.cccExpenseGroupingDateOptions);
172+
173+
// If the selected value is not valid after the export group change, reset the field
174+
const visibleValues = this.getExportDate(this.cccExpenseGroupingDateOptions, 'cccExportGroup').map(option => option.value);
175+
if (!visibleValues.includes(this.exportSettingForm.get('cccExportDate')?.value)) {
176+
this.exportSettingForm.get('cccExportDate')?.reset();
177+
}
164178
}
165179
});
180+
181+
this.exportSettingForm.get('reimbursableExportType')?.valueChanges.subscribe(() => this.updateExpenseGroupingValues());
182+
this.exportSettingForm.get('cccExportType')?.valueChanges.subscribe(() => this.updateExpenseGroupingValues());
166183
}
167184

168185
private optionSearchWatcher(): void {
169186
this.optionSearchUpdate.pipe(
170187
debounceTime(1000)
171188
).subscribe((event: ExportSettingOptionSearch) => {
172189

173-
if (event.destinationOptionKey === BCExportSettingDestinationOptionKey.REIMBURSABLE_BANK_ACCOUNT) {
190+
if (event.destinationOptionKey === BCExportSettingDestinationOptionKey.BANK_ACCOUNT) {
174191
const observables = [
175192
this.mappingService.getPaginatedDestinationAttributes('BANK_ACCOUNT', event.searchTerm),
176193
this.mappingService.getPaginatedDestinationAttributes(
@@ -182,22 +199,19 @@ export class BusinessCentralExportSettingsComponent implements OnInit {
182199
// Insert new options (if any) to existing options, and sort them
183200
const newOptions = [...bankAccounts.results, ...accounts.results];
184201
newOptions.forEach((newOption) => {
185-
if (!this.reimbursableBankOptions.find((existingOption) => existingOption.destination_id === newOption.destination_id)) {
186-
this.reimbursableBankOptions.push(newOption);
202+
if (!this.bankAccountOptions.find((existingOption) => existingOption.destination_id === newOption.destination_id)) {
203+
this.bankAccountOptions.push(newOption);
187204
}
188205
});
189206

190-
this.reimbursableBankOptions.sort((a, b) => (a.value || '').localeCompare(b.value || ''));
207+
this.bankAccountOptions.sort((a, b) => (a.value || '').localeCompare(b.value || ''));
191208
this.isOptionSearchInProgress = false;
192209
});
193210

194211
} else {
195212

196213
let existingOptions: DestinationAttribute[];
197214
switch (event.destinationOptionKey) {
198-
case BCExportSettingDestinationOptionKey.ACCOUNT:
199-
existingOptions = this.bankOptions;
200-
break;
201215
case BCExportSettingDestinationOptionKey.VENDOR:
202216
existingOptions = this.vendorOptions;
203217
break;
@@ -214,10 +228,6 @@ export class BusinessCentralExportSettingsComponent implements OnInit {
214228

215229

216230
switch (event.destinationOptionKey) {
217-
case BCExportSettingDestinationOptionKey.ACCOUNT:
218-
this.bankOptions = existingOptions.concat();
219-
this.bankOptions.sort((a, b) => (a.value || '').localeCompare(b.value || ''));
220-
break;
221231
case BCExportSettingDestinationOptionKey.VENDOR:
222232
this.vendorOptions = existingOptions.concat();
223233
this.vendorOptions.sort((a, b) => (a.value || '').localeCompare(b.value || ''));
@@ -237,6 +247,29 @@ export class BusinessCentralExportSettingsComponent implements OnInit {
237247
}
238248
}
239249

250+
addMissingOptions() {
251+
// Since pagination API response is a subset of all options, we're making use of the export settings response to fill in options
252+
253+
if (this.exportSettings) {
254+
this.helperService.addDestinationAttributeIfNotExists({
255+
options: this.bankAccountOptions,
256+
value: this.exportSettings.default_ccc_bank_account_name,
257+
destination_id: this.exportSettings.default_ccc_bank_account_id
258+
});
259+
this.helperService.addDestinationAttributeIfNotExists({
260+
options: this.bankAccountOptions,
261+
value: this.exportSettings.default_bank_account_name,
262+
destination_id: this.exportSettings.default_bank_account_id
263+
});
264+
265+
this.helperService.addDestinationAttributeIfNotExists({
266+
options: this.vendorOptions,
267+
value: this.exportSettings.default_vendor_name,
268+
destination_id: this.exportSettings.default_vendor_id
269+
});
270+
}
271+
}
272+
240273
private setupPage(): void {
241274
this.isOnboarding = this.router.url.includes('onboarding');
242275
const exportSettingValidatorRule: ExportSettingValidatorRule = {
@@ -254,11 +287,11 @@ export class BusinessCentralExportSettingsComponent implements OnInit {
254287
{
255288
'formController': 'cccExportType',
256289
'requiredValue': {
257-
'JOURNAL_ENTRY': ['defaultBankName', 'journalEntryNamePreference']
290+
'JOURNAL_ENTRY': ['cccDefaultBankName', 'journalEntryNamePreference']
258291
}
259292
}
260293
];
261-
const commonFormFields: string[] = ['defaultBankName'];
294+
const commonFormFields: string[] = [];
262295

263296
const destinationAttributes = [BusinessCentralField.ACCOUNT, FyleField.VENDOR];
264297

@@ -295,14 +328,15 @@ export class BusinessCentralExportSettingsComponent implements OnInit {
295328
});
296329
}
297330

298-
this.exportSettingForm = BusinessCentralExportSettingModel.mapAPIResponseToFormGroup(this.exportSettings, accounts.results, vendors.results);
331+
this.vendorOptions = vendors.results;
332+
this.bankAccountOptions = [...reimbursableBankAccounts.results, ...reimbursableAccounts.results];
333+
this.bankAccountOptions.sort((a, b) => (a.value || '').localeCompare(b.value || ''));
334+
this.addMissingOptions();
335+
this.exportSettingForm = BusinessCentralExportSettingModel.mapAPIResponseToFormGroup(this.exportSettings, this.bankAccountOptions, vendors.results);
336+
299337
this.helperService.addExportSettingFormValidator(this.exportSettingForm);
300338
this.helper.setConfigurationSettingValidatorsAndWatchers(exportSettingValidatorRule, this.exportSettingForm);
301339
this.helper.setExportTypeValidatorsAndWatchers(exportModuleRule, this.exportSettingForm, commonFormFields);
302-
this.bankOptions = accounts.results;
303-
this.vendorOptions = vendors.results;
304-
this.reimbursableBankOptions = [...reimbursableBankAccounts.results, ...reimbursableAccounts.results];
305-
this.reimbursableBankOptions.sort((a, b) => (a.value || '').localeCompare(b.value || ''));
306340

307341
this.setupCustomWatchers();
308342
this.optionSearchWatcher();

0 commit comments

Comments
 (0)