Skip to content

Commit

Permalink
refactor: donation history
Browse files Browse the repository at this point in the history
  • Loading branch information
fagundesjg committed Jun 5, 2024
1 parent cdad22a commit 5c3b21a
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 40 deletions.
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions prisma/migrations/20240605140756_/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- CreateTable
CREATE TABLE "shelter_users" (
"user_id" TEXT NOT NULL,
"shelter_id" TEXT NOT NULL,
"created_at" VARCHAR(32) NOT NULL,

CONSTRAINT "shelter_users_pkey" PRIMARY KEY ("user_id","shelter_id")
);

-- AddForeignKey
ALTER TABLE "shelter_users" ADD CONSTRAINT "shelter_users_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "shelter_users" ADD CONSTRAINT "shelter_users_shelter_id_fkey" FOREIGN KEY ("shelter_id") REFERENCES "shelters"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
16 changes: 15 additions & 1 deletion prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ model User {
shelterManagers ShelterManagers[]
suppliesHistory SupplyHistory[]
donationOrders DonationOrder[]
shelterUsers ShelterUsers[]
@@map("users")
}
Expand Down Expand Up @@ -134,7 +135,8 @@ model Shelter {
shelterManagers ShelterManagers[]
shelterSupplies ShelterSupply[]
supplyHistories SupplyHistory[]
DonationOrder DonationOrder[]
donationOrders DonationOrder[]
shelterUsers ShelterUsers[]
@@map("shelters")
}
Expand Down Expand Up @@ -222,3 +224,15 @@ model DonationOrder {
@@map("donation_orders")
}

model ShelterUsers {
userId String @map("user_id")
shelterId String @map("shelter_id")
createdAt String @map("created_at") @db.VarChar(32)
user User @relation(fields: [userId], references: [id])
shelter Shelter @relation(fields: [shelterId], references: [id])
@@id([userId, shelterId])
@@map("shelter_users")
}
9 changes: 7 additions & 2 deletions src/donation-order/donation-order.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,14 @@ export class DonationOrderController {

@Put(':orderId')
@UseGuards(UserGuard)
async update(@Param('orderId') orderId: string, @Body() body) {
async update(
@Request() req,
@Param('orderId') orderId: string,
@Body() body,
) {
try {
await this.donationOrderService.update(orderId, body);
const { userId } = req.user;
await this.donationOrderService.update(orderId, userId, body);
return new ServerResponse(200, 'Successfully updated donation order');
} catch (err: any) {
this.logger.error(`Failed to update donation order: ${err}`);
Expand Down
156 changes: 119 additions & 37 deletions src/donation-order/donation-order.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { z } from 'zod';
import { Injectable } from '@nestjs/common';
import { HttpException, Injectable } from '@nestjs/common';
import { Prisma } from '@prisma/client';
import { DefaultArgs } from '@prisma/client/runtime/library';

Expand All @@ -9,16 +9,44 @@ import { SearchSchema } from '../types';

@Injectable()
export class DonationOrderService {
private donationOrderVisibleFields: Prisma.DonationOrderSelect = {
id: true,
status: true,
userId: true,
shelter: {
select: {
id: true,
name: true,
},
},
donationOrderSupplies: {
select: {
quantity: true,
supply: {
select: {
name: true,
measure: true,
},
},
},
},
createdAt: true,
updatedAt: true,
};

constructor(private readonly prismaService: PrismaService) {}

async index(userId: string, query: any) {
const { shelterId } = query;
const { shelterId, op } = query;
const { order, orderBy, page, perPage } = SearchSchema.parse(query);

const where: Prisma.DonationOrderWhereInput = {
shelterId,
userId,
};
let where = {};

if (op === 'received') {
where = await this.getAllReceivedDonations(userId);
} else {
where = this.getAllDonationsMade(userId, shelterId);
}

const count = await this.prismaService.donationOrder.count({ where });

Expand All @@ -34,30 +62,7 @@ export class DonationOrderService {

const results = await this.prismaService.donationOrder.findMany({
...whereData,
select: {
id: true,
status: true,
userId: true,
shelter: {
select: {
id: true,
name: true,
},
},
donationOrderSupplies: {
select: {
quantity: true,
supply: {
select: {
name: true,
measure: true,
},
},
},
},
createdAt: true,
updatedAt: true,
},
select: this.donationOrderVisibleFields,
orderBy: {
createdAt: 'desc',
},
Expand Down Expand Up @@ -127,17 +132,94 @@ export class DonationOrderService {

async update(
orderId: string,
userId: string,
body: z.infer<typeof UpdateDonationOrderScheme>,
) {
const { status } = UpdateDonationOrderScheme.parse(body);
await this.prismaService.donationOrder.update({
where: {
id: orderId,
},
data: {
status,
updatedAt: new Date().toISOString(),
const order = await this.prismaService.donationOrder.findFirst({
where: { id: orderId },
select: {
shelterId: true,
userId: true,
donationOrderSupplies: true,
},
});

if (!order) return new HttpException('Donation not found', 404);

if (order.userId !== userId) {
const isEmployer = await this.prismaService.shelterUsers.findFirst({
where: {
userId,
shelterId: order.shelterId,
},
});

if (!isEmployer)
return new HttpException(
'User not allowed to update this donation',
404,
);
}

await this.prismaService.$transaction([
...order.donationOrderSupplies.map((d) =>
this.prismaService.shelterSupply.update({
where: {
shelterId_supplyId: {
shelterId: order.shelterId,
supplyId: d.supplyId,
},
},
data: {
quantity: {
decrement: d.quantity,
},
},
}),
),
this.prismaService.donationOrder.update({
where: {
id: orderId,
},
data: {
status,
updatedAt: new Date().toISOString(),
},
}),
]);
}

private async getAllReceivedDonations(userId: string, shelterId?: string) {
const where: Prisma.DonationOrderWhereInput = {
shelterId,
};

if (!shelterId) {
const sheltersByUser = await this.prismaService.shelterUsers.findMany({
where: {
userId,
},
select: {
shelterId: true,
},
});

const shelterIds = sheltersByUser.map((s) => s.shelterId);
where.shelterId = {
in: shelterIds,
};
}

return where;
}

private getAllDonationsMade(userId: string, shelterId?: string) {
const where: Prisma.DonationOrderWhereInput = {
userId,
shelterId,
};

return where;
}
}

0 comments on commit 5c3b21a

Please sign in to comment.