Skip to content

Commit

Permalink
resolve conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
luacmartins committed Dec 11, 2023
2 parents 2840684 + e1d334a commit 0ab005f
Show file tree
Hide file tree
Showing 13 changed files with 79 additions and 45 deletions.
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1001041103
versionName "1.4.11-3"
versionCode 1001041106
versionName "1.4.11-6"
}

flavorDimensions "default"
Expand Down
36 changes: 33 additions & 3 deletions docs/articles/new-expensify/get-paid-back/Request-Money.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
---
title: Request Money
description: Request Money
title: Request Money and Split Bills with Friends
description: Everything you need to know about Requesting Money and Splitting Bills with Friends!
redirect_from: articles/request-money/Request-and-Split-Bills/
---
## Resource Coming Soon!

<!-- The lines above are required by Jekyll to process the .md file -->

# How do these Payment Features work?
Our suite of money movement features enables you to request money owed by an individual or split a bill with a group.

**Request Money** lets your friends pay you back directly in Expensify. When you send a payment request to a friend, Expensify will display the amount owed and the option to pay the corresponding request in a chat between you.

**Split Bill** allows you to split payments between friends and ensures the person who settled the tab gets paid back.

These two features ensure you can live in the moment and settle up afterward.

# How to Request Money
- Select the Green **+** button and choose **Request Money**
- Enter the amount **$** they owe and click **Next**
- Search for the user or enter their email!
- Enter a reason for the request (optional)
- Click **Request!**
- If you change your mind, all you have to do is click **Cancel**
- The user will be able to **Settle up outside of Expensify** or pay you via **Venmo** or **PayPal.me**

# How to Split a Bill
- Select the Green **+** button and choose **Split Bill**
- Enter the total amount for the bill and click **Next**
- Search for users or enter their emails and **Select**
- Enter a reason for the split
- The split is then shared equally between the attendees

# FAQs
## Can I request money from more than one person at a time?
If you need to request money for more than one person at a time, you’ll want to use the Split Bill feature. The Request Money option is for one-to-one payments between two people.
2 changes: 1 addition & 1 deletion ios/NewExpensify/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>1.4.11.3</string>
<string>1.4.11.6</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationQueriesSchemes</key>
Expand Down
2 changes: 1 addition & 1 deletion ios/NewExpensifyTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.4.11.3</string>
<string>1.4.11.6</string>
</dict>
</plist>
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "new.expensify",
"version": "1.4.11-3",
"version": "1.4.11-6",
"author": "Expensify, Inc.",
"homepage": "https://new.expensify.com",
"description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",
Expand Down
29 changes: 15 additions & 14 deletions src/components/MoneyTemporaryForRefactorRequestConfirmationList.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
receiptPath,
reportActionID,
reportID,
selectedParticipants,
selectedParticipants: pickedParticipants,
session: {accountID},
shouldShowSmartScanFields,
transaction,
Expand Down Expand Up @@ -358,7 +358,7 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
];
}, [isTypeSplit, isTypeRequest, iouType, iouAmount, receiptPath, formattedAmount, isDistanceRequestWithoutRoute, translate]);

const selectedParticipantsFiltered = useMemo(() => _.filter(selectedParticipants, (participant) => participant.selected), [selectedParticipants]);
const selectedParticipants = useMemo(() => _.filter(pickedParticipants, (participant) => participant.selected), [pickedParticipants]);
const personalDetailsOfPayee = useMemo(() => payeePersonalDetails || currentUserPersonalDetails, [payeePersonalDetails, currentUserPersonalDetails]);
const userCanModifyParticipants = useRef(!isReadOnly && canModifyParticipants && hasMultipleParticipants);
useEffect(() => {
Expand All @@ -368,9 +368,9 @@ function MoneyTemporaryForRefactorRequestConfirmationList({

const optionSelectorSections = useMemo(() => {
const sections = [];
const unselectedParticipants = _.filter(selectedParticipantsFiltered, (participant) => !participant.selected);
const unselectedParticipants = _.filter(pickedParticipants, (participant) => !participant.selected);
if (hasMultipleParticipants) {
const formattedSelectedParticipants = getParticipantsWithAmount(selectedParticipantsFiltered);
const formattedSelectedParticipants = getParticipantsWithAmount(selectedParticipants);
let formattedParticipantsList = _.union(formattedSelectedParticipants, unselectedParticipants);

if (!userCanModifyParticipants.current) {
Expand All @@ -380,7 +380,7 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
}));
}

const myIOUAmount = IOUUtils.calculateAmount(selectedParticipantsFiltered.length, iouAmount, iouCurrencyCode, true);
const myIOUAmount = IOUUtils.calculateAmount(selectedParticipants.length, iouAmount, iouCurrencyCode, true);
const formattedPayeeOption = OptionsListUtils.getIOUConfirmationOptionsFromPayeePersonalDetail(
personalDetailsOfPayee,
iouAmount > 0 ? CurrencyUtils.convertToDisplayString(myIOUAmount, iouCurrencyCode) : '',
Expand All @@ -402,7 +402,7 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
},
);
} else {
const formattedSelectedParticipants = _.map(selectedParticipantsFiltered, (participant) => ({
const formattedSelectedParticipants = _.map(selectedParticipants, (participant) => ({
...participant,
isDisabled: ReportUtils.isOptimisticPersonalDetail(participant.accountID),
}));
Expand All @@ -415,7 +415,8 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
}
return sections;
}, [
selectedParticipantsFiltered,
selectedParticipants,
pickedParticipants,
hasMultipleParticipants,
iouAmount,
iouCurrencyCode,
Expand All @@ -430,8 +431,8 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
if (!hasMultipleParticipants) {
return [];
}
return [...selectedParticipantsFiltered, OptionsListUtils.getIOUConfirmationOptionsFromPayeePersonalDetail(personalDetailsOfPayee)];
}, [selectedParticipantsFiltered, hasMultipleParticipants, personalDetailsOfPayee]);
return [...selectedParticipants, OptionsListUtils.getIOUConfirmationOptionsFromPayeePersonalDetail(personalDetailsOfPayee)];
}, [selectedParticipants, hasMultipleParticipants, personalDetailsOfPayee]);

useEffect(() => {
if (!isDistanceRequest) {
Expand Down Expand Up @@ -474,7 +475,7 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
*/
const confirm = useCallback(
(paymentMethod) => {
if (_.isEmpty(selectedParticipantsFiltered)) {
if (_.isEmpty(selectedParticipants)) {
return;
}

Expand Down Expand Up @@ -502,10 +503,10 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
}

setDidConfirm(true);
onConfirm(selectedParticipantsFiltered);
onConfirm(selectedParticipants);
}
},
[selectedParticipantsFiltered, onSendMoney, onConfirm, isEditingSplitBill, iouType, isDistanceRequest, isDistanceRequestWithoutRoute, iouCurrencyCode, iouAmount, transaction],
[selectedParticipants, onSendMoney, onConfirm, isEditingSplitBill, iouType, isDistanceRequest, isDistanceRequestWithoutRoute, iouCurrencyCode, iouAmount, transaction],
);

const footerContent = useMemo(() => {
Expand All @@ -514,7 +515,7 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
}

const shouldShowSettlementButton = iouType === CONST.IOU.TYPE.SEND;
const shouldDisableButton = selectedParticipantsFiltered.length === 0;
const shouldDisableButton = selectedParticipants.length === 0;

const button = shouldShowSettlementButton ? (
<SettlementButton
Expand Down Expand Up @@ -558,7 +559,7 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
{button}
</>
);
}, [confirm, bankAccountRoute, iouCurrencyCode, iouType, isReadOnly, policyID, selectedParticipantsFiltered, splitOrRequestOptions, translate, formError, styles.ph1, styles.mb2]);
}, [confirm, bankAccountRoute, iouCurrencyCode, iouType, isReadOnly, policyID, selectedParticipants, splitOrRequestOptions, translate, formError, styles.ph1, styles.mb2]);

const {image: receiptImage, thumbnail: receiptThumbnail} = receiptPath && receiptFilename ? ReceiptUtils.getThumbnailAndImageURIs(transaction, receiptPath, receiptFilename) : {};
return (
Expand Down
26 changes: 11 additions & 15 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1549,14 +1549,14 @@ function isWaitingForAssigneeToCompleteTask(report: OnyxEntry<Report>, parentRep
return isTaskReport(report) && isReportManager(report) && isOpenTaskReport(report, parentReportAction);
}

function isUnreadWithMention(report: OnyxEntry<Report> | OptionData): boolean {
if (!report) {
function isUnreadWithMention(reportOrOption: OnyxEntry<Report> | OptionData): boolean {
if (!reportOrOption) {
return false;
}
// lastMentionedTime and lastReadTime are both datetime strings and can be compared directly
const lastMentionedTime = report.lastMentionedTime ?? '';
const lastReadTime = report.lastReadTime ?? '';
return lastReadTime < lastMentionedTime;
const lastMentionedTime = reportOrOption.lastMentionedTime ?? '';
const lastReadTime = reportOrOption.lastReadTime ?? '';
return Boolean('isUnreadWithMention' in reportOrOption && reportOrOption.isUnreadWithMention) || lastReadTime < lastMentionedTime;
}

/**
Expand All @@ -1568,29 +1568,25 @@ function isUnreadWithMention(report: OnyxEntry<Report> | OptionData): boolean {
* @param option (report or optionItem)
* @param parentReportAction (the report action the current report is a thread of)
*/
function requiresAttentionFromCurrentUser(option: OnyxEntry<Report> | OptionData, parentReportAction: EmptyObject | OnyxEntry<ReportAction> = {}) {
if (!option) {
return false;
}

if (isArchivedRoom(option)) {
function requiresAttentionFromCurrentUser(optionOrReport: OnyxEntry<Report> | OptionData, parentReportAction: EmptyObject | OnyxEntry<ReportAction> = {}) {
if (!optionOrReport) {
return false;
}

if (isArchivedRoom(getReport(option.parentReportID))) {
if (isArchivedRoom(optionOrReport) || isArchivedRoom(getReport(optionOrReport.parentReportID))) {
return false;
}

if (Boolean('isUnreadWithMention' in option && option.isUnreadWithMention) || isUnreadWithMention(option)) {
if (isUnreadWithMention(optionOrReport)) {
return true;
}

if (isWaitingForAssigneeToCompleteTask(option, parentReportAction)) {
if (isWaitingForAssigneeToCompleteTask(optionOrReport, parentReportAction)) {
return true;
}

// Has a child report that is awaiting action (e.g. approve, pay, add bank account) from current user
if (option.hasOutstandingChildRequest) {
if (optionOrReport.hasOutstandingChildRequest) {
return true;
}

Expand Down
3 changes: 2 additions & 1 deletion src/libs/SidebarUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,8 @@ function getOrderedReportIDs(
report.iouReportAmount = ReportUtils.getMoneyRequestReimbursableTotal(report, allReports);

const isPinned = report.isPinned ?? false;
if (isPinned || ReportUtils.requiresAttentionFromCurrentUser(report)) {
const reportAction = ReportActionsUtils.getReportAction(report.parentReportID ?? '', report.parentReportActionID ?? '');
if (isPinned || ReportUtils.requiresAttentionFromCurrentUser(report, reportAction)) {
pinnedAndGBRReports.push(report);
} else if (report.hasDraft) {
draftReports.push(report);
Expand Down
2 changes: 1 addition & 1 deletion src/pages/iou/request/step/IOURequestStepConfirmation.js
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ function IOURequestStepConfirmation({
<HeaderWithBackButton
title={headerTitle}
onBackButtonPress={navigateBack}
shouldShowThreeDotsButton={requestType === CONST.IOU.REQUEST_TYPE.MANUAL}
shouldShowThreeDotsButton={requestType === CONST.IOU.REQUEST_TYPE.MANUAL && iouType === CONST.IOU.TYPE.REQUEST}
threeDotsAnchorPosition={styles.threeDotsPopoverOffsetNoCloseButton(windowWidth)}
threeDotsMenuItems={[
{
Expand Down
4 changes: 3 additions & 1 deletion src/pages/iou/request/step/IOURequestStepScan/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ import PressableWithFeedback from '@components/Pressable/PressableWithFeedback';
import useLocalize from '@hooks/useLocalize';
import useWindowDimensions from '@hooks/useWindowDimensions';
import * as Browser from '@libs/Browser';
import compose from '@libs/compose';
import * as FileUtils from '@libs/fileDownload/FileUtils';
import Navigation from '@libs/Navigation/Navigation';
import ReceiptDropUI from '@pages/iou/ReceiptDropUI';
import IOURequestStepRoutePropTypes from '@pages/iou/request/step/IOURequestStepRoutePropTypes';
import StepScreenDragAndDropWrapper from '@pages/iou/request/step/StepScreenDragAndDropWrapper';
import withFullTransactionOrNotFound from '@pages/iou/request/step/withFullTransactionOrNotFound';
import withWritableReportOrNotFound from '@pages/iou/request/step/withWritableReportOrNotFound';
import reportPropTypes from '@pages/reportPropTypes';
import useTheme from '@styles/themes/useTheme';
Expand Down Expand Up @@ -341,4 +343,4 @@ IOURequestStepScan.defaultProps = defaultProps;
IOURequestStepScan.propTypes = propTypes;
IOURequestStepScan.displayName = 'IOURequestStepScan';

export default withWritableReportOrNotFound(IOURequestStepScan);
export default compose(withWritableReportOrNotFound, withFullTransactionOrNotFound)(IOURequestStepScan);
9 changes: 6 additions & 3 deletions src/pages/iou/request/step/IOURequestStepScan/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ import Icon from '@components/Icon';
import * as Expensicons from '@components/Icon/Expensicons';
import PressableWithFeedback from '@components/Pressable/PressableWithFeedback';
import useLocalize from '@hooks/useLocalize';
import compose from '@libs/compose';
import * as FileUtils from '@libs/fileDownload/FileUtils';
import Log from '@libs/Log';
import Navigation from '@libs/Navigation/Navigation';
import IOURequestStepRoutePropTypes from '@pages/iou/request/step/IOURequestStepRoutePropTypes';
import StepScreenWrapper from '@pages/iou/request/step/StepScreenWrapper';
import withFullTransactionOrNotFound from '@pages/iou/request/step/withFullTransactionOrNotFound';
import withWritableReportOrNotFound from '@pages/iou/request/step/withWritableReportOrNotFound';
import reportPropTypes from '@pages/reportPropTypes';
import useTheme from '@styles/themes/useTheme';
import useThemeStyles from '@styles/useThemeStyles';
Expand All @@ -41,7 +44,7 @@ const defaultProps = {
function IOURequestStepScan({
report,
route: {
params: {iouType, reportID, transactionID, pageIndex, backTo},
params: {iouType, reportID, transactionID, backTo},
},
}) {
const theme = useTheme();
Expand Down Expand Up @@ -217,7 +220,7 @@ function IOURequestStepScan({
style={[styles.cameraView]}
zoom={device.neutralZoom}
photo
cameraTabIndex={pageIndex}
cameraTabIndex={1}
/>
)}
<View style={[styles.flexRow, styles.justifyContentAround, styles.alignItemsCenter, styles.pv3]}>
Expand Down Expand Up @@ -300,4 +303,4 @@ IOURequestStepScan.defaultProps = defaultProps;
IOURequestStepScan.propTypes = propTypes;
IOURequestStepScan.displayName = 'IOURequestStepScan';

export default IOURequestStepScan;
export default compose(withWritableReportOrNotFound, withFullTransactionOrNotFound)(IOURequestStepScan);
1 change: 1 addition & 0 deletions tests/unit/ReportUtilsTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ describe('ReportUtils', () => {
...LHNTestUtils.getFakeReport(),
type: CONST.REPORT.TYPE.TASK,
managerID: currentUserAccountID,
isUnreadWithMention: false,
stateNum: CONST.REPORT.STATE_NUM.OPEN,
statusNum: CONST.REPORT.STATUS.OPEN,
};
Expand Down

0 comments on commit 0ab005f

Please sign in to comment.