diff --git a/lamassu-admin-elm/src/Common/TransactionTypes.elm b/lamassu-admin-elm/src/Common/TransactionTypes.elm index cd801b54..d256509f 100644 --- a/lamassu-admin-elm/src/Common/TransactionTypes.elm +++ b/lamassu-admin-elm/src/Common/TransactionTypes.elm @@ -18,6 +18,7 @@ type alias CashInTxRec = , cryptoAtoms : Int , cryptoCode : CryptoCode , fiat : Float + , commissionPercentage : Maybe Float , fiatCode : String , txHash : Maybe String , phone : Maybe String @@ -37,6 +38,7 @@ type alias CashOutTxRec = , cryptoAtoms : Int , cryptoCode : CryptoCode , fiat : Float + , commissionPercentage : Maybe Float , fiatCode : String , status : String , dispense : Bool diff --git a/lamassu-admin-elm/src/Transaction/Decoder.elm b/lamassu-admin-elm/src/Transaction/Decoder.elm index a5a98d72..b9cfa652 100644 --- a/lamassu-admin-elm/src/Transaction/Decoder.elm +++ b/lamassu-admin-elm/src/Transaction/Decoder.elm @@ -65,6 +65,7 @@ cashInTxDecoder = |> required "cryptoAtoms" intString |> required "cryptoCode" cryptoCodeDecoder |> required "fiat" floatString + |> required "commissionPercentage" (nullable floatString) |> required "fiatCode" string |> required "txHash" (nullable string) |> required "phone" (nullable string) @@ -91,6 +92,7 @@ cashOutTxDecoder = |> required "cryptoAtoms" intString |> required "cryptoCode" cryptoCodeDecoder |> required "fiat" floatString + |> required "commissionPercentage" (nullable floatString) |> required "fiatCode" string |> required "status" string |> required "dispense" bool diff --git a/lamassu-admin-elm/src/Transactions.elm b/lamassu-admin-elm/src/Transactions.elm index be77c4ff..d4870f21 100644 --- a/lamassu-admin-elm/src/Transactions.elm +++ b/lamassu-admin-elm/src/Transactions.elm @@ -134,6 +134,7 @@ rowView tx = ] , td [] [ cryptoCodeDisplay cashIn.cryptoCode ] , td [ class [ C.NumberColumn ] ] [ text (format "0,0.00" cashIn.fiat) ] + , td [ class [ C.NumberColumn ] ] [ text (format "0,0.00" (Maybe.withDefault 0.0 cashIn.commissionPercentage)) ] , td [ class [ C.NumberColumn ] ] [ text (Maybe.withDefault "" cashIn.phone) ] , td [ class [ C.TxAddress ] ] [ text cashIn.toAddress ] ] @@ -158,6 +159,7 @@ rowView tx = ] , td [] [ cryptoCodeDisplay cashOut.cryptoCode ] , td [ class [ C.NumberColumn ] ] [ text (format "0,0.00" cashOut.fiat) ] + , td [ class [ C.NumberColumn ] ] [ text (format "0,0.00" (Maybe.withDefault 0.0 cashOut.commissionPercentage)) ] , td [ class [ C.NumberColumn ] ] [ text (Maybe.withDefault "" cashOut.phone) ] , td [ class [ C.TxAddress ] ] [ text cashOut.toAddress ] ] @@ -177,6 +179,7 @@ tableView txs = , td [ class [ C.TxMachine ] ] [ text "Machine" ] , td [ colspan 2 ] [ text "Crypto" ] , td [ class [ C.TxAmount ] ] [ text "Fiat" ] + , td [ class [ C.TxAmount ] ] [ text "Commission" ] , td [ class [ C.TxPhone ] ] [ text "Phone" ] , td [ class [ C.TxAddress ] ] [ text "To address" ] ] diff --git a/lib/cash-out/cash-out-helper.js b/lib/cash-out/cash-out-helper.js index f6e79357..f4e7ccf9 100644 --- a/lib/cash-out/cash-out-helper.js +++ b/lib/cash-out/cash-out-helper.js @@ -11,7 +11,7 @@ module.exports = {redeemableTxs, toObj, toDb} const mapValuesWithKey = _.mapValues.convert({cap: false}) function convertBigNumFields (obj) { - const convert = (value, key) => _.includes(key, ['cryptoAtoms', 'fiat']) + const convert = (value, key) => _.includes(key, ['cryptoAtoms', 'fiat', 'commissionPercentage']) ? value.toString() : value diff --git a/lib/plugins.js b/lib/plugins.js index c21bab22..dca6d3a1 100644 --- a/lib/plugins.js +++ b/lib/plugins.js @@ -32,6 +32,15 @@ const PONG_TTL = '1 week' const tradesQueues = {} function plugins (settings, deviceId) { + function getCommissionForTx (tx) { + const direction = _.get('direction', tx) + const cryptoCode = _.get('cryptoCode', tx) + const cryptoConfig = configManager.scoped(cryptoCode, deviceId, settings.config) + + if (direction === 'cashIn') return /* cashInCommission */ BN(cryptoConfig.cashInCommission).div(100) + if (direction === 'cashOut') return /* cashOutCommission */ BN(cryptoConfig.cashOutCommission).div(100) + } + function buildRates (tickers) { const config = configManager.machineScoped(deviceId, settings.config) const cryptoCodes = config.cryptoCurrencies @@ -783,7 +792,8 @@ function plugins (settings, deviceId) { buy, sell, notificationsEnabled, - notifyOperator + notifyOperator, + getCommissionForTx } } diff --git a/lib/tx.js b/lib/tx.js index 5afd97cb..63d454f5 100644 --- a/lib/tx.js +++ b/lib/tx.js @@ -4,7 +4,7 @@ const CashInTx = require('./cash-in/cash-in-tx') const CashOutTx = require('./cash-out/cash-out-tx') function process (tx, pi) { - const mtx = massage(tx) + const mtx = massage(tx, pi) if (mtx.direction === 'cashIn') return CashInTx.post(mtx, pi) if (mtx.direction === 'cashOut') return CashOutTx.post(mtx, pi) @@ -16,11 +16,12 @@ function post (tx, pi) { .then(_.set('dirty', false)) } -function massage (tx) { +function massage (tx, pi) { const isDateField = r => r === 'created' || _.endsWith('_time', r) const transformDate = (v, k) => isDateField(k) ? new Date(v) : v const mapValuesWithKey = _.mapValues.convert({'cap': false}) const transformDates = r => mapValuesWithKey(transformDate, r) + const logCommission = r => _.assign(r, {commissionPercentage: pi.getCommissionForTx(tx)}) const mapBN = r => { const update = r.direction === 'cashIn' @@ -39,7 +40,7 @@ function massage (tx) { return _.assign(r, update) } - const mapper = _.flow(transformDates, mapBN, _.unset('dirty')) + const mapper = _.flow(transformDates, logCommission, mapBN, _.unset('dirty')) return mapper(tx) } diff --git a/public/elm.js b/public/elm.js index a8444e50..315eddde 100644 --- a/public/elm.js +++ b/public/elm.js @@ -28477,7 +28477,9 @@ var _user$project$Common_TransactionTypes$CashInTxRec = function (a) { return function (m) { return function (n) { return function (o) { - return {id: a, machineName: b, toAddress: c, cryptoAtoms: d, cryptoCode: e, fiat: f, fiatCode: g, txHash: h, phone: i, error: j, operatorCompleted: k, send: l, sendConfirmed: m, expired: n, created: o}; + return function (p) { + return {id: a, machineName: b, toAddress: c, cryptoAtoms: d, cryptoCode: e, fiat: f, commissionPercentage: g, fiatCode: h, txHash: i, phone: j, error: k, operatorCompleted: l, send: m, sendConfirmed: n, expired: o, created: p}; + }; }; }; }; @@ -28508,7 +28510,9 @@ var _user$project$Common_TransactionTypes$CashOutTxRec = function (a) { return function (m) { return function (n) { return function (o) { - return {id: a, machineName: b, toAddress: c, cryptoAtoms: d, cryptoCode: e, fiat: f, fiatCode: g, status: h, dispense: i, notified: j, redeemed: k, phone: l, error: m, created: n, confirmed: o}; + return function (p) { + return {id: a, machineName: b, toAddress: c, cryptoAtoms: d, cryptoCode: e, fiat: f, commissionPercentage: g, fiatCode: h, status: i, dispense: j, notified: k, redeemed: l, phone: m, error: n, created: o, confirmed: p}; + }; }; }; }; @@ -33986,29 +33990,33 @@ var _user$project$Transaction_Decoder$cashInTxDecoder = A3( _elm_lang$core$Json_Decode$string, A3( _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$required, - 'fiat', - _user$project$Transaction_Decoder$floatString, + 'commissionPercentage', + _elm_lang$core$Json_Decode$nullable(_user$project$Transaction_Decoder$floatString), A3( _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$required, - 'cryptoCode', - _user$project$Transaction_Decoder$cryptoCodeDecoder, + 'fiat', + _user$project$Transaction_Decoder$floatString, A3( _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$required, - 'cryptoAtoms', - _user$project$Transaction_Decoder$intString, + 'cryptoCode', + _user$project$Transaction_Decoder$cryptoCodeDecoder, A3( _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$required, - 'toAddress', - _elm_lang$core$Json_Decode$string, + 'cryptoAtoms', + _user$project$Transaction_Decoder$intString, A3( _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$required, - 'machineName', + 'toAddress', _elm_lang$core$Json_Decode$string, A3( _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$required, - 'id', + 'machineName', _elm_lang$core$Json_Decode$string, - _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$decode(_user$project$Common_TransactionTypes$CashInTxRec)))))))))))))))); + A3( + _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$required, + 'id', + _elm_lang$core$Json_Decode$string, + _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$decode(_user$project$Common_TransactionTypes$CashInTxRec))))))))))))))))); var _user$project$Transaction_Decoder$cashOutTxDecoder = A3( _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$required, 'confirmedAt', @@ -34047,29 +34055,33 @@ var _user$project$Transaction_Decoder$cashOutTxDecoder = A3( _elm_lang$core$Json_Decode$string, A3( _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$required, - 'fiat', - _user$project$Transaction_Decoder$floatString, + 'commissionPercentage', + _elm_lang$core$Json_Decode$nullable(_user$project$Transaction_Decoder$floatString), A3( _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$required, - 'cryptoCode', - _user$project$Transaction_Decoder$cryptoCodeDecoder, + 'fiat', + _user$project$Transaction_Decoder$floatString, A3( _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$required, - 'cryptoAtoms', - _user$project$Transaction_Decoder$intString, + 'cryptoCode', + _user$project$Transaction_Decoder$cryptoCodeDecoder, A3( _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$required, - 'toAddress', - _elm_lang$core$Json_Decode$string, + 'cryptoAtoms', + _user$project$Transaction_Decoder$intString, A3( _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$required, - 'machineName', + 'toAddress', _elm_lang$core$Json_Decode$string, A3( _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$required, - 'id', + 'machineName', _elm_lang$core$Json_Decode$string, - _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$decode(_user$project$Common_TransactionTypes$CashOutTxRec)))))))))))))))); + A3( + _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$required, + 'id', + _elm_lang$core$Json_Decode$string, + _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$decode(_user$project$Common_TransactionTypes$CashOutTxRec))))))))))))))))); var _user$project$Transaction_Decoder$txDecode = function (txClass) { var _p4 = txClass; switch (_p4) { @@ -34289,7 +34301,10 @@ var _user$project$Transactions$rowView = function (tx) { { ctor: '::', _0: _elm_lang$html$Html$text( - A2(_elm_lang$core$Maybe$withDefault, '', _p3.phone)), + A2( + _ggb$numeral_elm$Numeral$format, + '0,0.00', + A2(_elm_lang$core$Maybe$withDefault, 0.0, _p3.commissionPercentage))), _1: {ctor: '[]'} }), _1: { @@ -34301,17 +34316,38 @@ var _user$project$Transactions$rowView = function (tx) { _0: _user$project$Css_Admin$class( { ctor: '::', - _0: _user$project$Css_Classes$TxAddress, + _0: _user$project$Css_Classes$NumberColumn, _1: {ctor: '[]'} }), _1: {ctor: '[]'} }, { ctor: '::', - _0: _elm_lang$html$Html$text(_p3.toAddress), + _0: _elm_lang$html$Html$text( + A2(_elm_lang$core$Maybe$withDefault, '', _p3.phone)), _1: {ctor: '[]'} }), - _1: {ctor: '[]'} + _1: { + ctor: '::', + _0: A2( + _elm_lang$html$Html$td, + { + ctor: '::', + _0: _user$project$Css_Admin$class( + { + ctor: '::', + _0: _user$project$Css_Classes$TxAddress, + _1: {ctor: '[]'} + }), + _1: {ctor: '[]'} + }, + { + ctor: '::', + _0: _elm_lang$html$Html$text(_p3.toAddress), + _1: {ctor: '[]'} + }), + _1: {ctor: '[]'} + } } } } @@ -34460,7 +34496,10 @@ var _user$project$Transactions$rowView = function (tx) { { ctor: '::', _0: _elm_lang$html$Html$text( - A2(_elm_lang$core$Maybe$withDefault, '', _p4.phone)), + A2( + _ggb$numeral_elm$Numeral$format, + '0,0.00', + A2(_elm_lang$core$Maybe$withDefault, 0.0, _p4.commissionPercentage))), _1: {ctor: '[]'} }), _1: { @@ -34472,17 +34511,38 @@ var _user$project$Transactions$rowView = function (tx) { _0: _user$project$Css_Admin$class( { ctor: '::', - _0: _user$project$Css_Classes$TxAddress, + _0: _user$project$Css_Classes$NumberColumn, _1: {ctor: '[]'} }), _1: {ctor: '[]'} }, { ctor: '::', - _0: _elm_lang$html$Html$text(_p4.toAddress), + _0: _elm_lang$html$Html$text( + A2(_elm_lang$core$Maybe$withDefault, '', _p4.phone)), _1: {ctor: '[]'} }), - _1: {ctor: '[]'} + _1: { + ctor: '::', + _0: A2( + _elm_lang$html$Html$td, + { + ctor: '::', + _0: _user$project$Css_Admin$class( + { + ctor: '::', + _0: _user$project$Css_Classes$TxAddress, + _1: {ctor: '[]'} + }), + _1: {ctor: '[]'} + }, + { + ctor: '::', + _0: _elm_lang$html$Html$text(_p4.toAddress), + _1: {ctor: '[]'} + }), + _1: {ctor: '[]'} + } } } } @@ -34633,14 +34693,14 @@ var _user$project$Transactions$tableView = function (txs) { _0: _user$project$Css_Admin$class( { ctor: '::', - _0: _user$project$Css_Classes$TxPhone, + _0: _user$project$Css_Classes$TxAmount, _1: {ctor: '[]'} }), _1: {ctor: '[]'} }, { ctor: '::', - _0: _elm_lang$html$Html$text('Phone'), + _0: _elm_lang$html$Html$text('Commission'), _1: {ctor: '[]'} }), _1: { @@ -34652,17 +34712,37 @@ var _user$project$Transactions$tableView = function (txs) { _0: _user$project$Css_Admin$class( { ctor: '::', - _0: _user$project$Css_Classes$TxAddress, + _0: _user$project$Css_Classes$TxPhone, _1: {ctor: '[]'} }), _1: {ctor: '[]'} }, { ctor: '::', - _0: _elm_lang$html$Html$text('To address'), + _0: _elm_lang$html$Html$text('Phone'), _1: {ctor: '[]'} }), - _1: {ctor: '[]'} + _1: { + ctor: '::', + _0: A2( + _elm_lang$html$Html$td, + { + ctor: '::', + _0: _user$project$Css_Admin$class( + { + ctor: '::', + _0: _user$project$Css_Classes$TxAddress, + _1: {ctor: '[]'} + }), + _1: {ctor: '[]'} + }, + { + ctor: '::', + _0: _elm_lang$html$Html$text('To address'), + _1: {ctor: '[]'} + }), + _1: {ctor: '[]'} + } } } }