refactor: reuse tx to csv gql query and overall function simplification

This commit is contained in:
José Oliveira 2021-08-26 13:23:52 +01:00 committed by Josh Harvey
parent 5826a29c53
commit fe518b21d7
4 changed files with 74 additions and 69 deletions

View file

@ -301,8 +301,7 @@ const typeDefs = gql`
offset: Int offset: Int
deviceId: ID deviceId: ID
): [Transaction] ): [Transaction]
transactionsCsv(from: Date, until: Date, limit: Int, offset: Int): String transactionsCsv(from: Date, until: Date, limit: Int, offset: Int, simplified: Boolean): String
simplifiedTransactionsCsv(from: Date, until: Date, limit: Int, offset: Int): String
accounts: JSONObject accounts: JSONObject
config: JSONObject config: JSONObject
blacklist: [Blacklist] blacklist: [Blacklist]
@ -398,10 +397,8 @@ const resolvers = {
serverLogs.getServerLogs(from, until, limit, offset).then(parseAsync), serverLogs.getServerLogs(from, until, limit, offset).then(parseAsync),
transactions: (...[, { from, until, limit, offset, deviceId }]) => transactions: (...[, { from, until, limit, offset, deviceId }]) =>
transactions.batch(from, until, limit, offset, deviceId), transactions.batch(from, until, limit, offset, deviceId),
transactionsCsv: (...[, { from, until, limit, offset }]) => transactionsCsv: (...[, { from, until, limit, offset, simplified }]) =>
transactions.batch(from, until, limit, offset).then(parseAsync), transactions.batch(from, until, limit, offset, null, simplified).then(parseAsync),
simplifiedTransactionsCsv: (...[, { from, until, limit, offset }]) =>
transactions.simplifiedBatch(from, until, limit, offset).then(parseAsync),
config: () => settingsLoader.loadLatestConfigOrNone(), config: () => settingsLoader.loadLatestConfigOrNone(),
accounts: () => settingsLoader.showAccounts(), accounts: () => settingsLoader.showAccounts(),
blacklist: () => blacklist.getBlacklist(), blacklist: () => blacklist.getBlacklist(),

View file

@ -26,7 +26,7 @@ function addNames (txs) {
const camelize = _.mapKeys(_.camelCase) const camelize = _.mapKeys(_.camelCase)
function batch (from = new Date(0).toISOString(), until = new Date().toISOString(), limit = null, offset = 0, id = null) { function batch (from = new Date(0).toISOString(), until = new Date().toISOString(), limit = null, offset = 0, id = null, simplified = false) {
const packager = _.flow(_.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addNames) const packager = _.flow(_.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addNames)
const cashInSql = `select 'cashIn' as tx_class, txs.*, const cashInSql = `select 'cashIn' as tx_class, txs.*,
@ -76,39 +76,48 @@ function batch (from = new Date(0).toISOString(), until = new Date().toISOString
]), ]),
db.any(cashOutSql, [REDEEMABLE_AGE, from, until, limit, offset, id]) db.any(cashOutSql, [REDEEMABLE_AGE, from, until, limit, offset, id])
]).then(packager) ]).then(packager)
}
function simplifiedBatch (from = new Date(0).toISOString(), until = new Date().toISOString(), limit = null, offset = 0) {
return batch(from, until, limit, offset)
.then(res => { .then(res => {
const fields = ['txClass', 'id', 'created', 'machineName', if (simplified) return simplifiedBatch(res)
'cryptoCode', 'fiat', 'fiatCode', 'phone', 'toAddress', else return res
'txHash', 'dispense', 'error', 'status', 'fiatProfit', 'cryptoAmount']
return _.map(_.compose(_.pick(fields), getStatus, getProfit, getCryptoAmount))(res)
}) })
} }
const getCryptoAmount = it => { return { ...it, cryptoAmount: coinUtils.toUnit(BN(it.cryptoAtoms), it.cryptoCode).toString() } } function simplifiedBatch (data) {
const fields = ['txClass', 'id', 'created', 'machineName',
'cryptoCode', 'fiat', 'fiatCode', 'phone', 'toAddress',
'txHash', 'dispense', 'error', 'status', 'fiatProfit', 'cryptoAmount']
const addSimplifiedFields = _.map(it => ({
...it,
status: getStatus(it),
fiatProfit: getProfit(it).toString(),
cryptoAmount: getCryptoAmount(it)
}))
return _.compose(_.map(_.pick(fields)), addSimplifiedFields)(data)
}
const getCryptoAmount = it => coinUtils.toUnit(BN(it.cryptoAtoms), it.cryptoCode).toString()
const getProfit = it => { const getProfit = it => {
const getCommissionFee = it => Number.parseFloat(it.commissionPercentage) * Number.parseFloat(it.fiat) const getCommissionFee = it => BN(it.commissionPercentage).mul(BN(it.fiat))
if (!it.cashInFee) return { ...it, fiatProfit: getCommissionFee(it) } if (!it.cashInFee) return getCommissionFee(it)
return { ...it, fiatProfit: getCommissionFee(it) + Number.parseFloat(it.cashInFee) } return getCommissionFee(it).add(BN(it.cashInFee))
} }
const getCashOutStatus = it => { const getCashOutStatus = it => {
if (it.hasError) return { ...it, status: 'Error' } if (it.hasError) return 'Error'
if (it.dispense) return { ...it, status: 'Success' } if (it.dispense) return 'Success'
if (it.expired) return { ...it, status: 'Expired' } if (it.expired) return 'Expired'
return { ...it, status: 'Pending' } return 'Pending'
} }
const getCashInStatus = it => { const getCashInStatus = it => {
if (it.operatorCompleted) return { ...it, status: 'Cancelled' } if (it.operatorCompleted) return 'Cancelled'
if (it.hasError) return { ...it, status: 'Error' } if (it.hasError) return 'Error'
if (it.sendConfirmed) return { ...it, status: 'Sent' } if (it.sendConfirmed) return 'Sent'
if (it.expired) return { ...it, status: 'Expired' } if (it.expired) return 'Expired'
return { ...it, status: 'Pending' } return 'Pending'
} }
const getStatus = it => { const getStatus = it => {

View file

@ -133,25 +133,21 @@ const SIMPLIFIED = 'simplified'
const LogsDownloaderPopover = ({ const LogsDownloaderPopover = ({
name, name,
queries, query,
args, args,
title, title,
getLogs, getLogs,
getSimplifiedLogs simplified
}) => { }) => {
const [selectedRadio, setSelectedRadio] = useState(ALL) const [selectedRadio, setSelectedRadio] = useState(ALL)
const [selectedAdvancedRadio, setSelectedAdvancedRadio] = useState(ADVANCED) const [selectedAdvancedRadio, setSelectedAdvancedRadio] = useState(ADVANCED)
const [range, setRange] = useState({ from: null, until: null }) const [range, setRange] = useState({ from: null, until: null })
const [anchorEl, setAnchorEl] = useState(null) const [anchorEl, setAnchorEl] = useState(null)
const [fetchLogs] = useLazyQuery(queries[0], { const [fetchLogs] = useLazyQuery(query, {
onCompleted: data => createLogsFile(getLogs(data), range) onCompleted: data => createLogsFile(getLogs(data), range)
}) })
const [fetchSimplifiedLogs] = useLazyQuery(queries[1], {
onCompleted: data => createLogsFile(getSimplifiedLogs(data), range)
})
const classes = useStyles() const classes = useStyles()
const dateRangePickerClasses = { const dateRangePickerClasses = {
@ -168,7 +164,6 @@ const LogsDownloaderPopover = ({
const handleAdvancedRadioButtons = evt => { const handleAdvancedRadioButtons = evt => {
const selectedAdvancedRadio = R.path(['target', 'value'])(evt) const selectedAdvancedRadio = R.path(['target', 'value'])(evt)
setSelectedAdvancedRadio(selectedAdvancedRadio) setSelectedAdvancedRadio(selectedAdvancedRadio)
if (selectedAdvancedRadio === ALL) setRange({ from: null, until: null })
} }
const handleRangeChange = useCallback( const handleRangeChange = useCallback(
@ -179,12 +174,11 @@ const LogsDownloaderPopover = ({
) )
const downloadLogs = (range, args) => { const downloadLogs = (range, args) => {
const fetch =
selectedAdvancedRadio === SIMPLIFIED ? fetchSimplifiedLogs : fetchLogs
if (selectedRadio === ALL) { if (selectedRadio === ALL) {
fetch({ fetchLogs({
variables: { variables: {
...args ...args,
simplified: selectedAdvancedRadio === SIMPLIFIED
} }
}) })
} }
@ -193,11 +187,12 @@ const LogsDownloaderPopover = ({
if (range.from && !range.until) range.until = moment() if (range.from && !range.until) range.until = moment()
if (selectedRadio === RANGE) { if (selectedRadio === RANGE) {
fetch({ fetchLogs({
variables: { variables: {
...args, ...args,
from: range.from, from: range.from,
until: range.until until: range.until,
simplified: selectedAdvancedRadio === SIMPLIFIED
} }
}) })
} }
@ -232,7 +227,10 @@ const LogsDownloaderPopover = ({
const radioButtonOptions = [ const radioButtonOptions = [
{ display: 'All logs', code: ALL }, { display: 'All logs', code: ALL },
{ display: 'Date range', code: RANGE }, { display: 'Date range', code: RANGE }
]
const advancedRadioButtonOptions = [
{ display: 'Advanced logs', code: ADVANCED }, { display: 'Advanced logs', code: ADVANCED },
{ display: 'Simplified logs', code: SIMPLIFIED } { display: 'Simplified logs', code: SIMPLIFIED }
] ]
@ -256,7 +254,7 @@ const LogsDownloaderPopover = ({
<RadioGroup <RadioGroup
name="logs-select" name="logs-select"
value={selectedRadio} value={selectedRadio}
options={radioButtonOptions.slice(0, 2)} options={radioButtonOptions}
ariaLabel="logs-select" ariaLabel="logs-select"
onChange={handleRadioButtons} onChange={handleRadioButtons}
className={classes.radioButtons} className={classes.radioButtons}
@ -281,16 +279,18 @@ const LogsDownloaderPopover = ({
/> />
</div> </div>
)} )}
<div className={classes.radioButtonsContainer}> {simplified && (
<RadioGroup <div className={classes.radioButtonsContainer}>
name="simplified-tx-logs" <RadioGroup
value={selectedAdvancedRadio} name="simplified-tx-logs"
options={radioButtonOptions.slice(2, 4)} value={selectedAdvancedRadio}
ariaLabel="simplified-tx-logs" options={advancedRadioButtonOptions}
onChange={handleAdvancedRadioButtons} ariaLabel="simplified-tx-logs"
className={classes.radioButtons} onChange={handleAdvancedRadioButtons}
/> className={classes.radioButtons}
</div> />
</div>
)}
<div className={classes.download}> <div className={classes.download}>
<Link color="primary" onClick={() => downloadLogs(range, args)}> <Link color="primary" onClick={() => downloadLogs(range, args)}>
Download Download

View file

@ -24,14 +24,18 @@ const useStyles = makeStyles(mainStyles)
const NUM_LOG_RESULTS = 1000 const NUM_LOG_RESULTS = 1000
const GET_TRANSACTIONS_CSV = gql` const GET_TRANSACTIONS_CSV = gql`
query transactions($limit: Int, $from: Date, $until: Date) { query transactions(
transactionsCsv(limit: $limit, from: $from, until: $until) $simplified: Boolean
} $limit: Int
` $from: Date
$until: Date
const GET_SIMPLIFIED_TRANSACTIONS_CSV = gql` ) {
query transactions($limit: Int, $from: Date, $until: Date) { transactionsCsv(
simplifiedTransactionsCsv(limit: $limit, from: $from, until: $until) simplified: $simplified
limit: $limit
from: $from
until: $until
)
} }
` `
@ -173,14 +177,9 @@ const Transactions = () => {
<LogsDowloaderPopover <LogsDowloaderPopover
title="Download logs" title="Download logs"
name="transactions" name="transactions"
queries={[ query={GET_TRANSACTIONS_CSV}
GET_TRANSACTIONS_CSV,
GET_SIMPLIFIED_TRANSACTIONS_CSV
]}
getLogs={logs => R.path(['transactionsCsv'])(logs)} getLogs={logs => R.path(['transactionsCsv'])(logs)}
getSimplifiedLogs={logs => simplified
R.path(['simplifiedTransactionsCsv'])(logs)
}
/> />
</div> </div>
)} )}