feat: simplified tx exports

This commit is contained in:
José Oliveira 2021-08-18 13:26:24 +01:00 committed by Josh Harvey
parent 2f6aac8f6d
commit 5826a29c53
4 changed files with 102 additions and 12 deletions

View file

@ -302,6 +302,7 @@ const typeDefs = gql`
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): String
simplifiedTransactionsCsv(from: Date, until: Date, limit: Int, offset: Int): String
accounts: JSONObject accounts: JSONObject
config: JSONObject config: JSONObject
blacklist: [Blacklist] blacklist: [Blacklist]
@ -399,6 +400,8 @@ const resolvers = {
transactions.batch(from, until, limit, offset, deviceId), transactions.batch(from, until, limit, offset, deviceId),
transactionsCsv: (...[, { from, until, limit, offset }]) => transactionsCsv: (...[, { from, until, limit, offset }]) =>
transactions.batch(from, until, limit, offset).then(parseAsync), transactions.batch(from, until, limit, offset).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

@ -6,6 +6,8 @@ const machineLoader = require('../machine-loader')
const tx = require('../tx') const tx = require('../tx')
const cashInTx = require('../cash-in/cash-in-tx') const cashInTx = require('../cash-in/cash-in-tx')
const { REDEEMABLE_AGE } = require('../cash-out/cash-out-helper') const { REDEEMABLE_AGE } = require('../cash-out/cash-out-helper')
const coinUtils = require('../coin-utils')
const BN = require('../bn')
const NUM_RESULTS = 1000 const NUM_RESULTS = 1000
@ -76,6 +78,46 @@ function batch (from = new Date(0).toISOString(), until = new Date().toISOString
]).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 => {
const fields = ['txClass', 'id', 'created', 'machineName',
'cryptoCode', 'fiat', 'fiatCode', 'phone', 'toAddress',
'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() } }
const getProfit = it => {
const getCommissionFee = it => Number.parseFloat(it.commissionPercentage) * Number.parseFloat(it.fiat)
if (!it.cashInFee) return { ...it, fiatProfit: getCommissionFee(it) }
return { ...it, fiatProfit: getCommissionFee(it) + Number.parseFloat(it.cashInFee) }
}
const getCashOutStatus = it => {
if (it.hasError) return { ...it, status: 'Error' }
if (it.dispense) return { ...it, status: 'Success' }
if (it.expired) return { ...it, status: 'Expired' }
return { ...it, status: 'Pending' }
}
const getCashInStatus = it => {
if (it.operatorCompleted) return { ...it, status: 'Cancelled' }
if (it.hasError) return { ...it, status: 'Error' }
if (it.sendConfirmed) return { ...it, status: 'Sent' }
if (it.expired) return { ...it, status: 'Expired' }
return { ...it, status: 'Pending' }
}
const getStatus = it => {
if (it.txClass === 'cashOut') {
return getCashOutStatus(it)
}
return getCashInStatus(it)
}
function getCustomerTransactionsBatch (ids) { function getCustomerTransactionsBatch (ids) {
const packager = _.flow(it => { const packager = _.flow(it => {
return it return it
@ -168,4 +210,4 @@ function cancel (txId) {
.then(() => single(txId)) .then(() => single(txId))
} }
module.exports = { batch, single, cancel, getCustomerTransactionsBatch } module.exports = { simplifiedBatch, batch, single, cancel, getCustomerTransactionsBatch }

View file

@ -128,15 +128,30 @@ const styles = {
const useStyles = makeStyles(styles) const useStyles = makeStyles(styles)
const ALL = 'all' const ALL = 'all'
const RANGE = 'range' const RANGE = 'range'
const ADVANCED = 'advanced'
const SIMPLIFIED = 'simplified'
const LogsDownloaderPopover = ({ name, query, args, title, getLogs }) => { const LogsDownloaderPopover = ({
name,
queries,
args,
title,
getLogs,
getSimplifiedLogs
}) => {
const [selectedRadio, setSelectedRadio] = useState(ALL) const [selectedRadio, setSelectedRadio] = useState(ALL)
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(query, { const [fetchLogs] = useLazyQuery(queries[0], {
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 = {
@ -150,6 +165,12 @@ const LogsDownloaderPopover = ({ name, query, args, title, getLogs }) => {
if (selectedRadio === ALL) setRange({ from: null, until: null }) if (selectedRadio === ALL) setRange({ from: null, until: null })
} }
const handleAdvancedRadioButtons = evt => {
const selectedAdvancedRadio = R.path(['target', 'value'])(evt)
setSelectedAdvancedRadio(selectedAdvancedRadio)
if (selectedAdvancedRadio === ALL) setRange({ from: null, until: null })
}
const handleRangeChange = useCallback( const handleRangeChange = useCallback(
(from, until) => { (from, until) => {
setRange({ from, until }) setRange({ from, until })
@ -157,9 +178,11 @@ const LogsDownloaderPopover = ({ name, query, args, title, getLogs }) => {
[setRange] [setRange]
) )
const downloadLogs = (range, args, fetchLogs) => { const downloadLogs = (range, args) => {
const fetch =
selectedAdvancedRadio === SIMPLIFIED ? fetchSimplifiedLogs : fetchLogs
if (selectedRadio === ALL) { if (selectedRadio === ALL) {
fetchLogs({ fetch({
variables: { variables: {
...args ...args
} }
@ -170,7 +193,7 @@ const LogsDownloaderPopover = ({ name, query, args, title, getLogs }) => {
if (range.from && !range.until) range.until = moment() if (range.from && !range.until) range.until = moment()
if (selectedRadio === RANGE) { if (selectedRadio === RANGE) {
fetchLogs({ fetch({
variables: { variables: {
...args, ...args,
from: range.from, from: range.from,
@ -209,7 +232,9 @@ const LogsDownloaderPopover = ({ name, query, args, title, getLogs }) => {
const radioButtonOptions = [ const radioButtonOptions = [
{ display: 'All logs', code: ALL }, { display: 'All logs', code: ALL },
{ display: 'Date range', code: RANGE } { display: 'Date range', code: RANGE },
{ display: 'Advanced logs', code: ADVANCED },
{ display: 'Simplified logs', code: SIMPLIFIED }
] ]
const open = Boolean(anchorEl) const open = Boolean(anchorEl)
@ -231,7 +256,7 @@ const LogsDownloaderPopover = ({ name, query, args, title, getLogs }) => {
<RadioGroup <RadioGroup
name="logs-select" name="logs-select"
value={selectedRadio} value={selectedRadio}
options={radioButtonOptions} options={radioButtonOptions.slice(0, 2)}
ariaLabel="logs-select" ariaLabel="logs-select"
onChange={handleRadioButtons} onChange={handleRadioButtons}
className={classes.radioButtons} className={classes.radioButtons}
@ -256,10 +281,18 @@ const LogsDownloaderPopover = ({ name, query, args, title, getLogs }) => {
/> />
</div> </div>
)} )}
<div className={classes.radioButtonsContainer}>
<RadioGroup
name="simplified-tx-logs"
value={selectedAdvancedRadio}
options={radioButtonOptions.slice(2, 4)}
ariaLabel="simplified-tx-logs"
onChange={handleAdvancedRadioButtons}
className={classes.radioButtons}
/>
</div>
<div className={classes.download}> <div className={classes.download}>
<Link <Link color="primary" onClick={() => downloadLogs(range, args)}>
color="primary"
onClick={() => downloadLogs(range, args, fetchLogs)}>
Download Download
</Link> </Link>
</div> </div>

View file

@ -29,6 +29,12 @@ const GET_TRANSACTIONS_CSV = gql`
} }
` `
const GET_SIMPLIFIED_TRANSACTIONS_CSV = gql`
query transactions($limit: Int, $from: Date, $until: Date) {
simplifiedTransactionsCsv(limit: $limit, from: $from, until: $until)
}
`
const GET_TRANSACTIONS = gql` const GET_TRANSACTIONS = gql`
query transactions($limit: Int, $from: Date, $until: Date) { query transactions($limit: Int, $from: Date, $until: Date) {
transactions(limit: $limit, from: $from, until: $until) { transactions(limit: $limit, from: $from, until: $until) {
@ -167,8 +173,14 @@ const Transactions = () => {
<LogsDowloaderPopover <LogsDowloaderPopover
title="Download logs" title="Download logs"
name="transactions" name="transactions"
query={GET_TRANSACTIONS_CSV} queries={[
GET_TRANSACTIONS_CSV,
GET_SIMPLIFIED_TRANSACTIONS_CSV
]}
getLogs={logs => R.path(['transactionsCsv'])(logs)} getLogs={logs => R.path(['transactionsCsv'])(logs)}
getSimplifiedLogs={logs =>
R.path(['simplifiedTransactionsCsv'])(logs)
}
/> />
</div> </div>
)} )}