Skip to content

Commit

Permalink
fix(invoices): throw error when trying to pay paid invoice (#112)
Browse files Browse the repository at this point in the history
* fix(invoices): throw error when trying to pay paid invoice

* fix: transaction is optional
  • Loading branch information
antonstjernquist committed Oct 3, 2022
1 parent 4dbedbe commit 172430f
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 9 deletions.
7 changes: 5 additions & 2 deletions src/server/services/account/account.db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ export class AccountDB {
return await AccountModel.findAll({ where: { ownerIdentifier: identifier } });
}

async getUniqueAccountByIdentifier(identifier: string): Promise<AccountModel | null> {
return await AccountModel.findOne({ where: { ownerIdentifier: identifier } });
async getUniqueAccountByIdentifier(
identifier: string,
transaction?: Transaction,
): Promise<AccountModel | null> {
return await AccountModel.findOne({ where: { ownerIdentifier: identifier }, transaction });
}

async getDefaultAccountByIdentifier(
Expand Down
5 changes: 3 additions & 2 deletions src/server/services/invoice/invoice.db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { singleton } from 'tsyringe';
import { CreateInvoiceInput, GetInvoicesInput, InvoiceStatus } from '@typings/Invoice';
import { InvoiceModel } from './invoice.model';
import { MS_TWO_WEEKS } from '@utils/constants';
import { Transaction } from 'sequelize/types';

@singleton()
export class InvoiceDB {
Expand All @@ -26,8 +27,8 @@ export class InvoiceDB {
});
}

async getInvoiceById(id: number): Promise<InvoiceModel | null> {
return await InvoiceModel.findOne({ where: { id } });
async getInvoiceById(id: number, transaction: Transaction): Promise<InvoiceModel | null> {
return await InvoiceModel.findOne({ where: { id }, transaction });
}

async createInvoice(input: CreateInvoiceInput): Promise<InvoiceModel> {
Expand Down
19 changes: 14 additions & 5 deletions src/server/services/invoice/invoice.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { singleton } from 'tsyringe';
import { Request } from '../../../../typings/http';
import { CreateInvoiceInput, GetInvoicesInput, PayInvoiceInput } from '../../../../typings/Invoice';
import {
CreateInvoiceInput,
GetInvoicesInput,
InvoiceStatus,
PayInvoiceInput,
} from '../../../../typings/Invoice';
import { sequelize } from '../../utils/pool';
import { mainLogger } from '../../sv_logger';
import { UserService } from '../user/user.service';
Expand Down Expand Up @@ -86,16 +91,20 @@ export class InvoiceService {

const t = await sequelize.transaction();
try {
const fromAccount = await this._accountDB.getAccountById(req.data.fromAccountId);
const invoice = await this._invoiceDB.getInvoiceById(req.data.invoiceId);
const fromAccount = await this._accountDB.getAccountById(req.data.fromAccountId, t);
const invoice = await this._invoiceDB.getInvoiceById(req.data.invoiceId, t);

/* Should we insert money to a specific account? */
const receiverAccountIdentifier = invoice?.getDataValue('receiverAccountIdentifier');
const toAccountIdentifier = invoice?.getDataValue('fromIdentifier');

const toAccount = receiverAccountIdentifier
? await this._accountDB.getUniqueAccountByIdentifier(receiverAccountIdentifier)
: await this._accountDB.getDefaultAccountByIdentifier(toAccountIdentifier ?? '');
? await this._accountDB.getUniqueAccountByIdentifier(receiverAccountIdentifier, t)
: await this._accountDB.getDefaultAccountByIdentifier(toAccountIdentifier ?? '', t);

if (invoice?.getDataValue('status') === InvoiceStatus.PAID) {
throw new ServerError('This invoice is already paid. Tell author of resource to fix UI');
}

if (!invoice || !fromAccount || !toAccount) {
throw new ServerError(GenericErrors.NotFound);
Expand Down

0 comments on commit 172430f

Please sign in to comment.