Skip to content

Commit

Permalink
Merge pull request #31647 from rezkiy37/feature/31631-tags-in-split-b…
Browse files Browse the repository at this point in the history
…ills

Allow Adding/Viewing tag on a Split Bill
  • Loading branch information
puneetlath authored Dec 1, 2023
2 parents 3208c62 + 83451a8 commit fc86789
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 65 deletions.
2 changes: 1 addition & 1 deletion src/components/MoneyRequestConfirmationList.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ function MoneyRequestConfirmationList(props) {
const policyTagList = lodashGet(policyTag, 'tags', {});
const policyTagListName = lodashGet(policyTag, 'name', translate('common.tag'));
// A flag for showing the tags field
const shouldShowTags = props.isPolicyExpenseChat && OptionsListUtils.hasEnabledOptions(_.values(policyTagList));
const shouldShowTags = props.isPolicyExpenseChat && (props.iouTag || OptionsListUtils.hasEnabledOptions(_.values(policyTagList)));

// A flag for showing the billable field
const shouldShowBillable = !lodashGet(props.policy, 'disabledFields.defaultBillable', true);
Expand Down
2 changes: 1 addition & 1 deletion src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ function isUserCreatedPolicyRoom(report: OnyxEntry<Report>): boolean {
* Whether the provided report is a Policy Expense chat.
*/
function isPolicyExpenseChat(report: OnyxEntry<Report>): boolean {
return getChatType(report) === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT;
return getChatType(report) === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT || (report?.isPolicyExpenseChat ?? false);
}

/** Wether the provided report belongs to a Control policy and is an epxense chat
Expand Down
83 changes: 20 additions & 63 deletions src/libs/actions/IOU.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,34 +63,6 @@ Onyx.connect({
},
});

let allRecentlyUsedTags = {};
Onyx.connect({
key: ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS,
waitForCollectionCallback: true,
callback: (value) => {
if (!value) {
allRecentlyUsedTags = {};
return;
}

allRecentlyUsedTags = value;
},
});

let allPolicyTags = {};
Onyx.connect({
key: ONYXKEYS.COLLECTION.POLICY_TAGS,
waitForCollectionCallback: true,
callback: (value) => {
if (!value) {
allPolicyTags = {};
return;
}

allPolicyTags = value;
},
});

let userAccountID = '';
let currentUserEmail = '';
Onyx.connect({
Expand Down Expand Up @@ -508,21 +480,9 @@ function getMoneyRequestInformation(
billable,
);

let optimisticPolicyRecentlyUsedCategories = [];
if (category) {
optimisticPolicyRecentlyUsedCategories = Policy.buildOptimisticPolicyRecentlyUsedCategories(iouReport.policyID, category);
}
const optimisticPolicyRecentlyUsedCategories = Policy.buildOptimisticPolicyRecentlyUsedCategories(iouReport.policyID, category);

const optimisticPolicyRecentlyUsedTags = {};
const policyTags = allPolicyTags[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${iouReport.policyID}`];
const recentlyUsedPolicyTags = allRecentlyUsedTags[`${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS}${iouReport.policyID}`];

if (policyTags) {
// For now it only uses the first tag of the policy, since multi-tags are not yet supported
const tagListKey = _.first(_.keys(policyTags));
const uniquePolicyRecentlyUsedTags = recentlyUsedPolicyTags ? _.filter(recentlyUsedPolicyTags[tagListKey], (recentlyUsedPolicyTag) => recentlyUsedPolicyTag !== tag) : [];
optimisticPolicyRecentlyUsedTags[tagListKey] = [tag, ...uniquePolicyRecentlyUsedTags];
}
const optimisticPolicyRecentlyUsedTags = Policy.buildOptimisticPolicyRecentlyUsedTags(iouReport.policyID, tag);

// If there is an existing transaction (which is the case for distance requests), then the data from the existing transaction
// needs to be manually merged into the optimistic transaction. This is because buildOnyxDataForMoneyRequest() uses `Onyx.set()` for the transaction
Expand Down Expand Up @@ -920,11 +880,12 @@ function requestMoney(
* @param {String} comment
* @param {String} currency
* @param {String} category
* @param {String} tag
* @param {String} existingSplitChatReportID - the report ID where the split bill happens, could be a group chat or a workspace chat
*
* @return {Object}
*/
function createSplitsAndOnyxData(participants, currentUserLogin, currentUserAccountID, amount, comment, currency, category, existingSplitChatReportID = '') {
function createSplitsAndOnyxData(participants, currentUserLogin, currentUserAccountID, amount, comment, currency, category, tag, existingSplitChatReportID = '') {
const currentUserEmailForIOUSplit = OptionsListUtils.addSMSDomainIfPhoneNumber(currentUserLogin);
const participantAccountIDs = _.map(participants, (participant) => Number(participant.accountID));
const existingSplitChatReport =
Expand Down Expand Up @@ -952,6 +913,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, currentUserAcco
undefined,
undefined,
category,
tag,
);

// Note: The created action must be optimistically generated before the IOU action so there's no chance that the created action appears after the IOU action in the chat
Expand Down Expand Up @@ -1142,6 +1104,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, currentUserAcco
undefined,
undefined,
category,
tag,
);

// STEP 4: Build optimistic reportActions. We need:
Expand Down Expand Up @@ -1190,10 +1153,10 @@ function createSplitsAndOnyxData(participants, currentUserLogin, currentUserAcco
}

// Add category to optimistic policy recently used categories when a participant is a workspace
let optimisticPolicyRecentlyUsedCategories = [];
if (isPolicyExpenseChat) {
optimisticPolicyRecentlyUsedCategories = Policy.buildOptimisticPolicyRecentlyUsedCategories(participant.policyID, category);
}
const optimisticPolicyRecentlyUsedCategories = isPolicyExpenseChat ? Policy.buildOptimisticPolicyRecentlyUsedCategories(participant.policyID, category) : [];

// Add tag to optimistic policy recently used tags when a participant is a workspace
const optimisticPolicyRecentlyUsedTags = isPolicyExpenseChat ? Policy.buildOptimisticPolicyRecentlyUsedTags(participant.policyID, tag) : {};

// STEP 5: Build Onyx Data
const [oneOnOneOptimisticData, oneOnOneSuccessData, oneOnOneFailureData] = buildOnyxDataForMoneyRequest(
Expand All @@ -1206,7 +1169,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, currentUserAcco
oneOnOnePersonalDetailListAction,
oneOnOneReportPreviewAction,
optimisticPolicyRecentlyUsedCategories,
{},
optimisticPolicyRecentlyUsedTags,
isNewOneOnOneChatReport,
shouldCreateNewOneOnOneIOUReport,
);
Expand Down Expand Up @@ -1256,10 +1219,11 @@ function createSplitsAndOnyxData(participants, currentUserLogin, currentUserAcco
* @param {String} comment
* @param {String} currency
* @param {String} category
* @param {String} tag
* @param {String} existingSplitChatReportID - Either a group DM or a workspace chat
*/
function splitBill(participants, currentUserLogin, currentUserAccountID, amount, comment, currency, category, existingSplitChatReportID = '') {
const {splitData, splits, onyxData} = createSplitsAndOnyxData(participants, currentUserLogin, currentUserAccountID, amount, comment, currency, category, existingSplitChatReportID);
function splitBill(participants, currentUserLogin, currentUserAccountID, amount, comment, currency, category, tag, existingSplitChatReportID = '') {
const {splitData, splits, onyxData} = createSplitsAndOnyxData(participants, currentUserLogin, currentUserAccountID, amount, comment, currency, category, tag, existingSplitChatReportID);
API.write(
'SplitBill',
{
Expand All @@ -1269,6 +1233,7 @@ function splitBill(participants, currentUserLogin, currentUserAccountID, amount,
currency,
comment,
category,
tag,
transactionID: splitData.transactionID,
reportActionID: splitData.reportActionID,
createdReportActionID: splitData.createdReportActionID,
Expand All @@ -1290,10 +1255,10 @@ function splitBill(participants, currentUserLogin, currentUserAccountID, amount,
* @param {String} comment
* @param {String} currency
* @param {String} category
* @param {String} tag
*/
function splitBillAndOpenReport(participants, currentUserLogin, currentUserAccountID, amount, comment, currency, category) {
const {splitData, splits, onyxData} = createSplitsAndOnyxData(participants, currentUserLogin, currentUserAccountID, amount, comment, currency, category);

function splitBillAndOpenReport(participants, currentUserLogin, currentUserAccountID, amount, comment, currency, category, tag) {
const {splitData, splits, onyxData} = createSplitsAndOnyxData(participants, currentUserLogin, currentUserAccountID, amount, comment, currency, category, tag);
API.write(
'SplitBillAndOpenReport',
{
Expand All @@ -1303,6 +1268,7 @@ function splitBillAndOpenReport(participants, currentUserLogin, currentUserAccou
currency,
comment,
category,
tag,
transactionID: splitData.transactionID,
reportActionID: splitData.reportActionID,
createdReportActionID: splitData.createdReportActionID,
Expand Down Expand Up @@ -1832,16 +1798,7 @@ function editRegularMoneyRequest(transactionID, transactionThreadReportID, trans
updatedChatReport.lastMessageHtml = messageText;
}

const optimisticPolicyRecentlyUsedTags = {};
if (_.has(transactionChanges, 'tag')) {
const tagListName = transactionChanges.tagListName;
const recentlyUsedPolicyTags = allRecentlyUsedTags[`${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS}${iouReport.policyID}`];

const uniquePolicyRecentlyUsedTags = recentlyUsedPolicyTags
? _.filter(recentlyUsedPolicyTags[tagListName], (recentlyUsedPolicyTag) => recentlyUsedPolicyTag !== transactionChanges.tag)
: [];
optimisticPolicyRecentlyUsedTags[tagListName] = [transactionChanges.tag, ...uniquePolicyRecentlyUsedTags];
}
const optimisticPolicyRecentlyUsedTags = Policy.buildOptimisticPolicyRecentlyUsedTags(iouReport.policyID, transactionChanges.tag);

const isScanning = TransactionUtils.hasReceipt(updatedTransaction) && TransactionUtils.isReceiptBeingScanned(updatedTransaction);

Expand Down
43 changes: 43 additions & 0 deletions src/libs/actions/Policy.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,27 @@ Onyx.connect({
callback: (val) => (allRecentlyUsedCategories = val),
});

let allPolicyTags = {};
Onyx.connect({
key: ONYXKEYS.COLLECTION.POLICY_TAGS,
waitForCollectionCallback: true,
callback: (value) => {
if (!value) {
allPolicyTags = {};
return;
}

allPolicyTags = value;
},
});

let allRecentlyUsedTags = {};
Onyx.connect({
key: ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS,
waitForCollectionCallback: true,
callback: (val) => (allRecentlyUsedTags = val),
});

let networkStatus = {};
Onyx.connect({
key: ONYXKEYS.NETWORK,
Expand Down Expand Up @@ -1471,6 +1492,27 @@ function buildOptimisticPolicyRecentlyUsedCategories(policyID, category) {
return lodashUnion([category], policyRecentlyUsedCategories);
}

/**
* @param {String} policyID
* @param {String} tag
* @returns {Object}
*/
function buildOptimisticPolicyRecentlyUsedTags(policyID, tag) {
if (!policyID || !tag) {
return {};
}

const policyTags = lodashGet(allPolicyTags, `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`, {});
// For now it only uses the first tag of the policy, since multi-tags are not yet supported
const tagListKey = _.first(_.keys(policyTags));
const policyRecentlyUsedTags = lodashGet(allRecentlyUsedTags, `${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS}${policyID}`, {});

return {
...policyRecentlyUsedTags,
[tagListKey]: lodashUnion([tag], lodashGet(policyRecentlyUsedTags, [tagListKey], [])),
};
}

/**
* This flow is used for bottom up flow converting IOU report to an expense report. When user takes this action,
* we create a Collect type workspace when the person taking the action becomes an owner and an admin, while we
Expand Down Expand Up @@ -1900,6 +1942,7 @@ export {
dismissAddedWithPrimaryLoginMessages,
openDraftWorkspaceRequest,
buildOptimisticPolicyRecentlyUsedCategories,
buildOptimisticPolicyRecentlyUsedTags,
createDraftInitialWorkspace,
setWorkspaceInviteMessageDraft,
};
2 changes: 2 additions & 0 deletions src/pages/iou/SplitBillDetailsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ function SplitBillDetailsPage(props) {
merchant: splitMerchant,
created: splitCreated,
category: splitCategory,
tag: splitTag,
} = isEditingSplitBill && props.draftTransaction ? ReportUtils.getTransactionDetails(props.draftTransaction) : ReportUtils.getTransactionDetails(props.transaction);

const onConfirm = useCallback(
Expand Down Expand Up @@ -131,6 +132,7 @@ function SplitBillDetailsPage(props) {
iouCreated={splitCreated}
iouMerchant={splitMerchant}
iouCategory={splitCategory}
iouTag={splitTag}
iouType={CONST.IOU.TYPE.SPLIT}
isReadOnly={!isEditingSplitBill}
shouldShowSmartScanFields
Expand Down
3 changes: 3 additions & 0 deletions src/pages/iou/steps/MoneyRequestConfirmPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ function MoneyRequestConfirmPage(props) {
trimmedComment,
props.iou.currency,
props.iou.category,
props.iou.tag,
reportID,
);
return;
Expand All @@ -249,6 +250,7 @@ function MoneyRequestConfirmPage(props) {
trimmedComment,
props.iou.currency,
props.iou.category,
props.iou.tag,
);
return;
}
Expand All @@ -272,6 +274,7 @@ function MoneyRequestConfirmPage(props) {
props.currentUserPersonalDetails.accountID,
props.iou.currency,
props.iou.category,
props.iou.tag,
props.iou.receiptPath,
props.iou.receiptFilename,
isDistanceRequest,
Expand Down
3 changes: 3 additions & 0 deletions src/types/onyx/Report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ type Report = {
/** Whether the user is not an admin of policyExpenseChat chat */
isOwnPolicyExpenseChat?: boolean;

/** Whether the report is policyExpenseChat */
isPolicyExpenseChat?: boolean;

/** Indicates if the report is pinned to the LHN or not */
isPinned?: boolean;

Expand Down

0 comments on commit fc86789

Please sign in to comment.