Skip to content

Commit

Permalink
delivery creation by supplier done
Browse files Browse the repository at this point in the history
  • Loading branch information
Sandaru-IT21001352 committed Oct 25, 2023
1 parent 20df5fe commit c67b165
Show file tree
Hide file tree
Showing 21 changed files with 739 additions and 100 deletions.
207 changes: 207 additions & 0 deletions backend/src/__tests__/delivery.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
import supertest from "supertest";
import { MongoMemoryServer } from "mongodb-memory-server";
import createServer from "../utils/server";
import mongoose from "mongoose";
import { signJwt } from "../utils/jwt.utils";
import { createUser } from "../service/user.service";
import { createItem } from "../service/item.service";

import { createOrder } from "../service/order.service";
import { OrderDocument } from "../models/order.model";
import { UserInput } from "../models/user.model";

const app = createServer();

const userId = new mongoose.Types.ObjectId().toString();

const userPayload: UserInput = {
email: "jane.doe@example.com",
name: "Jane Doe",
role: "supplier",
contactNumber: "0712345678",
password: "Password456!",
};
const supplierPayload: UserInput = {
email: "supplier23@example.com",
name: "Supplier",
role: "supplier",
contactNumber: "0712345678",
password: "Password456!",
};

export const orderPayload = {
supplier: new mongoose.Types.ObjectId().toString(),
items: [
{
item: new mongoose.Types.ObjectId().toString(),
quantity: 2,
},
{
item: new mongoose.Types.ObjectId().toString(),
quantity: 5,
},
],
siteManager: userId,
site: new mongoose.Types.ObjectId().toString(),
comments: "comments",
dateToBeDelivered: new Date("2021-10-10 10:00:00").toString(),
//orders needs to be placed to be displayed for the supplier
status: "placed",
};

describe("deliveries", () => {
beforeAll(async () => {
const mongoServer = await MongoMemoryServer.create();
await mongoose.connect(mongoServer.getUri());
});
let user: any;
let supplier: any;
let jwt: string;
let order: OrderDocument;

afterAll(async () => {
await mongoose.disconnect();
await mongoose.connection.close();
});
beforeAll(async () => {
user = await createUser(userPayload);
supplier = await createUser(supplierPayload);
jwt = signJwt({ ...userPayload, role: "procurementStaff" });
const item = await createItem({
name: "item1",
description: "item description",
price: 100,
supplier: user._id,
});
order = await createOrder({
...orderPayload,
supplier: user._id,
items: [{ item: item._id, quantity: 5 }],
});
});

// testing supplier making partial and full deliveries
describe("make delivery for supplier", () => {
describe("given the user is not logged in", () => {
it("should return a 403", async () => {
const { statusCode } = await supertest(app).post(
"/api/supplier/orders/:purchaseOrderId/deliver"
);

expect(statusCode).toBe(403);
});
});
describe("given the users not logged in as a supplier", () => {
it("should return a 403", async () => {
const jwt = signJwt({ ...userPayload, role: "procurementStaff" });

const { statusCode } = await supertest(app)
.post("/api/supplier/orders/:purchaseOrderId/deliver")
.set("Authorization", `Bearer ${jwt}`);

expect(statusCode).toBe(403);
});
});
describe("given the user is logged in", () => {
// negative test case
// testing supplier making delivery quantity more than the order quantity
describe("given the delivery quantity is more than the order quantity", () => {
it("should return a 409 and not make the delivery", async () => {
const jwt = signJwt(user);

const { statusCode, body } = await supertest(app)
.post(`/api/supplier/orders/${order.orderId}/deliver`)
.set("Authorization", `Bearer ${jwt}`)
.send({
items: [
{
item: order.items[0].item._id.toString(),
quantity: 10,
},
],
});

expect(statusCode).toBe(409);
});
});

// testing supplier making partial delivery
describe("given the delivery quantity is less than the order quantity", () => {
it("should return a 201 and make the delivery", async () => {
const jwt = signJwt(user);

const { statusCode, body } = await supertest(app)
.post(`/api/supplier/orders/${order.orderId}/deliver`)
.set("Authorization", `Bearer ${jwt}`)
.send({
items: [
{
item: order.items[0].item._id.toString(),
quantity: 1,
},
],
});

expect(statusCode).toBe(200);
});
});
// testing supplier making full delivery
describe("given the delivery quantity is equal to the order quantity", () => {
it("should return a 201 and make the delivery", async () => {
const jwt = signJwt(user);

const { statusCode, body } = await supertest(app)
.post(`/api/supplier/orders/${order.orderId}/deliver`)
.set("Authorization", `Bearer ${jwt}`)
.send({
items: [
{
item: order.items[0].item._id.toString(),
quantity: 1,
},
],
});

expect(statusCode).toBe(200);
});
});
});

// testing supplier getting all their goods receipts they they delivered - pending and confirmed
describe("get goods receipts for supplier", () => {
describe("given the user is not logged in", () => {
it("should return a 403", async () => {
const { statusCode } = await supertest(app).get(
"/api/supplier/orders/goodsReceipts"
);

expect(statusCode).toBe(403);
});
});
describe("given the users not logged in as a supplier", () => {
it("should return a 403", async () => {
const jwt = signJwt({ ...userPayload, role: "procurementStaff" });

const { statusCode } = await supertest(app)
.get("/api/supplier/orders/goodsReceipts")
.set("Authorization", `Bearer ${jwt}`);

expect(statusCode).toBe(403);
});
});
describe("given the user is logged in", () => {
it("should return a 200 and get the orders", async () => {
const jwt = signJwt(userPayload);

const { statusCode, body } = await supertest(app)
.get("/api/supplier/orders/goodsReceipts")
.set("Authorization", `Bearer ${jwt}`);

expect(statusCode).toBe(200);

expect(body).toBeDefined();
});
});
});
});
});
12 changes: 6 additions & 6 deletions backend/src/__tests__/hierarchy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ describe("hierarchy test suite", () => {
const hierarchyPayload: HierarchyInput = {
lowerBoundPrice: 5000,
upperBoundPrice: 12000,
managerInCharge: "Supply Chain Manager",
managerInCharge: "Supply Chain Manager 1",
};

const { statusCode, body } = await supertest(app)
Expand Down Expand Up @@ -74,9 +74,9 @@ describe("hierarchy test suite", () => {
/* Test case 1 - success scenario */
test("success scenario", async () => {
const hierarchyPayload: HierarchyInput = {
lowerBoundPrice: 5000,
upperBoundPrice: 12000,
managerInCharge: "Supply Chain Manager",
lowerBoundPrice: 200,
upperBoundPrice: 400,
managerInCharge: "Supply Chain Manager 2",
};

const response1 = await supertest(app)
Expand Down Expand Up @@ -111,8 +111,8 @@ describe("hierarchy test suite", () => {
/* Test case 1 - success scenario */
test("success scenario", async () => {
const hierarchyPayload: HierarchyInput = {
lowerBoundPrice: 5000,
upperBoundPrice: 12000,
lowerBoundPrice: 2000,
upperBoundPrice: 11000,
managerInCharge: "Supply Chain Manager",
};

Expand Down
84 changes: 83 additions & 1 deletion backend/src/controller/order-for-supplier.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import logger from "../utils/logger";
import { listUsers } from "../service/user-management.service";
import { getItemList } from "../service/item.service";
import { createOrder, findOrder, getOrderList } from "../service/order.service";
import { CreateDeliveryInput } from "../schema/order-for-supplier.schema";
import { createDelivery, getDeliveryList } from "../service/deliver.service";

// for supplier to view their orders
export async function getOrdersForSupplierHandler(
Expand All @@ -18,7 +20,10 @@ export async function getOrdersForSupplierHandler(
try {
const supplierId = res.locals.user._id;
const orders = await getOrderList(
{ status: "placed", supplier: supplierId },
{
status: { $in: ["placed", "partially-shipped"] },
supplier: supplierId,
},
true
);
return res.send(orders);
Expand Down Expand Up @@ -49,3 +54,80 @@ export async function getOrdersHistoryForSupplierHandler(
return res.status(409).send(error.message);
}
}

// for supplier to create a delivery
export async function createDeliveryHandler(
req: Request<CreateDeliveryInput["params"], {}, CreateDeliveryInput["body"]>,
res: Response
) {
try {
const supplierId = res.locals.user._id;
const purchaseOrderId = req.params.purchaseOrderId;
const order = await findOrder(
{
orderId: purchaseOrderId,
},
{ lean: false }
);
if (!order) {
return res.status(404).send("Order not found");
}
if (order.status !== "placed" && order.status !== "partially-shipped") {
return res.status(409).send("Order cannot be delivered");
}

order.status = "partially-shipped";

order.items.forEach((item, index) => {
const itemInDelivery = req.body.items.find(
(i: CreateDeliveryInput["body"]["items"][0]) =>
i.item === item.item._id.toString()
);

if (itemInDelivery) {
if (itemInDelivery.quantity > item.quantity - item.shipped) {
throw new Error(
"Quantity in delivery cannot be more than quantity in order"
);
}
order.items[index].shipped += itemInDelivery.quantity;
}
});

if (
order.items.every((item) => item.quantity === item.shipped) &&
order.items.length > 0
) {
order.status = "shipped";
}

const updatedOrder = await order.save();

await createDelivery({
items: req.body.items,
order: order._id,
supplier: supplierId,
});
return res.send(updatedOrder);
} catch (error: any) {
logger.error(error);
return res.status(409).send(error.message);
}
}

// for supplier to view their delivery list
export async function getDeliveryListForSupplierHandler(
req: Request<{}, {}, {}>,
res: Response
) {
try {
const supplierId = res.locals.user._id;
const orders = await getDeliveryList({
supplier: supplierId,
});
return res.send(orders);
} catch (error: any) {
logger.error(error);
return res.status(409).send(error.message);
}
}
Loading

0 comments on commit c67b165

Please sign in to comment.