-
Notifications
You must be signed in to change notification settings - Fork 0
[SSF-108] Pantry food request management backend updates #82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| import { FoodType } from '../../donationItems/types'; | ||
| import { OrderStatus } from '../../orders/types'; | ||
|
|
||
| export class OrderItemDetailsDto { | ||
| name: string; | ||
| quantity: number; | ||
| foodType: FoodType; | ||
| } | ||
|
|
||
| export class OrderDetailsDto { | ||
| orderId: number; | ||
| status: OrderStatus; | ||
| foodManufacturerName: string; | ||
| items: OrderItemDetailsDto[]; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,8 @@ import { Readable } from 'stream'; | |
| import { FoodRequest } from './request.entity'; | ||
| import { RequestSize } from './types'; | ||
| import { OrderStatus } from '../orders/types'; | ||
| import { FoodType } from '../donationItems/types'; | ||
| import { OrderDetailsDto } from './dtos/order-details.dto'; | ||
|
|
||
| const mockRequestsService = mock<RequestsService>(); | ||
| const mockOrdersService = mock<OrdersService>(); | ||
|
|
@@ -26,6 +28,7 @@ describe('RequestsController', () => { | |
| mockRequestsService.find.mockReset(); | ||
| mockRequestsService.create.mockReset(); | ||
| mockRequestsService.updateDeliveryDetails?.mockReset(); | ||
| mockRequestsService.getOrderDetails.mockReset(); | ||
| mockAWSS3Service.upload.mockReset(); | ||
| mockOrdersService.updateStatus.mockReset(); | ||
|
|
||
|
|
@@ -91,6 +94,55 @@ describe('RequestsController', () => { | |
| }); | ||
| }); | ||
|
|
||
| describe('GET /get-all-order-details/:requestId', () => { | ||
| it('should call requestsService.getOrderDetails and return all associated orders and their details', async () => { | ||
| const mockOrderDetails = [ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we type this? |
||
| { | ||
| orderId: 10, | ||
| status: OrderStatus.DELIVERED, | ||
| foodManufacturerName: 'Test Manufacturer', | ||
| items: [ | ||
| { | ||
| name: 'Rice', | ||
| quantity: 5, | ||
| foodType: FoodType.GRANOLA, | ||
| }, | ||
| { | ||
| name: 'Beans', | ||
| quantity: 3, | ||
| foodType: FoodType.DRIED_BEANS, | ||
| }, | ||
| ], | ||
| }, | ||
| { | ||
| orderId: 11, | ||
| status: OrderStatus.PENDING, | ||
| foodManufacturerName: 'Another Manufacturer', | ||
| items: [ | ||
| { | ||
| name: 'Milk', | ||
| quantity: 2, | ||
| foodType: FoodType.DAIRY_FREE_ALTERNATIVES, | ||
| }, | ||
| ], | ||
| }, | ||
| ]; | ||
|
|
||
| const requestId = 1; | ||
|
|
||
| mockRequestsService.getOrderDetails.mockResolvedValueOnce( | ||
| mockOrderDetails as OrderDetailsDto[], | ||
| ); | ||
|
|
||
| const result = await controller.getAllOrderDetailsFromRequest(requestId); | ||
|
|
||
| expect(result).toEqual(mockOrderDetails); | ||
| expect(mockRequestsService.getOrderDetails).toHaveBeenCalledWith( | ||
| requestId, | ||
| ); | ||
| }); | ||
| }); | ||
|
|
||
| describe('POST /create', () => { | ||
| it('should call requestsService.create and return the created food request', async () => { | ||
| const createBody: Partial<FoodRequest> = { | ||
|
|
@@ -107,7 +159,7 @@ describe('RequestsController', () => { | |
| requestId: 1, | ||
| ...createBody, | ||
| requestedAt: new Date(), | ||
| order: null, | ||
| orders: null, | ||
| }; | ||
|
|
||
| mockRequestsService.create.mockResolvedValueOnce( | ||
|
|
@@ -181,7 +233,7 @@ describe('RequestsController', () => { | |
| mockRequestsService.findOne.mockResolvedValue({ | ||
| requestId, | ||
| pantryId: 1, | ||
| order: { orderId: 99 }, | ||
| orders: [{ orderId: 99 }], | ||
| } as FoodRequest); | ||
|
|
||
| mockOrdersService.updateStatus.mockResolvedValue(); | ||
|
|
@@ -230,7 +282,7 @@ describe('RequestsController', () => { | |
| mockRequestsService.findOne.mockResolvedValue({ | ||
| requestId, | ||
| pantryId: 1, | ||
| order: { orderId: 100 }, | ||
| orders: [{ orderId: 100 }], | ||
| } as FoodRequest); | ||
|
|
||
| mockOrdersService.updateStatus.mockResolvedValue(); | ||
|
|
@@ -275,7 +327,7 @@ describe('RequestsController', () => { | |
| mockRequestsService.findOne.mockResolvedValue({ | ||
| requestId, | ||
| pantryId: 1, | ||
| order: { orderId: 101 }, | ||
| orders: [{ orderId: 101 }], | ||
| } as FoodRequest); | ||
|
|
||
| mockOrdersService.updateStatus.mockResolvedValue(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,9 +16,9 @@ import { AWSS3Service } from '../aws/aws-s3.service'; | |
| import { FilesInterceptor } from '@nestjs/platform-express'; | ||
| import * as multer from 'multer'; | ||
| import { OrdersService } from '../orders/order.service'; | ||
| import { Order } from '../orders/order.entity'; | ||
| import { RequestSize } from './types'; | ||
| import { OrderStatus } from '../orders/types'; | ||
| import { OrderDetailsDto } from './dtos/order-details.dto'; | ||
|
|
||
| @Controller('requests') | ||
| // @UseInterceptors() | ||
|
|
@@ -43,6 +43,13 @@ export class RequestsController { | |
| return this.requestsService.find(pantryId); | ||
| } | ||
|
|
||
| @Get('/get-all-order-details/:requestId') | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: i think we are trying to move away from putting the CRUD method in the name. Can we change it to /all-order-details/:requestId |
||
| async getAllOrderDetailsFromRequest( | ||
| @Param('requestId', ParseIntPipe) requestId: number, | ||
| ): Promise<OrderDetailsDto[]> { | ||
| return this.requestsService.getOrderDetails(requestId); | ||
| } | ||
|
|
||
| @Post('/create') | ||
| @ApiBody({ | ||
| description: 'Details for creating a food request', | ||
|
|
@@ -158,9 +165,11 @@ export class RequestsController { | |
| ); | ||
|
|
||
| const request = await this.requestsService.findOne(requestId); | ||
| await this.ordersService.updateStatus( | ||
| request.order.orderId, | ||
| OrderStatus.DELIVERED, | ||
|
|
||
| await Promise.all( | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we move this actually to be after we update the delivery details, and ensure there are no problems there? Once we confirm that, then we can mark all of the orders as delivered. |
||
| request.orders.map((order) => | ||
| this.ordersService.updateStatus(order.orderId, OrderStatus.DELIVERED), | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this would update all orders associated with a specific request id to 'delivered' - but when would this be used if orders arrive at different times & need individual confirmation, instead of confirming all orders for a request at the same time
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i see in pantry demo vid that pantries confirm deliveries for individual/specific orders instead of for all orders of a request |
||
| ), | ||
| ); | ||
|
|
||
| return this.requestsService.updateDeliveryDetails( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,6 +46,6 @@ export class FoodRequest { | |
| @Column({ name: 'photos', type: 'text', array: true, nullable: true }) | ||
| photos: string[]; | ||
|
|
||
| @OneToMany(() => Order, (order) => order.request, { nullable: true }) | ||
| order: Order; | ||
| @OneToMany(() => Order, (order) => order.request) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this no longer nullable? When we make a new request, this should be able to exist as null until the orders have been assigned to the request, unless I am missing somethin. |
||
| orders: Order[]; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thoughts on making this nullable: false the same way itemId is set as they're both FKs with many to one relationship? that way an allocation is set to for sure have an order that it is derived from.