Skip to content
This repository has been archived by the owner on May 11, 2021. It is now read-only.

Commit

Permalink
feat(mr-butcher): add fake api for future service
Browse files Browse the repository at this point in the history
  • Loading branch information
igorkamyshev committed Apr 7, 2020
1 parent 5f8e304 commit b3dddc5
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 7 deletions.
6 changes: 4 additions & 2 deletions back/.env.dist
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ API_PUBLIC_URL=https://api.checkmoney.space

GOOGLE_CLIENT_ID_WEB=Secret
GOOGLE_CLIENT_ID_IOS=Secret
GOOGLE_CLIENT_ID_ANDOID=Secret
GOOGLE_CLIENT_SECRET=Secret
GOOGLE_CLIENT_ID_ANDROID=Secret
GOOGLE_CLIENT_SECRET=Secret

MR_SOLOMONS_URL=localhost:solomons
2 changes: 1 addition & 1 deletion back/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class AppModule implements NestModule {

if (this.config.isDev()) {
// in dev use long poll
this.telegramBot.startPolling();
// this.telegramBot.startPolling();
}
}
}
2 changes: 1 addition & 1 deletion back/src/money/application/CurrencyConverter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Injectable } from '@nestjs/common';
import { MrSolomons } from '@checkmoney/soap-opera';
import { Injectable } from '@nestjs/common';

import { Currency } from '&shared/enum/Currency';

Expand Down
44 changes: 44 additions & 0 deletions back/src/money/domain/IncomeRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,50 @@ class IncomeRepo implements TransactionRepository {
private readonly incomeRepo: Repository<Income>,
) {}

async fetchByIdsForUser(ids: string[], userLogin: string) {
if (ids.length === 0) {
return [];
}

const incomes = await this.incomeRepo
.createQueryBuilder('income')
.innerJoin('income.author', 'author', 'author.login = :userLogin', {
userLogin,
})
.where('income.id IN (:...ids)', { ids })
.getMany();

console.log(userLogin, ids, incomes);

return incomes;
}

async getTotalCountForUser(userLogin: string) {
const count = await this.incomeRepo
.createQueryBuilder('income')
.where('income.author = :userLogin', { userLogin })
.getCount();

return count;
}

async fetchIds(
userLogin: string,
offset: number,
limit: number,
): Promise<string[]> {
const result = await this.incomeRepo
.createQueryBuilder('income')
.where('income.author = :userLogin', { userLogin })
.orderBy('income.date')
.offset(offset)
.limit(limit)
.select('id')
.getRawMany();

return result.map(({ id }) => id);
}

public async findForUser(
id: string,
userLogin: string,
Expand Down
42 changes: 42 additions & 0 deletions back/src/money/domain/OutcomeRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,48 @@ class OutomeRepo implements TransactionRepository {
private readonly outcomeRepo: Repository<Outcome>,
) {}

async fetchByIdsForUser(ids: string[], userLogin: string) {
if (ids.length === 0) {
return [];
}

const outcomes = await this.outcomeRepo
.createQueryBuilder('outcome')
.innerJoin('outcome.author', 'author', 'author.login = :userLogin', {
userLogin,
})
.where('outcome.id IN (:...ids)', { ids })
.getMany();

return outcomes;
}

async getTotalCountForUser(userLogin: string) {
const count = await this.outcomeRepo
.createQueryBuilder('outcome')
.where('outcome.author = :userLogin', { userLogin })
.getCount();

return count;
}

async fetchIds(
userLogin: string,
offset: number,
limit: number,
): Promise<string[]> {
const result = await this.outcomeRepo
.createQueryBuilder('outcome')
.where('outcome.author = :userLogin', { userLogin })
.orderBy('outcome.date')
.offset(offset)
.limit(limit)
.select('id')
.getRawMany();

return result.map(({ id }) => id);
}

public async findForUser(
id: string,
userLogin: string,
Expand Down
10 changes: 8 additions & 2 deletions back/src/money/money.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

import { PlatformModule } from '&back/platform/platform.module';
import { UserModule } from '&back/user/user.module';
import { UtilsModule } from '&back/utils/utils.module';

Expand All @@ -13,12 +14,12 @@ import { IncomeRepository } from './domain/IncomeRepository';
import { Outcome } from './domain/Outcome.entity';
import { OutcomeRepository } from './domain/OutcomeRepository';
import { HistoryController } from './presentation/http/controller/HistoryController';
import { MrButcherController } from './presentation/http/controller/MrButcherController';
import { StatisticsController } from './presentation/http/controller/StatisticsController';
import { TransactionController } from './presentation/http/controller/TransactionController';
import { ConversationFailedFilter } from './presentation/http/filter/ConversationFailedFilter';
import { TransactionActions } from './presentation/telegram/actions/TransactionActions';
import { UnexpectedParameterCatcher } from './presentation/telegram/catcher/UnexpectedParameterCatcher';
import { PlatformModule } from '&back/platform/platform.module';

@Module({
imports: [
Expand All @@ -27,7 +28,12 @@ import { PlatformModule } from '&back/platform/platform.module';
UtilsModule,
TypeOrmModule.forFeature([Income, Outcome]),
],
controllers: [TransactionController, HistoryController, StatisticsController],
controllers: [
TransactionController,
HistoryController,
StatisticsController,
MrButcherController,
],
providers: [
ConversationFailedFilter.provider(),
Accountant,
Expand Down
83 changes: 83 additions & 0 deletions back/src/money/presentation/http/controller/MrButcherController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { Controller, Get, Post, Query, Body } from '@nestjs/common';
import { ApiBearerAuth, ApiImplicitBody } from '@nestjs/swagger';

import { IncomeRepository } from '&back/money/domain/IncomeRepository';
import { OutcomeRepository } from '&back/money/domain/OutcomeRepository';
import { CurrentUser } from '&back/user/presentation/http/decorator/CurrentUser';
import { OnlyForUsers } from '&back/user/presentation/http/security/OnlyForUsers';
import { TokenPayloadModel } from '&shared/models/user/TokenPayloadModel';

@Controller('mr-butcher/v1/transactions')
@OnlyForUsers()
@ApiBearerAuth()
export class MrButcherController {
public constructor(
private readonly outcomeRepo: OutcomeRepository,
private readonly incomeRepo: IncomeRepository,
) {}

@Post('fetch-batch')
@ApiImplicitBody({ name: 'ids', type: String, isArray: true })
public async fetchTransactionsByIds(
@Body('ids') ids: string[],
@CurrentUser() { login }: TokenPayloadModel,
) {
const [incomes, outcomes] = await Promise.all([
this.incomeRepo.fetchByIdsForUser(ids, login),
this.outcomeRepo.fetchByIdsForUser(ids, login),
]);

const transactions = [
...incomes.map(income => ({
...income,
category: income.source,
amount: `${income.amount}`,
})),
...outcomes.map(outcome => ({
...outcome,
amount: `${-outcome.amount}`,
})),
];

return transactions;
}

@Get('ids')
public async fetchTransactionIds(
@Query('offset') offsetQuery: string,
@Query('limit') limitQuery: string,
@CurrentUser()
{ login }: TokenPayloadModel,
) {
const limit = parseInt(limitQuery, 10);
const offset = parseInt(offsetQuery, 10);

const [totalIncomeCount, totalOutcomeCount] = await Promise.all([
this.incomeRepo.getTotalCountForUser(login),
this.outcomeRepo.getTotalCountForUser(login),
]);

const incomeIds = await this.incomeRepo.fetchIds(login, offset, limit);

let outcomeIds = [];
if (incomeIds.length !== limit) {
let outcomeOffset: number;
if (offset > totalIncomeCount) {
outcomeOffset = offset - totalIncomeCount;
} else {
outcomeOffset = 0;
}
const outcomeLimit = limit - incomeIds.length;
outcomeIds = await this.outcomeRepo.fetchIds(
login,
outcomeOffset,
outcomeLimit,
);
}

return {
total: totalIncomeCount + totalOutcomeCount,
items: [...incomeIds, ...outcomeIds],
};
}
}
2 changes: 1 addition & 1 deletion back/src/platform/platform.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { MrSolomons } from '@checkmoney/soap-opera';
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';

import { ConfigModule } from '&back/config/config.module';

Expand Down

0 comments on commit b3dddc5

Please sign in to comment.