diff --git a/bruno/Common Cents/Categories/LOC POST Category.bru b/bruno/Common Cents/Categories/LOC POST Category.bru index 3e6e20f..5465b82 100644 --- a/bruno/Common Cents/Categories/LOC POST Category.bru +++ b/bruno/Common Cents/Categories/LOC POST Category.bru @@ -12,6 +12,6 @@ post { body:json { { - "name": "Groceries:Food" + "name": "Auto:Gas" } } diff --git a/bruno/Common Cents/Merchants/LOC POST Merchant.bru b/bruno/Common Cents/Merchants/LOC POST Merchant.bru index 1279825..b5665ab 100644 --- a/bruno/Common Cents/Merchants/LOC POST Merchant.bru +++ b/bruno/Common Cents/Merchants/LOC POST Merchant.bru @@ -12,6 +12,6 @@ post { body:json { { - "name": "Walmart" + "name": "Casey's" } } diff --git a/bruno/Common Cents/Tags/LOC POST Tag.bru b/bruno/Common Cents/Tags/LOC POST Tag.bru index d9657c3..4fcc6e3 100644 --- a/bruno/Common Cents/Tags/LOC POST Tag.bru +++ b/bruno/Common Cents/Tags/LOC POST Tag.bru @@ -12,6 +12,6 @@ post { body:json { { - "name": "Sienna" + "name": "Tundra" } } diff --git a/src/expenses/dto/create-expense.dto.ts b/src/expenses/dto/create-expense.dto.ts index 829a5be..1db1b84 100644 --- a/src/expenses/dto/create-expense.dto.ts +++ b/src/expenses/dto/create-expense.dto.ts @@ -1,5 +1,8 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Temporal } from '@js-temporal/polyfill'; +import { Category } from '../../categories/entities/category.entity'; +import { Merchant } from '../../merchants/entities/merchant.entity'; +import { Tag } from '../../tags/entities/tag.entity'; export class CreateExpenseDto { @ApiProperty({ @@ -13,23 +16,23 @@ export class CreateExpenseDto { cents: number; @ApiProperty({ - description: 'Category ID of expense' + description: 'Category of expense' }) - categoryId: string; + category: Category; @ApiPropertyOptional({ description: 'Optional note about expense' }) - note?: string; + note: string; @ApiPropertyOptional({ - description: 'Optional merchant ID for the expense' + description: 'Optional merchant for the expense' }) - merchantId?: string; + merchant: Merchant; @ApiPropertyOptional({ - type: [String], - description: 'Optional list of tag IDs for the expense' + type: [Tag], + description: 'Optional list of tags for the expense' }) - tagIds: string[]; + tags: Tag[]; } diff --git a/src/expenses/dto/get-expense.dto.ts b/src/expenses/dto/get-expense.dto.ts index 0e9454e..724578d 100644 --- a/src/expenses/dto/get-expense.dto.ts +++ b/src/expenses/dto/get-expense.dto.ts @@ -28,16 +28,16 @@ export class GetExpenseDto { @ApiPropertyOptional({ description: 'Note about expense' }) - note?: string; + note: string; @ApiPropertyOptional({ description: 'Merchant for the expense' }) - merchant?: Merchant; + merchant: Merchant; @ApiPropertyOptional({ type: [Tag], description: 'List of tags for the expense' }) - tags?: Tag[]; + tags: Tag[]; } diff --git a/src/expenses/entities/expense.entity.ts b/src/expenses/entities/expense.entity.ts index bc83082..55fc1c5 100644 --- a/src/expenses/entities/expense.entity.ts +++ b/src/expenses/entities/expense.entity.ts @@ -18,7 +18,13 @@ export class Expense { id: string; @Column() - date: string; + year: number; + + @Column() + month: number; + + @Column() + day: number; @Column() cents: number; diff --git a/src/expenses/expense-data.service.ts b/src/expenses/expense-data.service.ts index ba960e5..7dcb6c6 100644 --- a/src/expenses/expense-data.service.ts +++ b/src/expenses/expense-data.service.ts @@ -1,6 +1,9 @@ import { Injectable } from '@nestjs/common'; import { DataSource, Repository } from 'typeorm'; import { Expense } from './entities/expense.entity'; +import { Category } from '../categories/entities/category.entity'; +import { Merchant } from '../merchants/entities/merchant.entity'; +import { Tag } from '../tags/entities/tag.entity'; @Injectable() export class ExpenseDataService { @@ -19,14 +22,13 @@ export class ExpenseDataService { } public async create(expense: CreateExpense): Promise { - const created = await this.expenses.save(expense); - return await this.expenses.findOneBy({ id: created.id }) as Expense; + return await this.expenses.save(expense as Expense); } - public async update(expense: UpdateExpense): Promise { - await this.expenses.save(expense); - return await this.expenses.findOneBy({ id: expense.id }) as Expense; - } + // public async update(expense: UpdateExpense): Promise { + // await this.expenses.save(expense); + // return await this.expenses.findOneBy({ id: expense.id }) as Expense; + // } public async delete(id: string): Promise { await this.expenses.delete({ id }); @@ -34,18 +36,14 @@ export class ExpenseDataService { } export interface CreateExpense { - date: string; + year: number; + month: number; + day: number; cents: number; - category: { - id: string; - }; - note?: string; - merchant?: { - id: string; - }; - tags?: { - id: string; - }[]; + category: Category; + note: string; + merchant: Merchant; + tags: Tag[]; } export interface UpdateExpense extends CreateExpense{ diff --git a/src/expenses/expenses.controller.ts b/src/expenses/expenses.controller.ts index 7550273..2377c45 100644 --- a/src/expenses/expenses.controller.ts +++ b/src/expenses/expenses.controller.ts @@ -48,6 +48,7 @@ export class ExpensesController { if (!expense) { throw new BadRequestException('Expense name cannot be empty.'); } + // TODO: Validate date/cents/category exist... try { return await this.expensesService.create(expense); @@ -57,15 +58,15 @@ export class ExpensesController { } } - @Put() - @HttpCode(HttpStatus.OK) - public async update(@Body() expense: UpdateExpenseDto): Promise { - if (!expense.id) { - throw new BadRequestException('Expense ID cannot be empty.'); - } - - return await this.expensesService.update(expense); - } + // @Put() + // @HttpCode(HttpStatus.OK) + // public async update(@Body() expense: UpdateExpenseDto): Promise { + // if (!expense.id) { + // throw new BadRequestException('Expense ID cannot be empty.'); + // } + // + // return await this.expensesService.update(expense); + // } @Delete(':id') @HttpCode(HttpStatus.NO_CONTENT) diff --git a/src/expenses/expenses.service.ts b/src/expenses/expenses.service.ts index c419e00..2985d9c 100644 --- a/src/expenses/expenses.service.ts +++ b/src/expenses/expenses.service.ts @@ -4,6 +4,7 @@ import { UpdateExpenseDto } from './dto/update-expense.dto'; import { ExpenseDataService } from './expense-data.service'; import { GetExpenseDto } from './dto/get-expense.dto'; import { Temporal } from '@js-temporal/polyfill'; +import { Expense } from './entities/expense.entity'; @Injectable() export class ExpensesService { @@ -13,58 +14,78 @@ export class ExpensesService { const expenses = await this.expenseDataService.getAll(); return expenses.map(exp => { - return { ...exp, date: Temporal.PlainDate.from(exp.date) }; + return { + id: exp.id, + date: new Temporal.PlainDate(exp.year, exp.month, exp.day), + cents: exp.cents, + category: exp.category, + merchant: exp.merchant, + note: exp.note, + tags: exp.tags + }; }) } public async findById(id: string): Promise { - const expense = await this.expenseDataService.getById(id); - if (!expense) { + const exp = await this.expenseDataService.getById(id); + if (!exp) { throw new Error('No expense found'); } - return { ...expense, date: Temporal.PlainDate.from(expense.date) }; + return { + id: exp.id, + date: new Temporal.PlainDate(exp.year, exp.month, exp.day), + cents: exp.cents, + category: exp.category, + merchant: exp.merchant, + note: exp.note, + tags: exp.tags + }; } public async create(createExpense: CreateExpenseDto): Promise { - const date = createExpense.date.toString(); - const category = { id: createExpense.categoryId }; - const merchant = createExpense.merchantId ? { id: createExpense.merchantId } : undefined; - const tags = createExpense.tagIds?.map(id => { - return { id }; - }) - - const expense = await this.expenseDataService.create({ - date, + const date = createExpense.date.toString().split('-'); + const exp = await this.expenseDataService.create({ + year: Number(date[0]), + month: Number(date[1]), + day: Number(date[2]), cents: createExpense.cents, note: createExpense.note, - category, - merchant, - tags + category: createExpense.category, + merchant: createExpense.merchant, + tags: createExpense.tags }); - return { ...expense, date: Temporal.PlainDate.from(expense.date) }; + return { + id: exp.id, + date: new Temporal.PlainDate(exp.year, exp.month, exp.day), + cents: exp.cents, + category: exp.category, + merchant: exp.merchant, + note: exp.note, + tags: exp.tags + }; } - public async update(updateExpense: UpdateExpenseDto): Promise { - const date = updateExpense.date.toString(); - const category = { id: updateExpense.categoryId }; - const merchant = updateExpense.merchantId ? { id: updateExpense.merchantId } : undefined; - const tags = updateExpense.tagIds?.map(id => { - return { id }; - }) - const expense = await this.expenseDataService.update({ - id: updateExpense.id, - date, - cents: updateExpense.cents, - note: updateExpense.note, - category, - merchant, - tags - }); - - return { ...expense, date: Temporal.PlainDate.from(expense.date) }; - } + // public async update(updateExpense: UpdateExpenseDto): Promise { + // const date = updateExpense.date.toString(); + // const category = { id: updateExpense.categoryId }; + // const merchant = updateExpense.merchantId ? { id: updateExpense.merchantId } : undefined; + // const tags = updateExpense.tagIds?.map(id => { + // return { id }; + // }) + // const expense = await this.expenseDataService.update({ + // id: updateExpense.id, + // date, + // cents: updateExpense.cents, + // note: updateExpense.note, + // category, + // merchant, + // tags + // }); + // + // return { ...expense, date: Temporal.PlainDate.from(expense.date) }; + // } public async remove(id: string): Promise { await this.expenseDataService.delete(id);