import { Request, Response } from 'express'; import db, { handlePrismaError } from '../../../../handlers/db.js'; // Database import log from '../../../../handlers/log.js'; import { parseDynamicSortBy } from '../../../../helpers/prisma_helpers.js'; import { schema_get, schema_post, schema_patch, schema_del } from './transaction_schema.js'; import { Prisma } from '@prisma/client'; // MARK: GET transaction async function get(req: Request, res: Response) { const { error, value } = schema_get.validate(req.query); if (error) { log.api?.debug('GET transaction Error:', req.query, value, error.details[0].message); res.status(400).json({ status: 'ERROR', errorcode: 'VALIDATION_ERROR', message: error.details[0].message }); } else { log.api?.debug('GET transaction Success:', req.query, value); if (value.id !== undefined || value.user_id !== undefined) { // get by id or user_id await db .$transaction([ // Same query for count and findMany db.transactions.count({ where: { OR: [{ id: value.id }, { userId: value.user_id }], paid: value.paid }, orderBy: parseDynamicSortBy(value.sort.toString(), value.order.toString()), skip: value.skip, take: value.take }), db.transactions.findMany({ where: { OR: [{ id: value.id }, { userId: value.user_id }], paid: value.paid }, orderBy: parseDynamicSortBy(value.sort.toString(), value.order.toString()), skip: value.skip, take: value.take }) ]) .then(([count, result]) => { if (result.length !== 0) { res.status(200).json({ count, result }); } else { res.status(404).json({ status: 'ERROR', errorcode: 'NOT_FOUND', message: 'Could not find specified transaction' }); } }) .catch((err) => { handlePrismaError(err, res, 'GET transaction'); }); } else { // get all await db .$transaction([ // Same query for count and findMany db.transactions.count({ where: { paid: value.paid }, orderBy: parseDynamicSortBy(value.sort.toString(), value.order.toString()), skip: value.skip, take: value.take }), db.transactions.findMany({ where: { paid: value.paid }, orderBy: parseDynamicSortBy(value.sort.toString(), value.order.toString()), skip: value.skip, take: value.take }) ]) .then(([count, result]) => { if (result.length !== 0) { res.status(200).json({ count, result }); } else { res.status(404).json({ status: 'ERROR', errorcode: 'NOT_FOUND', message: 'Could not find specified transaction' }); } }) .catch((err) => { handlePrismaError(err, res, 'GET transaction'); }); } } } // MARK: CREATE transaction async function post(req: Request, res: Response) { const { error, value } = schema_post.validate(req.body); if (error) { log.api?.debug('POST transaction Error:', req.body, value, error.details[0].message); res.status(400).json({ status: 'ERROR', errorcode: 'VALIDATION_ERROR', message: error.details[0].message }); } else { log.api?.debug('POST transaction Success:', req.body, value); const products: Array = value.products; let total = new Prisma.Decimal(0); const salesData: { productId: number; price: number }[] = []; try { // Start Prisma transaction await db.$transaction(async (prisma) => { for (let i = 0; i < products.length; i++) { log.api?.debug('Product:', products[i]); const product = await prisma.products.findUnique({ where: { id: products[i] }, select: { price: true } }); if (product) { log.api?.debug('Price:', product.price, Number(product.price)); //total += Number(product.price); total = total.add(product.price); salesData.push({ productId: products[i], price: Number(product.price) }); } else { log.api?.debug('Product not found:', products[i]); } } log.api?.debug('Total:', total.toFixed(2)); // TODO: Check if user exists // Create transaction with sales const transaction = await prisma.transactions.create({ data: { userId: value.user_id, total: total, paid: false, sales: { create: salesData } }, select: { id: true } }); res.status(201).json({ status: 'CREATED', message: 'Successfully created transaction', id: transaction.id }); }); } catch (err) { handlePrismaError(err, res, 'POST transaction'); } } } // MARK: UPDATE transaction async function patch(req: Request, res: Response) { const { error, value } = schema_patch.validate(req.body); if (error) { log.api?.debug('PATCH transaction Error:', req.body, value, error.details[0].message); res.status(400).json({ status: 'ERROR', errorcode: 'VALIDATION_ERROR', message: error.details[0].message }); } else { log.api?.debug('PATCH transaction Success:', req.body, value); await db.transactions .update({ where: { id: value.id }, data: { userId: value.user_id, paid: value.paid }, select: { id: true } }) .then((result) => { res.status(200).json({ status: 'UPDATED', message: 'Successfully updated transaction', id: result.id }); }) .catch((err) => { handlePrismaError(err, res, 'PATCH transaction'); }); } } // MARK: DELETE transaction async function del(req: Request, res: Response) { const { error, value } = schema_del.validate(req.body); if (error) { log.api?.debug('DEL transaction Error:', req.body, value, error.details[0].message); res.status(400).json({ status: 'ERROR', errorcode: 'VALIDATION_ERROR', message: error.details[0].message }); } else { log.api?.debug('DEL transaction Success:', req.body, value); await db.transactions .delete({ where: { id: value.id } }) .then((result) => { res.status(200).json({ status: 'DELETED', message: 'Successfully deleted transaction', id: result.id }); }) .catch((err) => { handlePrismaError(err, res, 'DEL transaction'); }); } } export default { get, post, patch, del };