feat: customer matching on individual discounts panel

This commit is contained in:
Sérgio Salgado 2021-07-23 04:02:27 +01:00 committed by Josh Harvey
parent eda6decae0
commit 03fd19e0cf
5 changed files with 101 additions and 8 deletions

View file

@ -1,6 +1,7 @@
const db = require('./db')
const uuid = require('uuid')
const _ = require('lodash/fp')
const pgp = require('pg-promise')()
function getAvailablePromoCodes () {
const sql = `SELECT * FROM coupons WHERE soft_deleted=false`
@ -52,6 +53,38 @@ function deleteIndividualDiscount (id) {
return db.none(sql, [id])
}
function getCustomersWithDiscounts (discounts) {
let phoneNumbers = []
let idCardNumbers = []
_.each(it => {
switch (it.idType) {
case 'phone':
phoneNumbers.push(it.value)
break
case 'idNumber':
idCardNumbers.push(it.value)
break
default:
break
}
}, discounts)
if (_.isEmpty(phoneNumbers) && _.isEmpty(idCardNumbers)) {
return Promise.resolve([])
}
const phoneNumbersSql = _.map(pgp.as.text, phoneNumbers).join(',')
const idCardNumbersSql = _.map(pgp.as.text, idCardNumbers).join(',')
const hasPhoneNumbers = !_.isEmpty(phoneNumbers)
const hasIDNumbers = !_.isEmpty(phoneNumbers)
const sql = `SELECT * FROM customers WHERE ${hasPhoneNumbers && `phone IN ($1^)`} ${hasPhoneNumbers && hasIDNumbers && `OR`} ${hasIDNumbers && `id_card_data_number IN ($2^)`}`
return db.any(sql, [phoneNumbersSql, idCardNumbersSql])
.then(res => _.map(it => it ? _.mapKeys(_.camelCase, it) : null, res))
}
module.exports = {
getAvailablePromoCodes,
getPromoCode,
@ -60,5 +93,6 @@ module.exports = {
getNumberOfAvailablePromoCodes,
getAvailableIndividualDiscounts,
createIndividualDiscount,
deleteIndividualDiscount
deleteIndividualDiscount,
getCustomersWithDiscounts
}

View file

@ -1,6 +1,7 @@
const anonymous = require('../../../constants').anonymousCustomer
const customers = require('../../../customers')
const filters = require('../../filters')
const loyalty = require('../../../loyalty')
const resolvers = {
Customer: {
@ -9,7 +10,8 @@ const resolvers = {
Query: {
customers: (...[, { phone, name, address, id }]) => customers.getCustomersList(phone, name, address, id),
customer: (...[, { customerId }]) => customers.getCustomerById(customerId),
customerFilters: () => filters.customer()
customerFilters: () => filters.customer(),
getCustomersWithDiscounts: (...[, { discounts }]) => loyalty.getCustomersWithDiscounts(discounts)
},
Mutation: {
setCustomer: (root, { customerId, customerInput }, context, info) => {

View file

@ -59,6 +59,7 @@ const typeDef = gql`
customers(phone: String, name: String, address: String, id: String): [Customer] @auth
customer(customerId: ID!): Customer @auth
customerFilters: [Filter] @auth
getCustomersWithDiscounts(discounts: [IndividualDiscountInput]): [Customer] @auth
}
type Mutation {

View file

@ -8,6 +8,13 @@ const typeDef = gql`
discount: Int
}
input IndividualDiscountInput {
id: ID
idType: DiscountIdentificationType
value: String
discount: Int
}
enum DiscountIdentificationType {
phone
idNumber

View file

@ -1,4 +1,4 @@
import { useQuery, useMutation } from '@apollo/react-hooks'
import { useQuery, useLazyQuery, useMutation } from '@apollo/react-hooks'
import { makeStyles, Box } from '@material-ui/core'
import gql from 'graphql-tag'
import * as R from 'ramda'
@ -52,6 +52,16 @@ const CREATE_DISCOUNT = gql`
}
`
const GET_CUSTOMERS_WITH_DISCOUNTS = gql`
query getCustomersWithDiscounts($discounts: [IndividualDiscountInput]!) {
getCustomersWithDiscounts(discounts: $discounts) {
id
phone
idCardData
}
}
`
const IndividualDiscounts = () => {
const classes = useStyles()
@ -62,7 +72,27 @@ const IndividualDiscounts = () => {
const [showModal, setShowModal] = useState(false)
const toggleModal = () => setShowModal(!showModal)
const { data: discountResponse, loading } = useQuery(GET_INDIVIDUAL_DISCOUNTS)
const [
getCustomers,
{ data: customerData, loading: customerLoading }
] = useLazyQuery(GET_CUSTOMERS_WITH_DISCOUNTS)
const { data: discountResponse, loading } = useQuery(
GET_INDIVIDUAL_DISCOUNTS,
{
onCompleted: res => {
const discounts = R.map(it =>
R.pick(['id', 'idType', 'value', 'discount'])(it)
)(res.individualDiscounts)
return getCustomers({
variables: {
discounts: discounts
}
})
}
}
)
const [createDiscount, { error: creationError }] = useMutation(
CREATE_DISCOUNT,
@ -80,6 +110,13 @@ const IndividualDiscounts = () => {
refetchQueries: () => ['individualDiscounts']
})
const findCustomer = (customers = [], idType, value) =>
R.find(it =>
idType === 'phone'
? it.phone === value
: it.idCardData.documentNumber === value
)(customers)
const elements = [
{
header: 'Identification',
@ -98,7 +135,17 @@ const IndividualDiscounts = () => {
width: 300,
textAlign: 'left',
size: 'sm',
view: t => <>{'-'}</>
view: t => {
const customer = findCustomer(
customerData?.getCustomersWithDiscounts,
t.idType,
t.value
)
if (R.isNil(customer)) return <>{'-'}</>
return (
<>{`${customer.idCardData.firstName} ${customer.idCardData.lastName}`}</>
)
}
},
{
header: 'Discount rate',
@ -128,9 +175,11 @@ const IndividualDiscounts = () => {
}
]
const isLoading = loading || customerLoading
return (
<>
{!loading && !R.isEmpty(discountResponse.individualDiscounts) && (
{!isLoading && !R.isEmpty(discountResponse.individualDiscounts) && (
<Box
marginBottom={4}
marginTop={-7}
@ -142,7 +191,7 @@ const IndividualDiscounts = () => {
</Link>
</Box>
)}
{!loading && !R.isEmpty(discountResponse.individualDiscounts) && (
{!isLoading && !R.isEmpty(discountResponse.individualDiscounts) && (
<>
<DataTable
elements={elements}
@ -162,7 +211,7 @@ const IndividualDiscounts = () => {
/>
</>
)}
{!loading && R.isEmpty(discountResponse.individualDiscounts) && (
{!isLoading && R.isEmpty(discountResponse.individualDiscounts) && (
<Box display="flex" alignItems="left" flexDirection="column">
<Label3>
It seems there are no active individual customer discounts on your