/var/www/qr4y.com/server/delivery/api/controllers
Edit: /var/www/qr4y.com/server/delivery/api/controllers/productReview.controller.js (6164B)
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'] = userId
}
if (productId) {
where['productId'] = 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: [
['createdAt', '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 { id } = req.params
const review = await db.productReview.findOne({ where: { id } })
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 { id } = req.body
if(!isSet(id) || isEmpty(id)){
throw new BadRequest({ lang: req.user?.languageCode })
}
transaction = await db.sequelize.transaction()
const review = await db.productReview.findOne({ where: { id } })
review.isVerified = true
await review.save()
await calculateProductRating(review.productId)
await transaction.commit()
return res.status(200).json({ status: 'success', id })
} catch (err) {
transaction?.rollback()
next(err)
}
}
this.Create = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
try {
const { productId, text, rating } = req.body
if(!isSet(productId) || isEmpty(productId)){
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: { id: productId }
})
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 id = review.id;
const review2 = await db.productReview.findOne({ where: { id } })
review2.isVerified = true
await review2.save()
// company counters
const company = await db.company.findOne({ where: { id: product.companyId } })
if (company) {
company.countProductReviews++
company.save()
}
await transaction.commit()
await calculateProductRating(review2.productId)
} catch (err) {
transaction?.rollback()
}
// <---
return res.status(200).json({ success: 'success', id: review.id, review: review })
} catch (err) {
next(err)
}
}
this.Edit = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
let transaction = null
try {
const { id, rating, text } = req.body
if(!isSet(id) || isEmpty(id)){
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: { id } })
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 { id } = req.body
if(!isSet(id) || isEmpty(id)){
throw new BadRequest({ lang: req.user?.languageCode })
}
transaction = await db.sequelize.transaction()
const review = await db.productReview.findOne({ where: { id } })
const productId = review.productId
const isVerified = review.isVerified
await review.destroy()
// если отзыв был проверен то пересчитать рейтинг
if (isVerified) {
let product = await db.product.findOne({
where: { id: productId }
})
const company = await db.company.findOne({ where: { id: product.companyId } })
if (company) {
company.countProductReviews--
company.save()
}
}
await transaction.commit()
await calculateBranchRating(branchId)
return res.status(200).json({ status: 'success', id })
} 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 sum = await db.productReview.sum('rating',
{
where: { productId: productId, isVerified: true }
}
)
const count = await db.productReview.count(
{
where: { productId: productId, isVerified: true }
}
)
if (sum > 0) {
product.rating = sum / count
await product.save()
}
}
}