fix: change coupons to promo codes
This commit is contained in:
parent
840afa866d
commit
59cb33570b
8 changed files with 87 additions and 88 deletions
|
|
@ -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('../../coupons')
|
||||
const promoCodeManager = require('../../promo-codes')
|
||||
|
||||
const serverVersion = require('../../../package.json').version
|
||||
const transactions = require('../transactions')
|
||||
|
|
@ -177,7 +177,7 @@ const typeDefs = gql`
|
|||
ip_address: String
|
||||
}
|
||||
|
||||
type Coupon {
|
||||
type PromoCode {
|
||||
id: ID!
|
||||
code: String!
|
||||
discount: Int!
|
||||
|
|
@ -276,7 +276,7 @@ const typeDefs = gql`
|
|||
config: JSONObject
|
||||
blacklist: [Blacklist]
|
||||
# userTokens: [UserToken]
|
||||
coupons: [Coupon]
|
||||
promoCodes: [PromoCode]
|
||||
cryptoRates: JSONObject
|
||||
fiatRates: [Rate]
|
||||
}
|
||||
|
|
@ -310,8 +310,8 @@ const typeDefs = gql`
|
|||
# revokeToken(token: String!): UserToken
|
||||
deleteBlacklistRow(cryptoCode: String!, address: String!): Blacklist
|
||||
insertBlacklistRow(cryptoCode: String!, address: String!): Blacklist
|
||||
createCoupon(code: String!, discount: Int!): Coupon
|
||||
deleteCoupon(couponId: ID!): Coupon
|
||||
createPromoCode(code: String!, discount: Int!): PromoCode
|
||||
deletePromoCode(codeId: ID!): PromoCode
|
||||
}
|
||||
`
|
||||
|
||||
|
|
@ -362,7 +362,7 @@ const resolvers = {
|
|||
accounts: () => settingsLoader.loadAccounts(),
|
||||
blacklist: () => blacklist.getBlacklist(),
|
||||
// userTokens: () => tokenManager.getTokenList()
|
||||
coupons: () => couponManager.getAvailableCoupons(),
|
||||
promoCodes: () => promoCodeManager.getAvailablePromoCodes(),
|
||||
cryptoRates: () =>
|
||||
settingsLoader.loadLatest().then(settings => {
|
||||
const pi = plugins(settings)
|
||||
|
|
@ -372,7 +372,7 @@ const resolvers = {
|
|||
withoutCommissions: pi.buildRatesNoCommission(r)
|
||||
}
|
||||
})
|
||||
}),
|
||||
}),
|
||||
fiatRates: () => forex.getFiatRates()
|
||||
},
|
||||
Mutation: {
|
||||
|
|
@ -396,8 +396,8 @@ const resolvers = {
|
|||
insertBlacklistRow: (...[, { cryptoCode, address }]) =>
|
||||
blacklist.insertIntoBlacklist(cryptoCode, address),
|
||||
// revokeToken: (...[, { token }]) => tokenManager.revokeToken(token)
|
||||
createCoupon: (...[, { code, discount }]) => couponManager.createCoupon(code, discount),
|
||||
deleteCoupon: (...[, { couponId }]) => couponManager.deleteCoupon(couponId)
|
||||
createPromoCode: (...[, { code, discount }]) => promoCodeManager.createPromoCode(code, discount),
|
||||
deletePromoCode: (...[, { codeId }]) => promoCodeManager.deletePromoCode(codeId)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ const machineLoader = require('./machine-loader')
|
|||
const customers = require('./customers')
|
||||
const coinUtils = require('./coin-utils')
|
||||
const commissionMath = require('./commission-math')
|
||||
const coupons = require('./coupons')
|
||||
const promoCodes = require('./promo-codes')
|
||||
|
||||
const mapValuesWithKey = _.mapValues.convert({
|
||||
cap: false
|
||||
|
|
@ -224,13 +224,13 @@ function plugins (settings, deviceId) {
|
|||
const testnetPromises = cryptoCodes.map(c => wallet.cryptoNetwork(settings, c))
|
||||
const pingPromise = recordPing(deviceTime, machineVersion, machineModel)
|
||||
const currentConfigVersionPromise = fetchCurrentConfigVersion()
|
||||
const currentAvailableCoupons = coupons.getNumberOfAvailableCoupons()
|
||||
const currentAvailablePromoCodes = promoCodes.getNumberOfAvailablePromoCodes()
|
||||
|
||||
const promises = [
|
||||
buildAvailableCassettes(),
|
||||
pingPromise,
|
||||
currentConfigVersionPromise
|
||||
].concat(tickerPromises, balancePromises, testnetPromises, currentAvailableCoupons)
|
||||
].concat(tickerPromises, balancePromises, testnetPromises, currentAvailablePromoCodes)
|
||||
|
||||
return Promise.all(promises)
|
||||
.then(arr => {
|
||||
|
|
@ -242,7 +242,7 @@ function plugins (settings, deviceId) {
|
|||
const testNets = arr.slice(2 * cryptoCodesCount + 3, arr.length - 1)
|
||||
const coinParams = _.zip(cryptoCodes, testNets)
|
||||
const coinsWithoutRate = _.map(mapCoinSettings, coinParams)
|
||||
const areThereAvailableCoupons = arr[arr.length - 1] > 0
|
||||
const areThereAvailablePromoCodes = arr[arr.length - 1] > 0
|
||||
|
||||
return {
|
||||
cassettes,
|
||||
|
|
@ -250,7 +250,7 @@ function plugins (settings, deviceId) {
|
|||
balances: buildBalances(balances),
|
||||
coins: _.zipWith(_.assign, coinsWithoutRate, tickers),
|
||||
configVersion,
|
||||
areThereAvailableCoupons
|
||||
areThereAvailablePromoCodes
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,29 @@
|
|||
const db = require('./db')
|
||||
const uuid = require('uuid')
|
||||
|
||||
function getAvailableCoupons () {
|
||||
function getAvailablePromoCodes () {
|
||||
const sql = `SELECT * FROM coupons WHERE soft_deleted=false`
|
||||
return db.any(sql)
|
||||
}
|
||||
|
||||
function getCoupon (code) {
|
||||
function getPromoCode (code) {
|
||||
const sql = `SELECT * FROM coupons WHERE code=$1 AND soft_deleted=false`
|
||||
return db.oneOrNone(sql, [code])
|
||||
}
|
||||
|
||||
function createCoupon (code, discount) {
|
||||
function createPromoCode (code, discount) {
|
||||
const sql = `INSERT INTO coupons (id, code, discount) VALUES ($1, $2, $3) RETURNING *`
|
||||
return db.one(sql, [uuid.v4(), code, discount])
|
||||
}
|
||||
|
||||
function deleteCoupon (couponId) {
|
||||
function deletePromoCode (id) {
|
||||
const sql = `UPDATE coupons SET soft_deleted=true WHERE id=$1`
|
||||
return db.none(sql, [couponId])
|
||||
return db.none(sql, [id])
|
||||
}
|
||||
|
||||
function getNumberOfAvailableCoupons () {
|
||||
function getNumberOfAvailablePromoCodes () {
|
||||
const sql = `SELECT COUNT(id) FROM coupons WHERE soft_deleted=false`
|
||||
return db.one(sql).then(res => res.count)
|
||||
}
|
||||
|
||||
module.exports = { getAvailableCoupons, getCoupon, createCoupon, deleteCoupon, getNumberOfAvailableCoupons }
|
||||
module.exports = { getAvailablePromoCodes, getPromoCode, createPromoCode, deletePromoCode, getNumberOfAvailablePromoCodes }
|
||||
|
|
@ -25,7 +25,7 @@ const E = require('./error')
|
|||
const customers = require('./customers')
|
||||
const logs = require('./logs')
|
||||
const compliance = require('./compliance')
|
||||
const couponManager = require('./coupons')
|
||||
const promoCodes = require('./promo-codes')
|
||||
const BN = require('./bn')
|
||||
const commissionMath = require('./commission-math')
|
||||
|
||||
|
|
@ -216,15 +216,15 @@ function verifyTx (req, res, next) {
|
|||
.catch(next)
|
||||
}
|
||||
|
||||
function verifyCoupon (req, res, next) {
|
||||
couponManager.getCoupon(req.body.codeInput)
|
||||
.then(coupon => {
|
||||
if (!coupon) return next()
|
||||
function verifyPromoCode (req, res, next) {
|
||||
promoCodes.getPromoCode(req.body.codeInput)
|
||||
.then(promoCode => {
|
||||
if (!promoCode) return next()
|
||||
|
||||
const transaction = req.body.tx
|
||||
const commissions = configManager.getCommissions(transaction.cryptoCode, req.deviceId, req.settings.config)
|
||||
const tickerRate = BN(transaction.rawTickerPrice)
|
||||
const discount = commissionMath.getDiscountRate(coupon.discount, commissions[transaction.direction])
|
||||
const discount = commissionMath.getDiscountRate(promoCode.discount, commissions[transaction.direction])
|
||||
const rates = {
|
||||
[transaction.cryptoCode]: {
|
||||
[transaction.direction]: (transaction.direction === 'cashIn')
|
||||
|
|
@ -234,7 +234,7 @@ function verifyCoupon (req, res, next) {
|
|||
}
|
||||
|
||||
respond(req, res, {
|
||||
coupon: coupon,
|
||||
promoCode: promoCode,
|
||||
newRates: rates
|
||||
})
|
||||
})
|
||||
|
|
@ -479,7 +479,7 @@ const configRequiredRoutes = [
|
|||
'/phone_code',
|
||||
'/customer',
|
||||
'/tx',
|
||||
'/verify_coupon'
|
||||
'/verify_promo_code'
|
||||
]
|
||||
|
||||
const app = express()
|
||||
|
|
@ -506,7 +506,7 @@ app.post('/state', stateChange)
|
|||
|
||||
app.post('/verify_user', verifyUser)
|
||||
app.post('/verify_transaction', verifyTx)
|
||||
app.post('/verify_coupon', verifyCoupon)
|
||||
app.post('/verify_promo_code', verifyPromoCode)
|
||||
|
||||
app.post('/phone_code', getCustomerWithPhoneCode)
|
||||
app.patch('/customer/:id', updateCustomer)
|
||||
|
|
|
|||
|
|
@ -10,17 +10,17 @@ import DataTable from 'src/components/tables/DataTable'
|
|||
import { H2, TL1 } from 'src/components/typography'
|
||||
import { ReactComponent as DeleteIcon } from 'src/styling/icons/action/delete/enabled.svg'
|
||||
|
||||
import styles from './CouponCodes.styles'
|
||||
import CouponCodesModal from './CouponCodesModal'
|
||||
import styles from './PromoCodes.styles'
|
||||
import PromoCodesModal from './PromoCodesModal'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const DUPLICATE_ERROR_MSG = 'There is already a coupon with that code!'
|
||||
const DUPLICATE_ERROR_MSG = 'There is already a promotion with that code!'
|
||||
const DEFAULT_ERROR_MSG = 'Failed to save'
|
||||
|
||||
const GET_COUPONS = gql`
|
||||
query coupons {
|
||||
coupons {
|
||||
const GET_PROMO_CODES = gql`
|
||||
query promoCodes {
|
||||
promoCodes {
|
||||
id
|
||||
code
|
||||
discount
|
||||
|
|
@ -28,17 +28,17 @@ const GET_COUPONS = gql`
|
|||
}
|
||||
`
|
||||
|
||||
const DELETE_COUPON = gql`
|
||||
mutation deleteCoupon($couponId: ID!) {
|
||||
deleteCoupon(couponId: $couponId) {
|
||||
const DELETE_CODE = gql`
|
||||
mutation deletePromoCode($codeId: ID!) {
|
||||
deletePromoCodes(codeId: $codeId) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const CREATE_COUPON = gql`
|
||||
mutation createCoupon($code: String!, $discount: Int!) {
|
||||
createCoupon(code: $code, discount: $discount) {
|
||||
const CREATE_CODE = gql`
|
||||
mutation createPromoCode($code: String!, $discount: Int!) {
|
||||
createPromoCode(code: $code, discount: $discount) {
|
||||
id
|
||||
code
|
||||
discount
|
||||
|
|
@ -46,38 +46,36 @@ const CREATE_COUPON = gql`
|
|||
}
|
||||
`
|
||||
|
||||
const Coupons = () => {
|
||||
const PromoCodes = () => {
|
||||
const classes = useStyles()
|
||||
|
||||
const [showModal, setShowModal] = useState(false)
|
||||
const [errorMsg, setErrorMsg] = useState(null)
|
||||
const toggleModal = () => setShowModal(!showModal)
|
||||
|
||||
const { data: couponResponse, loading } = useQuery(GET_COUPONS)
|
||||
const { data: codeResponse, loading } = useQuery(GET_PROMO_CODES)
|
||||
|
||||
const [deleteCoupon] = useMutation(DELETE_COUPON, {
|
||||
refetchQueries: () => ['coupons']
|
||||
const [deleteCode] = useMutation(DELETE_CODE, {
|
||||
refetchQueries: () => ['promoCodes']
|
||||
})
|
||||
|
||||
const [createCoupon] = useMutation(CREATE_COUPON, {
|
||||
refetchQueries: () => ['coupons']
|
||||
const [createCode] = useMutation(CREATE_CODE, {
|
||||
refetchQueries: () => ['promoCodes']
|
||||
})
|
||||
|
||||
const addCoupon = (code, discount) => {
|
||||
const addCode = (code, discount) => {
|
||||
setErrorMsg(null)
|
||||
createCoupon({
|
||||
createCode({
|
||||
variables: { code: code, discount: discount }
|
||||
})
|
||||
.then(res => {
|
||||
if (!res.errors) return setShowModal(false)
|
||||
|
||||
const duplicateCouponError = R.any(it =>
|
||||
const duplicateCodeError = R.any(it =>
|
||||
R.includes('duplicate', it?.message)
|
||||
)(res.errors)
|
||||
|
||||
const msg = duplicateCouponError
|
||||
? DUPLICATE_ERROR_MSG
|
||||
: DEFAULT_ERROR_MSG
|
||||
const msg = duplicateCodeError ? DUPLICATE_ERROR_MSG : DEFAULT_ERROR_MSG
|
||||
setErrorMsg(msg)
|
||||
})
|
||||
.catch(err => {
|
||||
|
|
@ -88,7 +86,7 @@ const Coupons = () => {
|
|||
|
||||
const elements = [
|
||||
{
|
||||
header: 'Coupon Code',
|
||||
header: 'Code',
|
||||
width: 300,
|
||||
textAlign: 'left',
|
||||
size: 'sm',
|
||||
|
|
@ -113,7 +111,7 @@ const Coupons = () => {
|
|||
view: t => (
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
deleteCoupon({ variables: { couponId: t.id } })
|
||||
deleteCode({ variables: { codeId: t.id } })
|
||||
}}>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
|
|
@ -123,8 +121,8 @@ const Coupons = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<TitleSection title="Discount Coupons"></TitleSection>
|
||||
{!loading && !R.isEmpty(couponResponse.coupons) && (
|
||||
<TitleSection title="Promo Codes"></TitleSection>
|
||||
{!loading && !R.isEmpty(codeResponse.promoCodes) && (
|
||||
<Box
|
||||
marginBottom={4}
|
||||
marginTop={-5}
|
||||
|
|
@ -132,32 +130,32 @@ const Coupons = () => {
|
|||
display="flex"
|
||||
justifyContent="flex-end">
|
||||
<Link color="primary" onClick={toggleModal}>
|
||||
Add new coupon
|
||||
Add new code
|
||||
</Link>
|
||||
</Box>
|
||||
)}
|
||||
{!loading && !R.isEmpty(couponResponse.coupons) && (
|
||||
{!loading && !R.isEmpty(codeResponse.promoCodes) && (
|
||||
<DataTable
|
||||
elements={elements}
|
||||
data={R.path(['coupons'])(couponResponse)}
|
||||
data={R.path(['promoCodes'])(codeResponse)}
|
||||
/>
|
||||
)}
|
||||
{!loading && R.isEmpty(couponResponse.coupons) && (
|
||||
{!loading && R.isEmpty(codeResponse.promoCodes) && (
|
||||
<Box display="flex" alignItems="left" flexDirection="column">
|
||||
<H2>Currently, there are no active coupon codes on your network.</H2>
|
||||
<Button onClick={toggleModal}>Add coupon</Button>
|
||||
<H2>Currently, there are no active promo codes on your network.</H2>
|
||||
<Button onClick={toggleModal}>Add Code</Button>
|
||||
</Box>
|
||||
)}
|
||||
<CouponCodesModal
|
||||
<PromoCodesModal
|
||||
showModal={showModal}
|
||||
onClose={() => {
|
||||
setErrorMsg(null)
|
||||
setShowModal(false)
|
||||
}}
|
||||
errorMsg={errorMsg}
|
||||
addCoupon={addCoupon}
|
||||
addCode={addCode}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default Coupons
|
||||
export default PromoCodes
|
||||
|
|
@ -11,7 +11,7 @@ import { Button } from 'src/components/buttons'
|
|||
import { TextInput, NumberInput } from 'src/components/inputs/formik'
|
||||
import { H3, TL1, P } from 'src/components/typography'
|
||||
|
||||
import styles from './CouponCodes.styles'
|
||||
import styles from './PromoCodes.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
|
|
@ -31,18 +31,18 @@ const validationSchema = Yup.object().shape({
|
|||
.max(100)
|
||||
})
|
||||
|
||||
const CouponCodesModal = ({ showModal, onClose, errorMsg, addCoupon }) => {
|
||||
const PromoCodesModal = ({ showModal, onClose, errorMsg, addCode }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const handleAddCoupon = (code, discount) => {
|
||||
addCoupon(R.toUpper(code), parseInt(discount))
|
||||
const handleAddCode = (code, discount) => {
|
||||
addCode(R.toUpper(code), parseInt(discount))
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{showModal && (
|
||||
<Modal
|
||||
title="Add coupon code discount"
|
||||
title="Add promo code discount"
|
||||
closeOnBackdropClick={true}
|
||||
width={600}
|
||||
height={500}
|
||||
|
|
@ -52,10 +52,10 @@ const CouponCodesModal = ({ showModal, onClose, errorMsg, addCoupon }) => {
|
|||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={({ code, discount }) => {
|
||||
handleAddCoupon(code, discount)
|
||||
handleAddCode(code, discount)
|
||||
}}>
|
||||
<Form id="coupon-form" className={classes.form}>
|
||||
<H3 className={classes.modalLabel1}>Coupon code name</H3>
|
||||
<Form id="promo-form" className={classes.form}>
|
||||
<H3 className={classes.modalLabel1}>Promo code name</H3>
|
||||
<Field
|
||||
name="code"
|
||||
autoFocus
|
||||
|
|
@ -69,13 +69,14 @@ const CouponCodesModal = ({ showModal, onClose, errorMsg, addCoupon }) => {
|
|||
<H3 className={classes.modalLabel2}>Define discount rate</H3>
|
||||
<Tooltip width={304}>
|
||||
<P>
|
||||
The discount rate inserted will be applied to the
|
||||
commissions of all transactions performed with this
|
||||
respective coupon code.
|
||||
This is a percentage discount off of your existing
|
||||
commission rates for a customer entering this code at the
|
||||
machine.
|
||||
</P>
|
||||
<P>
|
||||
(It should be a number between 0 (zero) and 100 (one
|
||||
hundred)).
|
||||
For instance, if you charge 8% commissions, and this code is
|
||||
set for 50%, then you'll instead be charging 4% on
|
||||
transactions using the code.
|
||||
</P>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
|
@ -97,9 +98,9 @@ const CouponCodesModal = ({ showModal, onClose, errorMsg, addCoupon }) => {
|
|||
{errorMsg && <ErrorMessage>{errorMsg}</ErrorMessage>}
|
||||
<Button
|
||||
type="submit"
|
||||
form="coupon-form"
|
||||
form="promo-form"
|
||||
className={classes.submit}>
|
||||
Add coupon
|
||||
Add code
|
||||
</Button>
|
||||
</div>
|
||||
</Form>
|
||||
|
|
@ -110,4 +111,4 @@ const CouponCodesModal = ({ showModal, onClose, errorMsg, addCoupon }) => {
|
|||
)
|
||||
}
|
||||
|
||||
export default CouponCodesModal
|
||||
export default PromoCodesModal
|
||||
|
|
@ -22,7 +22,7 @@ import { Customers, CustomerProfile } from 'src/pages/Customers'
|
|||
import Dashboard from 'src/pages/Dashboard'
|
||||
import Funding from 'src/pages/Funding'
|
||||
import Locales from 'src/pages/Locales'
|
||||
import Coupons from 'src/pages/LoyaltyPanel/CouponCodes'
|
||||
import PromoCodes from 'src/pages/LoyaltyPanel/PromoCodes'
|
||||
import MachineLogs from 'src/pages/MachineLogs'
|
||||
import Machines from 'src/pages/Machines'
|
||||
import CashCassettes from 'src/pages/Maintenance/CashCassettes'
|
||||
|
|
@ -212,10 +212,10 @@ const tree = [
|
|||
component: Blacklist
|
||||
},
|
||||
{
|
||||
key: 'discount-coupons',
|
||||
label: 'Discount Coupons',
|
||||
route: '/compliance/loyalty/coupons',
|
||||
component: Coupons
|
||||
key: 'promo-codes',
|
||||
label: 'Promo Codes',
|
||||
route: '/compliance/loyalty/codes',
|
||||
component: PromoCodes
|
||||
},
|
||||
{
|
||||
key: 'customer',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue