diff --git a/lib/commission-math.js b/lib/commission-math.js
new file mode 100644
index 00000000..a3fc89c0
--- /dev/null
+++ b/lib/commission-math.js
@@ -0,0 +1,41 @@
+const BN = require('./bn')
+const configManager = require('./new-config-manager')
+const coinUtils = require('./coin-utils')
+
+function truncateCrypto (cryptoAtoms, cryptoCode) {
+ const DECIMAL_PLACES = 3
+ if (cryptoAtoms.eq(0)) return cryptoAtoms
+
+ const scale = 5 // TODO: change this to coins.displayScale when coins have that attribute
+ const scaleFactor = BN(10).pow(scale)
+
+ return BN(cryptoAtoms).truncated().div(scaleFactor)
+ .round(DECIMAL_PLACES).times(scaleFactor)
+}
+
+function fiatToCrypto (tx, rec, deviceId, config) {
+ const usableFiat = rec.fiat - rec.cashInFee
+
+ const commissions = configManager.getCommissions(tx.cryptoCode, deviceId, config)
+ const tickerRate = BN(tx.rawTickerPrice)
+ const discount = getDiscountRate(tx.discount, commissions[tx.direction])
+ const rate = tickerRate.mul(discount).round(5)
+ const unitScale = coinUtils.getCryptoCurrency(tx.cryptoCode).unitScale
+ const unitScaleFactor = BN(10).pow(unitScale)
+
+ return truncateCrypto(BN(usableFiat).div(rate.div(unitScaleFactor)), tx.cryptoCode)
+}
+
+function getDiscountRate (discount, commission) {
+ const bnDiscount = discount ? BN(discount) : BN(0)
+ const bnCommission = BN(commission)
+ const percentageDiscount = BN(1).sub(bnDiscount.div(100))
+ const percentageCommission = bnCommission.div(100)
+ return BN(1).add(percentageDiscount.mul(percentageCommission))
+}
+
+module.exports = {
+ truncateCrypto,
+ fiatToCrypto,
+ getDiscountRate
+}
diff --git a/lib/coupon-manager.js b/lib/coupons.js
similarity index 77%
rename from lib/coupon-manager.js
rename to lib/coupons.js
index 7963484e..f6bb1254 100644
--- a/lib/coupon-manager.js
+++ b/lib/coupons.js
@@ -21,4 +21,9 @@ function softDeleteCoupon (couponId) {
return db.none(sql, [couponId])
}
-module.exports = { getAvailableCoupons, getCoupon, createCoupon, softDeleteCoupon }
+function getNumberOfAvailableCoupons () {
+ const sql = `SELECT COUNT(id) FROM coupons WHERE soft_deleted=false`
+ return db.one(sql).then(res => res.count)
+}
+
+module.exports = { getAvailableCoupons, getCoupon, createCoupon, softDeleteCoupon, getNumberOfAvailableCoupons }
diff --git a/lib/new-admin/graphql/schema.js b/lib/new-admin/graphql/schema.js
index 529da459..5648e229 100644
--- a/lib/new-admin/graphql/schema.js
+++ b/lib/new-admin/graphql/schema.js
@@ -13,7 +13,7 @@ const settingsLoader = require('../../new-settings-loader')
// const tokenManager = require('../../token-manager')
const blacklist = require('../../blacklist')
const machineEventsByIdBatch = require("../../postgresql_interface").machineEventsByIdBatch
-const couponManager = require('../../coupon-manager')
+const couponManager = require('../../coupons')
const serverVersion = require('../../../package.json').version
@@ -179,7 +179,6 @@ const typeDefs = gql`
id: ID!
code: String!
discount: Int!
- soft_deleted: Boolean
}
type Transaction {
@@ -295,7 +294,7 @@ const typeDefs = gql`
deleteBlacklistRow(cryptoCode: String!, address: String!): Blacklist
insertBlacklistRow(cryptoCode: String!, address: String!): Blacklist
createCoupon(code: String!, discount: Int!): Coupon
- softDeleteCoupon(couponId: ID!): Coupon
+ deleteCoupon(couponId: ID!): Coupon
}
`
@@ -370,7 +369,7 @@ const resolvers = {
blacklist.insertIntoBlacklist(cryptoCode, address),
// revokeToken: (...[, { token }]) => tokenManager.revokeToken(token)
createCoupon: (...[, { code, discount }]) => couponManager.createCoupon(code, discount),
- softDeleteCoupon: (...[, { couponId }]) => couponManager.softDeleteCoupon(couponId)
+ deleteCoupon: (...[, { couponId }]) => couponManager.deleteCoupon(couponId)
}
}
diff --git a/lib/plugins.js b/lib/plugins.js
index c567b358..139a6a34 100644
--- a/lib/plugins.js
+++ b/lib/plugins.js
@@ -21,6 +21,8 @@ const cashOutHelper = require('./cash-out/cash-out-helper')
const machineLoader = require('./machine-loader')
const customers = require('./customers')
const coinUtils = require('./coin-utils')
+const commissionMath = require('./commission-math')
+const coupons = require('./coupons')
const mapValuesWithKey = _.mapValues.convert({
cap: false
@@ -190,11 +192,6 @@ function plugins (settings, deviceId) {
.then(row => row.id)
}
- function getNumberOfAvailableCoupons () {
- const sql = `SELECT COUNT(id) FROM coupons WHERE soft_deleted=false`
- return db.one(sql).then(res => res.count)
- }
-
function mapCoinSettings (coinParams) {
const cryptoCode = coinParams[0]
const cryptoNetwork = coinParams[1]
@@ -227,7 +224,7 @@ function plugins (settings, deviceId) {
const testnetPromises = cryptoCodes.map(c => wallet.cryptoNetwork(settings, c))
const pingPromise = recordPing(deviceTime, machineVersion, machineModel)
const currentConfigVersionPromise = fetchCurrentConfigVersion()
- const currentAvailableCoupons = getNumberOfAvailableCoupons()
+ const currentAvailableCoupons = coupons.getNumberOfAvailableCoupons()
const promises = [
buildAvailableCassettes(),
@@ -459,7 +456,7 @@ function plugins (settings, deviceId) {
function buyAndSell (rec, doBuy, tx) {
const cryptoCode = rec.cryptoCode
const fiatCode = rec.fiatCode
- const cryptoAtoms = doBuy ? fiatToCrypto(tx, rec) : rec.cryptoAtoms.neg()
+ const cryptoAtoms = doBuy ? commissionMath.fiatToCrypto(tx, rec, deviceId, settings.config) : rec.cryptoAtoms.neg()
const market = [fiatCode, cryptoCode].join('')
@@ -475,38 +472,6 @@ function plugins (settings, deviceId) {
})
}
- function truncateCrypto (cryptoAtoms, cryptoCode) {
- const DECIMAL_PLACES = 3
- if (cryptoAtoms.eq(0)) return cryptoAtoms
-
- const scale = 5 // TODO: change this to coins.displayScale when coins have that attribute
- const scaleFactor = BN(10).pow(scale)
-
- return BN(cryptoAtoms).truncated().div(scaleFactor)
- .round(DECIMAL_PLACES).times(scaleFactor)
- }
-
- function fiatToCrypto (tx, rec) {
- const usableFiat = rec.fiat - rec.cashInFee
-
- const commissions = configManager.getCommissions(tx.cryptoCode, deviceId, settings.config)
- const tickerRate = BN(tx.rawTickerPrice)
- const discount = getDiscountRate(tx.discount, commissions[tx.direction])
- const rate = tickerRate.mul(discount).round(5)
- const unitScale = coinUtils.getCryptoCurrency(tx.cryptoCode).unitScale
- const unitScaleFactor = BN(10).pow(unitScale)
-
- return truncateCrypto(BN(usableFiat).div(rate.div(unitScaleFactor)), tx.cryptoCode)
- }
-
- function getDiscountRate (discount, commission) {
- const bnDiscount = discount ? BN(discount) : BN(0)
- const bnCommission = BN(commission)
- const percentageDiscount = BN(1).sub(bnDiscount.div(100))
- const percentageCommission = bnCommission.div(100)
- return BN(1).add(percentageDiscount.mul(percentageCommission))
- }
-
function consolidateTrades (cryptoCode, fiatCode) {
const market = [fiatCode, cryptoCode].join('')
diff --git a/lib/routes.js b/lib/routes.js
index e57f6a23..71fc86e3 100644
--- a/lib/routes.js
+++ b/lib/routes.js
@@ -25,8 +25,9 @@ const E = require('./error')
const customers = require('./customers')
const logs = require('./logs')
const compliance = require('./compliance')
-const couponManager = require('./coupon-manager')
+const couponManager = require('./coupons')
const BN = require('./bn')
+const commissionMath = require('./commission-math')
const version = require('../package.json').version
@@ -223,7 +224,7 @@ function verifyCoupon (req, res, next) {
const transaction = req.body.tx
const commissions = configManager.getCommissions(transaction.cryptoCode, req.deviceId, req.settings.config)
const tickerRate = BN(transaction.rawTickerPrice)
- const discount = getDiscountRate(coupon.discount, commissions[transaction.direction])
+ const discount = commissionMath.getDiscountRate(coupon.discount, commissions[transaction.direction])
const rates = {
[transaction.cryptoCode]: {
[transaction.direction]: (transaction.direction === 'cashIn')
@@ -240,12 +241,6 @@ function verifyCoupon (req, res, next) {
.catch(next)
}
-function getDiscountRate (discount, commission) {
- const percentageDiscount = BN(1).sub(BN(discount).div(100))
- const percentageCommission = BN(commission).div(100)
- return BN(1).add(percentageDiscount.mul(percentageCommission))
-}
-
function addOrUpdateCustomer (req) {
const customerData = req.body
const machineVersion = req.query.version
diff --git a/migrations/1603886141913-coupon-codes.js b/migrations/1603886141913-coupon-codes.js
index 442fd335..e3180715 100644
--- a/migrations/1603886141913-coupon-codes.js
+++ b/migrations/1603886141913-coupon-codes.js
@@ -8,7 +8,7 @@ exports.up = function (next) {
code TEXT NOT NULL,
discount SMALLINT NOT NULL,
soft_deleted BOOLEAN DEFAULT false )`,
- `CREATE UNIQUE INDEX uq_code ON coupons USING btree(code) WHERE NOT soft_deleted`
+ `CREATE UNIQUE INDEX uq_code ON coupons (code) WHERE NOT soft_deleted`
]
db.multi(sql, next)
diff --git a/migrations/1606910357208-change-trades.js b/migrations/1606910357208-change-trades.js
deleted file mode 100644
index a7a402c8..00000000
--- a/migrations/1606910357208-change-trades.js
+++ /dev/null
@@ -1,16 +0,0 @@
-const db = require('./db')
-
-exports.up = function (next) {
- var sql = [
- 'ALTER TABLE trades ADD COLUMN tx_in_id UUID UNIQUE',
- 'ALTER TABLE trades ADD CONSTRAINT fk_tx_in FOREIGN KEY (tx_in_id) REFERENCES cash_in_txs (id)',
- 'ALTER TABLE trades ADD COLUMN tx_out_id UUID UNIQUE',
- 'ALTER TABLE trades ADD CONSTRAINT fk_tx_out FOREIGN KEY (tx_in_id) REFERENCES cash_out_txs (id)'
- ]
-
- db.multi(sql, next)
-}
-
-exports.down = function (next) {
- next()
-}
diff --git a/new-lamassu-admin/src/pages/LoyaltyPanel/CouponCodes.js b/new-lamassu-admin/src/pages/LoyaltyPanel/CouponCodes.js
index 16ebfbd4..98ee1f4a 100644
--- a/new-lamassu-admin/src/pages/LoyaltyPanel/CouponCodes.js
+++ b/new-lamassu-admin/src/pages/LoyaltyPanel/CouponCodes.js
@@ -21,14 +21,13 @@ const GET_COUPONS = gql`
id
code
discount
- soft_deleted
}
}
`
-const SOFT_DELETE_COUPON = gql`
- mutation softDeleteCoupon($couponId: ID!) {
- softDeleteCoupon(couponId: $couponId) {
+const DELETE_COUPON = gql`
+ mutation deleteCoupon($couponId: ID!) {
+ deleteCoupon(couponId: $couponId) {
id
}
}
@@ -40,7 +39,6 @@ const CREATE_COUPON = gql`
id
code
discount
- soft_deleted
}
}
`
@@ -53,7 +51,7 @@ const Coupons = () => {
const { data: couponResponse, loading } = useQuery(GET_COUPONS)
- const [softDeleteCoupon] = useMutation(SOFT_DELETE_COUPON, {
+ const [softDeleteCoupon] = useMutation(DELETE_COUPON, {
refetchQueries: () => ['coupons']
})
diff --git a/new-lamassu-admin/src/pages/LoyaltyPanel/LoyaltyPanel.js b/new-lamassu-admin/src/pages/LoyaltyPanel/LoyaltyPanel.js
deleted file mode 100644
index 0b624386..00000000
--- a/new-lamassu-admin/src/pages/LoyaltyPanel/LoyaltyPanel.js
+++ /dev/null
@@ -1,97 +0,0 @@
-import { makeStyles } from '@material-ui/core'
-import Grid from '@material-ui/core/Grid'
-import React from 'react'
-import {
- Route,
- Switch,
- Redirect,
- useLocation,
- useHistory
-} from 'react-router-dom'
-
-import Sidebar from 'src/components/layout/Sidebar'
-import TitleSection from 'src/components/layout/TitleSection'
-
-import CouponCodes from './CouponCodes'
-import IndividualDiscounts from './IndividualDiscounts'
-import LoyaltyDiscounts from './LoyaltyDiscounts'
-
-const styles = {
- grid: {
- flex: 1,
- height: '100%'
- },
- content: {
- flex: 1,
- marginLeft: 48,
- paddingTop: 15
- }
-}
-
-const useStyles = makeStyles(styles)
-
-const innerRoutes = [
- {
- key: 'individual-discounts',
- label: 'Individual Discounts',
- route: '/compliance/loyalty/individual-discounts',
- component: IndividualDiscounts
- },
- {
- key: 'loyalty-discounts',
- label: 'Loyalty Discounts',
- route: '/compliance/loyalty/discounts',
- component: LoyaltyDiscounts
- },
- {
- key: 'coupon-codes',
- label: 'Coupon Codes',
- route: '/compliance/loyalty/coupons',
- component: CouponCodes
- }
-]
-
-const Routes = ({ wizard }) => (
-
-
-
- {innerRoutes.map(({ route, component: Page, key }) => (
-
-
-
- ))}
-
-)
-
-const LoyaltyPanel = ({ wizard = false }) => {
- const classes = useStyles()
- const history = useHistory()
- const location = useLocation()
-
- const isSelected = it => location.pathname === it.route
-
- const onClick = it => history.push(it.route)
-
- return (
- <>
-
-
- it.label}
- onClick={onClick}
- />
-
-
-
-
- >
- )
-}
-
-export default LoyaltyPanel