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

[$250] [Dupe detection] Use new ResolveDuplicates when approver is resolving duplicates #48416

Open
pecanoro opened this issue Sep 2, 2024 · 46 comments
Assignees
Labels
Bug Something is broken. Auto assigns a BugZero manager. External Added to denote the issue can be worked on by a contributor Reviewing Has a PR in review Weekly KSv2

Comments

@pecanoro
Copy link
Contributor

pecanoro commented Sep 2, 2024

Part of the Duplicate Detection project

Main issue: https://github.com/Expensify/Expensify/issues/411008
Project: Dupe detection

Feature Description

image

Right now, we always call MergeTransactions when resolving duplicates and click Confirm at the last page of resolving duplicates. However, we need to call a new command called ResolveDuplicates when an approver or admin (basically anyone but the submitter) is the person resolving the duplicates. The behaviour (so we can create the proper optimistic actions) should be as follows:

  • ResolveDuplicates API endpoint needs the following parameters:
            'authToken' => $authToken,
            'transactionIDToKeep' => $transactionIDToKeep,
            'transactionIDList' => $transactionIDList,
            'created' => $created,
            'merchant' => $merchant,
            'amount' => $amount,
            'currency' => $currency,
            'category' => $category,
            'comment' => $comment,
            'billable' => $billable,
            'reimbursable' => $reimbursable,
            'tag' => $tag,
            'optimisticReportActionID' => $optimisticReportActionID,
            'reportActionIDList' => $reportActionIDList,

This command will update the transaction to match the fields we chose during the flow. It should already be doing this.

  • It won't delete the rest of the transactions in transactionIDList but it will HOLD them by adding the hold NVP to it and will add the corresponding HOLD actions to each of them.
  • It will add a DISMISSEDVIOLATION action to the transactionIDToKeep
  • It will dismiss the violation by adding the corresponding transaction NVP for all transactions.

Main issue: https://github.com/Expensify/Expensify/issues/411008

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~011781060ec2a6c428
  • Upwork Job ID: 1830626997874011636
  • Last Price Increase: 2024-09-02
  • Automatic offers:
    • nkdengineer | Contributor | 103792699
Issue OwnerCurrent Issue Owner: @
@pecanoro pecanoro changed the title Use new ResolveDuplicates [Dupe detection] Use new ResolveDuplicates when approver is resolving duplicates Sep 2, 2024
@pecanoro
Copy link
Contributor Author

pecanoro commented Sep 2, 2024

@parasharrajat I am assigning you as the C+ in this issue since you reviewed the main ones.

@pecanoro pecanoro added the Bug Something is broken. Auto assigns a BugZero manager. label Sep 2, 2024
@parasharrajat
Copy link
Member

Sure

Copy link

melvin-bot bot commented Sep 2, 2024

Triggered auto assignment to @sonialiap (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.

@melvin-bot melvin-bot bot added the Daily KSv2 label Sep 2, 2024
@pecanoro pecanoro added External Added to denote the issue can be worked on by a contributor and removed Daily KSv2 labels Sep 2, 2024
@melvin-bot melvin-bot bot changed the title [Dupe detection] Use new ResolveDuplicates when approver is resolving duplicates [$250] [Dupe detection] Use new ResolveDuplicates when approver is resolving duplicates Sep 2, 2024
Copy link

melvin-bot bot commented Sep 2, 2024

Job added to Upwork: https://www.upwork.com/jobs/~011781060ec2a6c428

@melvin-bot melvin-bot bot added the Help Wanted Apply this label when an issue is open to proposals by contributors label Sep 2, 2024
Copy link

melvin-bot bot commented Sep 2, 2024

Current assignee @parasharrajat is eligible for the External assigner, not assigning anyone new.

@melvin-bot melvin-bot bot added the Daily KSv2 label Sep 2, 2024
@nkdengineer
Copy link
Contributor

Proposal

Please re-state the problem that we are trying to solve in this issue.

Add a new command for admin/approver when resolving the duplicate transaction from submitter

What is the root cause of that problem?

We're always calling mergeDuplicates function without checking the current user is admin/approver or not

const transactionsMergeParams = useMemo(() => TransactionUtils.buildTransactionsMergeParams(reviewDuplicates, transaction), [reviewDuplicates, transaction]);
const mergeDuplicates = useCallback(() => {
IOU.mergeDuplicates(transactionsMergeParams);
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(reportAction?.childReportID ?? '-1'));

What changes do you think we should make in order to solve the problem?

  1. To check the user is admin/approver we can use the same way we do here.

App/src/libs/ReportUtils.ts

Lines 3074 to 3079 in e60b821

const isActionOwner =
typeof parentReportAction?.actorAccountID === 'number' &&
typeof currentUserPersonalDetails?.accountID === 'number' &&
parentReportAction.actorAccountID === currentUserPersonalDetails?.accountID;
const isApprover = isMoneyRequestReport(moneyRequestReport) && moneyRequestReport?.managerID !== null && currentUserPersonalDetails?.accountID === moneyRequestReport?.managerID;
const isAdmin = isPolicyAdmin(moneyRequestReport.policyID ?? '-1', allPolicies);

  1. Create a new function resolveDuplicates that will call ResolveDuplicates comman with the param as described here. It will be almost the same with mergeDuplicates, the only difference with mergeDuplicates is

It won't delete the rest of the transactions in transactionIDList but it will HOLD them by adding the hold NVP to it and will add the corresponding HOLD actions to each of them.

  • We will not delete the transaction in transactionIDList. Instead, we will add a hold action for these transaction thread reports in optimistic data and reset in failure data and also add hold violation for these transaction

It will add a DISMISSEDVIOLATION action to the transactionIDToKeep

  • Add a DISMISSEDVIOLATION action with reason in originalMessage is duplicatedTransaction for the transaction thread report of transactionIDToKeep list

It will dismiss the violation by adding the corresponding transaction NVP for all transactions.

  • Remove violation of all transactions in transactionIDToKeep

What alternative solutions did you explore? (Optional)

@parasharrajat
Copy link
Member

The proposal sounds good @nkdengineer sounds good to me.

🎀 👀 🎀 C+ reviewed

Copy link

melvin-bot bot commented Sep 2, 2024

Current assignee @pecanoro is eligible for the choreEngineerContributorManagement assigner, not assigning anyone new.

@pecanoro
Copy link
Contributor Author

pecanoro commented Sep 3, 2024

Assigning @nkdengineer!

@melvin-bot melvin-bot bot removed the Help Wanted Apply this label when an issue is open to proposals by contributors label Sep 3, 2024
Copy link

melvin-bot bot commented Sep 3, 2024

📣 @nkdengineer 🎉 An offer has been automatically sent to your Upwork account for the Contributor role 🎉 Thanks for contributing to the Expensify app!

Offer link
Upwork job
Please accept the offer and leave a comment on the Github issue letting us know when we can expect a PR to be ready for review 🧑‍💻
Keep in mind: Code of Conduct | Contributing 📖

@nkdengineer
Copy link
Contributor

Will raise the PR tomorrow.

@nkdengineer
Copy link
Contributor

@pecanoro In the ResolveDuplicates API, what is the structure of reportActionIDList params?

@pecanoro
Copy link
Contributor Author

pecanoro commented Sep 4, 2024

In the ResolveDuplicates API, what is the structure of reportActionIDList params?

A comma-separated list of report actions

@nkdengineer
Copy link
Contributor

A comma-separated list of report actions

@pecanoro Can you give an example? Do we need to add reportID in data?

@pecanoro
Copy link
Contributor Author

pecanoro commented Sep 5, 2024

@pecanoro Can you give an example?

Imagine we have 3 duplicates with transactionIDs 111, 222 and 333. We want to keep 111 and hold the other two. Then:

'transactionIDToKeep' => '111',
'transactionIDList' => '222,333',

Do we need to add reportID in data?

Nope, no reportID since they are not changing reports

@nkdengineer
Copy link
Contributor

@pecanoro I mean I need an example for reportActionIDList param.

@nkdengineer
Copy link
Contributor

@pecanoro When I call ResolveDuplicates, BE returns the error like this video. Here is the parameter that I called this API. Am I missing something?

{
    "amount": -200,
    "currency": "VND",
    "created": "2024-09-09",
    "transactionIDList": [
        "4002616464040896678"
    ],
    "billable": false,
    "reimbursable": true,
    "category": "",
    "tag": "",
    "merchant": "ssd",
    "comment": "",
    "transactionIDToKeep": "5332969134080823220",
    "reportActionIDList": [
        "637476526581947356"
    ],
    "optimisticReportActionID": "3766068727586466325"
}
Screen.Recording.2024-09-09.at.11.35.19.mov

@pecanoro
Copy link
Contributor Author

pecanoro commented Sep 9, 2024

Oh, it's a BE problem, I j just checked the logs. Let me create a PR to fix it

@pecanoro
Copy link
Contributor Author

pecanoro commented Sep 9, 2024

The PR is merged, we are waiting for a deploy and then you will be able to use the endpoint in staging again. I renamed transactionIDToKeep for just transactionID

@dylanexpensify
Copy link
Contributor

@nkdengineer PR is deployed to prod now!

@melvin-bot melvin-bot bot added Reviewing Has a PR in review Weekly KSv2 and removed Daily KSv2 labels Sep 11, 2024
@nkdengineer
Copy link
Contributor

@parasharrajat The PR is here.

@parasharrajat
Copy link
Member

it will HOLD them by adding the hold NVP to it

What do you mean by NVP @pecanoro?

@nkdengineer
Copy link
Contributor

@pecanoro While testing I found another BE bug, the dismiss violation action isn't stored from BE side.

@pecanoro
Copy link
Contributor Author

What do you mean by NVP @pecanoro?

Ah sorry, when the transaction is put on HOLD, we add a value to the transaction namevaluepairs in the comment.

@pecanoro
Copy link
Contributor Author

@pecanoro While testing I found another BE bug, the dismiss violation action isn't stored from BE side.

Are you sure? It is added for the transaction we want to keep, not for the others.

@nkdengineer
Copy link
Contributor

Yes, I tested and after reset cache this action is removed since BE doesn't return this action. Also the resolve duplicate API doesn't return dismiss violation action data.

@pecanoro
Copy link
Contributor Author

Let me double-check manually, but it's pretty odd since I even wrote automated tests for this and they are passing

@pecanoro
Copy link
Contributor Author

@nkdengineer Can you paste here what the BE is returning for you?

@nkdengineer
Copy link
Contributor

nkdengineer commented Sep 12, 2024

{
    "accountID": 18311825,
    "accounts": {
        "18311825": {
            "lastUpdateID": 1775760902,
            "previousUpdateID": 1775614249,
            "updateIDs": [
                1775760897,
                1775760898,
                1775760899,
                1775760900,
                1775760901,
                1775760902
            ]
        }
    },
    "authToken": "ED538D6882FC6B872FD1E38C8B75EC3ED4799DAF2809D40258D5A38DF3F448972D57954AF21C6EF04D9DBA533734CD6FC5B8908331F9904CF87AF73E8B286E9DDC523F8C2153DB499A0D6E433B2BD2E21CB71155B10A7F6D64826D4ACD1CA0443ECF354E9006107CD6DAC056448043E0FBDE3C32367A157108E87CBB53EDBFFD03E891BCEB5DA77E8EBEF24B5AF0D7E9FD9A757BDA391A6568E463678C8EF1BF1E55E96771BEEE6228EF37F1B8FF3BE280B9E5C6B2235E5FAD8E30F652EAA244C06EFE2E8B18BFB3CB8DA94286CC32C74D0B5F03C003CD78D2BB8A9D02A9478C89F64E9674B229779DDC5DEA5EED7B3DF5A513373D224C022CE70012AEAEA03F4BF4CF18ED5EBE8DF44F7A53F64C623731EF5689A91E9FB3E061CDF663B373ED10CECB4758B6D759E25715BB2EF0BE6C729E7A3928CF1F89005D8434D3BD4556A86E95D218CB4353E3B6E6A20E66F7775725A89AEB459453192F36B84EA2742A",
    "email": "[email protected]",
    "fetchableOnyxUpdates": [
        "1775760897",
        "1775760898",
        "1775760899",
        "1775760900",
        "1775760901",
        "1775760902"
    ],
    "onyxUpdates": {
        "1775760897": [
            {
                "key": "transactions_398480206897163307",
                "onyxMethod": "merge",
                "value": {
                    "comment": {
                        "dismissedViolations": {
                            "duplicatedTransaction": {
                                "[email protected]": 1726161878570510
                            }
                        }
                    }
                }
            }
        ],
        "1775760898": [
            {
                "key": "transactions_1367302367436179941",
                "onyxMethod": "merge",
                "value": {
                    "comment": {
                        "comment": "",
                        "dismissedViolations": {
                            "duplicatedTransaction": {
                                "[email protected]": 1726161878570610
                            }
                        }
                    }
                }
            }
        ],
        "1775760899": [
            {
                "key": "report_1113086820473870",
                "onyxMethod": "merge",
                "value": {
                    "participants": {
                        "18301280": {
                            "hidden": true,
                            "notificationPreference": "hidden"
                        },
                        "18308128": {
                            "hidden": true,
                            "notificationPreference": "hidden"
                        },
                        "18311825": {
                            "hidden": true,
                            "notificationPreference": "hidden"
                        }
                    }
                }
            }
        ],
        "1775760900": [
            {
                "key": "report_1113086820473870",
                "onyxMethod": "merge",
                "value": {
                    "chatType": "",
                    "description": "",
                    "lastActorAccountID": 18311825,
                    "lastMessageText": "held this expense with the comment: ",
                    "lastVisibleActionCreated": "2024-09-12 17:24:38.571",
                    "managerID": null,
                    "ownerAccountID": 0,
                    "parentReportActionID": "2951370456346266262",
                    "parentReportID": "8755324512976856",
                    "policyID": "2D62A4DBCE91AD7E",
                    "reportID": "1113086820473870",
                    "reportName": "Chat Report",
                    "state": "OPEN",
                    "stateNum": 0,
                    "statusNum": 0,
                    "type": "chat",
                    "visibility": null
                }
            },
            {
                "key": "reportActions_1113086820473870",
                "onyxMethod": "merge",
                "value": {
                    "2272851721205218606": {
                        "actionName": "HOLD",
                        "actorAccountID": 18311825,
                        "avatar": "https://d2k5nsl2zxldvw.cloudfront.net/images/avatars/default-avatar_18.png",
                        "created": "2024-09-12 17:24:38.571",
                        "lastModified": "2024-09-12 17:24:38.571",
                        "message": [
                            {
                                "html": "",
                                "text": "",
                                "type": "COMMENT",
                                "whisperedTo": []
                            }
                        ],
                        "originalMessage": {
                            "accountID": 18311825,
                            "date": "2024-09-12 17:24:38",
                            "isDuplicate": "true",
                            "lastModified": "2024-09-12 17:24:38.571",
                            "message": ""
                        },
                        "person": [
                            {
                                "style": "strong",
                                "text": "nkd102",
                                "type": "TEXT"
                            }
                        ],
                        "reportActionID": "2272851721205218606",
                        "shouldShow": true
                    }
                }
            }
        ],
        "1775760901": [
            {
                "key": "personalDetailsList",
                "onyxMethod": "merge",
                "value": {
                    "18311825": {
                        "accountID": 18311825,
                        "avatar": "https://d2k5nsl2zxldvw.cloudfront.net/images/avatars/default-avatar_18.png",
                        "displayName": "nkd102",
                        "firstName": "nkd102",
                        "lastName": "",
                        "login": "[email protected]",
                        "phoneNumber": "",
                        "pronouns": "",
                        "status": null,
                        "timezone": {
                            "automatic": true,
                            "selected": "Asia/Ho_Chi_Minh"
                        },
                        "validated": true
                    }
                }
            }
        ],
        "1775760902": [
            {
                "key": "transactions_1367302367436179941",
                "onyxMethod": "merge",
                "value": {
                    "comment": {
                        "hold": "2272851721205218606"
                    }
                }
            }
        ]
    },
    "httpCode": 200,
    "jsonCode": 200,
    "authResponseMessage": "200 OK",
    "requestID": "8c21979b5e5e1fbc-HKG",
    "onyxData": [
        {
            "key": "transactions_398480206897163307",
            "onyxMethod": "merge",
            "value": {
                "comment": {
                    "dismissedViolations": {
                        "duplicatedTransaction": {
                            "[email protected]": 1726161878570510
                        }
                    }
                }
            }
        },
        {
            "key": "transactions_1367302367436179941",
            "onyxMethod": "merge",
            "value": {
                "comment": {
                    "comment": "",
                    "dismissedViolations": {
                        "duplicatedTransaction": {
                            "[email protected]": 1726161878570610
                        }
                    }
                }
            }
        },
        {
            "key": "report_1113086820473870",
            "onyxMethod": "merge",
            "value": {
                "participants": {
                    "18301280": {
                        "hidden": true,
                        "notificationPreference": "hidden"
                    },
                    "18308128": {
                        "hidden": true,
                        "notificationPreference": "hidden"
                    },
                    "18311825": {
                        "hidden": true,
                        "notificationPreference": "hidden"
                    }
                }
            }
        },
        {
            "key": "report_1113086820473870",
            "onyxMethod": "merge",
            "value": {
                "chatType": "",
                "description": "",
                "lastActorAccountID": 18311825,
                "lastMessageText": "held this expense with the comment: ",
                "lastVisibleActionCreated": "2024-09-12 17:24:38.571",
                "managerID": null,
                "ownerAccountID": 0,
                "parentReportActionID": "2951370456346266262",
                "parentReportID": "8755324512976856",
                "policyID": "2D62A4DBCE91AD7E",
                "reportID": "1113086820473870",
                "reportName": "Chat Report",
                "state": "OPEN",
                "stateNum": 0,
                "statusNum": 0,
                "type": "chat",
                "visibility": null
            }
        },
        {
            "key": "reportActions_1113086820473870",
            "onyxMethod": "merge",
            "value": {
                "2272851721205218606": {
                    "actionName": "HOLD",
                    "actorAccountID": 18311825,
                    "avatar": "https://d2k5nsl2zxldvw.cloudfront.net/images/avatars/default-avatar_18.png",
                    "created": "2024-09-12 17:24:38.571",
                    "lastModified": "2024-09-12 17:24:38.571",
                    "message": [
                        {
                            "html": "",
                            "text": "",
                            "type": "COMMENT",
                            "whisperedTo": []
                        }
                    ],
                    "originalMessage": {
                        "accountID": 18311825,
                        "date": "2024-09-12 17:24:38",
                        "isDuplicate": "true",
                        "lastModified": "2024-09-12 17:24:38.571",
                        "message": ""
                    },
                    "person": [
                        {
                            "style": "strong",
                            "text": "nkd102",
                            "type": "TEXT"
                        }
                    ],
                    "reportActionID": "2272851721205218606",
                    "shouldShow": true
                }
            }
        },
        {
            "key": "personalDetailsList",
            "onyxMethod": "merge",
            "value": {
                "18311825": {
                    "accountID": 18311825,
                    "avatar": "https://d2k5nsl2zxldvw.cloudfront.net/images/avatars/default-avatar_18.png",
                    "displayName": "nkd102",
                    "firstName": "nkd102",
                    "lastName": "",
                    "login": "[email protected]",
                    "phoneNumber": "",
                    "pronouns": "",
                    "status": null,
                    "timezone": {
                        "automatic": true,
                        "selected": "Asia/Ho_Chi_Minh"
                    },
                    "validated": true
                }
            }
        },
        {
            "key": "transactions_1367302367436179941",
            "onyxMethod": "merge",
            "value": {
                "comment": {
                    "hold": "2272851721205218606"
                }
            }
        }
    ],
    "previousUpdateID": 1775614249,
    "lastUpdateID": 1775760902
}

@nkdengineer
Copy link
Contributor

@pecanoro The response here.

@nkdengineer
Copy link
Contributor

The payload here.

Screenshot 2024-09-13 at 00 26 11

@pecanoro
Copy link
Contributor Author

There is something off, also because both hold actions are returned for the same report

@pecanoro
Copy link
Contributor Author

pecanoro commented Sep 12, 2024

Ah nvm, forget my previous comment, you were resolving duplicates with only two transactions. I am going to check the database

@pecanoro
Copy link
Contributor Author

Ah I found the problem, another parameter name that got cleared because of sanitization. I am going to rename it to something better either way. I will create a PR in the back-end

@pecanoro
Copy link
Contributor Author

@nkdengineer BE fix is on staging, you can test it in the PR now! New parameter is called dismissedViolationReportActionID instead of optimisticReportActionID

@parasharrajat
Copy link
Member

parasharrajat commented Sep 19, 2024

@pecanoro Does this change affect keep All functionality as well? Do we need to change that too?

@pecanoro
Copy link
Contributor Author

@parasharrajat No, it should not change it

@parasharrajat
Copy link
Member

Got it. Thanks.

@parasharrajat
Copy link
Member

Note for future: I noticed that when admin resolves a duplicate, the transaction is no more duplicate for admin but same transaction still shown duplicate for the original user who requested. I confirmed that this is expected #48522 (comment)

@nkdengineer
Copy link
Contributor

@parasharrajat The original PR was reverted so I created a new one here to fix another bug #49900

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something is broken. Auto assigns a BugZero manager. External Added to denote the issue can be worked on by a contributor Reviewing Has a PR in review Weekly KSv2
Projects
Status: No status
Development

No branches or pull requests

5 participants