Skip to content

Commit

Permalink
Added converte shopping item to transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
BasileusErwin committed Jun 19, 2023
1 parent 102e0bd commit b61ae30
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 40 deletions.
19 changes: 17 additions & 2 deletions src/controllers/shopping_list.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ async function createShoppingList(req: Request, res: Response, next: NextFunctio

return res.send(new CustomResponse(true, list));
}

// return res.send(new CustomResponse(true, list));
} catch (err) {
next(err);
}
Expand Down Expand Up @@ -92,6 +90,22 @@ async function deleteShoppingListItem(req: Request, res: Response, next: NextFun
}
}

async function convertShoppingListItemToTransaction(req: Request, res: Response, next: NextFunction) {
try {
validationHelper.checkValidation(req);

const transaction = await shoppingListService.converShoppingListItemToTransaction(
req.params.itemId,
res.locals.userId,
req.body,
);

return res.send(new CustomResponse(true, transaction));
} catch (err) {
next(err);
}
}

export const shoppingListController = {
createShoppingList,
getAllShoppingList,
Expand All @@ -100,4 +114,5 @@ export const shoppingListController = {
checkShoppingListItem,
deleteShoppingList,
deleteShoppingListItem,
convertShoppingListItemToTransaction,
};
2 changes: 1 addition & 1 deletion src/helpers/shopping_list.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function createShoppingListValidation(lists: ShoppingListModel[]): CustomValidat
typeof item.exchangeRate !== 'number'
) {
error.push({
msg: `Please enter a currency: ${Object.values(CurrencyEnum).join('|')}`,
msg: 'Please enter an exchange rate',
param: `shoppingList[${index}].items[${indexItem}].exchangeRate`,
value: item.exchangeRate,
});
Expand Down
7 changes: 6 additions & 1 deletion src/routes/shopping_list.route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Router } from 'express';
import { shoppingListValidation } from '../validations';
import { middlewareController, shoppingListController } from '../controllers';

const router: Router = Router();
Expand All @@ -7,7 +8,7 @@ router
.route('/')
.all(middlewareController.onlyLogin)
.get(shoppingListController.getAllShoppingList)
.post(shoppingListController.createShoppingList);
.post(shoppingListValidation.createShoppingList, shoppingListController.createShoppingList);

router
.route('/:listId')
Expand All @@ -28,6 +29,10 @@ router
router
.route('/item/:itemId')
.all(middlewareController.onlyLogin)
.post(
shoppingListValidation.convertShoppingListItemToTransaction,
shoppingListController.convertShoppingListItemToTransaction,
)
.delete(shoppingListController.deleteShoppingListItem);

export const shoppingListRouter: Router = router;
34 changes: 21 additions & 13 deletions src/services/shopping_list.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CustomError, logger } from '../lib';
import { ShoppingList } from '../mongo';
import { ShoppingListItemModel, ShoppingListModel } from '../types/shopping_list';
import { ApiError, MonthEnum, TransactionType } from '../enums';
import { ApiError, CurrencyEnum, MonthEnum, TransactionType } from '../enums';
import { TransactionDTO } from '../types/DTOs';
import { transactionService } from './transactions.service';
import { BodyRequest } from '../types/request/trsactions';
Expand Down Expand Up @@ -33,7 +33,7 @@ async function getShoppingListItemByListId(listId: string, userId: string): Prom
userId,
});

return list.items;
return list?.items;
}

async function checkShoppingListItem(listId: string, itemId: string, userId: string): Promise<void> {
Expand Down Expand Up @@ -104,6 +104,10 @@ async function getShoppingListItemById(itemId: string, userId: string): Promise<
userId,
});

logger.debug({
shoppingList,
});

if (!shoppingList) {
throw new CustomError(ApiError.ShoppingList.SHOPPING_LIST_NOT_EXIST);
}
Expand All @@ -117,6 +121,7 @@ interface ExtraData {
year: number;
note: string;
categoryId?: string;
exchangeRate?: number;
category?: CategoryModel;
goalId?: string;
}
Expand All @@ -126,28 +131,30 @@ async function converShoppingListItemToTransaction(
userId: string,
extraData: ExtraData,
): Promise<TransactionDTO> {
const shoppingList = await ShoppingList.findOne({
'items.itemId': itemId,
userId,
});
const shoppingListItem = await getShoppingListItemById(itemId, userId);

if (!shoppingList) {
throw new CustomError(ApiError.ShoppingList.SHOPPING_LIST_ITEM_NOT_EXIST);
if ([CurrencyEnum.USD, CurrencyEnum.EUR].includes(shoppingListItem.currency) && !extraData?.exchangeRate) {
throw new CustomError(ApiError.Server.PARAMS_REQUIRED, [
{
msg: 'Please enter an exchange rate',
param: 'exchangeRate',
value: extraData.exchangeRate,
},
]);
}

const shoppingListItem = await getShoppingListItemById(itemId, userId);

const createTransactionRequest: BodyRequest = {
userId,
amount: shoppingListItem.price,
currency: shoppingListItem.currency,
day: extraData.day ? extraData.day : null,
month: extraData.month
? extraData.month
: Object.values(MonthEnum)[moment(shoppingListItem.createdAt).month()],
month: extraData.month,
type: TransactionType.EXPENSE,
year: extraData.year ? extraData.year : moment().year(),
note: extraData.note ? extraData.note : shoppingListItem.name,
exchangeRate: [CurrencyEnum.USD, CurrencyEnum.EUR].includes(shoppingListItem.currency)
? extraData.exchangeRate
: null,
categoryId: extraData.categoryId,
category: extraData.category,
};
Expand All @@ -163,4 +170,5 @@ export const shoppingListService = {
checkShoppingListItem,
deleteShoppingList,
deleteShoppingListItem,
converShoppingListItemToTransaction,
};
1 change: 1 addition & 0 deletions src/validations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export { userValidation } from './user.validation';
export { transactionValidation } from './transaction.validation';
export { financialGoalValidation } from './financial_goal.validation';
export { categoryValidation } from './category.validation';
export { shoppingListValidation } from './shopping_list.validation';
53 changes: 31 additions & 22 deletions src/validations/shopping_list.validation.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,7 @@
import { body, param } from 'express-validator';
import { CurrencyEnum } from '../enums';

interface ShoppingListItemModel {
_id: string;
name: string;
quantity: number;
price: number;
exchangeRate: number;
currency: CurrencyEnum;
checked: boolean;
createdAt: Date;
updatedAt: Date;
}

interface ShoppingListModel {
_id: string;
userId: string;
name: string;
items: ShoppingListItemModel[];
createdAt: Date;
updatedAt: Date;
}
import moment from 'moment';
import { dayHelper } from '../helpers';
import { CurrencyEnum, MonthEnum, TransactionType } from '../enums';

const createShoppingList = [
body('shoppingList', 'Please enter a shopping list').if(body('type').not().exists()).isArray(),
Expand All @@ -32,8 +13,36 @@ const shoppingListIdInParam = [param('itemId').isUUID()];

const itemIdInParam = [param('listId').isUUID()];

const convertShoppingListItemToTransaction = [
param('itemId').isUUID(),
body('day', 'Please enter a day')
.optional()
.isInt({ min: 1, max: 31 })
.custom((value: number, { req }) => value > 0 && value <= dayHelper.getMaxDayByMonth(req.body.month))
.trim(),
body('month', 'Please enter a month').isIn(Object.values(MonthEnum)).trim(),
body('year', 'Please enter a year').isInt({ min: 2000, max: moment().year() }).trim(),
body('note', 'Please enter a note').optional().isString(),
body('categoryId', 'Please enter a categoryId or category')
.if(body('transactions').not().exists())
.if(body('category').not().exists())
.isUUID(),
body('category', 'Please enter a categoryId or category')
.if(body('transactions').not().exists())
.if(body('categoryId').not().exists())
.isObject(),
body('category.type', 'Please enter a category type, and make it equal to the transaction type.')
.if(body('category').exists())
.optional()
.isIn(Object.values(TransactionType))
.custom((value: TransactionType, { req }) => value === req.body.type),
body('category.name', 'Please enter a name').if(body('category').exists()).isString().trim(),
body('goalId', 'Please enter a goal id').optional().isUUID(),
];

export const shoppingListValidation = {
createShoppingList,
shoppingListIdInParam,
itemIdInParam,
convertShoppingListItemToTransaction,
};
3 changes: 2 additions & 1 deletion src/validations/transaction.validation.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { CurrencyEnum, MonthEnum, TransactionType } from '../enums';
import { dayHelper } from '../helpers';
import { body, query, param } from 'express-validator';
import moment from 'moment';

const createTransaction = [
body('transactions', 'Please enter a transactions').if(body('type').not().exists()).isArray(),
Expand All @@ -24,7 +25,7 @@ const createTransaction = [
.if(body('transactions').not().exists())
.isIn(Object.values(MonthEnum))
.trim(),
body('year', 'Please enter a year').if(body('transactions').not().exists()).isInt({ min: 2000 }).trim(),
body('year', 'Please enter a year').if(body('transactions').not().exists()).isInt({ min: 2000, max: moment().year() }).trim(),
body('exchangeRate', 'Please enter a exchangeRate')
.if(body('currency').custom((value) => value === CurrencyEnum.USD || value === CurrencyEnum.EUR))
.isNumeric()
Expand Down

0 comments on commit b61ae30

Please sign in to comment.