/var/www/p4ela.kz/server/delivery/api/controllers
Edit: /var/www/p4ela.kz/server/delivery/api/controllers/product.controller.js (25793B)
const logger = require('../../logger')({ service: 'api' })
const checkPermission = require('../utils/checkPermission.util')
const { NotFound, BadRequest } = require('../responseModels/errors')
const { isSet, isEmpty, minLength } = require('../utils/validator.util')
const { performance } = require('perf_hooks')
const { ProductListModel } = require('../responseModels')
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 { branchId, categoryId, companyId, productGroupId, productTypeId, limit, page } =
req.query
let where = {}
if (categoryId > 0) {
where['categoryId'] = categoryId
}
if (companyId > 0) {
where['companyId'] = companyId
}
if (productGroupId > 0) {
where['productGroupId'] = productGroupId
}
if (productTypeId > 0) {
where['productTypeId'] = productTypeId
}
let whereBranchProduct = {}
if (branchId > 0) {
whereBranchProduct['branchId'] = branchId
}
// let whereProductImage = { isDefault: true }
let whereProductImage = {}
let whereProductVariant = {}
let whereProductExtra = {}
let whereProductIngridient = {}
let offset = page > 0 ? (page - 1) * (limit || 10) : 0
const { count, rows } = await db.product.findAndCountAll({
include: [
{ model: db.category},
{ model: db.branchProduct, where: whereBranchProduct, required: false },
{ model: db.productFeature, include: { model: db.productTypeFeature } },
{ model: db.productImage, where: whereProductImage, required: false },
{ model: db.productVariant, where: whereProductVariant, required: false },
{ model: db.productExtra, where: whereProductExtra, required: false },
{ model: db.productIngridient, where: whereProductIngridient, required: false },
{ model: db.company, where: { deletedAt: null } }
],
where,
order: [
['position', 'ASC']
],
offset,
limit: parseInt(limit) || 10
})
if (rows.length == 0 || !rows) {
throw new NotFound({ lang: req.user?.languageCode })
}
const time = performance.now() - t1
return res.status(200).json({ list: rows, time, count })
} catch (err) {
next(err)
}
}
this.Details = async (req, res, next) => {
logger.child({ path: req.path, request: req.params }).info()
try {
let t1 = performance.now()
const { uid } = req.params
if (!uid) {
throw new BadRequest({ lang: req.user?.languageCode })
}
const product = await db.product.findOne({
include: [
{ model: db.productImage },
{ model: db.branchProduct },
{ model: db.productExtra},
{ model: db.productVariant},
{ model: db.productIngridient},
{ model: db.productFeature, include: { model: db.productTypeFeature } }
],
where: { uid: uid }
})
if (!product) {
throw new NotFound({ lang: req.user?.languageCode })
}
const time = performance.now() - t1
return res.status(200).json(product)
} catch (err) {
next(err)
}
}
this.ListFavorite = async (req, res, next) => {
logger.child({ path: req.path, request: req.params }).info()
try {
let t1 = performance.now()
const uid = req.user.uid
const { limit, page } = req.query
let offset = page ? (page - 1) * (limit || 10) : 0
let whereProductImage = {}
let whereProductVariant = {}
let whereProductExtra = {}
let whereProductIngridient = {}
let { rows, count } = await db.product.findAndCountAll({
include: [
{ model: db.category},
{ model: db.productExtra},
{ model: db.productVariant},
{ model: db.productIngridient},
{ model: db.productFeature, include: { model: db.productTypeFeature } },
{ model: db.productImage, where: whereProductImage, required: false },
{ model: db.productVariant, where: whereProductVariant, required: false },
{ model: db.productExtra, where: whereProductExtra, required: false },
{ model: db.productIngridient, where: whereProductIngridient, required: false },
{ model:
db.company,
as: 'company',
paranoid: false,
include: { model: db.branch, as: "branches" },
where: { deletedAt: null },
},
{
model: db.user,
through: 'favorite_products',
as: 'favoriteUsers',
where: { uid }
}
],
// where: {'$company.deletedAt$': null },
offset,
limit: parseInt(limit)
})
if (!rows || rows.length == 0) {
throw new NotFound({ lang: req.user?.languageCode })
}
const time = performance.now() - t1
return res.status(200).json(new ProductListModel({ rows, time, page }))
} catch (err) {
next(err)
}
}
this.AddFavorite = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
try {
const { productUid, userUid } = req.body
if (!isSet(productUid) || !isSet(userUid) || isEmpty(productUid) || isEmpty(userUid)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
const product = await db.product.findOne({ where: { uid: productUid } })
const user = await db.user.findOne({ where: { uid: userUid } })
if (!user || !product) {
throw new NotFound({ lang: req.user?.languageCode })
}
user.addFavoriteProduct(product)
return res.status(200).json({ status: 'success' })
} catch (err) {
next(err)
}
}
this.RemoveFavorite = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
try {
const { productUid, userUid } = req.body
if (!isSet(productUid) || !isSet(userUid) || isEmpty(productUid) || isEmpty(userUid)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
const product = await db.product.findOne({ where: { uid: productUid } })
const user = await db.user.findOne({ where: { uid: userUid } })
if (!user || !product) {
throw new NotFound({ lang: req.user?.languageCode })
}
user.removeFavoriteProduct(product)
return res.status(200).json({ status: 'success' })
} catch (err) {
next(err)
}
}
this.Create = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
try {
let t1 = performance.now()
checkPermission(req, 'product_edit')
if (!isSet(req.body.name) || isEmpty(req.body.name) || !minLength(req.body.name, 4)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
if (!isSet(req.body.companyId) || isEmpty(req.body.companyId)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
if (!isSet(req.body.categoryId) || isEmpty(req.body.categoryId)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
if (!isSet(req.body.productTypeId) || isEmpty(req.body.productTypeId)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
if (!isSet(req.body.productGroupId) || isEmpty(req.body.productGroupId)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
if (!isSet(req.body.productFeatures) || !Array.isArray(req.body.productFeatures)) {
req.body.productFeatures = []
}
if (!isSet(!req.body.productVariants) || !Array.isArray(req.body.productVariants)) {
req.body.productVariants = []
}
if (!isSet(!req.body.productExtras) || !Array.isArray(req.body.productExtras)) {
req.body.productExtras = []
}
if (!isSet(!req.body.productIngridients) || !Array.isArray(req.body.productIngridients)) {
req.body.productIngridients = []
}
if (!isSet(!req.body.productImages) || !Array.isArray(req.body.productImages)) {
req.body.productImages = []
}
if (!isSet(req.body.branchProducts) || !Array.isArray(req.body.branchProducts)) {
req.body.branchProducts = []
}
const {
name,
position,
active,
active_delivery,
article,
remote_id,
description,
tag,
companyId,
categoryId,
printerId,
productTypeId,
productGroupId,
productFeatures,
productVariants,
productExtras,
productIngridients,
productImages,
branchProducts
} = req.body
const product = await db.product.create(
{
name,
position,
active,
active_delivery,
article,
remote_id,
description,
tag,
companyId,
categoryId,
printerId,
productTypeId,
productGroupId,
productFeatures,
productVariants,
productExtras,
productIngridients,
productImages,
branchProducts
},
{
include: [
{ model: db.productVariant },
{ model: db.productExtra },
{ model: db.productIngridient },
{ model: db.productImage },
{ model: db.branchProduct },
{ model: db.productFeature, include: { model: db.productTypeFeature } }
]
}
)
const time = performance.now() - t1
return res.status(200).json({
status: 'success',
uid: product.uid
})
} catch (err) {
next(err)
}
}
this.Edit = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
const transaction = await db.sequelize.transaction()
try {
let t1 = performance.now()
checkPermission(req, 'product_edit')
if (!isSet(req.body.uid) || isEmpty(req.body.uid)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
if (!isSet(req.body.name) || isEmpty(req.body.name) || !minLength(req.body.name, 1)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
if (!isSet(req.body.companyId) || isEmpty(req.body.companyId)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
if (!isSet(req.body.categoryId) || isEmpty(req.body.categoryId)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
if (!isSet(req.body.productTypeId) || isEmpty(req.body.productTypeId)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
if (!isSet(req.body.productGroupId) || isEmpty(req.body.productGroupId)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
const {
uid,
name,
position,
active,
active_delivery,
article,
remote_id,
description,
tag,
companyId,
categoryId,
printerId,
productTypeId,
productGroupId,
productFeatures,
productImages,
productVariants,
productExtras,
productIngridients,
branchProducts
} = req.body
let product = await db.product.findOne({
include: [
{ model: db.productVariant },
{ model: db.productExtra },
{ model: db.productIngridient },
{ model: db.productImage },
{ model: db.branchProduct },
{ model: db.productFeature, include: { model: db.productTypeFeature } }
],
where: { uid: uid }
})
if (!product) {
throw new NotFound({ lang: req.user?.languageCode })
}
product.name = name
product.tag = tag
product.position = position
product.active = active
product.active_delivery = active_delivery
product.article = article
product.remote_id = remote_id
product.description = description
product.companyId = companyId
product.printerId = printerId
product.productTypeId = productTypeId
product.productGroupId = productGroupId
product.categoryId = categoryId
// создать новые или обновить цены
if (isSet(branchProducts) && Array.isArray(branchProducts)) {
for (const bp of branchProducts) {
let idx = product.branchProducts.findIndex((p) => p.branchId == bp?.branchId)
if (idx === -1) {
await db.branchProduct.create(bp)
} else {
await db.branchProduct.update(bp, { where: { id: bp.id } })
}
}
}
// // удалить цены
// if (product.branchProducts != null && Array.isArray(product.branchProducts)) {
// for (const bp of product.branchProducts) {
// let idx = product.branchProducts.findIndex((p) => p.id == bp?.id)
// if (idx === -1) {
// await db.branchProduct.destroy({ where: { id: bp.id } })
// }
// }
// }
// создать новые или обновить характеристики
if (isSet(productFeatures) && Array.isArray(productFeatures)) {
for (const feature of productFeatures) {
let idx = product.productFeatures.findIndex((p) => p.id == feature?.id)
if (idx === -1) {
await db.productFeature.create(feature)
} else {
await db.productFeature.update(feature, { where: { id: feature.id } })
}
}
}
// удалить характеристики
if (
isSet(product.productFeatures) &&
Array.isArray(product.productFeatures) &&
isSet(productFeatures) &&
Array.isArray(productFeatures)
) {
for (const feature of product.productFeatures) {
let idx = productFeatures.findIndex((p) => p.id == feature?.id)
if (idx === -1) {
await db.productFeature.destroy({ where: { id: feature.id } })
}
}
}
// создать новые или обновить изображения
if (isSet(productImages) && Array.isArray(productImages)) {
for (const image of productImages) {
let idx = product.productImages.findIndex((p) => p.id == image?.id)
if (idx === -1) {
await db.productImage.create(image)
} else {
await db.productImage.update(image, { where: { id: image.id } })
}
}
}
// удалить изображения
if (
isSet(product.productImages) &&
Array.isArray(product.productImages) &&
isSet(productImages) &&
Array.isArray(productImages)
) {
for (const image of product.productImages) {
let idx = productImages.findIndex((p) => p.id == image?.id) // будет работать
//let idx = product.productImages.findIndex((p) => p.id == image?.id) // не будет работать
if (idx === -1) {
await db.productImage.destroy({ where: { id: image.id } })
// удалить изображение с сервера
// ...
}
}
}
// создать новые или обновить варианты
if (isSet(productVariants) && Array.isArray(productVariants)) {
for (const item of productVariants) {
let idx = product.productVariants.findIndex((p) => p.id == item?.id)
if (idx === -1) {
await db.productVariant.create(item)
} else {
await db.productVariant.update(item, { where: { id: item.id } })
}
}
}
// удалить варианты
if (
isSet(product.productVariants) &&
Array.isArray(product.productVariants) &&
isSet(productVariants) &&
Array.isArray(productVariants)
) {
for (const image of product.productVariants) {
let idx = productVariants.findIndex((p) => p.id == image?.id) // будет работать
if (idx === -1) {
await db.productVariant.destroy({ where: { id: image.id } })
}
}
}
// создать новые или обновить extra
if (isSet(productExtras) && Array.isArray(productExtras)) {
for (const item of productExtras) {
let idx = product.productExtras.findIndex((p) => p.id == item?.id)
if (idx === -1) {
await db.productExtra.create(item)
} else {
await db.productExtra.update(item, { where: { id: item.id } })
}
}
}
// удалить extra
if (
isSet(product.productExtras) &&
Array.isArray(product.productExtras) &&
isSet(productExtras) &&
Array.isArray(productExtras)
) {
for (const image of product.productExtras) {
let idx = productExtras.findIndex((p) => p.id == image?.id) // будет работать
if (idx === -1) {
await db.productExtra.destroy({ where: { id: image.id } })
}
}
}
// создать новые или обновить ingridients
if (isSet(productIngridients) && Array.isArray(productIngridients)) {
for (const item of productIngridients) {
let idx = product.productIngridients.findIndex((p) => p.id == item?.id)
if (idx === -1) {
await db.productIngridient.create(item)
} else {
await db.productIngridient.update(item, { where: { id: item.id } })
}
}
}
// удалить ingridients
if (
isSet(product.productIngridients) &&
Array.isArray(product.productIngridients) &&
isSet(productIngridients) &&
Array.isArray(productIngridients)
) {
for (const image of product.productIngridients) {
let idx = productIngridients.findIndex((p) => p.id == image?.id) // будет работать
if (idx === -1) {
await db.productIngridient.destroy({ where: { id: image.id } })
}
}
}
// установить изображение по умолчанию
// ...
await product.save()
await transaction.commit()
await product.reload()
const time = performance.now() - t1
return res.status(200).json(product)
} catch (err) {
await transaction.rollback()
next(err)
}
}
this.Delete = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
try {
let t1 = performance.now()
checkPermission(req, 'product_edit')
const { uid } = req.body
if (!isSet(uid) || isEmpty(uid)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
const product = await db.product.findOne({ where: { uid: uid } })
if (!product) {
throw new NotFound({ lang: req.user?.languageCode })
}
await db.product.destroy({ where: { uid: uid } })
const time = performance.now() - t1
return res.status(200).json({ status: 'success', uid: product.uid })
} catch (err) {
next(err)
}
}
this.AddImage = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
try {
let t1 = performance.now()
checkPermission(req, 'product_edit')
const { productUid, productImage } = req.body
if (!isSet(productUid) || isEmpty(productUid)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
if (!isSet(productImage) || isEmpty(productImage)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
const product = await db.product.findOne({
where: { uid: productUid }
})
if (!product) {
throw new NotFound({ lang: req.user?.languageCode })
}
let image = JSON.parse(productImage)
image.productId = product.id
const result = await db.productImage.create(image)
const time = performance.now() - t1
return res.status(200).json({ status: 'success', uid: result.uid })
} catch (err) {
next(err)
}
}
this.RemoveImage = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
try {
let t1 = performance.now()
checkPermission(req, 'product_edit')
const { imageUid } = req.body
if (!isSet(imageUid) || isEmpty(imageUid)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
await db.productImage.destroy({ where: { uid: imageUid } })
const time = performance.now() - t1
return res.status(200).json({ status: 'success', uid: imageUid })
} catch (err) {
next(err)
}
}
this.SetDefaultImage = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
try {
let t1 = performance.now()
checkPermission(req, 'product_edit')
const { imageUid } = req.body
if (!isSet(imageUid) || isEmpty(imageUid)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
let product_image = await db.productImage.findOne({
where: { uid: imageUid }
})
await db.productImage.update(
{ isDefault: false },
{ where: { productId: product_image.productId } }
)
product_image.isDefault = true
product_image.save()
const time = performance.now() - t1
return res.status(200).json({ status: 'success', uid: imageUid })
} catch (err) {
next(err)
}
}
this.AddFeature = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
try {
let t1 = performance.now()
checkPermission(req, 'product_edit')
const { productUid, productFeature } = req.body
if (!isSet(productUid) || isEmpty(productUid)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
if (!isSet(productFeature) || isEmpty(productFeature)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
const product = await db.product.findOne({
where: { uid: productUid }
})
if (!product) {
throw new NotFound({ lang: req.user?.languageCode })
}
productFeature.productId = product.id
productFeature.productTypeFeatureId = productFeature.productTypeFeatureId
const result = await db.productFeature.create(productFeature)
const time = performance.now() - t1
return res.status(200).json({ status: 'success', uid: result.uid })
} catch (err) {
next(err)
}
}
this.RemoveFeature = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
try {
let t1 = performance.now()
checkPermission(req, 'product_edit')
const { featureUid } = req.body
if (!isSet(featureUid) || isEmpty(featureUid)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
await db.productFeature.destroy({ where: { uid: featureUid } })
const time = performance.now() - t1
return res.status(200).json({ status: 'success', uid: featureUid })
} catch (err) {
next(err)
}
}
// EXTRA
this.AddExtra = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
try {
let t1 = performance.now()
checkPermission(req, 'product_edit')
const { productUid, productExtra } = req.body
if (!isSet(productUid) || isEmpty(productUid)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
if (!isSet(productExtra) || isEmpty(productExtra)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
const product = await db.product.findOne({
where: { uid: productUid }
})
if (!product) {
throw new NotFound({ lang: req.user?.languageCode })
}
let extra = JSON.parse(productExtra)
extra.productId = product.id
const result = await db.productExtra.create(extra)
const time = performance.now() - t1
return res.status(200).json({ status: 'success', uid: result.uid })
} catch (err) {
next(err)
}
}
this.RemoveExtra = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
try {
let t1 = performance.now()
checkPermission(req, 'product_edit')
const { extraUid } = req.body
if (!isSet(extraUid) || isEmpty(extraUid)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
await db.productExtra.destroy({ where: { uid: extraUid } })
const time = performance.now() - t1
return res.status(200).json({ status: 'success', uid: extraUid })
} catch (err) {
next(err)
}
}
// VARIANTS
this.AddVariant = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
try {
let t1 = performance.now()
checkPermission(req, 'product_edit')
const { productUid, productVariant } = req.body
if (!isSet(productUid) || isEmpty(productUid)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
if (!isSet(productVariant) || isEmpty(productVariant)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
const product = await db.product.findOne({
where: { uid: productUid }
})
if (!product) {
throw new NotFound({ lang: req.user?.languageCode })
}
let extra = JSON.parse(productVariant)
extra.productId = product.id
const result = await db.productVariant.create(extra)
const time = performance.now() - t1
return res.status(200).json({ status: 'success', uid: result.uid })
} catch (err) {
next(err)
}
}
this.RemoveVariant = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
try {
let t1 = performance.now()
checkPermission(req, 'product_edit')
const { variantUid } = req.body
if (!isSet(variantUid) || isEmpty(variantUid)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
await db.productVariant.destroy({ where: { uid: variantUid } })
const time = performance.now() - t1
return res.status(200).json({ status: 'success', uid: variantUid })
} catch (err) {
next(err)
}
}
// INGRIDIENTS
this.AddIngridient = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
try {
let t1 = performance.now()
checkPermission(req, 'product_edit')
const { productUid, productIngridient } = req.body
if (!isSet(productUid) || isEmpty(productUid)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
if (!isSet(productIngridient) || isEmpty(productIngridient)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
const product = await db.product.findOne({
where: { uid: productUid }
})
if (!product) {
throw new NotFound({ lang: req.user?.languageCode })
}
let extra = JSON.parse(productIngridient)
extra.productId = product.id
const result = await db.productIngridient.create(extra)
const time = performance.now() - t1
return res.status(200).json({ status: 'success', uid: result.uid })
} catch (err) {
next(err)
}
}
this.RemoveIngridient = async (req, res, next) => {
logger.child({ path: req.path, request: req.body }).info()
try {
let t1 = performance.now()
checkPermission(req, 'product_edit')
const { ingridientUid } = req.body
if (!isSet(ingridientUid) || isEmpty(ingridientUid)) {
throw new BadRequest({ lang: req.user?.languageCode })
}
await db.productIngridient.destroy({ where: { uid: ingridientUid } })
const time = performance.now() - t1
return res.status(200).json({ status: 'success', uid: ingridientUid })
} catch (err) {
next(err)
}
}
}