- Implemented api field validation in item api routes - Implemented PATCH api route for item endpoint
253 lines
7.4 KiB
TypeScript
253 lines
7.4 KiB
TypeScript
import { Request, Response } from 'express';
|
|
import { prisma, __path, log } from '../../../index.js';
|
|
import { itemStatus } from '@prisma/client';
|
|
import { parseIntRelation, parseIntOrUndefined } from '../../../assets/helper.js';
|
|
// Get item.
|
|
function get(req: Request, res: Response) {
|
|
if (req.query.getAll === undefined) {
|
|
// Check if required fields are present
|
|
if (!req.query.id) {
|
|
res.status(400).json({ errorcode: 'VALIDATION_ERROR', error: 'One or more required fields are missing' });
|
|
return;
|
|
}
|
|
|
|
// Check if number is a valid integer
|
|
if (!Number.isInteger(parseInt(req.query.id.toString()))) {
|
|
res.status(400).json({ errorcode: 'VALIDATION_ERROR', error: 'The id field must be an integer' });
|
|
return;
|
|
}
|
|
prisma.item
|
|
.findUnique({
|
|
where: {
|
|
id: parseInt(req.query.id.toString())
|
|
},
|
|
// Get contactInfo, category, storageLocation( storageUnit<contactInfo> ) from relations
|
|
include: {
|
|
contactInfo: true,
|
|
category: true,
|
|
storageLocation: {
|
|
include: {
|
|
storageUnit: {
|
|
include: {
|
|
contactInfo: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
.then((items) => {
|
|
if (items) {
|
|
res.status(200).json(JSON.stringify(items));
|
|
} else {
|
|
res.status(410).json({ errorcode: 'NOT_EXISTING', error: 'Item does not exist' });
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
log.db.error(err);
|
|
res.status(500).json({ errorcode: 'DB_ERROR', error: err });
|
|
});
|
|
} else {
|
|
prisma.item
|
|
.findMany({
|
|
// Get contactInfo, category, storageLocation( storageUnit<contactInfo> ) from relations.
|
|
include: {
|
|
contactInfo: true,
|
|
category: true,
|
|
storageLocation: {
|
|
include: {
|
|
storageUnit: {
|
|
include: {
|
|
contactInfo: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
.then((items) => {
|
|
if (items) {
|
|
res.status(200).json(JSON.stringify(items));
|
|
} else {
|
|
res.status(410).json({ errorcode: 'NOT_EXISTING', error: 'Item does not exist' });
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
log.db.error(err);
|
|
res.status(500).json({ errorcode: 'DB_ERROR', error: err });
|
|
});
|
|
}
|
|
}
|
|
|
|
// Create item.
|
|
function post(req: Request, res: Response) {
|
|
// Check if required fields are present.
|
|
if (!req.body.name) {
|
|
res.status(400).json({ errorcode: 'VALIDATION_ERROR', error: 'One or more required fields are missing' });
|
|
return;
|
|
}
|
|
|
|
// Check if status is valid.
|
|
if (req.body.status !== undefined && !Object.keys(itemStatus).includes(req.body.status)) {
|
|
res.status(400).json({ errorcode: 'VALIDATION_ERROR', error: `Status is not valid, valid values are: ${Object.keys(itemStatus).join(', ')}` });
|
|
return;
|
|
}
|
|
|
|
prisma.item
|
|
.create({
|
|
data: {
|
|
SKU: req.body.sku,
|
|
amount: parseIntOrUndefined(req.body.ammount), // FIXME: This is silently failing if NaN..
|
|
name: req.body.name,
|
|
comment: req.body.comment,
|
|
status: req.body.status, // Only enum(itemStatus) values are valid
|
|
// Relations
|
|
contactInfo: parseIntRelation(req.body.contactInfoId),
|
|
category: parseIntRelation(req.body.categoryId),
|
|
storageLocation: parseIntRelation(req.body.storageLocationId),
|
|
|
|
manufacturer: req.body.manufacturer,
|
|
|
|
//contents: {
|
|
// connect: [{ id: 1 }, { id: 2 }, { id: 3 }]
|
|
//},
|
|
//baseItem: {
|
|
// connect: {
|
|
// id: req.body.baseitemId
|
|
// }
|
|
//},
|
|
createdBy: req.body.createdBy
|
|
}
|
|
})
|
|
.then((data) => {
|
|
res.status(201).json({ status: 'created', 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({ errorcode: 'EXISTING', error: 'Item already exists' });
|
|
} else if (err.code == 'P2003') {
|
|
// P2003 -> "Foreign key constraint failed on the field: {field_name}"
|
|
// https://www.prisma.io/docs/reference/api-reference/error-reference
|
|
// FIXME: Is this errormessage right?
|
|
res.status(404).json({ errorcode: 'NOT_EXISTING', error: 'Specified item does not exist' });
|
|
} else {
|
|
log.db.error(err);
|
|
res.status(500).json({ errorcode: 'DB_ERROR', error: err });
|
|
}
|
|
});
|
|
}
|
|
|
|
// Update storageLocation. -> Only existing contactInfo.
|
|
async function patch(req: Request, res: Response) {
|
|
// Check if required fields are present.
|
|
if (!req.body.id) {
|
|
res.status(400).json({ errorcode: 'VALIDATION_ERROR', error: 'One or more required fields are missing' });
|
|
return;
|
|
}
|
|
|
|
// Check if number is a valid integer
|
|
if (!Number.isInteger(parseInt(req.body.id.toString()))) {
|
|
res.status(400).json({ errorcode: 'VALIDATION_ERROR', error: 'The id field must be an integer' });
|
|
return;
|
|
}
|
|
|
|
// Check if status is valid.
|
|
if (req.body.status !== undefined && !Object.keys(itemStatus).includes(req.body.status)) {
|
|
res.status(400).json({ errorcode: 'VALIDATION_ERROR', error: `Status is not valid, valid values are: ${Object.keys(itemStatus).join(', ')}` });
|
|
return;
|
|
}
|
|
|
|
prisma.item
|
|
.update({
|
|
where: {
|
|
id: parseInt(req.body.id)
|
|
},
|
|
data: {
|
|
SKU: req.body.sku,
|
|
amount: parseIntOrUndefined(req.body.ammount), // FIXME: This is silently failing if NaN..
|
|
name: req.body.name,
|
|
comment: req.body.comment,
|
|
status: req.body.status, // Only enum(itemStatus) values are valid
|
|
// Relations
|
|
contactInfo: parseIntRelation(req.body.contactInfoId),
|
|
category: parseIntRelation(req.body.categoryId),
|
|
storageLocation: parseIntRelation(req.body.storageLocationId),
|
|
|
|
manufacturer: req.body.manufacturer,
|
|
|
|
//contents: {
|
|
// connect: [{ id: 1 }, { id: 2 }, { id: 3 }]
|
|
//},
|
|
//baseItem: {
|
|
// connect: {
|
|
// id: req.body.baseitemId
|
|
// }
|
|
//},
|
|
createdBy: req.body.createdBy
|
|
}
|
|
})
|
|
.then(() => {
|
|
res.status(201).json({ status: 'updated' });
|
|
})
|
|
.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({ errorcode: 'EXISTING', error: 'Item already exists', err: err });
|
|
} else if (err.code == 'P2003') {
|
|
// P2003 -> "Foreign key constraint failed on the field: {field_name}"
|
|
// https://www.prisma.io/docs/reference/api-reference/error-reference
|
|
res.status(404).json({ errorcode: 'NOT_EXISTING', error: 'Specified item does not exist' });
|
|
} else {
|
|
log.db.error(err);
|
|
res.status(500).json({ errorcode: 'DB_ERROR', error: err });
|
|
}
|
|
});
|
|
}
|
|
|
|
// Delete item.
|
|
async function del(req: Request, res: Response) {
|
|
// Check if required fields are present.
|
|
if (!req.body.id) {
|
|
res.status(400).json({ errorcode: 'VALIDATION_ERROR', error: 'One or more required fields are missing' });
|
|
return;
|
|
}
|
|
|
|
// Does the id exist? If not return 410 Gone.
|
|
try {
|
|
const result = await prisma.item.findUnique({
|
|
where: {
|
|
id: parseInt(req.body.id)
|
|
}
|
|
});
|
|
|
|
if (result === null) {
|
|
res.status(410).json({ errorcode: 'NOT_EXISTING', error: 'Item does not exist' });
|
|
return;
|
|
}
|
|
} catch (err) {
|
|
log.db.error(err);
|
|
res.status(500).json({ errorcode: 'DB_ERROR', error: err });
|
|
}
|
|
|
|
prisma.item
|
|
.delete({
|
|
where: {
|
|
id: parseInt(req.body.id)
|
|
}
|
|
})
|
|
.then(() => {
|
|
res.status(200).json({ errorcode: 'DELETED', error: 'Sucessfully deleted entry' });
|
|
})
|
|
.catch((err) => {
|
|
log.db.error(err);
|
|
res.status(500).json({ errorcode: 'DB_ERROR', error: err });
|
|
});
|
|
}
|
|
|
|
export default { get, post, patch, del };
|