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

[QBO Export] Implement offline pattern B for manual report exports #44733

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
7ad0af4
feat: add offline pattern B for manual report exports
kosmydel Jul 2, 2024
8d1f659
Merge branch '@kosmydel/qbo-export/manual-exports' into @kosmydel/qbo…
kosmydel Jul 3, 2024
deba812
Merge branch '@kosmydel/qbo-export/manual-exports' into @kosmydel/qbo…
kosmydel Jul 4, 2024
533097a
cleanup
kosmydel Jul 4, 2024
5f448b8
Merge branch '@kosmydel/qbo-export/manual-exports' into @kosmydel/qbo…
kosmydel Jul 4, 2024
1425235
fix: rbr
kosmydel Jul 4, 2024
652ce36
feat: add in progress status
kosmydel Jul 5, 2024
5f85e77
Merge branch '@kosmydel/qbo-export/manual-exports' into @kosmydel/qbo…
kosmydel Jul 5, 2024
a2a1c41
Merge branch '@kosmydel/qbo-export/manual-exports' into @kosmydel/qbo…
kosmydel Jul 5, 2024
afcee83
Merge branch '@kosmydel/qbo-export/manual-exports' into @kosmydel/qbo…
kosmydel Jul 5, 2024
42b923c
fix lang
kosmydel Jul 5, 2024
eefd928
Merge branch '@kosmydel/qbo-export/manual-exports' into @kosmydel/qbo…
kosmydel Jul 9, 2024
98c7443
fixes
kosmydel Jul 9, 2024
1d2e00c
Merge branch '@kosmydel/qbo-export/manual-exports' into @kosmydel/qbo…
kosmydel Jul 16, 2024
972f910
cleanup
kosmydel Jul 16, 2024
37a7735
add DeepL translations
kosmydel Jul 16, 2024
8cbf964
Merge branch 'main' into @kosmydel/qbo-export/manual-exports-offline-…
kosmydel Jul 16, 2024
d214d75
Merge branch 'main' into @kosmydel/qbo-export/manual-exports-offline-…
kosmydel Jul 17, 2024
fdcd827
fix: displaying friendly name
kosmydel Jul 17, 2024
a029907
address review
kosmydel Jul 19, 2024
59d7c77
Merge branch 'main' into @kosmydel/qbo-export/manual-exports-offline-…
kosmydel Jul 19, 2024
9af61d1
address review
kosmydel Jul 19, 2024
fce269d
Merge branch 'refs/heads/main' into @kosmydel/qbo-export/manual-expor…
war-in Jul 25, 2024
d024caf
adjust API calls parameters
war-in Jul 25, 2024
dd8d4bd
fix params
war-in Jul 25, 2024
805ae17
fix wrong export integration button conditions
war-in Jul 25, 2024
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
4 changes: 2 additions & 2 deletions src/components/ReportActionItem/ExportWithDropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ function ExportWithDropdownMenu({policy, report, connectionName}: ExportWithDrop
if (modalStatus === CONST.REPORT.EXPORT_OPTIONS.EXPORT_TO_INTEGRATION) {
ReportActions.exportToIntegration(reportID, connectionName);
} else if (modalStatus === CONST.REPORT.EXPORT_OPTIONS.MARK_AS_EXPORTED) {
ReportActions.markAsManuallyExported(reportID);
ReportActions.markAsManuallyExported(reportID, connectionName);
}
}, [connectionName, modalStatus, reportID]);

Expand Down Expand Up @@ -106,7 +106,7 @@ function ExportWithDropdownMenu({policy, report, connectionName}: ExportWithDrop
if (value === CONST.REPORT.EXPORT_OPTIONS.EXPORT_TO_INTEGRATION) {
ReportActions.exportToIntegration(reportID, connectionName);
} else if (value === CONST.REPORT.EXPORT_OPTIONS.MARK_AS_EXPORTED) {
ReportActions.markAsManuallyExported(reportID);
ReportActions.markAsManuallyExported(reportID, connectionName);
}
}}
onOptionSelected={({value}) => savePreferredExportMethod(value)}
Expand Down
8 changes: 4 additions & 4 deletions src/components/ReportActionItem/ReportPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ function ReportPreview({
const hasReceipts = transactionsWithReceipts.length > 0;
const isScanning = hasReceipts && areAllRequestsBeingSmartScanned;
const hasErrors =
hasMissingSmartscanFields ||
(hasMissingSmartscanFields && !iouSettled) ||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
(canUseViolations && (ReportUtils.hasViolations(iouReportID, transactionViolations) || ReportUtils.hasWarningTypeViolations(iouReportID, transactionViolations))) ||
(ReportUtils.isReportOwner(iouReport) && ReportUtils.hasReportViolations(iouReportID)) ||
Expand Down Expand Up @@ -285,7 +285,7 @@ function ReportPreview({
const shouldShowSettlementButton = (shouldShowPayButton || shouldShowApproveButton) && !showRTERViolationMessage;

const shouldPromptUserToAddBankAccount = ReportUtils.hasMissingPaymentMethod(userWallet, iouReportID);
const shouldShowRBR = !iouSettled && hasErrors;
const shouldShowRBR = hasErrors;

/*
Show subtitle if at least one of the expenses is not being smart scanned, and either:
Expand Down Expand Up @@ -425,7 +425,7 @@ function ReportPreview({
)}
</View>
</View>
{shouldShowSettlementButton && !shouldShowExportIntegrationButton && (
{shouldShowSettlementButton && (
<SettlementButton
formattedAmount={getSettlementAmount() ?? ''}
currency={iouReport?.currency}
Expand All @@ -451,7 +451,7 @@ function ReportPreview({
isLoading={!isOffline && !canAllowSettlement}
/>
)}
{shouldShowExportIntegrationButton && (
{shouldShowExportIntegrationButton && !shouldShowSettlementButton && (
<ExportWithDropdownMenu
policy={policy}
report={iouReport}
Expand Down
2 changes: 1 addition & 1 deletion src/languages/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ type ChangeTypeParams = {oldType: string; newType: string};

type DelegateSubmitParams = {delegateUser: string; originalManager: string};

type ExportedToIntegrationParams = {label: string};
type ExportedToIntegrationParams = {label: string; markedManually?: boolean; inProgress?: boolean; lastModified?: string};

type ForwardedParams = {amount: string; currency: string};

Expand Down
12 changes: 10 additions & 2 deletions src/libs/API/parameters/MarkAsExportedParams.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
type MarkAsExportedParams = {
reportIDList: string;
markedManually: true;
markedManually: boolean;
/**
* Stringified JSON object with type of following structure:
* Array<{
* reportID: number;
* label: string;
* optimisticReportActionID: string;
* }>
*/
data: string;
};

export default MarkAsExportedParams;
7 changes: 7 additions & 0 deletions src/libs/API/parameters/ReportExportParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ type ReportExportParams = {
reportIDList: string;
connectionName: ValueOf<typeof CONST.POLICY.CONNECTIONS.NAME>;
type: 'MANUAL';
/**
* Stringified JSON object with type of following structure:
* {
* [reportID]: optimisticReportActionID;
* }>
*/
optimisticReportActions: string;
};

export default ReportExportParams;
42 changes: 42 additions & 0 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import type {
UserWallet,
} from '@src/types/onyx';
import type {Participant} from '@src/types/onyx/IOU';
import type {OriginalMessageExportedToIntegration} from '@src/types/onyx/OldDotAction';
import type Onboarding from '@src/types/onyx/Onboarding';
import type {Errors, Icon, PendingAction} from '@src/types/onyx/OnyxCommon';
import type {OriginalMessageChangeLog, PaymentMethodType} from '@src/types/onyx/OriginalMessage';
Expand Down Expand Up @@ -287,6 +288,12 @@ type OptimisticChatReport = Pick<
isOptimisticReport: true;
};

type OptimisticExportIntegrationAction = OriginalMessageExportedToIntegration &
Pick<
ReportAction<typeof CONST.REPORT.ACTIONS.TYPE.EXPORTED_TO_INTEGRATION>,
'reportActionID' | 'actorAccountID' | 'avatar' | 'created' | 'lastModified' | 'message' | 'person' | 'shouldShow' | 'pendingAction' | 'errors' | 'automatic'
>;

type OptimisticTaskReportAction = Pick<
ReportAction,
| 'reportActionID'
Expand Down Expand Up @@ -5184,6 +5191,40 @@ function buildOptimisticTaskReport(
};
}

/**
* Builds an optimistic EXPORTED_TO_INTEGRATION report action
*
* @param integration - The connectionName of the integration
* @param markedManually - Whether the integration was marked as manually exported
*/
function buildOptimisticExportIntegrationAction(integration: ConnectionName, markedManually = false): OptimisticExportIntegrationAction {
const label = CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[integration];
return {
reportActionID: NumberUtils.rand64(),
actionName: CONST.REPORT.ACTIONS.TYPE.EXPORTED_TO_INTEGRATION,
pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
actorAccountID: currentUserAccountID,
message: [],
person: [
{
type: CONST.REPORT.MESSAGE.TYPE.TEXT,
style: 'strong',
text: getCurrentUserDisplayNameOrEmail(),
},
],
automatic: false,
avatar: getCurrentUserAvatar(),
created: DateUtils.getDBTime(),
shouldShow: true,
originalMessage: {
label,
lastModified: DateUtils.getDBTime(),
markedManually,
inProgress: true,
},
};
}

/**
* A helper method to create transaction thread
*
Expand Down Expand Up @@ -7528,6 +7569,7 @@ export {
isAdminOwnerApproverOrReportOwner,
createDraftWorkspaceAndNavigateToConfirmationScreen,
isChatUsedForOnboarding,
buildOptimisticExportIntegrationAction,
getChatUsedForOnboarding,
getFieldViolationTranslation,
getFieldViolation,
Expand Down
90 changes: 84 additions & 6 deletions src/libs/actions/Report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ import type {
InviteToGroupChatParams,
InviteToRoomParams,
LeaveRoomParams,
MarkAsExportedParams,
MarkAsUnreadParams,
OpenReportParams,
OpenRoomMembersPageParams,
ReadNewestActionParams,
RemoveEmojiReactionParams,
RemoveFromGroupChatParams,
RemoveFromRoomParams,
ReportExportParams,
ResolveActionableMentionWhisperParams,
ResolveActionableReportMentionWhisperParams,
SearchForReportsParams,
Expand Down Expand Up @@ -3835,18 +3837,94 @@ function setGroupDraft(newGroupDraft: Partial<NewGroupChatDraft>) {
}

function exportToIntegration(reportID: string, connectionName: ConnectionName) {
API.write(WRITE_COMMANDS.REPORT_EXPORT, {
const action = ReportUtils.buildOptimisticExportIntegrationAction(connectionName);
const optimisticReportActionID = action.reportActionID;

const optimisticData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`,
value: {
[optimisticReportActionID]: action,
},
},
];

const failureData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`,
value: {
[optimisticReportActionID]: {
errors: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'),
},
},
},
];

const params = {
reportIDList: reportID,
connectionName,
type: 'MANUAL',
});
optimisticReportActions: JSON.stringify({
[reportID]: optimisticReportActionID,
}),
} satisfies ReportExportParams;

API.write(WRITE_COMMANDS.REPORT_EXPORT, params, {optimisticData, failureData});
}

function markAsManuallyExported(reportID: string) {
API.write(WRITE_COMMANDS.MARK_AS_EXPORTED, {
reportIDList: reportID,
function markAsManuallyExported(reportID: string, connectionName: ConnectionName) {
const action = ReportUtils.buildOptimisticExportIntegrationAction(connectionName, true);
const label = CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connectionName];
const optimisticReportActionID = action.reportActionID;

const optimisticData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`,
value: {
[optimisticReportActionID]: action,
},
},
];

const successData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`,
value: {
[optimisticReportActionID]: {
pendingAction: null,
},
},
},
];

const failureData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`,
value: {
[optimisticReportActionID]: {
errors: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'),
},
},
},
];

const params = {
markedManually: true,
});
data: JSON.stringify([
{
reportID,
label,
optimisticReportActionID,
},
]),
} satisfies MarkAsExportedParams;
Copy link
Contributor

Choose a reason for hiding this comment

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

We also need to change the shape of MarkAsExported params:

const params = {
    markedManually: true,
    data: JSON.stringify([
        {
            reportID: Number(reportID),
            label,
            optimisticReportActionID
        }
    ])
} satisfies MarkAsExportedParams;

data should be a stringified array of the export data we need


API.write(WRITE_COMMANDS.MARK_AS_EXPORTED, params, {optimisticData, successData, failureData});
}

export {
Expand Down
2 changes: 1 addition & 1 deletion src/pages/home/report/ReportDetailsExportPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ function ReportDetailsExportPage({route}: ReportDetailsExportPageProps) {
if (type === CONST.REPORT.EXPORT_OPTIONS.EXPORT_TO_INTEGRATION) {
ReportActions.exportToIntegration(reportID, connectionName);
} else if (type === CONST.REPORT.EXPORT_OPTIONS.MARK_AS_EXPORTED) {
ReportActions.markAsManuallyExported(reportID);
ReportActions.markAsManuallyExported(reportID, connectionName);
}
setModalStatus(null);
Navigation.dismissModal();
Expand Down
Loading