Skip to content

Commit

Permalink
feat(BE): 의과 약품 히스토리 조회 API 구현 (#72)
Browse files Browse the repository at this point in the history
* feat: deletedAt 컬럼 select 옵션 수정

* feat: 의과 약품 히스토리 조회 DTO 추가

* feat: 의과 약품 히스토리 조회 API 구현
  • Loading branch information
eeseung authored Jul 8, 2024
1 parent b6c7168 commit d9a8cbe
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class M_Medicine_Categories extends BaseModel {
subCategory: string;

/** 소분류 삭제 여부 */
@DeleteDateColumn({ select: false })
@DeleteDateColumn()
deletedAt: Date | null;

@OneToMany(() => M_Medicines, (medicine) => medicine.category)
Expand Down
2 changes: 1 addition & 1 deletion backend/src/m-medicines/entity/m-medicines.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export class M_Medicines extends BaseModel {
isExcluded: boolean;

/** 삭제 여부 */
@DeleteDateColumn({ select: false })
@DeleteDateColumn()
deletedAt: Date | null;

@OneToMany(() => M_Prescriptions, (prescription) => prescription.medicine)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ApiPropertyOptional, OmitType } from '@nestjs/swagger';
import { IsOptional, IsString } from 'class-validator';
import { BasePaginationDto } from 'src/common/dto/base-pagination.dto';

export class PaginateMPrescriptionHistoryDto extends OmitType(
BasePaginationDto,
['page'],
) {
@ApiPropertyOptional({
description: '약품명',
})
@IsString()
@IsOptional()
name: string;

@ApiPropertyOptional({
description: '성분명/함량',
})
@IsString()
@IsOptional()
ingredient: string;
}
20 changes: 20 additions & 0 deletions backend/src/m-prescriptions/m-prescriptions.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ import {
Body,
Controller,
Delete,
Get,
HttpStatus,
Param,
ParseIntPipe,
Patch,
Query,
} from '@nestjs/common';
import { MPrescriptionsService } from './m-prescriptions.service';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { UpdateMPrescriptionDto } from './dto/update-m-prescription.dto';
import { PaginateMPrescriptionHistoryDto } from './dto/paginate-m-prescription-history.dto';

@ApiTags('의과')
@Controller('m/prescriptions')
Expand Down Expand Up @@ -50,4 +53,21 @@ export class MPrescriptionsController {
) {
return this.mPrescriptionsService.deletePrescription(prescriptionId);
}

@Get('history/:startDate/:endDate')
@ApiOperation({
summary: '히스토리 조회',
description: 'cursor pagination - cursor 쿼리 파라미터를 이용해야 합니다.',
})
async getMPrescriptionHistory(
@Param('startDate') startDate: string,
@Param('endDate') endDate: string,
@Query() paginateMPrescriptionHistoryDto: PaginateMPrescriptionHistoryDto,
) {
return this.mPrescriptionsService.getPaginateHistory(
startDate,
endDate,
paginateMPrescriptionHistoryDto,
);
}
}
80 changes: 80 additions & 0 deletions backend/src/m-prescriptions/m-prescriptions.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { CreateMPrescriptionDto } from './dto/create-m-prescription.dto';
import { M_Charts } from 'src/m-charts/entity/m-charts.entity';
import { M_Medicines } from 'src/m-medicines/entity/m-medicines.entity';
import { UpdateMPrescriptionDto } from './dto/update-m-prescription.dto';
import { PaginateMPrescriptionHistoryDto } from './dto/paginate-m-prescription-history.dto';
import { endOfDay, startOfDay } from 'date-fns';

@Injectable()
export class MPrescriptionsService {
Expand Down Expand Up @@ -103,4 +105,82 @@ export class MPrescriptionsService {

return prescriptionId;
}

async getPaginateHistory(
startDate: string,
endDate: string,
paginateDto: PaginateMPrescriptionHistoryDto,
) {
const start = startOfDay(startDate);
const end = endOfDay(endDate);

if (start.getTime() > end.getTime()) {
throw new BadRequestException('날짜를 올바르게 설정해주세요.');
}

const query = this.mPrescriptionsRepository
.createQueryBuilder('prescription')
.withDeleted()
.innerJoinAndSelect('prescription.medicine', 'medicine')
.leftJoinAndSelect(
'medicine.category',
'category',
'medicine.categoryId = category.id',
)
.where('prescription.isCompleted = :isCompleted', { isCompleted: true })
.andWhere('prescription.createdAt >= :start', { start })
.andWhere('prescription.createdAt <= :end', { end });

if (paginateDto.name) {
query.andWhere('medicine.name like :name', {
name: `%${paginateDto.name}%`,
});
}
if (paginateDto.ingredient) {
query.andWhere('medicine.ingredient like :ingredient', {
ingredient: `%${paginateDto.ingredient}%`,
});
}
if (paginateDto.cursor) {
query.andWhere('medicine.id < :cursor', { cursor: paginateDto.cursor });
}

query
.select([
'prescription.medicineId',
'medicine.id',
'medicine.name',
'medicine.ingredient',
'medicine.totalAmount',
'medicine.deletedAt',
'category.mainCategory',
'category.subCategory',
'category.deletedAt',
])
.addSelect('SUM(prescription.dosesTotal) as dosesTotalSum')
.groupBy('prescription.medicineId')
.orderBy({ 'medicine.id': 'DESC' })
.limit(paginateDto.take);

const data = await query.getRawMany();
const count = await query.getCount();
let hasNext: boolean = true;
let cursor: number;

if (count <= paginateDto.take || data.length <= 0) {
hasNext = false;
cursor = null;
} else {
cursor = data[data.length - 1].medicine_id;
}

return {
data: data,
meta: {
count: data.length,
cursor,
hasNext,
},
};
}
}

0 comments on commit d9a8cbe

Please sign in to comment.