Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
130 commits
Select commit Hold shift + click to select a range
3f28b78
initial bulk edit multiple
waterim Nov 28, 2025
4f6e4c8
Merge remote-tracking branch 'upstream/main' into feat/waterim/bulk-e…
waterim Dec 3, 2025
5a36aff
updates
waterim Dec 4, 2025
532f8f7
fix prettier
waterim Dec 4, 2025
e7cc5b2
fixes
waterim Dec 4, 2025
b4dfea3
fix linters and adjustments
waterim Dec 4, 2025
059d210
Merge remote-tracking branch 'upstream/main' into feat/waterim/bulk-e…
waterim Dec 8, 2025
400c269
Merge remote-tracking branch 'upstream/main' into feat/waterim/bulk-e…
waterim Dec 9, 2025
8db293b
adjustments
waterim Dec 9, 2025
9c42ad3
linter fixes
waterim Dec 10, 2025
e1031a9
Merge remote-tracking branch 'upstream/main' into feat/waterim/bulk-e…
waterim Dec 11, 2025
4af4a21
updates
waterim Dec 11, 2025
eeb0d8d
fix params
waterim Dec 11, 2025
71aae05
Merge remote-tracking branch 'upstream/main' into feat/waterim/bulk-e…
waterim Dec 15, 2025
a234c09
fix merge conflict
waterim Dec 15, 2025
eee7036
add tax page
waterim Dec 15, 2025
70044ea
add reimbursable and billable
waterim Dec 15, 2025
28f0f15
add filtering
waterim Dec 15, 2025
1c14776
fil linter and ts
waterim Dec 15, 2025
06a7fbf
Merge remote-tracking branch 'upstream/main' into feat/waterim/bulk-e…
waterim Dec 15, 2025
5c7073f
fix linter
waterim Dec 15, 2025
641ea3e
Merge remote-tracking branch 'upstream/main' into feat/waterim/bulk-e…
waterim Dec 16, 2025
75ccd4c
feedback
waterim Dec 18, 2025
62555c8
resolve early return
waterim Dec 18, 2025
f4d6729
remove useCallback fromAmountPage
waterim Dec 18, 2025
4812faa
remove useCallback/useMemo
waterim Dec 18, 2025
b782db3
move getPolicyID to reusable function
waterim Dec 18, 2025
8fd8205
update translation
waterim Dec 18, 2025
1fa0169
fix linter
waterim Dec 18, 2025
c593517
fix linter
waterim Dec 18, 2025
56ad0c6
update canEditMultipleTransactions to be pure
waterim Dec 22, 2025
a4b51b8
update behaviour for unit expenses + filtering
waterim Dec 22, 2025
014bc49
Merge remote-tracking branch 'upstream/main' into feat/waterim/bulk-e…
waterim Jan 5, 2026
9e0ec07
update naming
waterim Jan 5, 2026
19371fe
update namings
waterim Jan 5, 2026
6984014
update to hasCustomUnitTransaction
waterim Jan 5, 2026
a053eae
update state_num
waterim Jan 5, 2026
7224c5b
update saveCategory
waterim Jan 5, 2026
6e3931b
update canEditField checks
waterim Jan 5, 2026
d4c1cc8
fix ts
waterim Jan 5, 2026
e4a7161
fix checks
waterim Jan 5, 2026
64f4198
add additional checks to the fields
waterim Jan 5, 2026
c3c8545
fix linter
waterim Jan 5, 2026
16fe572
fix linter
waterim Jan 5, 2026
f2be983
Merge remote-tracking branch 'upstream/main' into feat/waterim/bulk-e…
waterim Jan 7, 2026
cd10f47
Merge remote-tracking branch 'upstream/main' into feat/waterim/bulk-e…
waterim Jan 8, 2026
48f14a2
fix the closing animation
waterim Jan 8, 2026
4674997
Revert "fix the closing animation"
waterim Jan 8, 2026
784d955
Merge remote-tracking branch 'upstream/main' into feat/waterim/bulk-e…
waterim Jan 8, 2026
54e216f
fix warning
waterim Jan 8, 2026
727bccd
fix color and translate
waterim Jan 8, 2026
6f38d61
fix possible loop issue
waterim Jan 8, 2026
b620bd6
fix currency issue
waterim Jan 8, 2026
90b6144
fix autofocus
waterim Jan 8, 2026
306bde6
update policyID getting
waterim Jan 9, 2026
d93cfec
fix compiler
waterim Jan 9, 2026
7db0610
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Jan 16, 2026
e4f4ec0
Enhance SearchEditMultiplePage functionality by adding support for ca…
pasyukevich Jan 16, 2026
dd69106
Update SearchEditMultiplePage to hide currency handling and update re…
pasyukevich Jan 16, 2026
ecdde46
Refactor SearchEditMultiplePage to use convertToDisplayStringWithoutC…
pasyukevich Jan 16, 2026
ba27876
add tests
pasyukevich Jan 20, 2026
c2d713d
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Jan 20, 2026
2aebdf6
fix prettier
pasyukevich Jan 20, 2026
98c0f93
Enable negative values for bulk edit
pasyukevich Jan 21, 2026
480c059
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Jan 21, 2026
432c35b
Enhance multiple transaction handling in IOU actions for offline
pasyukevich Jan 22, 2026
a02f13b
fix comments
pasyukevich Jan 22, 2026
7fb71fb
Fix close report details on submit
pasyukevich Jan 23, 2026
1232b4f
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Jan 23, 2026
744fbe2
fix issues after merge
pasyukevich Jan 23, 2026
ce9b27c
Update edit billable logic in ReportUtils and IOU actions
pasyukevich Jan 26, 2026
f8dfefe
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Jan 26, 2026
f3f0f9f
Add billable field to edit permissions in canEditFieldOfMoneyRequest …
pasyukevich Jan 26, 2026
2ccaba3
fix prettier
pasyukevich Jan 26, 2026
b56c783
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Jan 29, 2026
15a389b
Fix tax rate selected logic
pasyukevich Jan 29, 2026
2a3e327
Add function to remove unchanged fields during bulk edit in IOU trans…
pasyukevich Jan 30, 2026
307a56b
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Jan 30, 2026
9d13520
fix typecheck
pasyukevich Jan 30, 2026
c8b3136
Refactor removeUnchangedBulkEditFields to return filtered changes and…
pasyukevich Jan 30, 2026
ba1a899
Optimize removeUnchangedBulkEditFields by simplifying value compariso…
pasyukevich Feb 2, 2026
49fdcf5
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Feb 2, 2026
eebc549
Update IOU test to reflect correct amount sign for expense reports
pasyukevich Feb 2, 2026
34c9c69
Update IOU transaction billable and reimbursable flags handlings
pasyukevich Feb 2, 2026
4484e1c
Fix update for billable and reimbursable
pasyukevich Feb 2, 2026
f507d51
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Feb 2, 2026
ac0fdf0
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Feb 3, 2026
05efdf2
feat: add approval check to prevent editing of approved reports
pasyukevich Feb 3, 2026
967ec39
feat: add autoFocus to date input in SearchEditMultipleDatePage
pasyukevich Feb 3, 2026
06077e2
remove unused routes
pasyukevich Feb 3, 2026
1cea604
fix: optimistic message for amount update
pasyukevich Feb 3, 2026
fb85fa3
feat: enhance tag handling in SearchEditMultiple and related components
pasyukevich Feb 3, 2026
8a798b5
fix prettier
pasyukevich Feb 3, 2026
6e9c9dc
feat: typecheck
pasyukevich Feb 4, 2026
f2361f1
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Feb 5, 2026
1bf7bf8
Update reimbursable and billable toggles to separate screens
pasyukevich Feb 5, 2026
210a395
fix: edit multiple option is present for paid reports
pasyukevich Feb 6, 2026
8e37df7
fix: multi-level dependent tags showing on edit multiple
pasyukevich Feb 6, 2026
fd19a91
fix name
pasyukevich Feb 6, 2026
6b7179f
fix: remove redundant comments
pasyukevich Feb 6, 2026
e2ccec6
fix comments
pasyukevich Feb 6, 2026
2f16841
fix: add validation for description input, update to markdown
pasyukevich Feb 6, 2026
b95d40d
fix: remove unused shouldSubmitForm prop
pasyukevich Feb 6, 2026
779000b
fix: add billable, reimbursable, and tax rate fields to transaction e…
pasyukevich Feb 6, 2026
ba3d83c
Fix typecheck
pasyukevich Feb 6, 2026
6734799
fix prettier
pasyukevich Feb 10, 2026
bce39d9
fix prettier
pasyukevich Feb 10, 2026
91eba95
feat: add deselect on second select
pasyukevich Feb 10, 2026
0cfdd6a
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Feb 11, 2026
e3cbfa0
fix test fail after merge
pasyukevich Feb 11, 2026
64f86ac
fix typecheck
pasyukevich Feb 11, 2026
8c8bf4c
fix prettier
pasyukevich Feb 11, 2026
52877c2
fix category reset
pasyukevich Feb 11, 2026
0ade637
fix: add bulk edit to reports tab
pasyukevich Feb 11, 2026
9c9be72
fix: allow bulk update to 0
pasyukevich Feb 11, 2026
6cc356f
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Feb 12, 2026
ec88352
restore comment
pasyukevich Feb 12, 2026
58eb533
fix issues after latest main
pasyukevich Feb 12, 2026
d65b8dc
Enhance TaxPicker component to support deselection of tax rates by flag
pasyukevich Feb 12, 2026
25916c3
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Feb 12, 2026
5ad16e8
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Feb 12, 2026
b0d16c9
Fix bottom offset for amount edit
pasyukevich Feb 12, 2026
4290048
fix: address comments
pasyukevich Feb 13, 2026
555ae1f
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Feb 13, 2026
3836ceb
fix selectedTransactionIDs inconsistency
pasyukevich Feb 16, 2026
03ea56b
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Feb 16, 2026
c4cd9c7
fix export after merge
pasyukevich Feb 16, 2026
0b84d6a
fix typecheck
pasyukevich Feb 16, 2026
eb941be
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Feb 16, 2026
f3018c7
Merge branch 'main' into feat/waterim/bulk-edit-expenses
pasyukevich Feb 17, 2026
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: 4 additions & 0 deletions src/CONST/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3029,6 +3029,8 @@ const CONST = {
QUANTITY_MAX_LENGTH: 12,
// This is the transactionID used when going through the create expense flow so that it mimics a real transaction (like the edit flow)
OPTIMISTIC_TRANSACTION_ID: '1',
// This is the transactionID used when bulk editing multiple expenses
OPTIMISTIC_BULK_EDIT_TRANSACTION_ID: 'optimisticBulkEditTransactionID',
// Note: These payment types are used when building IOU reportAction message values in the server and should
// not be changed.
LOCATION_PERMISSION_PROMPT_THRESHOLD_DAYS: 7,
Expand Down Expand Up @@ -4241,6 +4243,7 @@ const CONST = {
TAX_RATE: 'taxRate',
TAX_AMOUNT: 'taxAmount',
REIMBURSABLE: 'reimbursable',
BILLABLE: 'billable',
REPORT: 'report',
},
FOOTER: {
Expand Down Expand Up @@ -7015,6 +7018,7 @@ const CONST = {
TAG: 'tag',
},
BULK_ACTION_TYPES: {
EDIT: 'edit',
EXPORT: 'export',
APPROVE: 'approve',
PAY: 'pay',
Expand Down
9 changes: 9 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,12 @@ const ONYXKEYS = {
WORKSPACE_PER_DIEM_FORM_DRAFT: 'workspacePerDiemFormDraft',
ENABLE_GLOBAL_REIMBURSEMENTS: 'enableGlobalReimbursementsForm',
ENABLE_GLOBAL_REIMBURSEMENTS_DRAFT: 'enableGlobalReimbursementsFormDraft',
SEARCH_EDIT_MULTIPLE_DESCRIPTION_FORM: 'searchEditMultipleDescriptionForm',
SEARCH_EDIT_MULTIPLE_DESCRIPTION_FORM_DRAFT: 'searchEditMultipleDescriptionFormDraft',
SEARCH_EDIT_MULTIPLE_MERCHANT_FORM: 'searchEditMultipleMerchantForm',
SEARCH_EDIT_MULTIPLE_MERCHANT_FORM_DRAFT: 'searchEditMultipleMerchantFormDraft',
SEARCH_EDIT_MULTIPLE_DATE_FORM: 'searchEditMultipleDateForm',
SEARCH_EDIT_MULTIPLE_DATE_FORM_DRAFT: 'searchEditMultipleDateFormDraft',
CREATE_DOMAIN_FORM: 'createDomainForm',
CREATE_DOMAIN_FORM_DRAFT: 'createDomainFormDraft',
SPLIT_EXPENSE_EDIT_DATES: 'splitExpenseEditDates',
Expand Down Expand Up @@ -1141,6 +1147,9 @@ type OnyxFormValuesMapping = {
[ONYXKEYS.FORMS.INTERNATIONAL_BANK_ACCOUNT_FORM]: FormTypes.InternationalBankAccountForm;
[ONYXKEYS.FORMS.WORKSPACE_PER_DIEM_FORM]: FormTypes.WorkspacePerDiemForm;
[ONYXKEYS.FORMS.ENABLE_GLOBAL_REIMBURSEMENTS]: FormTypes.EnableGlobalReimbursementsForm;
[ONYXKEYS.FORMS.SEARCH_EDIT_MULTIPLE_DESCRIPTION_FORM]: FormTypes.SearchEditMultipleDescriptionForm;
[ONYXKEYS.FORMS.SEARCH_EDIT_MULTIPLE_MERCHANT_FORM]: FormTypes.SearchEditMultipleMerchantForm;
[ONYXKEYS.FORMS.SEARCH_EDIT_MULTIPLE_DATE_FORM]: FormTypes.SearchEditMultipleDateForm;
[ONYXKEYS.FORMS.CREATE_DOMAIN_FORM]: FormTypes.CreateDomainForm;
[ONYXKEYS.FORMS.SPLIT_EXPENSE_EDIT_DATES]: FormTypes.SplitExpenseEditDateForm;
[ONYXKEYS.FORMS.EXPENSE_RULE_FORM]: FormTypes.ExpenseRuleForm;
Expand Down
13 changes: 13 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,19 @@ const ROUTES = {
},
},
SEARCH_REJECT_REASON_RHP: 'search/reject',
SEARCH_EDIT_MULTIPLE_TRANSACTIONS_RHP: 'search/edit-multiple-transactions',
SEARCH_EDIT_MULTIPLE_AMOUNT_RHP: 'search/edit-multiple/amount',
SEARCH_EDIT_MULTIPLE_DESCRIPTION_RHP: 'search/edit-multiple/description',
SEARCH_EDIT_MULTIPLE_MERCHANT_RHP: 'search/edit-multiple/merchant',
SEARCH_EDIT_MULTIPLE_DATE_RHP: 'search/edit-multiple/date',
SEARCH_EDIT_MULTIPLE_CATEGORY_RHP: 'search/edit-multiple/category',
SEARCH_EDIT_MULTIPLE_TAG_RHP: {
route: 'search/edit-multiple/tag/:tagListIndex',
getRoute: (tagListIndex = 0) => `search/edit-multiple/tag/${tagListIndex}` as const,
},
SEARCH_EDIT_MULTIPLE_BILLABLE_RHP: 'search/edit-multiple/billable',
SEARCH_EDIT_MULTIPLE_REIMBURSABLE_RHP: 'search/edit-multiple/reimbursable',
SEARCH_EDIT_MULTIPLE_TAX_RHP: 'search/edit-multiple/tax',
MOVE_TRANSACTIONS_SEARCH_RHP: {
route: 'search/move-transactions/search/:backTo?',
getRoute: (backTo?: string) => {
Expand Down
10 changes: 10 additions & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,16 @@ const SCREENS = {
TRANSACTION_HOLD_REASON_RHP: 'Search_Transaction_Hold_Reason_RHP',
TRANSACTION_HOLD_REASON_SEARCH: 'Search_Transaction_Hold_Reason_Search',
SEARCH_REJECT_REASON_RHP: 'Search_Reject_Reason_RHP',
EDIT_MULTIPLE_TRANSACTIONS_RHP: 'Search_Edit_Multiple_Transactions_RHP',
EDIT_MULTIPLE_AMOUNT_RHP: 'Search_Edit_Multiple_Amount_RHP',
EDIT_MULTIPLE_DESCRIPTION_RHP: 'Search_Edit_Multiple_Description_RHP',
EDIT_MULTIPLE_MERCHANT_RHP: 'Search_Edit_Multiple_Merchant_RHP',
EDIT_MULTIPLE_DATE_RHP: 'Search_Edit_Multiple_Date_RHP',
EDIT_MULTIPLE_CATEGORY_RHP: 'Search_Edit_Multiple_Category_RHP',
EDIT_MULTIPLE_TAG_RHP: 'Search_Edit_Multiple_Tag_RHP',
EDIT_MULTIPLE_BILLABLE_RHP: 'Search_Edit_Multiple_Billable_RHP',
EDIT_MULTIPLE_REIMBURSABLE_RHP: 'Search_Edit_Multiple_Reimbursable_RHP',
EDIT_MULTIPLE_TAX_RHP: 'Search_Edit_Multiple_Tax_RHP',
TRANSACTIONS_CHANGE_REPORT_SEARCH_RHP: 'Search_Transactions_Change_Report_Search',
},
SETTINGS: {
Expand Down
28 changes: 2 additions & 26 deletions src/components/ReportActionItem/MoneyRequestView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ import {
isTrackExpenseReportNew,
shouldEnableNegative,
} from '@libs/ReportUtils';
import {hasEnabledTags} from '@libs/TagsOptionsListUtils';
import {hasEnabledTags, shouldShowDependentTagList} from '@libs/TagsOptionsListUtils';
import {
getBillable,
getCurrency,
Expand All @@ -84,7 +84,6 @@ import {
getOriginalAmountForDisplay,
getOriginalTransactionWithSplitInfo,
getReimbursable,
getTagArrayFromName,
getTagForDisplay,
getTaxName,
hasMissingSmartscanFields,
Expand Down Expand Up @@ -707,30 +706,7 @@ function MoneyRequestView({
const tagForDisplay = getTagForDisplay(updatedTransaction ?? transaction, index);
let shouldShow = false;
if (hasDependentTags) {
if (index === 0) {
shouldShow = true;
} else {
const prevTagValue = getTagForDisplay(transaction, index - 1);
if (!prevTagValue) {
shouldShow = false;
} else {
const parentTag = getTagArrayFromName(transactionTag ?? '')
.slice(0, index)
.join(':');

const availableTags = Object.values(tags).filter((policyTag) => {
const filterRegex = policyTag.rules?.parentTagsFilter;
if (!filterRegex) {
return true;
}

const regex = new RegExp(filterRegex);
return regex.test(parentTag ?? '');
});

shouldShow = availableTags.some((tag) => tag.enabled);
}
}
shouldShow = shouldShowDependentTagList(index, transactionTag, tags);
} else {
shouldShow = !!tagForDisplay || (canEdit && hasEnabledOptions(tags));
}
Expand Down
21 changes: 19 additions & 2 deletions src/components/TaxPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,25 @@ type TaxPickerProps = {
* If enabled, the content will have a bottom padding equal to account for the safe bottom area inset.
*/
addBottomSafeAreaPadding?: boolean;

/**
* If enabled, allows deselecting the currently selected tax rate by tapping it again.
* When disabled (default), tapping the selected tax rate will dismiss the picker without calling onSubmit.
*/
allowDeselect?: boolean;
};

function TaxPicker({selectedTaxRate = '', policyID, transactionID, onSubmit, action, iouType, onDismiss = Navigation.goBack, addBottomSafeAreaPadding}: TaxPickerProps) {
function TaxPicker({
selectedTaxRate = '',
policyID,
transactionID,
onSubmit,
action,
iouType,
onDismiss = Navigation.goBack,
addBottomSafeAreaPadding,
allowDeselect = false,
}: TaxPickerProps) {
const {translate, localeCompare} = useLocalize();
const [searchValue, setSearchValue] = useState('');
const [splitDraftTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT}${transactionID}`, {canBeMissing: true});
Expand Down Expand Up @@ -89,7 +105,8 @@ function TaxPicker({selectedTaxRate = '', policyID, transactionID, onSubmit, act
const selectedOptionKey = sections?.at(0)?.data?.find((taxRate) => taxRate.searchText === selectedTaxRate)?.keyForList;

const handleSelectRow = (newSelectedOption: TaxRatesOption) => {
if (selectedOptionKey === newSelectedOption.keyForList) {
// If deselection is not allowed and the same option is selected, just dismiss
if (!allowDeselect && selectedOptionKey === newSelectedOption.keyForList) {
onDismiss();
return;
}
Expand Down
33 changes: 32 additions & 1 deletion src/hooks/useSelectedTransactionsActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type {DropdownOption} from '@components/ButtonWithDropdownMenu/types';
import {useDelegateNoAccessActions, useDelegateNoAccessState} from '@components/DelegateNoAccessModalProvider';
import type {PopoverMenuItem} from '@components/PopoverMenu';
import {useSearchContext} from '@components/Search/SearchContext';
import {initBulkEditDraftTransaction} from '@libs/actions/IOU';
import {unholdRequest} from '@libs/actions/IOU/Hold';
import {initSplitExpense} from '@libs/actions/IOU/Split';
import {setupMergeTransactionDataAndNavigate} from '@libs/actions/MergeTransaction';
Expand All @@ -16,6 +17,7 @@ import {
canDeleteCardTransactionByLiabilityType,
canDeleteTransaction,
canEditFieldOfMoneyRequest,
canEditMultipleTransactions,
canHoldUnholdReportAction,
canRejectReportAction,
canUserPerformWriteAction as canUserPerformWriteActionReportUtils,
Expand Down Expand Up @@ -76,13 +78,27 @@ function useSelectedTransactionsActions({
const {selectedTransactionIDs, clearSelectedTransactions, currentSearchHash, selectedTransactions: selectedTransactionsMeta} = useSearchContext();
const allTransactions = useAllTransactions();
const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT, {canBeMissing: false});
const [allReportActions] = useOnyx(ONYXKEYS.COLLECTION.REPORT_ACTIONS, {canBeMissing: false});
const [allPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: false});
const [outstandingReportsByPolicyID] = useOnyx(ONYXKEYS.DERIVED.OUTSTANDING_REPORTS_BY_POLICY_ID, {canBeMissing: true});
const [lastVisitedPath] = useOnyx(ONYXKEYS.LAST_VISITED_PATH, {canBeMissing: true});
const [integrationsExportTemplates] = useOnyx(ONYXKEYS.NVP_INTEGRATION_SERVER_EXPORT_TEMPLATES, {canBeMissing: true});
const [csvExportLayouts] = useOnyx(ONYXKEYS.NVP_CSV_EXPORT_LAYOUTS, {canBeMissing: true});
const [allTransactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, {canBeMissing: true});

const expensifyIcons = useMemoizedLazyExpensifyIcons(['Stopwatch', 'Trashcan', 'ArrowRight', 'Table', 'DocumentMerge', 'Export', 'ArrowCollapse', 'ArrowSplit', 'ThumbsDown']);
const expensifyIcons = useMemoizedLazyExpensifyIcons([
'Stopwatch',
'Trashcan',
'ArrowRight',
'Table',
'DocumentMerge',
'Export',
'ArrowCollapse',
'ArrowSplit',
'ThumbsDown',
'Pencil',
] as const);

const {duplicateTransactions, duplicateTransactionViolations} = useDuplicateTransactionsAndViolations(selectedTransactionIDs);
const isReportArchived = useReportIsArchived(report?.reportID);
const {deleteTransactions} = useDeleteTransactions({report, reportActions, policy});
Expand Down Expand Up @@ -184,6 +200,20 @@ function useSelectedTransactionsActions({
let computedOptions: Array<DropdownOption<string>> = [];
if (selectedTransactionIDs.length) {
const options = [];

const canEditMultiple = canEditMultipleTransactions(selectedTransactionsList, allReportActions, allReports, allPolicies);

if (canEditMultiple) {
options.push({
text: translate('search.bulkActions.editMultiple'),
icon: expensifyIcons.Pencil,
value: CONST.SEARCH.BULK_ACTION_TYPES.EDIT,
onSelected: () => {
initBulkEditDraftTransaction(selectedTransactionIDs);
Navigation.navigate(ROUTES.SEARCH_EDIT_MULTIPLE_TRANSACTIONS_RHP);
},
});
}
const isMoneyRequestReport = isMoneyRequestReportUtils(report);
const isReportReimbursed = report?.stateNum === CONST.REPORT.STATE_NUM.APPROVED && report?.statusNum === CONST.REPORT.STATUS_NUM.REIMBURSED;

Expand Down Expand Up @@ -395,6 +425,7 @@ function useSelectedTransactionsActions({
onSelected: showDeleteModal,
});
}

computedOptions = options;
}

Expand Down
3 changes: 3 additions & 0 deletions src/languages/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7131,6 +7131,9 @@ Fordern Sie Spesendetails wie Belege und Beschreibungen an, legen Sie Limits und
topMerchants: 'Top-Händler',
groupedExpenses: 'gruppierte Ausgaben',
bulkActions: {
editMultiple: 'Mehrere bearbeiten',
editMultipleTitle: 'Mehrere Ausgaben bearbeiten',
editMultipleDescription: 'Änderungen werden für alle ausgewählten Ausgaben festgelegt und überschreiben alle zuvor festgelegten Werte.',
approve: 'Genehmigen',
pay: 'Bezahlen',
delete: 'Löschen',
Expand Down
4 changes: 4 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7076,6 +7076,10 @@ const translations = {
spendOverTime: 'Spend over time',
groupedExpenses: 'grouped expenses',
bulkActions: {
editMultiple: 'Edit multiple',
editMultipleTitle: 'Edit multiple expenses',
// cspell:disable
editMultipleDescription: "Changes will be set for all selected expenses and will override any previously set values. Just sayin'.",
approve: 'Approve',
pay: 'Pay',
delete: 'Delete',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6894,6 +6894,9 @@ ${amount} para ${merchant} - ${date}`,
deleteSavedSearchConfirm: '¿Estás seguro de que quieres eliminar esta búsqueda?',
groupedExpenses: 'gastos agrupados',
bulkActions: {
editMultiple: 'Editar múltiples',
editMultipleTitle: 'Editar múltiples gastos',
editMultipleDescription: 'Los cambios se aplicarán a todos los gastos seleccionados y anularán cualquier valor previamente establecido.',
approve: 'Aprobar',
pay: 'Pagar',
delete: 'Eliminar',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7155,6 +7155,9 @@ Rendez obligatoires des informations de dépense comme les reçus et les descrip
topMerchants: 'Commerçants principaux',
groupedExpenses: 'dépenses groupées',
bulkActions: {
editMultiple: 'Modifier plusieurs',
editMultipleTitle: 'Modifier plusieurs dépenses',
editMultipleDescription: 'Les modifications seront appliquées à toutes les dépenses sélectionnées et remplaceront toutes les valeurs précédemment définies.',
approve: 'Approuver',
pay: 'Payer',
delete: 'Supprimer',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7117,6 +7117,9 @@ Richiedi dettagli sulle spese come ricevute e descrizioni, imposta limiti e valo
topMerchants: 'Commercianti principali',
groupedExpenses: 'spese raggruppate',
bulkActions: {
editMultiple: 'Modifica multipli',
editMultipleTitle: 'Modifica più spese',
editMultipleDescription: 'Le modifiche verranno applicate a tutte le spese selezionate e sostituiranno i valori precedentemente impostati.',
approve: 'Approva',
pay: 'Paga',
delete: 'Elimina',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7047,6 +7047,9 @@ ${reportName}
topMerchants: '上位加盟店',
groupedExpenses: 'グループ化された経費',
bulkActions: {
editMultiple: '複数を編集',
editMultipleTitle: '複数の経費を編集',
editMultipleDescription: '変更は選択したすべての経費に適用され、以前に設定された値は上書きされます。',
approve: '承認',
pay: '支払う',
delete: '削除',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/nl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7102,6 +7102,9 @@ Vereis onkostendetails zoals bonnen en beschrijvingen, stel limieten en standaar
topMerchants: 'Topverkopers',
groupedExpenses: 'gegroepeerde uitgaven',
bulkActions: {
editMultiple: 'Meerdere bewerken',
editMultipleTitle: 'Meerdere uitgaven bewerken',
editMultipleDescription: 'Wijzigingen worden toegepast op alle geselecteerde uitgaven en overschrijven eerder ingestelde waarden.',
approve: 'Goedkeuren',
pay: 'Betalen',
delete: 'Verwijderen',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7085,6 +7085,9 @@ Wymagaj szczegółów wydatków, takich jak paragony i opisy, ustawiaj limity i
topMerchants: 'Najlepsi sprzedawcy',
groupedExpenses: 'zgrupowane wydatki',
bulkActions: {
editMultiple: 'Edytuj wiele',
editMultipleTitle: 'Edytuj wiele wydatków',
editMultipleDescription: 'Zmiany zostaną zastosowane do wszystkich wybranych wydatków i zastąpią wcześniej ustawione wartości.',
approve: 'Zatwierdź',
pay: 'Zapłać',
delete: 'Usuń',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/pt-BR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7087,6 +7087,9 @@ Exija dados de despesas como recibos e descrições, defina limites e padrões e
topMerchants: 'Principais comerciantes',
groupedExpenses: 'despesas agrupadas',
bulkActions: {
editMultiple: 'Editar múltiplos',
editMultipleTitle: 'Editar múltiplas despesas',
editMultipleDescription: 'As alterações serão aplicadas a todas as despesas selecionadas e substituirão quaisquer valores definidos anteriormente.',
approve: 'Aprovar',
pay: 'Pagar',
delete: 'Excluir',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/zh-hans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6947,6 +6947,9 @@ ${reportName}
topMerchants: '热门商家',
groupedExpenses: '已分组的报销费用',
bulkActions: {
editMultiple: '批量编辑',
editMultipleTitle: '编辑多个费用',
editMultipleDescription: '更改将应用于所有选定的费用,并将覆盖之前设置的任何值。',
approve: '批准',
pay: '支付',
delete: '删除',
Expand Down
2 changes: 2 additions & 0 deletions src/libs/API/parameters/UpdateMoneyRequestParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ type UpdateMoneyRequestParams = Partial<TransactionDetails> & {
reportID?: string;
transactionID?: string;
reportActionID?: string;
/** Used for bulk updates - JSON stringified object containing only changed fields */
updates?: string;
};

export default UpdateMoneyRequestParams;
2 changes: 2 additions & 0 deletions src/libs/API/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ const WRITE_COMMANDS = {
DELETE_REPORT_FIELD: 'RemoveReportField',
SET_REPORT_NAME: 'RenameReport',
COMPLETE_SPLIT_BILL: 'CompleteSplitBill',
UPDATE_MONEY_REQUEST: 'UpdateMoneyRequest',
UPDATE_MONEY_REQUEST_ATTENDEES: 'UpdateMoneyRequestAttendees',
UPDATE_MONEY_REQUEST_DATE: 'UpdateMoneyRequestDate',
UPDATE_MONEY_REQUEST_REIMBURSABLE: 'UpdateMoneyRequestReimbursable',
Expand Down Expand Up @@ -748,6 +749,7 @@ type WriteCommandParameters = {
[WRITE_COMMANDS.SET_REPORT_NAME]: Parameters.SetReportNameParams;
[WRITE_COMMANDS.DELETE_REPORT_FIELD]: Parameters.DeleteReportFieldParams;
[WRITE_COMMANDS.COMPLETE_SPLIT_BILL]: Parameters.CompleteSplitBillParams;
[WRITE_COMMANDS.UPDATE_MONEY_REQUEST]: Parameters.UpdateMoneyRequestParams;
[WRITE_COMMANDS.UPDATE_MONEY_REQUEST_ATTENDEES]: Parameters.UpdateMoneyRequestParams;
[WRITE_COMMANDS.UPDATE_MONEY_REQUEST_DATE]: Parameters.UpdateMoneyRequestParams;
[WRITE_COMMANDS.UPDATE_MONEY_REQUEST_MERCHANT]: Parameters.UpdateMoneyRequestParams;
Expand Down
Loading
Loading