/var/www/p4ela.kz/server/delivery/api/controllers
Edit: /var/www/p4ela.kz/server/delivery/api/controllers/productReview.controller.js (5992B)
const logger = require('../../logger')({ service: 'api' })
const { NotFound, BadRequest } = require('../responseModels/errors')
const { isSet, isEmpty, minLength, isPhone, isEmail } = require('../utils/validator.util')
module.exports = function ({ db }) {
this.List = async (req, res, next) => {
logger.child({ path: req.path, request: req.query }).info()
try {
let t1 = performance.now()
const { isVerified, userId, productId, limit, page } = req.query
let where = {}
if (userId) {
where['userId'] = parseInt(userId)
}
if (productId) {
where['productId'] = parseInt(productId)
}
if (typeof isVerified === 'undefined') {
where['isVerified'] = true
} else {
where['isVerified'] = isVerified
}
let offset = page > 0 ? (page - 1) * (limit || 10) : 0
const { count, rows } = await db.productReview.findAndCountAll({
include: db.user,
where,
offset,
order: [
['id', 'DESC']
// ['name', 'ASC'],
],
limit: parseInt(limit) || 10
})
const time = performance.now() - t1
return res.status(200).json({ list: rows, count, time, page })
} catch (err) {
next(err)
}
}
this.Details = async (req, res, next) => {
logger.child({ path: req.path, request: req.params }).info()
try {
const { uid } = req.params
const review = await db.productReview.findOne({ where: { uid } })
return res.status(200).json(review)
} catch (err) {
next(err)
}
}
this.Accept = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
let transaction = null
try {
const { uid } = req.body
if(!isSet(uid) || isEmpty(uid)){
throw new BadRequest({ lang: req.user?.languageCode })
}
transaction = await db.sequelize.transaction()
const review = await db.productReview.findOne({ where: { uid } })
review.isVerified = true
await review.save()
await calculateProductRating(review.productId)
await transaction.commit()
return res.status(200).json({ status: 'success', uid })
} catch (err) {
transaction?.rollback()
next(err)
}
}
this.Create = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
try {
const { productUid, text, rating } = req.body
if(!isSet(productUid) || isEmpty(productUid)){
throw new BadRequest({ lang: req.user?.languageCode })
}
if(!isSet(text) || isEmpty(text)){
throw new BadRequest({ lang: req.user?.languageCode })
}
if(!isSet(rating)){
throw new BadRequest({ lang: req.user?.languageCode })
}
let product = await db.product.findOne({
include: db.company,
where: { uid: productUid }
})
const review = await db.productReview.create({
productId: product.id,
userId: req.user.id,
text,
rating
})
// Расчет рейтинга не нужен. Расчет будет после подтверждения.
// ---> Пока что принимаем все подряд
let transaction = null
try {
transaction = await db.sequelize.transaction()
let uid = review.uid;
const review2 = await db.productReview.findOne({ where: { uid } })
review2.isVerified = true
await review2.save()
await calculateBranchRating(review2.branchId)
await transaction.commit()
// company counters
const company = await db.company.findOne({ where: { id: product.company.id } })
if (company) {
company.countProductReviews++
company.save()
}
} catch (err) {
transaction?.rollback()
}
// <---
return res.status(200).json({ success: 'success', uid: review.uid })
} catch (err) {
next(err)
}
}
this.Edit = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
let transaction = null
try {
const { uid, rating, text } = req.body
if(!isSet(uid) || isEmpty(uid)){
throw new BadRequest({ lang: req.user?.languageCode })
}
if(!isSet(text) || isEmpty(text)){
throw new BadRequest({ lang: req.user?.languageCode })
}
if(!isSet(rating)){
throw new BadRequest({ lang: req.user?.languageCode })
}
transaction = await db.sequelize.transaction()
let review = await db.productReview.findOne({ where: { uid } })
if (rating != review.rating || text != review.text) {
review.isVerified = false
}
review.rating = rating
review.text = text
await review.save()
await calculateProductRating(review.productId)
await transaction.commit()
return res.status(200).json(review)
} catch (err) {
transaction?.rollback()
next(err)
}
}
this.Delete = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
let transaction = null
try {
const { uid } = req.body
if(!isSet(uid) || isEmpty(uid)){
throw new BadRequest({ lang: req.user?.languageCode })
}
transaction = await db.sequelize.transaction()
const review = await db.productReview.findOne({ where: { uid } })
const productId = review.productId
const isVerified = review.isVerified
await review.destroy()
// если отзыв был проверен то пересчитать рейтинг
if(isVerified) await calculateProductRating(productId)
await transaction.commit()
return res.status(200).json({ status: 'success', uid })
} catch (err) {
transaction?.rollback()
next(err)
}
}
async function calculateProductRating(productId) {
let product = await db.product.findOne({ where: { id: productId } })
if(!product){
throw new NotFound({ lang: req.user?.languageCode })
}
const reviews = await db.productReview.findAll({
where: { productId: productId, isVerified: true }
})
if (reviews.length > 0) {
product.rating =
reviews.reduce((previousValue, review) => {
return (previousValue ? previousValue : 0) + (review ? review.rating : 0)
}, 0) / reviews.length
} else {
product.rating = 0
}
await product.save()
}
}