From 62284a1d334af9bd508a8c6ba65367898be76ab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Oliveira?= Date: Fri, 7 Jan 2022 18:44:08 +0000 Subject: [PATCH] feat: sms data editable fields --- lib/customers.js | 17 ++++++--- lib/new-admin/graphql/types/customer.type.js | 4 ++ ...376890-add-overrides-to-subscriber-info.js | 22 +++++++++++ .../src/pages/Customers/CustomerData.js | 37 ++++++++++++++++--- .../src/pages/Customers/CustomerProfile.js | 2 + 5 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 migrations/1641482376890-add-overrides-to-subscriber-info.js diff --git a/lib/customers.js b/lib/customers.js index 1f15dc91..589e21a9 100644 --- a/lib/customers.js +++ b/lib/customers.js @@ -24,6 +24,7 @@ const operatorDataDir = _.get('operatorDataDir', options) const sms = require('./sms') const settingsLoader = require('./new-settings-loader') const logger = require('./logger') +const consoleLogLevel = require('console-log-level') const TX_PASSTHROUGH_ERROR_CODES = ['operatorCancel'] @@ -121,7 +122,8 @@ async function updateCustomer (id, data, userToken) { 'us_ssn_override', 'sanctions_override', 'front_camera_override', - 'suspended_until' + 'suspended_until', + 'subscriber_info_override' ], _.mapKeys(_.snakeCase, data)) @@ -164,11 +166,13 @@ function edit (id, data, userToken) { 'id_card_photo', 'us_ssn', 'subscriber_info', - 'name' + 'name', + 'phone' ] const filteredData = _.pick(defaults, _.mapKeys(_.snakeCase, _.omitBy(_.isNil, data))) if (_.isEmpty(filteredData)) return getCustomerById(id) const formattedData = enhanceEditedPhotos(enhanceEditedFields(filteredData, userToken)) + const defaultDbData = { customer_id: id, created: new Date(), @@ -688,16 +692,16 @@ function getCustomersList (phone = null, name = null, address = null, id = null) function getCustomerById (id) { const passableErrorCodes = _.map(Pgp.as.text, TX_PASSTHROUGH_ERROR_CODES).join(',') const sql = `SELECT id, authorized_override, days_suspended, is_suspended, front_camera_path, front_camera_at, front_camera_override, - phone, sms_override, id_card_data_at, id_card_data, id_card_data_override, id_card_data_expiration, + phone, phone_at, sms_override, id_card_data_at, id_card_data, id_card_data_override, id_card_data_expiration, id_card_photo_path, id_card_photo_at, id_card_photo_override, us_ssn_at, us_ssn, us_ssn_override, sanctions, sanctions_at, sanctions_override, total_txs, total_spent, LEAST(created, last_transaction) AS last_active, fiat AS last_tx_fiat, - fiat_code AS last_tx_fiat_code, tx_class AS last_tx_class, subscriber_info, custom_fields, notes, is_test_customer + fiat_code AS last_tx_fiat_code, tx_class AS last_tx_class, subscriber_info, subscriber_info_at, subscriber_info_override, custom_fields, notes, is_test_customer FROM ( SELECT c.id, c.authorized_override, greatest(0, date_part('day', c.suspended_until - now())) AS days_suspended, c.suspended_until > now() AS is_suspended, c.front_camera_path, c.front_camera_override, c.front_camera_at, - c.phone, c.sms_override, c.id_card_data, c.id_card_data_at, c.id_card_data_override, c.id_card_data_expiration, + c.phone, c.phone_at, 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.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, @@ -750,7 +754,8 @@ function selectLatestData (customerData, customerEditedData) { 'id_card_photo', 'us_ssn', 'subscriber_info', - 'name' + 'name', + 'phone' ] _.map(field => { let fieldName = field diff --git a/lib/new-admin/graphql/types/customer.type.js b/lib/new-admin/graphql/types/customer.type.js index bf099647..ed41b6c0 100644 --- a/lib/new-admin/graphql/types/customer.type.js +++ b/lib/new-admin/graphql/types/customer.type.js @@ -33,6 +33,7 @@ const typeDef = gql` lastTxClass: String transactions: [Transaction] subscriberInfo: JSONObject + subscriberInfoOverride: String customFields: [CustomerCustomField] customInfoRequests: [CustomRequestData] notes: [CustomerNote] @@ -63,12 +64,15 @@ const typeDef = gql` lastTxClass: String suspendedUntil: Date subscriberInfo: Boolean + subscriberInfoOverride: String } input CustomerEdit { idCardData: JSONObject idCardPhoto: UploadGQL usSsn: String + subscriberInfo: JSONObject + phone: String } type CustomerNote { diff --git a/migrations/1641482376890-add-overrides-to-subscriber-info.js b/migrations/1641482376890-add-overrides-to-subscriber-info.js new file mode 100644 index 00000000..dcfd4f9f --- /dev/null +++ b/migrations/1641482376890-add-overrides-to-subscriber-info.js @@ -0,0 +1,22 @@ +var db = require('./db') + +exports.up = function (next) { + var sql = [ + `ALTER TABLE customers + ADD COLUMN subscriber_info_override VERIFICATION_TYPE, + ADD COLUMN subscriber_info_override_by UUID, + ADD COLUMN subscriber_info_override_at TIMESTAMPTZ + `, + `ALTER TABLE edited_customer_data + ADD COLUMN phone TEXT, + ADD COLUMN phone_at TIMESTAMPTZ, + ADD COLUMN phone_by UUID + ` + ] + + db.multi(sql, next) +} + +exports.down = function (next) { + next() +} diff --git a/new-lamassu-admin/src/pages/Customers/CustomerData.js b/new-lamassu-admin/src/pages/Customers/CustomerData.js index 30ee3837..cd366680 100644 --- a/new-lamassu-admin/src/pages/Customers/CustomerData.js +++ b/new-lamassu-admin/src/pages/Customers/CustomerData.js @@ -2,6 +2,7 @@ import { DialogActions, DialogContent, Dialog } from '@material-ui/core' import Grid from '@material-ui/core/Grid' import { makeStyles } from '@material-ui/core/styles' import { parse, format } from 'date-fns/fp' +import { parsePhoneNumber } from 'libphonenumber-js' import _ from 'lodash/fp' import * as R from 'ramda' import { useState, React } from 'react' @@ -25,6 +26,7 @@ import { ReactComponent as CustomerListViewIcon } from 'src/styling/icons/circle import { ReactComponent as OverviewReversedIcon } from 'src/styling/icons/circle buttons/overview/white.svg' import { ReactComponent as OverviewIcon } from 'src/styling/icons/circle buttons/overview/zodiac.svg' import { URI } from 'src/utils/apollo' +import { onlyFirstToUpper } from 'src/utils/string' import styles from './CustomerData.styles.js' import { EditableCard } from './components' @@ -103,7 +105,7 @@ const CustomerData = ({ ) const phone = R.path(['phone'])(customer) - const smsData = R.path(['subscriberInfo'])(customer) + const smsData = R.path(['subscriberInfo', 'result'])(customer) const isEven = elem => elem % 2 === 0 @@ -163,14 +165,24 @@ const CustomerData = ({ fields: customerDataElements.smsData, title: 'SMS data', titleIcon: , - authorize: () => {}, - reject: () => {}, - save: () => {}, + state: R.path(['subscriberInfoOverride'])(customer), + authorize: () => + updateCustomer({ subscriberInfoOverride: OVERRIDE_AUTHORIZED }), + reject: () => + updateCustomer({ subscriberInfoOverride: OVERRIDE_REJECTED }), + save: values => { + editCustomer({ + phone: parsePhoneNumber(values.phoneNumber).number, + subscriberInfo: { + result: _.merge(smsData, R.omit(['phoneNumber'])(values)) + } + }) + }, retrieveAditionalData: () => setRetrieve(true), validationSchema: customerDataSchemas.smsData, initialValues: initialValues.smsData, isAvailable: !_.isNil(phone), - hasAditionalData: !_.isNil(smsData) && !_.isEmpty(smsData.result) + hasAditionalData: !_.isNil(smsData) && !_.isEmpty(smsData) }, { title: 'Name', @@ -336,6 +348,21 @@ const CustomerData = ({ }) }, R.path(['customFields'])(customer) ?? []) + R.forEach(it => { + initialValues.smsData[it] = smsData[it] + smsDataElements.push({ + name: it, + label: onlyFirstToUpper(it), + component: TextInput + }) + Yup.object() + .shape({ + [it]: Yup.string() + }) + .required() + .concat(schemas.smsData) + }, R.keys(smsData) ?? []) + const editableCard = ( { title, diff --git a/new-lamassu-admin/src/pages/Customers/CustomerProfile.js b/new-lamassu-admin/src/pages/Customers/CustomerProfile.js index 3fe7cc56..8243bbfc 100644 --- a/new-lamassu-admin/src/pages/Customers/CustomerProfile.js +++ b/new-lamassu-admin/src/pages/Customers/CustomerProfile.js @@ -70,6 +70,7 @@ const GET_CUSTOMER = gql` isSuspended isTestCustomer subscriberInfo + subscriberInfoOverride customFields { id label @@ -139,6 +140,7 @@ const SET_CUSTOMER = gql` lastTxFiatCode lastTxClass subscriberInfo + subscriberInfoOverride } } `