diff --git a/apps/backend/src/config/migrations.ts b/apps/backend/src/config/migrations.ts index 62de4217..064a8662 100644 --- a/apps/backend/src/config/migrations.ts +++ b/apps/backend/src/config/migrations.ts @@ -33,6 +33,7 @@ import { UpdateOrderEntity1769990652833 } from '../migrations/1769990652833-Upda import { DonationItemFoodTypeNotNull1771524930613 } from '../migrations/1771524930613-DonationItemFoodTypeNotNull'; import { MoveRequestFieldsToOrders1770571145350 } from '../migrations/1770571145350-MoveRequestFieldsToOrders'; import { RenameDonationMatchingStatus1771260403657 } from '../migrations/1771260403657-RenameDonationMatchingStatus'; +import { AddAssigneeToOrders1773009000618 } from '../migrations/1773009000618-AddAssigneeToOrders'; import { DropDonationTotalColumns1772241115031 } from '../migrations/1772241115031-DropDonationTotalColumns'; import { FixTrackingLinks1773041840374 } from '../migrations/1773041840374-FixTrackingLinks'; import { CleanupRequestsAndAllocations1771821377918 } from '../migrations/1771821377918-CleanupRequestsAndAllocations'; @@ -73,6 +74,7 @@ const schemaMigrations = [ DonationItemFoodTypeNotNull1771524930613, MoveRequestFieldsToOrders1770571145350, RenameDonationMatchingStatus1771260403657, + AddAssigneeToOrders1773009000618, DropDonationTotalColumns1772241115031, FixTrackingLinks1773041840374, CleanupRequestsAndAllocations1771821377918, diff --git a/apps/backend/src/migrations/1773009000618-AddAssigneeToOrders.ts b/apps/backend/src/migrations/1773009000618-AddAssigneeToOrders.ts new file mode 100644 index 00000000..3dd09838 --- /dev/null +++ b/apps/backend/src/migrations/1773009000618-AddAssigneeToOrders.ts @@ -0,0 +1,30 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class AddAssigneeToOrders1773009000618 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE orders ADD COLUMN assignee_id INT`); + + await queryRunner.query(` + UPDATE orders o SET assignee_id = ( + SELECT va.volunteer_id FROM volunteer_assignments va + JOIN food_requests fr ON fr.pantry_id = va.pantry_id + WHERE fr.request_id = o.request_id + LIMIT 1 + ) + `); + + await queryRunner.query(` + ALTER TABLE orders + ALTER COLUMN assignee_id SET NOT NULL, + ADD CONSTRAINT fk_assignee_id FOREIGN KEY (assignee_id) REFERENCES users(user_id) ON DELETE RESTRICT + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE orders + DROP CONSTRAINT IF EXISTS fk_assignee_id, + DROP COLUMN assignee_id + `); + } +} diff --git a/apps/backend/src/orders/order.entity.ts b/apps/backend/src/orders/order.entity.ts index b8b3046a..81f41f0d 100644 --- a/apps/backend/src/orders/order.entity.ts +++ b/apps/backend/src/orders/order.entity.ts @@ -11,6 +11,7 @@ import { FoodRequest } from '../foodRequests/request.entity'; import { FoodManufacturer } from '../foodManufacturers/manufacturers.entity'; import { OrderStatus } from './types'; import { Allocation } from '../allocations/allocations.entity'; +import { User } from '../users/users.entity'; @Entity('orders') export class Order { @@ -99,4 +100,11 @@ export class Order { }, }) shippingCost!: number | null; + + @ManyToOne(() => User, { nullable: false, onDelete: 'RESTRICT' }) + @JoinColumn({ name: 'assignee_id' }) + assignee!: User; + + @Column({ name: 'assignee_id' }) + assigneeId!: number; } diff --git a/apps/backend/src/orders/order.service.ts b/apps/backend/src/orders/order.service.ts index 74d620fe..c0103879 100644 --- a/apps/backend/src/orders/order.service.ts +++ b/apps/backend/src/orders/order.service.ts @@ -31,7 +31,7 @@ export class OrdersService { .createQueryBuilder('order') .leftJoinAndSelect('order.request', 'request') .leftJoinAndSelect('request.pantry', 'pantry') - .leftJoinAndSelect('pantry.volunteers', 'volunteers') + .leftJoinAndSelect('order.assignee', 'assignee') .select([ 'order.orderId', 'order.status', @@ -40,9 +40,9 @@ export class OrdersService { 'order.deliveredAt', 'request.pantryId', 'pantry.pantryName', - 'volunteers.id', - 'volunteers.firstName', - 'volunteers.lastName', + 'assignee.id', + 'assignee.firstName', + 'assignee.lastName', ]); if (filters?.status) { diff --git a/apps/frontend/src/containers/adminOrderManagement.tsx b/apps/frontend/src/containers/adminOrderManagement.tsx index ebf5a866..545fac98 100644 --- a/apps/frontend/src/containers/adminOrderManagement.tsx +++ b/apps/frontend/src/containers/adminOrderManagement.tsx @@ -120,14 +120,6 @@ const AdminOrderManagement: React.FC = () => { const status = order.status; const orderWithColor: OrderWithColor = { ...order }; - if ( - order.request.pantry.volunteers && - order.request.pantry.volunteers.length > 0 - ) { - orderWithColor.assigneeColor = - ASSIGNEE_COLORS[counters[status] % ASSIGNEE_COLORS.length]; - counters[status]++; - } grouped[status].push(orderWithColor); } @@ -613,7 +605,6 @@ const OrderStatusSection: React.FC = ({ {orders.map((order, index) => { const pantry = order.request.pantry; - const volunteers = pantry.volunteers || []; return ( = ({ alignItems="center" justifyContent="center" > - {volunteers && volunteers.length > 0 ? ( - - {/* TODO: Change logic later to only get one volunteer */} - {volunteers[0].firstName.charAt(0).toUpperCase()} - {volunteers[0].lastName.charAt(0).toUpperCase()} - - ) : ( - No Assignees - )} + + {order.assignee.firstName.charAt(0).toUpperCase()} + {order.assignee.lastName.charAt(0).toUpperCase()} + = ({ - {/* TODO: IMPLEMENT WHAT GOES HERE */} - + bg="#FAFAFA" + > ); })} diff --git a/apps/frontend/src/types/types.ts b/apps/frontend/src/types/types.ts index 40a9ff21..188ba5d7 100644 --- a/apps/frontend/src/types/types.ts +++ b/apps/frontend/src/types/types.ts @@ -338,6 +338,11 @@ export interface OrderSummary { }[]; }; }; + assignee: { + id: number; + firstName: string; + lastName: string; + }; } export enum ApplicationStatus {