implemented all controller/service verbs
This commit is contained in:
parent
085e84b086
commit
f150fe84f2
9 changed files with 246 additions and 65 deletions
11
bruno/Common Cents/Expenses/LOC DEL Expense.bru
Normal file
11
bruno/Common Cents/Expenses/LOC DEL Expense.bru
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
meta {
|
||||||
|
name: LOC DEL Expense
|
||||||
|
type: http
|
||||||
|
seq: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
delete {
|
||||||
|
url: {{localBaseUrl}}/expenses/2aa94170-2c57-4c4f-a1e7-13544ba72917
|
||||||
|
body: none
|
||||||
|
auth: inherit
|
||||||
|
}
|
||||||
11
bruno/Common Cents/Expenses/LOC GET Expense By ID.bru
Normal file
11
bruno/Common Cents/Expenses/LOC GET Expense By ID.bru
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
meta {
|
||||||
|
name: LOC GET Expense By ID
|
||||||
|
type: http
|
||||||
|
seq: 2
|
||||||
|
}
|
||||||
|
|
||||||
|
get {
|
||||||
|
url: {{localBaseUrl}}/expenses/2aa94170-2c57-4c4f-a1e7-13544ba72917
|
||||||
|
body: none
|
||||||
|
auth: inherit
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
meta {
|
meta {
|
||||||
name: Expenses
|
name: LOC GET Expenses
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 1
|
||||||
}
|
}
|
||||||
23
bruno/Common Cents/Expenses/LOC POST Expense Full.bru
Normal file
23
bruno/Common Cents/Expenses/LOC POST Expense Full.bru
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
meta {
|
||||||
|
name: LOC POST Expense Full
|
||||||
|
type: http
|
||||||
|
seq: 4
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
url: {{localBaseUrl}}/expenses
|
||||||
|
body: json
|
||||||
|
auth: inherit
|
||||||
|
}
|
||||||
|
|
||||||
|
body:json {
|
||||||
|
{
|
||||||
|
"date": "2025-12-01",
|
||||||
|
"cents": 987,
|
||||||
|
"categoryId": "1",
|
||||||
|
"merchantId": "1",
|
||||||
|
"subcategoryIds": ["1","2"],
|
||||||
|
"tagIds": ["1","2"],
|
||||||
|
"description": "NEW FULL expense"
|
||||||
|
}
|
||||||
|
}
|
||||||
20
bruno/Common Cents/Expenses/LOC POST Expense Partial.bru
Normal file
20
bruno/Common Cents/Expenses/LOC POST Expense Partial.bru
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
meta {
|
||||||
|
name: LOC POST Expense Partial
|
||||||
|
type: http
|
||||||
|
seq: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
url: {{localBaseUrl}}/expenses
|
||||||
|
body: json
|
||||||
|
auth: inherit
|
||||||
|
}
|
||||||
|
|
||||||
|
body:json {
|
||||||
|
{
|
||||||
|
"date": "2025-12-01",
|
||||||
|
"cents": 987,
|
||||||
|
"categoryId": "1",
|
||||||
|
"description": "NEW PARTIAL expense"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,19 +1,24 @@
|
||||||
import { PartialType } from '@nestjs/mapped-types';
|
import { PartialType } from '@nestjs/mapped-types';
|
||||||
|
|
||||||
export class CreateExpenseDto {
|
export class CreateExpenseDto {
|
||||||
year: string;
|
date: Date;
|
||||||
month: string;
|
|
||||||
day: string;
|
|
||||||
cents: number;
|
cents: number;
|
||||||
category: string;
|
categoryId: string;
|
||||||
merchant: string;
|
merchantId?: string;
|
||||||
subcategory: string[];
|
subcategoryIds?: string[];
|
||||||
tags: string[];
|
tagIds?: string[];
|
||||||
description?: string;
|
description?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UpdateExpenseDto extends PartialType(CreateExpenseDto) {}
|
export class UpdateExpenseDto extends PartialType(CreateExpenseDto) {}
|
||||||
|
|
||||||
export class GetExpenseDto extends CreateExpenseDto{
|
export class GetExpenseDto {
|
||||||
id: number;
|
id: string;
|
||||||
|
date: Date;
|
||||||
|
cents: number;
|
||||||
|
category: string;
|
||||||
|
merchant?: string;
|
||||||
|
subcategories?: string[];
|
||||||
|
tags?: string[];
|
||||||
|
description?: string;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,30 @@
|
||||||
export class Expense {
|
export class Expense {
|
||||||
id: number;
|
id: string;
|
||||||
year: string;
|
date: Date;
|
||||||
month: string;
|
|
||||||
day: string;
|
|
||||||
cents: number;
|
cents: number;
|
||||||
category: Category;
|
categoryId: string;
|
||||||
subcategory?: SubCategory[];
|
merchantId?: string;
|
||||||
merchant?: Merchant;
|
subcategoryIds: string[];
|
||||||
tags?: Tag[];
|
tagIds: string[];
|
||||||
description?: string;
|
description?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Category {
|
export class Category {
|
||||||
id: number;
|
id: string;
|
||||||
category: string;
|
category: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SubCategory {
|
export class SubCategory {
|
||||||
id: number;
|
id: string;
|
||||||
subcategory: string;
|
subcategory: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Merchant {
|
export class Merchant {
|
||||||
id: number;
|
id: string;
|
||||||
merchant: string;
|
merchant: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Tag {
|
export class Tag {
|
||||||
id: number;
|
id: string;
|
||||||
tag: string;
|
tag: string;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
|
import { Controller, Get, Post, Body, Patch, Param, Delete, NotFoundException, HttpCode } from '@nestjs/common';
|
||||||
import { ExpensesService } from '../../services/expenses.service';
|
import { ExpensesService } from '../../services/expenses.service';
|
||||||
import { CreateExpenseDto, GetExpenseDto, UpdateExpenseDto } from './expense.dto';
|
import { CreateExpenseDto, UpdateExpenseDto } from './expense.dto';
|
||||||
|
|
||||||
@Controller('expenses')
|
@Controller('expenses')
|
||||||
export class ExpensesController {
|
export class ExpensesController {
|
||||||
|
|
@ -12,22 +12,33 @@ export class ExpensesController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
findAll(): GetExpenseDto[] {
|
findAll() {
|
||||||
return this.expensesService.findAll();
|
return this.expensesService.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
findOne(@Param('id') id: string) {
|
findOne(@Param('id') id: string) {
|
||||||
return this.expensesService.findOne(+id);
|
const expense = this.expensesService.findOne(id);
|
||||||
|
if (!expense) {
|
||||||
|
throw new NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Patch(':id')
|
return expense;
|
||||||
// update(@Param('id') id: string, @Body() updateExpenseDto: UpdateExpenseDto) {
|
}
|
||||||
// return this.expensesService.update(+id, updateExpenseDto);
|
|
||||||
// }
|
@Patch(':id')
|
||||||
//
|
update(@Param('id') id: string, @Body() updateExpenseDto: UpdateExpenseDto) {
|
||||||
// @Delete(':id')
|
const expense = this.expensesService.update(id, updateExpenseDto);
|
||||||
// remove(@Param('id') id: string) {
|
if (!expense) {
|
||||||
// return this.expensesService.remove(+id);
|
throw new NotFoundException();
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
return expense;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete(':id')
|
||||||
|
@HttpCode(204)
|
||||||
|
remove(@Param('id') id: string) {
|
||||||
|
return this.expensesService.remove(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,142 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Expense } from '../controllers/expenses/expense.entities';
|
import { Category, Expense, Merchant, SubCategory, Tag } from '../controllers/expenses/expense.entities';
|
||||||
import { CreateExpenseDto, GetExpenseDto, UpdateExpenseDto } from '../controllers/expenses/expense.dto';
|
import { CreateExpenseDto, GetExpenseDto, UpdateExpenseDto } from '../controllers/expenses/expense.dto';
|
||||||
|
import { randomUUID } from 'node:crypto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ExpensesService {
|
export class ExpensesService {
|
||||||
private fakeTempData: GetExpenseDto[] = [
|
private categories: Category[] = [
|
||||||
{
|
{
|
||||||
id: 123,
|
id: '1',
|
||||||
year: '2025',
|
category: 'Category 1'
|
||||||
month: '12',
|
}
|
||||||
day: '10',
|
];
|
||||||
cents: 987,
|
private merchants: Merchant[] = [
|
||||||
category: 'Automotive',
|
{
|
||||||
merchant: '',
|
id: '1',
|
||||||
subcategory: [],
|
merchant: 'Merchant 1'
|
||||||
tags: []
|
}
|
||||||
|
];
|
||||||
|
private subcategories: SubCategory[] = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
subcategory: 'Subcategory 1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
subcategory: 'Subcategory 2'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
private tags: Tag[] = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
tag: 'Tag 1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
tag: 'Tag 2'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
private expenses: Expense[] = [
|
||||||
|
{
|
||||||
|
id: '2aa94170-2c57-4c4f-a1e7-13544ba72917',
|
||||||
|
date: new Date('2025-12-01'),
|
||||||
|
cents: 15443,
|
||||||
|
categoryId: '1',
|
||||||
|
merchantId: '1',
|
||||||
|
subcategoryIds: ['1', '2'],
|
||||||
|
tagIds: ['1', '2'],
|
||||||
|
description: 'Full existing expense'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '0708e7f7-3a2a-4b93-81da-38954925ca78',
|
||||||
|
date: new Date('2025-12-02'),
|
||||||
|
cents: 8723,
|
||||||
|
categoryId: '1',
|
||||||
|
subcategoryIds: [],
|
||||||
|
tagIds: [],
|
||||||
|
description: 'Partial existing expense'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
create(createExpenseDto: CreateExpenseDto) {
|
create(createExpenseDto: CreateExpenseDto) {
|
||||||
return 'This action adds a new expense';
|
const expense = {
|
||||||
|
id: randomUUID(),
|
||||||
|
date: new Date(createExpenseDto.date),
|
||||||
|
cents: createExpenseDto.cents,
|
||||||
|
categoryId: createExpenseDto.categoryId,
|
||||||
|
merchantId: createExpenseDto.merchantId,
|
||||||
|
subcategoryIds: createExpenseDto.subcategoryIds ?? [],
|
||||||
|
tagIds: createExpenseDto.tagIds ?? [],
|
||||||
|
description: createExpenseDto.description
|
||||||
|
} as Expense;
|
||||||
|
this.expenses.push(expense);
|
||||||
|
|
||||||
|
return this.mapExpense(expense);
|
||||||
}
|
}
|
||||||
|
|
||||||
findAll(): GetExpenseDto[] {
|
findAll() {
|
||||||
return this.fakeTempData;
|
return this.expenses.map((expense) => {
|
||||||
|
return this.mapExpense(expense);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
findOne(id: number) {
|
findOne(id: string) {
|
||||||
return `This action returns a #${id} expense`;
|
const expense = this.getExpense(id);
|
||||||
|
return expense ? this.mapExpense(expense) : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update(id: number, updateExpenseDto: UpdateExpenseDto) {
|
update(id: string, updateExpenseDto: UpdateExpenseDto) {
|
||||||
// return `This action updates a #${id} expense`;
|
const index = this.expenses.findIndex((expense) => expense.id === id);
|
||||||
// }
|
if (index) {
|
||||||
//
|
const expense = this.expenses[index];
|
||||||
// remove(id: number) {
|
this.expenses[index] = {
|
||||||
// return `This action removes a #${id} expense`;
|
...expense,
|
||||||
// }
|
...updateExpenseDto
|
||||||
|
// date: updateExpenseDto.date ?? expense.date,
|
||||||
|
// cents: updateExpenseDto.cents ?? expense.cents,
|
||||||
|
// categoryId: updateExpenseDto.categoryId ?? expense.categoryId,
|
||||||
|
// merchant: updateExpenseDto.merchantId ?? expense.merchantId,
|
||||||
|
// subcategoryIds: updateExpenseDto.subcategoryIds ?? expense.subcategoryIds,
|
||||||
|
// tagIds: updateExpenseDto.tagIds ?? expense.tagIds,
|
||||||
|
// description: updateExpenseDto.description ?? expense.description
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.mapExpense(this.expenses[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(id: string) {
|
||||||
|
this.expenses = this.expenses.filter((expense) => expense.id !== id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getExpense(id: string) {
|
||||||
|
return this.expenses.find((expense) => expense.id === id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getSubcategories(ids: string[]) {
|
||||||
|
return this.subcategories.filter((sub) => ids.includes(sub.id)).map((s) => s.subcategory);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getTags(ids: string[]) {
|
||||||
|
return this.tags.filter((tag) => ids.includes(tag.id)).map((t) => t.tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
private mapExpense(expense: Expense) {
|
||||||
|
const category = this.categories.find((category) => category.id === expense.categoryId);
|
||||||
|
const merchant = this.merchants.find((merchant) => merchant.id === expense.merchantId);
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: expense.id,
|
||||||
|
date: expense.date,
|
||||||
|
cents: expense.cents,
|
||||||
|
category: category?.category,
|
||||||
|
merchant: merchant?.merchant,
|
||||||
|
subcategories: this.getSubcategories(expense.subcategoryIds),
|
||||||
|
tags: this.getTags(expense.tagIds),
|
||||||
|
description: expense.description
|
||||||
|
} as GetExpenseDto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue