diff --git a/src/routes/api/v1/contactInfo.ts b/src/routes/api/v1/contactInfo.ts new file mode 100644 index 0000000..48984ea --- /dev/null +++ b/src/routes/api/v1/contactInfo.ts @@ -0,0 +1,244 @@ +import { Request, Response } from 'express'; +import { prisma, __path, log } from '../../../index.js'; +import { parseIntOrUndefined, parseDynamicSortBy } from '../../../assets/helper.js'; + +// Get category +async function get(req: Request, res: Response) { + // Check if required fields are present. + if (req.query.sort === undefined) { + req.query.sort = 'id'; + } + if (req.query.order === undefined) { + req.query.order = 'asc'; + } + if (req.query.search === undefined) { + req.query.search = ''; + } + + if (req.query.id) { + prisma.contactInfo + .findUnique({ + where: { + id: parseInt(req.query.id.toString()) + } + }) + .then((item) => { + if (item) { + res.status(200).json(item); + } else { + res.status(410).json({ status: 'ERROR', errorcode: 'NOT_EXISTING', message: 'ContactInfo does not exist' }); + } + }) + .catch((err) => { + log.db.error(err); + res.status(500).json({ status: 'ERROR', errorcode: 'DB_ERROR', error: err, message: 'An error occurred during the database operation' }); + }); + } else { + // Get all items + const itemCountNotFiltered = await prisma.contactInfo.count({}); + + // Get all items (filtered) + const itemCountFiltered = await prisma.contactInfo.count({ + where: { + OR: [ + { + name: { + // @ts-ignore + contains: req.query.search.length > 0 ? req.query.search : '' + } + }, + { + street: { + // @ts-ignore + contains: req.query.search.length > 0 ? req.query.search : '' + } + } + ] + }, + orderBy: parseDynamicSortBy(req.query.sort.toString(), req.query.order.toString()) + }); + + prisma.contactInfo + .findMany({ + take: parseIntOrUndefined(req.query.limit), + skip: parseIntOrUndefined(req.query.offset), + orderBy: parseDynamicSortBy(req.query.sort.toString(), req.query.order.toString()), + where: { + OR: [ + { + name: { + // @ts-ignore + contains: req.query.search.length > 0 ? req.query.search : '' + } + }, + { + street: { + // @ts-ignore + contains: req.query.search.length > 0 ? req.query.search : '' + } + } + ] + }, + }) + .then((items) => { + if (items) { + res.status(200).json({ total: itemCountFiltered, totalNotFiltered: itemCountNotFiltered, items: items }); + } else { + res.status(410).json({ status: 'ERROR', errorcode: 'NOT_EXISTING', message: 'ContactInfo does not exist' }); + } + }) + .catch((err) => { + log.db.error(err); + res.status(500).json({ status: 'ERROR', errorcode: 'DB_ERROR', error: err, message: 'An error occurred during the database operation' }); + }); + } +} + +// Create category. +function post(req: Request, res: Response) { + // Check if required fields are present. + if (!req.body.street || !req.body.houseNumber || !req.body.zipCode || !req.body.city || !req.body.country) { + res.status(400).json({ status: 'ERROR', errorcode: 'VALIDATION_ERROR', message: 'One or more required fields are missing' }); + return; + } + + // Save data. + prisma.contactInfo + .create({ + data: { + name: req.body.name, + lastName: req.body.lastName, + street: req.body.street, + houseNumber: req.body.houseNumber, + zipCode: req.body.zipCode, + city: req.body.city, + country: req.body.country, + }, + select: { + id: true + } + }) + .then((data) => { + res.status(201).json({ status: 'CREATED', message: 'Successfully created contactInfo', id: data.id }); + }) + .catch((err) => { + // Check if an entry already exists. + if (err.code === 'P2002') { + // P2002 -> "Unique constraint failed on the {constraint}" + // https://www.prisma.io/docs/reference/api-reference/error-reference + res.status(409).json({ status: 'ERROR', errorcode: 'EXISTING', message: 'ContactInfo already exists' }); + } else if (err.code == 'P2000') { + // P2000 -> "The provided value for the column is too long for the column's type. Column: {column_name}" + // https://www.prisma.io/docs/reference/api-reference/error-reference + res.status(404).json({ status: 'ERROR', errorcode: 'VALIDATION_ERROR', message: 'One or more fields exceed the maximum length restriction' }); + } else { + log.db.error(err); + res.status(500).json({ status: 'ERROR', errorcode: 'DB_ERROR', error: err, message: 'An error occurred during the database operation' }); + } + }); +} + +// Update category. +async function patch(req: Request, res: Response) { + // Check if required fields are present. + if (!req.body.id || !req.body.name) { + res.status(400).json({ status: 'ERROR', errorcode: 'VALIDATION_ERROR', message: 'One or more required fields are missing' }); + return; + } + + // Check if the category id exists. If not return 410 Gone. + try { + const result = await prisma.contactInfo.findUnique({ + where: { + id: parseInt(req.body.id) + } + }); + + if (result === null) { + res.status(410).json({ status: 'ERROR', errorcode: 'NOT_EXISTING', message: 'Category does not exist' }); + return; + } + } catch (err) { + log.db.error(err); + res.status(500).json({ status: 'ERROR', errorcode: 'DB_ERROR', error: err, message: 'An error occurred during the database operation' }); + } + + prisma.contactInfo + .update({ + where: { + id: parseInt(req.body.id) + }, + data: { + name: req.body.name, + lastName: req.body.lastName, + street: req.body.street, + houseNumber: req.body.houseNumber, + zipCode: req.body.zipCode, + city: req.body.city, + country: req.body.country, + }, + select: { + id: true + } + }) + .then((data) => { + res.status(201).json({ status: 'UPDATED', message: 'Successfully updated category', id: data.id }); + }) + .catch((err) => { + // Check if an entry already exists. + if (err.code === 'P2002') { + // P2002 -> "Unique constraint failed on the {constraint}" + // https://www.prisma.io/docs/reference/api-reference/error-reference + res.status(409).json({ status: 'ERROR', errorcode: 'EXISTING', message: 'Category already exists' }); + } else if (err.code == 'P2000') { + // P2000 -> "The provided value for the column is too long for the column's type. Column: {column_name}" + // https://www.prisma.io/docs/reference/api-reference/error-reference + res.status(404).json({ status: 'ERROR', errorcode: 'VALIDATION_ERROR', message: 'One or more fields exceed the maximum length restriction' }); + } else { + log.db.error(err); + res.status(500).json({ status: 'ERROR', errorcode: 'DB_ERROR', error: err, message: 'An error occurred during the database operation' }); + } + }); +} + +// Delete category +async function del(req: Request, res: Response) { + // Check if required fields are present. + if (!req.body.id) { + res.status(400).json({ status: 'ERROR', errorcode: 'VALIDATION_ERROR', message: 'One or more required fields are missing' }); + return; + } + + // Does the id exist? If not return 410 Gone. + try { + const result = await prisma.contactInfo.findUnique({ + where: { + id: parseInt(req.body.id) + } + }); + + if (result === null) { + res.status(410).json({ status: 'ERROR', errorcode: 'NOT_EXISTING', message: 'ContactInfo does not exist' }); + return; + } + } catch (err) { + log.db.error(err); + res.status(500).json({ status: 'ERROR', errorcode: 'DB_ERROR', error: err, message: 'An error occurred during the database operation' }); + } + + prisma.contactInfo + .delete({ + where: { + id: parseInt(req.body.id) + } + }) + .then(() => { + res.status(200).json({ status: 'DELETED', message: 'Successfully deleted contactInfo' }); + }) + .catch((err) => { + log.db.error(err); + res.status(500).json({ status: 'ERROR', errorcode: 'DB_ERROR', error: err, message: 'An error occurred during the database operation' }); + }); +} + +export default { get, post, patch, del }; diff --git a/src/routes/api/v1/index.ts b/src/routes/api/v1/index.ts index 302fb4e..b978e1d 100644 --- a/src/routes/api/v1/index.ts +++ b/src/routes/api/v1/index.ts @@ -6,6 +6,7 @@ import itemRoute from './items.js'; import categoryRoute from './categories.js'; import storageUnitRoute from './storageUnits.js'; import storageLocationRoute from './storageLocations.js'; +import contactInfo from './contactInfo.js'; import versionRoute from './version.js' import search_routes from './search/index.js'; @@ -28,6 +29,8 @@ Router.route('/categories').get(categoryRoute.get).post(categoryRoute.post).patc // TODO: Migrate routes to lowercase. Router.route('/storageUnits').get(storageUnitRoute.get).post(storageUnitRoute.post).patch(storageUnitRoute.patch).delete(storageUnitRoute.del); Router.route('/storageLocations').get(storageLocationRoute.get).post(storageLocationRoute.post).patch(storageLocationRoute.patch).delete(storageLocationRoute.del); +Router.route('/contactInfo').get(contactInfo.get).post(contactInfo.post).patch(contactInfo.patch).delete(contactInfo.del); + Router.route('/version').get(versionRoute.get); Router.use('/search', search_routes);