feat: customer matching on individual discounts panel
This commit is contained in:
parent
eda6decae0
commit
03fd19e0cf
5 changed files with 101 additions and 8 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,13 @@ const typeDef = gql`
|
|||
discount: Int
|
||||
}
|
||||
|
||||
input IndividualDiscountInput {
|
||||
id: ID
|
||||
idType: DiscountIdentificationType
|
||||
value: String
|
||||
discount: Int
|
||||
}
|
||||
|
||||
enum DiscountIdentificationType {
|
||||
phone
|
||||
idNumber
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue