move old to legacy folder
This commit is contained in:
510
.bzr/legacy/basket/controller.js
Normal file
510
.bzr/legacy/basket/controller.js
Normal file
@@ -0,0 +1,510 @@
|
||||
const ObjectId = require('mongodb').ObjectID
|
||||
const getHash = require('pbkdf2-password')()
|
||||
|
||||
const { getDB } = require('../../../utils/mongo')
|
||||
|
||||
const USERS_COLLECTION = 'users'
|
||||
const LISTS_COLLECTION = 'lists'
|
||||
const CATEGORY_COLLECTION = 'default_categories'
|
||||
const USER_CATEGROY_COLLECTION = 'user_categories'
|
||||
const ITEM_COLLECTION = 'items'
|
||||
const fakeUserId = 'fakeUserId'
|
||||
|
||||
let db = null
|
||||
|
||||
const connect = async () => {
|
||||
db = await getDB('basket')
|
||||
}
|
||||
|
||||
const init = async () => {
|
||||
await connect()
|
||||
const categoriesCollection = db.collection(CATEGORY_COLLECTION)
|
||||
const findData = await categoriesCollection.find({
|
||||
}).toArray()
|
||||
if (findData.length === 0) {
|
||||
await categoriesCollection.insertMany([
|
||||
{
|
||||
name: 'Продукты',
|
||||
color: '#08AE0F',
|
||||
},
|
||||
{
|
||||
name: 'Одежда',
|
||||
color: '#9D79B9',
|
||||
},
|
||||
{
|
||||
name: 'Бытовая химия',
|
||||
color: '#B11F1F',
|
||||
},
|
||||
{
|
||||
name: 'Лекарства',
|
||||
color: '#3414F5',
|
||||
},
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
init()
|
||||
|
||||
const _idToId = (data) => {
|
||||
const { _id, ...rest } = data
|
||||
|
||||
return {
|
||||
id: _id,
|
||||
...rest,
|
||||
}
|
||||
}
|
||||
|
||||
const _idToIdArray = (data) => {
|
||||
const _idToIdMap = data.map((item) => _idToId(item))
|
||||
|
||||
return _idToIdMap
|
||||
}
|
||||
|
||||
const getResponse = (error, data, success = true) => {
|
||||
if (error) {
|
||||
return {
|
||||
success: false,
|
||||
error,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success,
|
||||
data,
|
||||
}
|
||||
}
|
||||
|
||||
const signUp = async ({ email, login, password }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const usersCollection = db.collection(USERS_COLLECTION)
|
||||
const userData = await usersCollection.findOne({
|
||||
$or: [{
|
||||
login,
|
||||
}, {
|
||||
email,
|
||||
}],
|
||||
})
|
||||
|
||||
if (userData?.login === login) {
|
||||
throw new Error('Логин занят')
|
||||
}
|
||||
if (userData?.email === email) {
|
||||
throw new Error('Email занят')
|
||||
}
|
||||
|
||||
getHash({ password }, async (err, pass, salt, hash) => {
|
||||
if (err) throw new Error(err)
|
||||
// eslint-disable-next-line max-len
|
||||
const { insertedCount } = await usersCollection.insertOne({ email, login, pwd: hash, salt })
|
||||
if (!insertedCount) throw new Error('insert error')
|
||||
})
|
||||
|
||||
return {}
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const getUser = async ({ email }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const usersCollection = db.collection(USERS_COLLECTION)
|
||||
const userData = await usersCollection.findOne(
|
||||
{
|
||||
email,
|
||||
},
|
||||
)
|
||||
if (userData) return userData
|
||||
throw new Error('Неправильный email или пароль')
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const addList = async ({ userId = fakeUserId, ...data }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const listsCollection = db.collection(LISTS_COLLECTION)
|
||||
const insertData = await listsCollection.insertOne({
|
||||
userId,
|
||||
timeStamp: Date.now(),
|
||||
...data,
|
||||
})
|
||||
|
||||
const { insertedCount, ops } = insertData
|
||||
if (insertedCount) { return _idToId(ops[0]) }
|
||||
throw new Error('insert error')
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const getLists = async ({ userId = fakeUserId }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const listsCollection = db.collection(LISTS_COLLECTION)
|
||||
const itemsCollection = db.collection(ITEM_COLLECTION)
|
||||
let newLists = []
|
||||
|
||||
const data = await listsCollection.find({
|
||||
userId,
|
||||
}).toArray()
|
||||
|
||||
await Promise.all(data.map(async (element) => {
|
||||
const total = await itemsCollection.countDocuments({
|
||||
parentId: element._id,
|
||||
})
|
||||
const purchased = await itemsCollection.countDocuments({
|
||||
parentId: element._id,
|
||||
bought: true,
|
||||
})
|
||||
|
||||
newLists.push({
|
||||
...element, total, purchased,
|
||||
})
|
||||
}))
|
||||
|
||||
newLists.sort((a, b) => (b.timeStamp - a.timeStamp))
|
||||
|
||||
return _idToIdArray(newLists)
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
/* добавил логику рекурсивного удаления дочерних документов */
|
||||
const deleteDoc = async ({ id, tag = false }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const listsCollection = db.collection(LISTS_COLLECTION)
|
||||
const itemsCollection = db.collection(ITEM_COLLECTION)
|
||||
|
||||
const findData = await itemsCollection.find({
|
||||
parentId: new ObjectId(id),
|
||||
}).toArray()
|
||||
|
||||
findData.forEach(async (element) => {
|
||||
await deleteDoc({
|
||||
id: element._id,
|
||||
tag: true,
|
||||
})
|
||||
})
|
||||
|
||||
let delData = null
|
||||
if (tag) {
|
||||
delData = await itemsCollection.deleteOne({
|
||||
_id: new ObjectId(id),
|
||||
})
|
||||
} else {
|
||||
delData = await listsCollection.deleteOne({
|
||||
_id: new ObjectId(id),
|
||||
})
|
||||
}
|
||||
|
||||
const { deletedCount } = delData
|
||||
if (deletedCount) {
|
||||
return {
|
||||
}
|
||||
} throw new Error('no data to delete')
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const renameList = async ({ id, listName }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const listsCollection = db.collection(LISTS_COLLECTION)
|
||||
const data = await listsCollection.updateOne({
|
||||
_id: new ObjectId(id),
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
listName,
|
||||
},
|
||||
})
|
||||
|
||||
const { matchedCount } = data
|
||||
if (matchedCount) {
|
||||
const findData = await listsCollection.findOne({
|
||||
_id: new ObjectId(id),
|
||||
})
|
||||
return _idToId(findData)
|
||||
} throw new Error('no data to rename')
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const duplicateList = async ({ id, parentId = null }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const listsCollection = db.collection(LISTS_COLLECTION)
|
||||
const itemsCollection = db.collection(ITEM_COLLECTION)
|
||||
|
||||
let addListData = null
|
||||
let newId = null
|
||||
|
||||
if (parentId) {
|
||||
const findData = await itemsCollection.findOne(
|
||||
{
|
||||
_id: new ObjectId(id),
|
||||
},
|
||||
)
|
||||
|
||||
const { _id, ...item } = findData
|
||||
item.parentId = parentId
|
||||
const insertData = await itemsCollection.insertOne({
|
||||
...item,
|
||||
})
|
||||
const { insertedCount } = insertData
|
||||
if (!insertedCount) throw new Error('insert new item error')
|
||||
} else {
|
||||
const findData = await listsCollection.findOne(
|
||||
{
|
||||
_id: new ObjectId(id),
|
||||
},
|
||||
)
|
||||
|
||||
const { _id, timeStamp, ...item } = findData
|
||||
item.listName = `(КОПИЯ) ${item.listName}`
|
||||
addListData = await addList({
|
||||
...item,
|
||||
})
|
||||
newId = addListData.id
|
||||
}
|
||||
|
||||
const childData = await itemsCollection.find({
|
||||
parentId: new ObjectId(id),
|
||||
}).toArray()
|
||||
|
||||
childData.forEach(async (element) => {
|
||||
await duplicateList({
|
||||
id: element._id, parentId: newId,
|
||||
})
|
||||
})
|
||||
|
||||
if (addListData) return _idToId(addListData)
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const getCategory = async ({ userId }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const categoriesCollection = db.collection(CATEGORY_COLLECTION)
|
||||
const defaultCategories = await categoriesCollection.find({
|
||||
}).toArray()
|
||||
const defaultCategoriesData = _idToIdArray(defaultCategories).map((dc) => ({
|
||||
...dc, userId,
|
||||
}))
|
||||
|
||||
const userCollection = db.collection(USER_CATEGROY_COLLECTION)
|
||||
const userCategoriesFilter = {}
|
||||
|
||||
if (userId) {
|
||||
userCategoriesFilter.userId = userId
|
||||
}
|
||||
const userFindData = await userCollection.find(userCategoriesFilter).toArray()
|
||||
|
||||
return [...defaultCategoriesData, ..._idToIdArray(userFindData)]
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const postCategory = async ({ userId = fakeUserId, ...categoryData }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const userCollection = db.collection(USER_CATEGROY_COLLECTION)
|
||||
const insertData = await userCollection.insertOne({
|
||||
userId, ...categoryData,
|
||||
})
|
||||
|
||||
// const {insertedCount, ops} = insertData
|
||||
// if (insertedCount)
|
||||
// _idToId(ops[0])
|
||||
// else
|
||||
// throw new Error('insert error')
|
||||
const userFindData = await userCollection.find({
|
||||
userId,
|
||||
}).toArray()
|
||||
return _idToIdArray(userFindData)
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const getShoppingList = async ({ userId = fakeUserId, id }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const listsCollection = db.collection(ITEM_COLLECTION)
|
||||
const itemsList = await listsCollection.find({
|
||||
parentId: new ObjectId(id),
|
||||
}).toArray()
|
||||
const categoryList = await getCategory({ })
|
||||
const coloredItemsList = itemsList.map((item) => ({
|
||||
...item,
|
||||
// eslint-disable-next-line max-len
|
||||
color: categoryList.find((category) => String(category.id) === String(item.categoryId))?.color,
|
||||
}))
|
||||
|
||||
return _idToIdArray(coloredItemsList)
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const addListItem = async ({ userId = fakeUserId, listId, categoryId, text }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const dataToInsert = {
|
||||
parentId: new ObjectId(listId),
|
||||
categoryId: new ObjectId(categoryId),
|
||||
text,
|
||||
count: 1,
|
||||
bought: false,
|
||||
createdBy: userId,
|
||||
createdDt: Date.now(),
|
||||
modifiedBy: userId,
|
||||
modifiedDt: Date.now(),
|
||||
}
|
||||
const itemCollection = db.collection(ITEM_COLLECTION)
|
||||
await itemCollection.insertOne(dataToInsert)
|
||||
|
||||
return _idToId(dataToInsert)
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const boughtItem = async ({ userId = fakeUserId, itemId, bought }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
try {
|
||||
const itemCollection = db.collection(ITEM_COLLECTION)
|
||||
const chengedData = await itemCollection.findOneAndUpdate({
|
||||
_id: new ObjectId(itemId),
|
||||
},
|
||||
[{
|
||||
$set: {
|
||||
bought: { $eq: [false, '$bought'] },
|
||||
modifiedBy: userId,
|
||||
modifiedDt: Date.now(),
|
||||
},
|
||||
}])
|
||||
return _idToId(chengedData)
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const incCountItem = async ({ userId = fakeUserId, itemId, count }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const itemCollection = db.collection(ITEM_COLLECTION)
|
||||
const chengedData = await itemCollection.findOneAndUpdate({
|
||||
_id: new ObjectId(itemId),
|
||||
},
|
||||
{
|
||||
$inc: {
|
||||
count,
|
||||
},
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
modifiedBy: userId,
|
||||
modifiedDt: Date.now(),
|
||||
},
|
||||
})
|
||||
const chengeData = await itemCollection.findOneAndUpdate({
|
||||
_id: new ObjectId(itemId),
|
||||
count: {
|
||||
$lt: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
count: 1,
|
||||
modifiedBy: userId,
|
||||
modifiedDt: Date.now(),
|
||||
},
|
||||
})
|
||||
return _idToId(chengedData || chengeData)
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const deleteItem = async ({ itemId }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const itemCollection = db.collection(ITEM_COLLECTION)
|
||||
const findItemData = await itemCollection.find({
|
||||
_id: new ObjectId(itemId),
|
||||
})
|
||||
|
||||
findItemData.forEach((item) => {
|
||||
deleteItem({
|
||||
id: item._id,
|
||||
})
|
||||
})
|
||||
|
||||
const deleteItemData = await itemCollection.deleteOne({
|
||||
_id: new ObjectId(itemId),
|
||||
})
|
||||
|
||||
const { deletedButton } = deleteItemData
|
||||
if (deletedButton) {
|
||||
return {
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const requiredFields = (fields) => (req, res, next) => {
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const fieldName of fields) {
|
||||
if (!req.body[fieldName]) {
|
||||
throw new Error(`Параметр ${fieldName} не установлен`)
|
||||
}
|
||||
}
|
||||
|
||||
next()
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getResponse,
|
||||
addList,
|
||||
getLists,
|
||||
deleteDoc,
|
||||
renameList,
|
||||
duplicateList,
|
||||
getCategory,
|
||||
postCategory,
|
||||
getShoppingList,
|
||||
addListItem,
|
||||
boughtItem,
|
||||
deleteItem,
|
||||
incCountItem,
|
||||
signUp,
|
||||
getUser,
|
||||
_idToId,
|
||||
requiredFields,
|
||||
}
|
||||
Reference in New Issue
Block a user