Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Xero tenant connection #646

Merged
merged 6 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 142 additions & 0 deletions src/app/branding/branding-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,77 @@ export const brandingDemoVideoLinks = demoVideoLinks[brandingConfig.brandId];

const content: ContentConfiguration = {
fyle: {
xero: {
landing: {
contentText: 'Import data from Xero to ' + brandingConfig.brandName + ' and export expenses from ' + brandingConfig.brandName + ' to Xero. ',
guideHeaderText: 'Guide to setup your integrations'
},
common: {
readMoreText: 'Read more',
exportLogTabName: 'Export log',
viewExpenseText: 'View expense',
corporateCard: 'Corporate card',
errors: 'errors',
autoMap: 'Auto map',
customField: 'Add new custom field',
customFieldName: 'Field name',
customFieldPlaceholderName: 'Placeholder name',
customFieldType: 'Field type',
customFieldCreateandSave: 'Create and save',
userId: 'user ID',
companyId: 'company ID',
userPassword: 'User password',
password: 'password',
tenantMapping: 'Tenant Mapping',
descriptionText: 'of the description field'
},
configuration: {
connector: {
stepName: 'Connect to Xero',
subLabel: 'Expenses will be posted to the Xero Tenant Mapping selected here. Once configured, you can not change ' + brandingConfig.brandName + ' organization or Tenant Mapping.'
},
exportSetting: {
stepName: 'Export settings',
headerText: '',
contentText: 'Enable this to export non-reimbursable expenses from ' + brandingConfig.brandName + '. If not enabled, any <b>corporate credit card</b> expenses will not be exported to Xero.',
corporateCard: {
cccExpensePaymentType: 'Set the default expense payment type as?',
cccExpensePaymentTypeSubLabel: 'The selected expense payment type will be added to the corporate credit card expenses exported from ' + brandingConfig.brandName + ' to Xero.',
creditCardVendor: 'Set the default credit card vendor as',
creditCardVendorSublabel: 'The vendor configured here will be added to all the credit card expenses exported as bills.',
chargeCard: 'Set the default charge card',
chargeCardPlaceholder: 'Select a charge card',
chargeCardSublabel: 'Expenses of corporate cards in ' + brandingConfig.brandName + ' that are not mapped to their respective cards in Xero will be posted to the card configured here. You can map your cards in the mapping section after configuring the integration.',
cccExpenseState: 'You can export expenses either when they are awaiting closure after approval (approved) or when the transactions has been settled (closed).',
cccExportGroup: 'Expenses can either be exported as single line items (expense) or as a grouped report with multiple line items (report).',
employeeFieldMapping: 'How are your employees represented in Xero?',
creditCard: 'To which general ledger account should the expenses be credited to?',
creditCardSubLabel: 'The integration will credit the account selected here for corporate credit card expenses exported as journal entries.'
}
},
advancedSettings: {
stepName: 'Advanced settings',
scheduleAutoExport: 'Schedule automatic export',
email: 'Send error notification to',
autoSyncPayments: 'Auto-sync payment status for reimbursable expenses',
defaultPaymentAccount: 'Select payment account',
autoCreateEmployeeVendor: 'Auto-create ',
postEntriesCurrentPeriod: 'Post entries in the current accounting period',
setDescriptionField: 'Set the description field in Xero',
dfvLabel: 'Default field values',
dfvSubLabel: 'If you\'ve made a field mandatory in Xero but don\'t collect a value from your employees in the expense form, you can set a default value here to be added to all the expenses. For location and department, you can opt to use the values from your employee records in Xero.',
location: 'location',
department: 'department',
project: 'project',
class: 'class',
item: 'item'
},
done: {
ctaText: '',
hintText: ''
}
}
},
intacct: {
landing: {
contentText: 'Import data from Sage Intacct to ' + brandingConfig.brandName + ' and Export expenses from ' + brandingConfig.brandName + ' to Sage Intacct. ',
Expand Down Expand Up @@ -418,6 +489,77 @@ const content: ContentConfiguration = {
}
},
co: {
xero: {
landing: {
contentText: 'Import data from Xero to ' + brandingConfig.brandName + ' and export expenses from ' + brandingConfig.brandName + ' to Xero. ',
guideHeaderText: 'Guide to setup your integrations'
},
common: {
readMoreText: 'Read more',
exportLogTabName: 'Export log',
viewExpenseText: 'View expense',
corporateCard: 'Corporate card',
errors: 'errors',
autoMap: 'Auto map',
customField: 'Add new custom field',
customFieldName: 'Field name',
customFieldPlaceholderName: 'Placeholder name',
customFieldType: 'Field type',
customFieldCreateandSave: 'Create and save',
userId: 'user ID',
companyId: 'company ID',
userPassword: 'User password',
password: 'password',
tenantMapping: 'Tenant Mapping',
descriptionText: 'of the description field'
},
configuration: {
connector: {
stepName: 'Connect to Xero',
subLabel: 'Expenses will be posted to the Xero Tenant Mapping selected here. Once configured, you can not change ' + brandingConfig.brandName + ' organization or Tenant Mapping.'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tenant Mapping t and m should be small. c1 uses sentence case

},
exportSetting: {
stepName: 'Export settings',
headerText: '',
contentText: 'Enable this to export non-reimbursable expenses from ' + brandingConfig.brandName + '. If not enabled, any <b>corporate credit card</b> expenses will not be exported to Xero.',
corporateCard: {
cccExpensePaymentType: 'Set the default expense payment type as?',
cccExpensePaymentTypeSubLabel: 'The selected expense payment type will be added to the corporate credit card expenses exported from ' + brandingConfig.brandName + ' to Xero.',
creditCardVendor: 'Set the default credit card vendor as',
creditCardVendorSublabel: 'The vendor configured here will be added to all the credit card expenses exported as bills.',
chargeCard: 'Set the default charge card',
chargeCardPlaceholder: 'Select a charge card',
chargeCardSublabel: 'Expenses of corporate cards in ' + brandingConfig.brandName + ' that are not mapped to their respective cards in Xero will be posted to the card configured here. You can map your cards in the mapping section after configuring the integration.',
cccExpenseState: 'You can export expenses either when they are awaiting closure after approval (approved) or when the transactions has been settled (closed).',
cccExportGroup: 'Expenses can either be exported as single line items (expense) or as a grouped report with multiple line items (report).',
employeeFieldMapping: 'How are your employees represented in Xero?',
creditCard: 'To which general ledger account should the expenses be credited to?',
creditCardSubLabel: 'The integration will credit the account selected here for corporate credit card expenses exported as journal entries.'
}
},
advancedSettings: {
stepName: 'Advanced settings',
scheduleAutoExport: 'Schedule automatic export',
email: 'Send error notification to',
autoSyncPayments: 'Auto-sync payment status for reimbursable expenses',
defaultPaymentAccount: 'Select payment account',
autoCreateEmployeeVendor: 'Auto-create ',
postEntriesCurrentPeriod: 'Post entries in the current accounting period',
setDescriptionField: 'Set the description field in Xero',
dfvLabel: 'Default field values',
dfvSubLabel: 'If you\'ve made a field mandatory in Xero but don\'t collect a value from your employees in the expense form, you can set a default value here to be added to all the expenses. For location and department, you can opt to use the values from your employee records in Xero.',
location: 'location',
department: 'department',
project: 'project',
class: 'class',
item: 'item'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

551 - 555 is specific to Intacct

},
done: {
ctaText: '',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if these values are not required in xero, please don't add it to model

hintText: ''
}
}
},
intacct: {
landing: {
contentText: 'Import data from Sage Intacct to ' + brandingConfig.brandName + ' and export expenses from ' + brandingConfig.brandName + ' to Sage Intacct. ',
Expand Down
71 changes: 71 additions & 0 deletions src/app/core/models/branding/content-configuration.model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,76 @@
export type ContentConfiguration = {
[brandingId: string]: {
xero: {
landing: {
contentText: string;
guideHeaderText: string;
},
common: {
readMoreText: string;
exportLogTabName: string;
viewExpenseText: string;
corporateCard: string;
errors: string;
autoMap: string;
customField: string;
customFieldName: string;
customFieldPlaceholderName: string;
customFieldType: string;
customFieldCreateandSave: string;
userId: string;
companyId: string;
userPassword: string;
password: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are specific to Intacct, please remove it off, 20-23

tenantMapping: string;
descriptionText: string;
},
configuration: {
connector: {
stepName: string;
subLabel: string;
},
exportSetting: {
stepName: string;
headerText: string;
contentText: string;
corporateCard: {
cccExpensePaymentType: string;
cccExpensePaymentTypeSubLabel: string;
creditCardVendor: string;
creditCardVendorSublabel: string;
chargeCard: string;
chargeCardPlaceholder: string;
chargeCardSublabel: string;
cccExpenseState: string;
cccExportGroup: string;
employeeFieldMapping: string;
creditCard: string;
creditCardSubLabel: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clean up line 37 to 48, introduce keys that are used in Xero only

}
},
advancedSettings: {
stepName: string;
scheduleAutoExport: string;
email: string;
autoSyncPayments: string;
defaultPaymentAccount: string;
autoCreateEmployeeVendor: string;
postEntriesCurrentPeriod: string;
setDescriptionField: string;
dfvLabel: string;
dfvSubLabel: string;
location: string;
department: string;
project: string;
class: string;
item: string;
},
done: {
ctaText: string;
hintText: string;
}
},
},
intacct : {
landing: {
contentText: string;
Expand Down
11 changes: 11 additions & 0 deletions src/app/core/models/xero/db/xero-destination-attribute.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { DestinationAttribute, GroupedDestinationAttribute } from "../../db/destination-attribute.model";

export type DestinationAttributeDetail = {
email: string;
fully_qualified_name: string;
};

export interface XeroDestinationAttributes extends DestinationAttribute {
auto_created: boolean;
detail: DestinationAttributeDetail | null;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all these are not used in code, these keys. Let's use the common DestinationAttribute model.

Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class XeroOnboardingModel {
step: 'Connect to Xero',
icon: 'link-vertical-medium',
route: '/integrations/xero/onboarding/connector',
styleClasses: ['step-name-connector--text']
styleClasses: ['step-name-connector--text tw-pl-24-px']
},
{
active: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { WorkspaceService } from '../../common/workspace.service';
import { CacheBuster, Cacheable, globalCacheBusterNotifier } from 'ts-cacheable';
import { XeroCredentials } from 'src/app/core/models/xero/db/xero-credential.model';
import { environment } from 'src/environments/environment';
import { DestinationAttribute } from 'src/app/core/models/db/destination-attribute.model';
import { TenantMapping, TenantMappingPost } from 'src/app/core/models/xero/db/xero-tenant-mapping.model';
import { XeroDestinationAttributes } from 'src/app/core/models/xero/db/xero-destination-attribute.model';

const xeroCredentialsCache = new Subject<void>();

Expand Down Expand Up @@ -49,11 +49,11 @@ export class XeroConnectorService {
return this.apiService.get(`/workspaces/${workspaceId}/xero/token_health/`, {});
}

getXeroTenants(): Observable<DestinationAttribute[]> {
getXeroTenants(): Observable<XeroDestinationAttributes[]> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use common model

return this.apiService.get(`/workspaces/${this.workspaceId}/xero/tenants/`, {attribute_type: 'TENANT'});
}

postXeroTenants(): Observable<DestinationAttribute[]> {
postXeroTenants(): Observable<XeroDestinationAttributes[]> {
const workspaceId = this.workspaceService.getWorkspaceId();

return this.apiService.post(`/workspaces/${workspaceId}/xero/tenants/`, {});
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,43 @@
<p>xero-onboarding-connector works!</p>
<div class="tw-pb-48-px">
<app-onboarding-steppers [onboardingSteps]="onboardingSteps"></app-onboarding-steppers>
<div>
<div *ngIf="isLoading" class="tw-flex tw-justify-center tw-items-center tw-pt-80-px">
<app-loader></app-loader>
</div>
<div *ngIf="!isLoading" class="configuration--contents tw-border-border-tertiary tw-mt-24-px" [ngClass]="{'tw-mx-120-px tw-shadow-app-card': brandingConfig.brandId === 'fyle', 'tw-mx-60-px tw-shadow-shadow-level-1': brandingConfig.brandId === 'co'}">
<div>
<app-configuration-step-header
[headerText]="'Connect to Xero Tenant'"
[contentText]="'Connect to the Xero Tenant from which you would like to import and export data. The ' + brandingConfig.brandName + ' org and Xero Tenant cannot be changed once the configuration steps are complete.'"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

T should be small for c1. Add it to content config and read it from there

[redirectLink]="redirectLink">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

</app-configuration-step-header>
</div>
<div class="tw-px-24-px">
<app-configuration-connector
[accountingAppTitle]="'Xero'"
[accountingCompanyName]="xeroCompanyName"
[fyleOrgName]="fyleOrgName"
[accountingCompanyTokenExpired]="xeroTokenExpired"
[isAccountingCompanyConnected]="isXeroConnected"
[showDisconnect]="showDisconnectXero"
[accountingCompanyConnectionInProgress]="xeroConnectionInProgress"
[accountingCompanyList]="tenantList"
[switchLinkText]="'Disconnect'"
(switchCompany)="disconnectXero()"
(connectCompany)="connectXero($event)">
</app-configuration-connector>

<app-configuration-confirmation-dialog
(warningAccepted)="acceptWarning($event)"
[isWarningVisible]="isWarningDialogVisible"
[event]="warningEvent"
[headerText]="warningHeaderText"
[contextText]="warningContextText"
[confirmBtnText]="primaryButtonText"
[showSecondaryCTA]="false">
</app-configuration-confirmation-dialog>
</div>
<app-configuration-step-footer [ctaText]="!saveInProgress ? ConfigurationCtaText.SAVE_AND_CONTINUE : ConfigurationCtaText.SAVING" [isButtonDisabled]="isContinueDisabled" (save)="save()"></app-configuration-step-footer>
</div>
</div>
</div>
Loading
Loading