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 db = require('./db')
|
||||||
const uuid = require('uuid')
|
const uuid = require('uuid')
|
||||||
const _ = require('lodash/fp')
|
const _ = require('lodash/fp')
|
||||||
|
const pgp = require('pg-promise')()
|
||||||
|
|
||||||
function getAvailablePromoCodes () {
|
function getAvailablePromoCodes () {
|
||||||
const sql = `SELECT * FROM coupons WHERE soft_deleted=false`
|
const sql = `SELECT * FROM coupons WHERE soft_deleted=false`
|
||||||
|
|
@ -52,6 +53,38 @@ function deleteIndividualDiscount (id) {
|
||||||
return db.none(sql, [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 = {
|
module.exports = {
|
||||||
getAvailablePromoCodes,
|
getAvailablePromoCodes,
|
||||||
getPromoCode,
|
getPromoCode,
|
||||||
|
|
@ -60,5 +93,6 @@ module.exports = {
|
||||||
getNumberOfAvailablePromoCodes,
|
getNumberOfAvailablePromoCodes,
|
||||||
getAvailableIndividualDiscounts,
|
getAvailableIndividualDiscounts,
|
||||||
createIndividualDiscount,
|
createIndividualDiscount,
|
||||||
deleteIndividualDiscount
|
deleteIndividualDiscount,
|
||||||
|
getCustomersWithDiscounts
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
const anonymous = require('../../../constants').anonymousCustomer
|
const anonymous = require('../../../constants').anonymousCustomer
|
||||||
const customers = require('../../../customers')
|
const customers = require('../../../customers')
|
||||||
const filters = require('../../filters')
|
const filters = require('../../filters')
|
||||||
|
const loyalty = require('../../../loyalty')
|
||||||
|
|
||||||
const resolvers = {
|
const resolvers = {
|
||||||
Customer: {
|
Customer: {
|
||||||
|
|
@ -9,7 +10,8 @@ const resolvers = {
|
||||||
Query: {
|
Query: {
|
||||||
customers: (...[, { phone, name, address, id }]) => customers.getCustomersList(phone, name, address, id),
|
customers: (...[, { phone, name, address, id }]) => customers.getCustomersList(phone, name, address, id),
|
||||||
customer: (...[, { customerId }]) => customers.getCustomerById(customerId),
|
customer: (...[, { customerId }]) => customers.getCustomerById(customerId),
|
||||||
customerFilters: () => filters.customer()
|
customerFilters: () => filters.customer(),
|
||||||
|
getCustomersWithDiscounts: (...[, { discounts }]) => loyalty.getCustomersWithDiscounts(discounts)
|
||||||
},
|
},
|
||||||
Mutation: {
|
Mutation: {
|
||||||
setCustomer: (root, { customerId, customerInput }, context, info) => {
|
setCustomer: (root, { customerId, customerInput }, context, info) => {
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ const typeDef = gql`
|
||||||
customers(phone: String, name: String, address: String, id: String): [Customer] @auth
|
customers(phone: String, name: String, address: String, id: String): [Customer] @auth
|
||||||
customer(customerId: ID!): Customer @auth
|
customer(customerId: ID!): Customer @auth
|
||||||
customerFilters: [Filter] @auth
|
customerFilters: [Filter] @auth
|
||||||
|
getCustomersWithDiscounts(discounts: [IndividualDiscountInput]): [Customer] @auth
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,13 @@ const typeDef = gql`
|
||||||
discount: Int
|
discount: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input IndividualDiscountInput {
|
||||||
|
id: ID
|
||||||
|
idType: DiscountIdentificationType
|
||||||
|
value: String
|
||||||
|
discount: Int
|
||||||
|
}
|
||||||
|
|
||||||
enum DiscountIdentificationType {
|
enum DiscountIdentificationType {
|
||||||
phone
|
phone
|
||||||
idNumber
|
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 { makeStyles, Box } from '@material-ui/core'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
import * as R from 'ramda'
|
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 IndividualDiscounts = () => {
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
|
|
||||||
|
|
@ -62,7 +72,27 @@ const IndividualDiscounts = () => {
|
||||||
const [showModal, setShowModal] = useState(false)
|
const [showModal, setShowModal] = useState(false)
|
||||||
const toggleModal = () => setShowModal(!showModal)
|
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(
|
const [createDiscount, { error: creationError }] = useMutation(
|
||||||
CREATE_DISCOUNT,
|
CREATE_DISCOUNT,
|
||||||
|
|
@ -80,6 +110,13 @@ const IndividualDiscounts = () => {
|
||||||
refetchQueries: () => ['individualDiscounts']
|
refetchQueries: () => ['individualDiscounts']
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const findCustomer = (customers = [], idType, value) =>
|
||||||
|
R.find(it =>
|
||||||
|
idType === 'phone'
|
||||||
|
? it.phone === value
|
||||||
|
: it.idCardData.documentNumber === value
|
||||||
|
)(customers)
|
||||||
|
|
||||||
const elements = [
|
const elements = [
|
||||||
{
|
{
|
||||||
header: 'Identification',
|
header: 'Identification',
|
||||||
|
|
@ -98,7 +135,17 @@ const IndividualDiscounts = () => {
|
||||||
width: 300,
|
width: 300,
|
||||||
textAlign: 'left',
|
textAlign: 'left',
|
||||||
size: 'sm',
|
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',
|
header: 'Discount rate',
|
||||||
|
|
@ -128,9 +175,11 @@ const IndividualDiscounts = () => {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const isLoading = loading || customerLoading
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{!loading && !R.isEmpty(discountResponse.individualDiscounts) && (
|
{!isLoading && !R.isEmpty(discountResponse.individualDiscounts) && (
|
||||||
<Box
|
<Box
|
||||||
marginBottom={4}
|
marginBottom={4}
|
||||||
marginTop={-7}
|
marginTop={-7}
|
||||||
|
|
@ -142,7 +191,7 @@ const IndividualDiscounts = () => {
|
||||||
</Link>
|
</Link>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
{!loading && !R.isEmpty(discountResponse.individualDiscounts) && (
|
{!isLoading && !R.isEmpty(discountResponse.individualDiscounts) && (
|
||||||
<>
|
<>
|
||||||
<DataTable
|
<DataTable
|
||||||
elements={elements}
|
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">
|
<Box display="flex" alignItems="left" flexDirection="column">
|
||||||
<Label3>
|
<Label3>
|
||||||
It seems there are no active individual customer discounts on your
|
It seems there are no active individual customer discounts on your
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue