diff --git a/lib/loyalty.js b/lib/loyalty.js index d378ed62..d49bba36 100644 --- a/lib/loyalty.js +++ b/lib/loyalty.js @@ -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 } diff --git a/lib/new-admin/graphql/resolvers/customer.resolver.js b/lib/new-admin/graphql/resolvers/customer.resolver.js index f33c3276..de12d26e 100644 --- a/lib/new-admin/graphql/resolvers/customer.resolver.js +++ b/lib/new-admin/graphql/resolvers/customer.resolver.js @@ -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) => { diff --git a/lib/new-admin/graphql/types/customer.type.js b/lib/new-admin/graphql/types/customer.type.js index 8ee9cdeb..ae1f3e8d 100644 --- a/lib/new-admin/graphql/types/customer.type.js +++ b/lib/new-admin/graphql/types/customer.type.js @@ -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 { diff --git a/lib/new-admin/graphql/types/loyalty.type.js b/lib/new-admin/graphql/types/loyalty.type.js index c5d8862e..3e8aa648 100644 --- a/lib/new-admin/graphql/types/loyalty.type.js +++ b/lib/new-admin/graphql/types/loyalty.type.js @@ -8,6 +8,13 @@ const typeDef = gql` discount: Int } + input IndividualDiscountInput { + id: ID + idType: DiscountIdentificationType + value: String + discount: Int + } + enum DiscountIdentificationType { phone idNumber diff --git a/new-lamassu-admin/src/pages/LoyaltyPanel/IndividualDiscounts.js b/new-lamassu-admin/src/pages/LoyaltyPanel/IndividualDiscounts.js index e874a797..0acaf876 100644 --- a/new-lamassu-admin/src/pages/LoyaltyPanel/IndividualDiscounts.js +++ b/new-lamassu-admin/src/pages/LoyaltyPanel/IndividualDiscounts.js @@ -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) && ( { )} - {!loading && !R.isEmpty(discountResponse.individualDiscounts) && ( + {!isLoading && !R.isEmpty(discountResponse.individualDiscounts) && ( <> { /> )} - {!loading && R.isEmpty(discountResponse.individualDiscounts) && ( + {!isLoading && R.isEmpty(discountResponse.individualDiscounts) && ( It seems there are no active individual customer discounts on your