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

Refactor custom unit rate update #10557

Merged
merged 38 commits into from
Sep 6, 2022
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
607e5c5
add copy
jasperhuangg Aug 25, 2022
55af930
update setCustomUnitRate
jasperhuangg Aug 25, 2022
4cbb5d4
update setCustomUnitRate
jasperhuangg Aug 25, 2022
ec577cd
merge main
jasperhuangg Aug 29, 2022
065909a
WIP, online updates work, but need to figure out issue with data shap…
jasperhuangg Aug 29, 2022
e068def
merge main
jasperhuangg Aug 30, 2022
131144f
merge main
jasperhuangg Aug 30, 2022
5cff69a
remove unused
jasperhuangg Aug 30, 2022
d0b1393
remove unused
jasperhuangg Aug 30, 2022
ef76111
remove unused
jasperhuangg Aug 30, 2022
d2a0ea3
flatten customUnit rate array
jasperhuangg Aug 30, 2022
942416f
flatten customUnit rate array
jasperhuangg Aug 30, 2022
46eb7b5
fix linter error
jasperhuangg Aug 30, 2022
f2dbc32
update comment
jasperhuangg Aug 30, 2022
230cf42
revert unused
jasperhuangg Aug 30, 2022
7f7cadd
key by ID to get rates
jasperhuangg Aug 30, 2022
0ced3e5
access directly
jasperhuangg Aug 30, 2022
651ab0a
cleanup
jasperhuangg Aug 30, 2022
1e93077
cleanup
jasperhuangg Aug 30, 2022
c6a2304
fix propTypes
jasperhuangg Aug 30, 2022
71447ec
update customUnitRate accessing
jasperhuangg Aug 30, 2022
1da0a2a
remove unused
jasperhuangg Aug 30, 2022
55252de
cleanup
jasperhuangg Aug 30, 2022
b31f47b
Merge branch 'main' of github.com:Expensify/App into jasper-refactorP…
jasperhuangg Aug 30, 2022
ca7638e
Merge branch 'main' of github.com:Expensify/App into jasper-refactorP…
jasperhuangg Aug 31, 2022
4591cef
add comment
jasperhuangg Aug 31, 2022
f862e26
use update instead of set
jasperhuangg Aug 31, 2022
7aa9ab6
remove _.omit
jasperhuangg Aug 31, 2022
74ff01e
round to 3 decimal places before multiplying and passing to Policy ac…
jasperhuangg Aug 31, 2022
49f7118
remove defaults
jasperhuangg Aug 31, 2022
be512f5
use onyxRates instead of rates
jasperhuangg Aug 31, 2022
0c591d1
use onyxRates instead of rates
jasperhuangg Sep 1, 2022
8004b38
merge main
jasperhuangg Sep 5, 2022
39c5042
fix stuff messed up in merge
jasperhuangg Sep 5, 2022
dbaaa36
rename rateValue => unitRateValue
jasperhuangg Sep 5, 2022
c55d97b
fix stuff messed up in merge
jasperhuangg Sep 5, 2022
555a489
rename variables
jasperhuangg Sep 5, 2022
d3e4d63
Merge branch 'main' of github.com:Expensify/App into jasper-refactorP…
jasperhuangg Sep 6, 2022
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
1 change: 1 addition & 0 deletions src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,7 @@ const CONST = {
ADMIN: 'admin',
},
ROOM_PREFIX: '#',
CUSTOM_UNIT_RATE_BASE_OFFSET: 100,
},

TERMS: {
Expand Down
1 change: 1 addition & 0 deletions src/components/OfflineWithFeedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ const OfflineWithFeedback = (props) => {
.keys()
.sortBy()
.map(key => props.errors[key])
.uniq()
jasperhuangg marked this conversation as resolved.
Show resolved Hide resolved
.value();

// Apply strikethrough to children if needed, but skip it if we are not going to render them
Expand Down
108 changes: 83 additions & 25 deletions src/libs/actions/Policy.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,22 @@ function getSimplifiedEmployeeList(employeeList) {
.value();
}

/**
* We pass customUnit rates from PHP as an array, even though there's only ever a single rate per custom unit.
* This flattens the array of rates so that we store the single rate directly.
*
* @param {Object} fullPolicyOrPolicySummary
* @param {Object} [fullPolicyOrPolicySummary.value.customUnits]
* @returns {Object}
*/
function getSimplifiedCustomUnits(fullPolicyOrPolicySummary) {
const customUnits = lodashGet(fullPolicyOrPolicySummary, 'value.customUnits', {});
_.forEach(customUnits, (customUnit, customUnitID) => {
customUnits[customUnitID].rates = lodashGet(customUnit, 'rates[0]', {});
});
return customUnits;
}

/**
* Takes a full policy that is returned from the policyList and simplifies it so we are only storing
* the pieces of data that we need to in Onyx
Expand All @@ -60,6 +76,8 @@ function getSimplifiedEmployeeList(employeeList) {
* @param {String} fullPolicyOrPolicySummary.role
* @param {String} fullPolicyOrPolicySummary.type
* @param {String} fullPolicyOrPolicySummary.outputCurrency
* @param {String} [fullPolicyOrPolicySummary.avatar]
* @param {String} [fullPolicyOrPolicySummary.value.avatar]
jasperhuangg marked this conversation as resolved.
Show resolved Hide resolved
* @param {String} [fullPolicyOrPolicySummary.avatarURL]
* @param {String} [fullPolicyOrPolicySummary.value.avatarURL]
* @param {Object} [fullPolicyOrPolicySummary.value.employeeList]
Expand All @@ -80,7 +98,7 @@ function getSimplifiedPolicyObject(fullPolicyOrPolicySummary, isFromFullPolicy)
// "GetFullPolicy" and "GetPolicySummaryList" returns different policy objects. If policy is retrieved by "GetFullPolicy",
// avatarUrl will be nested within the key "value"
avatarURL: fullPolicyOrPolicySummary.avatarURL || lodashGet(fullPolicyOrPolicySummary, 'value.avatarURL', ''),
customUnits: lodashGet(fullPolicyOrPolicySummary, 'value.customUnits', {}),
customUnits: getSimplifiedCustomUnits(fullPolicyOrPolicySummary),
};
}

Expand Down Expand Up @@ -558,12 +576,16 @@ function setWorkspaceErrors(policyID, errors) {
* @param {String} policyID
* @param {Number} customUnitID
*/
function removeUnitError(policyID, customUnitID) {
function clearCustomUnitErrors(policyID, customUnitID) {
Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {
customUnits: {
[customUnitID]: {
errors: null,
pendingAction: null,
rates: {
errors: null,
pendingAction: null,
},
},
},
});
Expand Down Expand Up @@ -639,34 +661,70 @@ function updateWorkspaceCustomUnit(policyID, currentCustomUnit, values) {

/**
* @param {String} policyID
* @param {Object} currentCustomUnitRate
* @param {String} customUnitID
* @param {Object} values
*/
function setCustomUnitRate(policyID, customUnitID, values) {
DeprecatedAPI.Policy_CustomUnitRate_Update({
policyID: policyID.toString(),
customUnitID: customUnitID.toString(),
customUnitRate: JSON.stringify(values),
lastModified: null,
})
.then((response) => {
if (response.jsonCode !== 200) {
throw new Error();
}
function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values) {
jasperhuangg marked this conversation as resolved.
Show resolved Hide resolved
const optimisticData = [
{
onyxMethod: 'merge',
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
value: {
customUnits: {
[customUnitID]: {
rates: {
jasperhuangg marked this conversation as resolved.
Show resolved Hide resolved
...values,
errors: null,
pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
},
},
},
},
},
];

const successData = [
{
onyxMethod: 'merge',
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
value: {
customUnits: {
[customUnitID]: {
rates: {
...values,
pendingAction: null,
},
},
},
},
},
];

updateLocalPolicyValues(policyID, {
customUnit: {
rate: {
id: values.customUnitRateID,
name: values.name,
value: Number(values.rate),
const failureData = [
{
onyxMethod: 'merge',
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
value: {
customUnits: {
[customUnitID]: {
rates: {
...currentCustomUnitRate,
errors: {
[DateUtils.getMicroseconds()]: Localize.translateLocal('workspace.reimburse.updateCustomUnitError'),
},
},
},
},
});
}).catch(() => {
// Show the user feedback
Growl.error(Localize.translateLocal('workspace.editor.genericFailureMessage'), 5000);
});
},
},
];

API.write('SetWorkspaceCustomUnitRate', {
policyID,
customUnitID,
customUnitRate: JSON.stringify(values),
}, {optimisticData, successData, failureData});
}

/**
Expand Down Expand Up @@ -747,7 +805,7 @@ export {
uploadAvatar,
update,
setWorkspaceErrors,
removeUnitError,
clearCustomUnitErrors,
hideWorkspaceAlertMessage,
deletePolicy,
createAndNavigate,
Expand Down
38 changes: 20 additions & 18 deletions src/pages/workspace/reimburse/WorkspaceReimburseView.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,11 @@ const propTypes = {
attributes: PropTypes.shape({
unit: PropTypes.string,
}),
rates: PropTypes.arrayOf(
PropTypes.shape({
customUnitRateID: PropTypes.string,
name: PropTypes.string,
rate: PropTypes.number,
}),
),
rates: PropTypes.shape({
customUnitRateID: PropTypes.string,
name: PropTypes.string,
rate: PropTypes.number,
}),
}),
),
outputCurrency: PropTypes.string,
Expand All @@ -64,9 +62,7 @@ class WorkspaceReimburseView extends React.Component {
unitID: lodashGet(distanceCustomUnit, 'customUnitID', ''),
unitName: lodashGet(distanceCustomUnit, 'name', ''),
unitValue: lodashGet(distanceCustomUnit, 'attributes.unit', 'mi'),
rateID: lodashGet(distanceCustomUnit, 'rates[0].customUnitRateID', ''),
rateName: lodashGet(distanceCustomUnit, 'rates[0].name', ''),
rateValue: this.getRateDisplayValue(lodashGet(distanceCustomUnit, 'rates[0].rate', 0) / 100),
rateValue: this.getRateDisplayValue(lodashGet(distanceCustomUnit, 'rates.rate', 0) / CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET),
outputCurrency: lodashGet(props, 'policy.outputCurrency', ''),
};

Expand Down Expand Up @@ -151,11 +147,12 @@ class WorkspaceReimburseView extends React.Component {
rateValue: numValue.toFixed(3),
});

Policy.setCustomUnitRate(this.props.policyID, this.state.unitID, {
customUnitRateID: this.state.rateID,
name: this.state.rateName,
rate: numValue.toFixed(3) * 100,
}, null);
const distanceCustomUnit = _.find(lodashGet(this.props, 'policy.customUnits', {}), unit => unit.name === 'Distance');
const currentCustomUnitRate = lodashGet(distanceCustomUnit, 'rates', {});
Policy.setCustomUnitRate(this.props.policyID, currentCustomUnitRate, this.state.unitID, {
..._.omit(currentCustomUnitRate, 'rate'),
jasperhuangg marked this conversation as resolved.
Show resolved Hide resolved
rate: numValue * CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET,
jasperhuangg marked this conversation as resolved.
Show resolved Hide resolved
});
}

render() {
Expand Down Expand Up @@ -194,9 +191,14 @@ class WorkspaceReimburseView extends React.Component {
<Text>{this.props.translate('workspace.reimburse.trackDistanceCopy')}</Text>
</View>
<OfflineWithFeedback
errors={lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'errors'])}
pendingAction={lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'pendingAction'])}
onClose={() => Policy.removeUnitError(this.props.policyID, this.state.unitID)}
errors={{
...lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'errors']),
...lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'rates', 'errors']),
}}
pendingAction={lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'pendingAction'])
|| lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'rates', 'pendingAction'])}
onClose={() => Policy.clearCustomUnitErrors(this.props.policyID, this.state.unitID)}
errorRowStyles={[styles.flex1]}
>
<View style={[styles.flexRow, styles.alignItemsCenter, styles.mv2]}>
<View style={[styles.rateCol]}>
Expand Down