Skip to content

Commit ae3f09c

Browse files
authored
feat: Single credit line for Journal Entry (#1017)
* feat: Single credit line for Journal Entry * new org case * fix new case
1 parent 5f99ab0 commit ae3f09c

File tree

7 files changed

+87
-14
lines changed

7 files changed

+87
-14
lines changed

src/app/branding/c1-contents-config.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ export const c1Contents = {
8585
preferenceLabel: 'Other preferences',
8686
preferenceSubLabel: 'Create new records in NetSuite if no vendor record is found or the accounting period is closed.',
8787
previewDescriptionFieldLabel: 'Preview of the description field',
88-
autoCreateMerchantsLabel: 'Auto create merchant on NetSuite for credit card charge'
88+
autoCreateMerchantsLabel: 'Auto create merchant on NetSuite for credit card charge',
89+
singleCreditLineJELabel: 'Create a single itemized offset credit entry for Journal',
90+
singleCreditLineJESubLabel: 'Merge all Credits in a Journal to create a single entry.'
8991
}
9092
}
9193
},

src/app/branding/fyle-contents-config.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ export const fyleContents = {
8585
preferenceLabel: 'Other Preferences',
8686
preferenceSubLabel: 'Based on your preference, you can choose whether you want to create any new records in NetSuite from Fyle. (when there is no employee record found, or when the accounting period is closed).',
8787
previewDescriptionFieldLabel: 'Preview of the Description Field',
88-
autoCreateMerchantsLabel: 'Auto Create Merchant on NetSuite for Credit Card Charge'
88+
autoCreateMerchantsLabel: 'Auto Create Merchant on NetSuite for Credit Card Charge',
89+
singleCreditLineJELabel: 'Create a single itemized offset credit entry for Journal',
90+
singleCreditLineJESubLabel: 'Merge all Credits in a Journal to create a single entry.'
8991
}
9092
}
9193
},

src/app/core/models/branding/content-configuration.model.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ export type ContentConfiguration = {
8282
scheduleSubLabel: string;
8383
previewDescriptionFieldLabel: string;
8484
autoCreateMerchantsLabel: string;
85+
singleCreditLineJELabel: string;
86+
singleCreditLineJESubLabel: string;
8587
}
8688
},
8789
},

src/app/core/models/netsuite/netsuite-configuration/netsuite-advanced-settings.model.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ export type NetsuiteAdvancedSettingConfiguration = {
1414
auto_create_destination_entity: boolean,
1515
auto_create_merchants: boolean,
1616
change_accounting_period: boolean,
17-
memo_structure: string[]
17+
memo_structure: string[],
18+
je_single_credit_line: boolean
1819
}
1920

2021
export type NetsuiteAdvancedSettingGeneralMapping = {
@@ -138,6 +139,7 @@ export class NetsuiteAdvancedSettingModel extends HelperUtility {
138139
useEmployeeClass: new FormControl(advancedSettings?.general_mappings.use_employee_class ? advancedSettings?.general_mappings.use_employee_class : false),
139140
changeAccountingPeriod: new FormControl(advancedSettings?.configuration.change_accounting_period),
140141
autoCreateVendors: new FormControl(advancedSettings?.configuration.auto_create_destination_entity),
142+
singleCreditLineJE: new FormControl(advancedSettings?.configuration.je_single_credit_line),
141143
exportSchedule: new FormControl(advancedSettings?.workspace_schedules?.enabled ? true : false),
142144
exportScheduleFrequency: new FormControl(advancedSettings?.workspace_schedules?.enabled ? advancedSettings?.workspace_schedules.interval_hours : 1),
143145
memoStructure: new FormControl(advancedSettings?.configuration.memo_structure),
@@ -160,7 +162,8 @@ export class NetsuiteAdvancedSettingModel extends HelperUtility {
160162
auto_create_destination_entity: advancedSettingsForm.get('autoCreateVendors')?.value,
161163
change_accounting_period: advancedSettingsForm.get('changeAccountingPeriod')?.value,
162164
memo_structure: advancedSettingsForm.get('memoStructure')?.value,
163-
auto_create_merchants: advancedSettingsForm.get('autoCreateMerchants')?.value
165+
auto_create_merchants: advancedSettingsForm.get('autoCreateMerchants')?.value,
166+
je_single_credit_line: advancedSettingsForm.get('singleCreditLineJE')?.value || false
164167
},
165168
general_mappings: {
166169
vendor_payment_account: advancedSettingsForm.get('paymentAccount')?.value ? advancedSettingsForm.get('paymentAccount')?.value : emptyDestinationAttribute,

src/app/integrations/netsuite/netsuite-shared/netsuite-advanced-settings/netsuite-advanced-settings.component.html

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,24 +87,30 @@
8787
[formControllerName]="'changeAccountingPeriod'">
8888
</app-configuration-toggle-field>
8989

90-
<div class="autoCreateVendor" *ngIf="isAutoCreateVendorsFieldVisible() && brandingFeatureConfig.featureFlags.advancedSettings.autoCreateVendors" [ngClass]="{'tw-mb-24-px' : !isAutoCreateMerchantsFieldVisible()}">
91-
<app-configuration-toggle-field
92-
[form]="advancedSettingForm"
93-
[iconPath]="'user-plus'"
94-
[label]="brandingContent.autoCreateVendorsLabel + getCreateVendorLabel() "
95-
[subLabel]="'While exporting reimbursable expenses from ' + brandingConfig.brandName + ', the integration will automatically create a ' + getCreateVendorLabel().toLowerCase() + ' if a match does not exist in NetSuite already.'"
96-
[formControllerName]="'autoCreateVendors'">
97-
</app-configuration-toggle-field>
98-
</div>
90+
<app-configuration-toggle-field *ngIf="isAutoCreateVendorsFieldVisible() && brandingFeatureConfig.featureFlags.advancedSettings.autoCreateVendors"
91+
[form]="advancedSettingForm"
92+
[iconPath]="'user-plus'"
93+
[label]="brandingContent.autoCreateVendorsLabel + getCreateVendorLabel() "
94+
[subLabel]="'While exporting reimbursable expenses from ' + brandingConfig.brandName + ', the integration will automatically create a ' + getCreateVendorLabel().toLowerCase() + ' if a match does not exist in NetSuite already.'"
95+
[formControllerName]="'autoCreateVendors'">
96+
</app-configuration-toggle-field>
9997

100-
<app-configuration-toggle-field *ngIf="isAutoCreateMerchantsFieldVisible() && brandingFeatureConfig.featureFlags.advancedSettings.autoCreateMerchants"
98+
<app-configuration-toggle-field *ngIf="isAutoCreateMerchantsFieldVisible() && brandingFeatureConfig.featureFlags.advancedSettings.autoCreateMerchants"
10199
[form]="advancedSettingForm"
102100
[iconPath]="'user-plus'"
103101
[label]="brandingContent.autoCreateVendorsLabel + getCreateMerchantLabel()"
104102
[subLabel]="'While exporting credit card expenses from ' + brandingConfig.brandName + ', the integration will automatically create a merchant if a match does not exist in NetSuite already.'"
105103
[formControllerName]="'autoCreateMerchants'">
106104
</app-configuration-toggle-field>
107105

106+
<app-configuration-toggle-field class="tw-pt-0" *ngIf="isSingleCreditLineJEFieldVisible() && brandingFeatureConfig.featureFlags.advancedSettings.singleCreditLineJE"
107+
[form]="advancedSettingForm"
108+
[iconPath]="'list'"
109+
[label]="brandingContent.singleCreditLineJELabel"
110+
[subLabel]="brandingContent.singleCreditLineJESubLabel"
111+
[formControllerName]="'singleCreditLineJE'">
112+
</app-configuration-toggle-field>
113+
108114
</div>
109115

110116
<div class="tw-mb-16-px">

src/app/integrations/netsuite/netsuite-shared/netsuite-advanced-settings/netsuite-advanced-settings.component.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ export class NetsuiteAdvancedSettingsComponent implements OnInit {
194194
return this.workspaceGeneralSettings.reimbursable_expenses_object && this.workspaceGeneralSettings.reimbursable_expenses_object !== NetsuiteReimbursableExpensesObject.JOURNAL_ENTRY;
195195
}
196196

197+
isSingleCreditLineJEFieldVisible(): boolean {
198+
return this.workspaceGeneralSettings.reimbursable_expenses_object === NetsuiteReimbursableExpensesObject.JOURNAL_ENTRY || this.workspaceGeneralSettings.corporate_credit_card_expenses_object === NetSuiteCorporateCreditCardExpensesObject.JOURNAL_ENTRY;
199+
}
200+
197201
onMultiSelectChange() {
198202
const memo = this.advancedSettingForm.controls.memoStructure.value;
199203
const changedMemo = AdvancedSettingsModel.formatMemoPreview(memo, this.defaultMemoOptions)[1];

src/app/integrations/netsuite/netsuite-shared/netsuite-export-settings/netsuite-export-settings.component.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ export class NetsuiteExportSettingsComponent implements OnInit {
206206
if (this.isOnboarding) {
207207
this.workspaceService.setOnboardingState(NetsuiteOnboardingState.IMPORT_SETTINGS);
208208
this.router.navigate([`/integrations/netsuite/onboarding/import_settings`]);
209+
} else if (this.isAdvancedSettingAffected()) {
210+
this.router.navigate(['/integrations/netsuite/main/configuration/advanced_settings']);
209211
}
210212
}, () => {
211213
this.isSaveInProgress = false;
@@ -218,7 +220,59 @@ export class NetsuiteExportSettingsComponent implements OnInit {
218220
this.router.navigate([`/integrations/netsuite/onboarding/connector`]);
219221
}
220222

223+
private isAdvancedSettingAffected(): boolean {
224+
return (this.exportSettings?.configuration?.reimbursable_expenses_object !== null && this.exportSettings?.configuration?.reimbursable_expenses_object !== NetsuiteReimbursableExpensesObject.JOURNAL_ENTRY && this.exportSettingForm.value.reimbursableExportType === NetsuiteReimbursableExpensesObject.JOURNAL_ENTRY) || (this.exportSettings?.configuration?.corporate_credit_card_expenses_object !== null && this.exportSettings?.configuration?.corporate_credit_card_expenses_object !== NetSuiteCorporateCreditCardExpensesObject.JOURNAL_ENTRY && this.exportSettingForm.value.creditCardExportType === NetSuiteCorporateCreditCardExpensesObject.JOURNAL_ENTRY);
225+
}
226+
227+
private replaceContentBasedOnConfiguration(updatedConfiguration: string, existingConfiguration: string | undefined | null, exportType: string): string {
228+
const configurationUpdate = `You have changed the export type of $exportType expense from <b>$existingExportType</b> to <b>$updatedExportType</b>,
229+
which would impact a few configurations in the <b>Advanced settings</b>. <br><br>Please revisit the <b>Advanced settings</b> to check and enable the
230+
features that could help customize and automate your integration workflows.`;
231+
232+
let content = '';
233+
// If both are not none and it is an update case else for the new addition case
234+
if (updatedConfiguration && existingConfiguration) {
235+
content = configurationUpdate.replace('$exportType', exportType).replace('$existingExportType', existingConfiguration.toLowerCase().replace(/^\w/, (c: string) => c.toUpperCase())).replace('$updatedExportType', updatedConfiguration.toLowerCase().replace(/^\w/, (c: string) => c.toUpperCase()));
236+
}
237+
238+
return content;
239+
}
240+
241+
private constructWarningMessage(): string {
242+
let content: string = '';
243+
const existingReimbursableExportType = this.exportSettings?.configuration?.reimbursable_expenses_object;
244+
const existingCorporateCardExportType = this.exportSettings?.configuration?.corporate_credit_card_expenses_object;
245+
246+
const updatedReimbursableExportType = this.exportSettingForm.value.reimbursableExportType ? this.exportSettingForm.value.reimbursableExportType : null;
247+
const updatedCorporateCardExportType = this.exportSettingForm.value.creditCardExportType ? this.exportSettingForm.value.creditCardExportType : null;
248+
249+
let updatedExportType;
250+
let existingExportType;
251+
let exportType;
252+
253+
if (existingReimbursableExportType !== updatedReimbursableExportType) {
254+
updatedExportType = updatedReimbursableExportType;
255+
existingExportType = existingReimbursableExportType;
256+
exportType = 'reimbursable';
257+
} else if (existingCorporateCardExportType !== updatedCorporateCardExportType) {
258+
updatedExportType = updatedCorporateCardExportType;
259+
existingExportType = existingCorporateCardExportType;
260+
exportType = 'credit card';
261+
}
262+
263+
if (this.isAdvancedSettingAffected() && exportType) {
264+
content = this.replaceContentBasedOnConfiguration(updatedExportType, existingExportType, exportType);
265+
}
266+
267+
return content;
268+
}
269+
221270
save(): void {
271+
if (this.isAdvancedSettingAffected() && this.exportSettings.configuration) {
272+
this.warningDialogText = this.constructWarningMessage();
273+
this.isConfirmationDialogVisible = true;
274+
return;
275+
}
222276
this.constructPayloadAndSave({hasAccepted: true, event: ConfigurationWarningEvent.NETSUITE_EXPORT_SETTINGS});
223277
}
224278

0 commit comments

Comments
 (0)