Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for deletion of testing customers #1186

Open
wants to merge 2 commits into
base: future-stuff-old-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions lib/customers.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function add (customer) {
* @returns {object} Customer
*/
function get (phone) {
const sql = 'select * from customers where phone=$1'
const sql = 'select * from customers where phone=$1 and enabled'
return db.oneOrNone(sql, [phone])
.then(camelize)
}
Expand Down Expand Up @@ -459,7 +459,7 @@ function addComplianceOverrides (id, customer, userToken) {
*/
function batch () {
const sql = `select * from customers
where id != $1
where id != $1 and enabled
order by created desc limit $2`
return db.any(sql, [ anonymous.uuid, NUM_RESULTS ])
.then(customers => Promise.all(_.map(customer => {
Expand Down Expand Up @@ -493,7 +493,8 @@ function getCustomersList (phone = null, name = null, address = null, id = null)
c.front_camera_path, c.front_camera_override,
c.phone, c.sms_override, c.id_card_data, c.id_card_data_override, c.id_card_data_expiration,
c.id_card_photo_path, c.id_card_photo_override, c.us_ssn, c.us_ssn_override, c.sanctions,
c.sanctions_at, c.sanctions_override, c.is_test_customer, c.created, t.tx_class, t.fiat, t.fiat_code, t.created as last_transaction, cn.notes,
c.sanctions_at, c.sanctions_override, c.is_test_customer, c.created,
t.tx_class, t.fiat, t.fiat_code, t.created as last_transaction, cn.notes,
row_number() OVER (partition by c.id order by t.created desc) AS rn,
sum(CASE WHEN t.id IS NOT NULL THEN 1 ELSE 0 END) OVER (partition by c.id) AS total_txs,
coalesce(sum(CASE WHEN error_code IS NULL OR error_code NOT IN ($1^) THEN t.fiat ELSE 0 END) OVER (partition by c.id), 0) AS total_spent, ccf.custom_fields
Expand All @@ -513,11 +514,12 @@ function getCustomersList (phone = null, name = null, address = null, id = null)
GROUP BY customer_notes.customer_id
) cn ON c.id = cn.customer_id
WHERE c.id != $2
AND c.enabled
) AS cl WHERE rn = 1
AND ($4 IS NULL OR phone = $4)
AND ($5 IS NULL OR CONCAT(id_card_data::json->>'firstName', ' ', id_card_data::json->>'lastName') = $5 OR id_card_data::json->>'firstName' = $5 OR id_card_data::json->>'lastName' = $5)
AND ($6 IS NULL OR id_card_data::json->>'address' = $6)
AND ($7 IS NULL OR id_card_data::json->>'documentNumber' = $7)
AND ($5 IS NULL OR CONCAT(id_card_data::json->>'firstName', ' ', id_card_data::json->>'lastName') = $5 OR id_card_data::json->>'firstName' = $5 OR id_card_data::json->>'lastName' = $5)
AND ($6 IS NULL OR id_card_data::json->>'address' = $6)
AND ($7 IS NULL OR id_card_data::json->>'documentNumber' = $7)
limit $3`
return db.any(sql, [ passableErrorCodes, anonymous.uuid, NUM_RESULTS, phone, name, address, id ])
.then(customers => Promise.all(_.map(customer =>
Expand Down Expand Up @@ -550,7 +552,8 @@ function getCustomerById (id) {
c.front_camera_path, c.front_camera_override, c.front_camera_at,
c.phone, c.phone_at, c.phone_override, c.sms_override, c.id_card_data, c.id_card_data_at, c.id_card_data_override, c.id_card_data_expiration,
c.id_card_photo_path, c.id_card_photo_at, c.id_card_photo_override, c.us_ssn, c.us_ssn_at, c.us_ssn_override, c.sanctions,
c.sanctions_at, c.sanctions_override, c.subscriber_info, c.subscriber_info_at, c.is_test_customer, c.created, t.tx_class, t.fiat, t.fiat_code, t.created as last_transaction, cn.notes,
c.sanctions_at, c.sanctions_override, c.subscriber_info, c.subscriber_info_at, c.is_test_customer, c.created, c.enabled,
t.tx_class, t.fiat, t.fiat_code, t.created as last_transaction, cn.notes,
row_number() OVER (PARTITION BY c.id ORDER BY t.created DESC) AS rn,
sum(CASE WHEN t.id IS NOT NULL THEN 1 ELSE 0 END) OVER (PARTITION BY c.id) AS total_txs,
sum(CASE WHEN error_code IS NULL OR error_code NOT IN ($1^) THEN t.fiat ELSE 0 END) OVER (PARTITION BY c.id) AS total_spent, ccf.custom_fields
Expand All @@ -570,6 +573,7 @@ function getCustomerById (id) {
GROUP BY customer_notes.customer_id
) cn ON c.id = cn.customer_id
WHERE c.id = $2
AND c.enabled
) AS cl WHERE rn = 1`
return db.oneOrNone(sql, [passableErrorCodes, id])
.then(assignCustomerData)
Expand Down Expand Up @@ -909,6 +913,11 @@ function disableTestCustomer (customerId) {
return db.none(sql, [customerId])
}

function deleteCustomer (customerId) {
const sql = `UPDATE customers SET enabled=false WHERE id=$1 AND is_test_customer`
return db.none(sql, [customerId])
}

module.exports = {
add,
get,
Expand All @@ -931,5 +940,6 @@ module.exports = {
enableTestCustomer,
disableTestCustomer,
selectLatestData,
getEditedData
getEditedData,
deleteCustomer
}
4 changes: 3 additions & 1 deletion lib/new-admin/graphql/resolvers/customer.resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ const resolvers = {
enableTestCustomer: (...[, { customerId }]) =>
customers.enableTestCustomer(customerId),
disableTestCustomer: (...[, { customerId }]) =>
customers.disableTestCustomer(customerId)
customers.disableTestCustomer(customerId),
deleteCustomer: (...[, { customerId }]) =>
customers.deleteCustomer(customerId)
}
}

Expand Down
1 change: 1 addition & 0 deletions lib/new-admin/graphql/types/customer.type.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ const typeDef = gql`
createCustomer(phoneNumber: String): Customer @auth
enableTestCustomer(customerId: ID!): Boolean @auth
disableTestCustomer(customerId: ID!): Boolean @auth
deleteCustomer(customerId: ID!): Boolean @auth(requires: [SUPERUSER])
}
`

Expand Down
15 changes: 15 additions & 0 deletions migrations/1649353351891-delete-test-customers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
var db = require('./db')

exports.up = function (next) {
var sql = [
`ALTER TABLE customers ADD COLUMN enabled BOOLEAN NOT NULL DEFAULT true`,
chaotixkilla marked this conversation as resolved.
Show resolved Hide resolved
`ALTER TABLE customers DROP CONSTRAINT customers_phone_key`,
`CREATE UNIQUE INDEX customers_phone_key ON customers (phone) WHERE enabled`
]

db.multi(sql, next)
}

exports.down = function (next) {
next()
}
41 changes: 40 additions & 1 deletion new-lamassu-admin/src/pages/Customers/CustomerProfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import {
import NavigateNextIcon from '@material-ui/icons/NavigateNext'
import gql from 'graphql-tag'
import * as R from 'ramda'
import React, { memo, useState } from 'react'
import React, { memo, useState, useContext } from 'react'
import { useHistory, useParams } from 'react-router-dom'

import AppContext from 'src/AppContext'
import { ConfirmDialog } from 'src/components/ConfirmDialog'
import ErrorMessage from 'src/components/ErrorMessage'
import { Button, IconButton, ActionButton } from 'src/components/buttons'
import { Switch } from 'src/components/inputs'
Expand All @@ -22,6 +24,8 @@ import {
OVERRIDE_REJECTED
} from 'src/pages/Customers/components/propertyCard'
import { ReactComponent as CloseIcon } from 'src/styling/icons/action/close/zodiac.svg'
import { ReactComponent as DeleteIcon } from 'src/styling/icons/action/delete/enabled.svg'
import { ReactComponent as DeleteIconReversedIcon } from 'src/styling/icons/action/delete/white.svg'
import { ReactComponent as AuthorizeReversedIcon } from 'src/styling/icons/button/authorize/white.svg'
import { ReactComponent as AuthorizeIcon } from 'src/styling/icons/button/authorize/zodiac.svg'
import { ReactComponent as BlockReversedIcon } from 'src/styling/icons/button/block/white.svg'
Expand Down Expand Up @@ -260,6 +264,12 @@ const DISABLE_TEST_CUSTOMER = gql`
}
`

const DELETE_CUSTOMER = gql`
mutation deleteCustomer($customerId: ID!) {
deleteCustomer(customerId: $customerId)
}
`

const GET_DATA = gql`
query getData {
config
Expand Down Expand Up @@ -289,10 +299,12 @@ const GET_ACTIVE_CUSTOM_REQUESTS = gql`

const CustomerProfile = memo(() => {
const history = useHistory()
const { userData } = useContext(AppContext)

const [retrieve, setRetrieve] = useState(false)
const [showCompliance, setShowCompliance] = useState(false)
const [wizard, setWizard] = useState(false)
const [toDelete, setToDelete] = useState(false)
const [error, setError] = useState(null)
const [clickedItem, setClickedItem] = useState('overview')
const { id: customerId } = useParams()
Expand Down Expand Up @@ -395,6 +407,11 @@ const CustomerProfile = memo(() => {
onCompleted: () => getCustomer()
})

const [deleteCustomer] = useMutation(DELETE_CUSTOMER, {
variables: { customerId },
onCompleted: () => history.push('/compliance/customers')
})

const updateCustomer = it =>
setCustomer({
variables: {
Expand Down Expand Up @@ -595,6 +612,17 @@ const CustomerProfile = memo(() => {
}>
{`${blocked ? 'Authorize' : 'Block'} customer`}
</ActionButton>
{Boolean(R.path(['isTestCustomer'])(customerData)) &&
userData?.role === 'superuser' && (
<ActionButton
color="primary"
className={classes.actionButton}
Icon={DeleteIcon}
InverseIcon={DeleteIconReversedIcon}
onClick={() => setToDelete(true)}>
{`Delete customer`}
</ActionButton>
)}
</div>
</div>
<div>
Expand Down Expand Up @@ -701,6 +729,17 @@ const CustomerProfile = memo(() => {
customInfoRequirementOptions={customInfoRequirementOptions}
/>
)}
{toDelete && (
<ConfirmDialog
open={toDelete}
title={`Delete this customer?`}
errorMessage={null}
toBeConfirmed={R.path(['phone'])(customerData)}
message={`This test customer will be deleted and cannot be reinstated. Are you sure?`}
onConfirmed={() => deleteCustomer()}
onDismissed={() => setToDelete(false)}
/>
)}
</div>
</>
)
Expand Down