summaryrefslogtreecommitdiff
path: root/src/pages/api/shop/search.js
blob: 3d6b3f266381da82657a3fa8c314c9ebf6f7742b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import axios from 'axios'
import camelcaseObjectDeep from 'camelcase-object-deep'

const productResponseMap = (products) => {
  return products.map((product) => {
    let productMapped = {
      id: product.product_id ? product.product_id[0] : '',
      image: product.image ? product.image[0] : '',
      code: product.default_code ? product.default_code[0] : '',
      name: product.product_name ? product.product_name[0] : '',
      lowestPrice: {
        price: product.price ? product.price[0] : 0,
        priceDiscount: product.price_discount ? product.price_discount[0] : 0,
        discountPercentage: product.discount ? product.discount[0] : 0
      },
      variantTotal: product.variant_total ? product.variant_total[0] : 0,
      stockTotal: product.stock_total ? product.stock_total[0] : 0,
      weight: product.weight ? product.weight[0] : 0,
      manufacture: {},
      categories: []
    }

    if (product.manufacture_id && product.brand) {
      productMapped.manufacture = {
        id: product.manufacture_id ? product.manufacture_id[0] : '',
        name: product.brand ? product.brand[0] : ''
      }
    }

    productMapped.categories = [
      {
        id: product.category_id ? product.category_id[0] : '',
        name: product.category_name ? product.category_name[0] : ''
      }
    ]

    return productMapped
  })
}

export default async function handler(req, res) {
  const {
    q = '*',
    page = 1,
    brand = '',
    category = '',
    priceFrom = 0,
    priceTo = 0,
    orderBy = '',
    operation = 'AND',
    fq = ''
  } = req.query

  let paramOrderBy = ''
  switch (orderBy) {
    case 'price-asc':
      paramOrderBy = ', price_discount ASC'
      break
    case 'price-desc':
      paramOrderBy = ', price_discount DESC'
      break
    case 'popular':
      paramOrderBy = ', search_rank DESC'
      break
    case 'stock':
      paramOrderBy = ', stock_total DESC'
      break
  }

  let limit = 30
  let offset = (page - 1) * limit
  let parameter = [
    'facet.field=brand_str',
    'facet.field=category_name_str',
    'facet=true',
    'indent=true',
    `facet.query=${q}`,
    `q.op=${operation}`,
    `q=${q}`,
    `start=${offset}`,
    `rows=${limit}`,
    `sort=product_rating DESC ${paramOrderBy}`,
    `fq=price_discount:[${priceFrom == '' ? '*' : priceFrom} TO ${priceTo == '' ? '*' : priceTo}]`
  ]

  if (brand) parameter.push(`fq=brand:${brand}`)
  if (category) parameter.push(`fq=category_name:${category}`)

  // Single fq in url params
  if (typeof fq === 'string') parameter.push(`fq=${fq}`)
  // Multi fq in url params
  if (Array.isArray(fq)) parameter = parameter.concat(fq.map((val) => `fq=${val}`))

  let result = await axios(process.env.SOLR_HOST + '/solr/products/select?' + parameter.join('&'))
  try {
    result.data.response.products = productResponseMap(result.data.response.docs)
    result.data.responseHeader.params.start = parseInt(result.data.responseHeader.params.start)
    result.data.responseHeader.params.rows = parseInt(result.data.responseHeader.params.rows)
    delete result.data.response.docs
    result.data = camelcaseObjectDeep(result.data)
    res.status(200).json(result.data)
  } catch (error) {
    res.status(400).json({ error: error.message })
  }
}