add payments routes
This commit is contained in:
34
src/payments/payment.controller.ts
Normal file
34
src/payments/payment.controller.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { FastifyReply, FastifyRequest } from "fastify";
|
||||
import { getPayment, listPayments } from "./payments.service";
|
||||
import { PageQueryParams } from "../pagination";
|
||||
|
||||
export async function getPaymentHandler(
|
||||
req: FastifyRequest,
|
||||
res: FastifyReply
|
||||
) {
|
||||
const { paymentId } = req.params as { paymentId: string };
|
||||
|
||||
try {
|
||||
const payment = await getPayment(paymentId, req.user);
|
||||
if (payment === null)
|
||||
return res.code(404).send({ error: "resource not found" });
|
||||
|
||||
return res.code(200).send(payment);
|
||||
} catch (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
export async function listPaymentHandler(
|
||||
req: FastifyRequest,
|
||||
res: FastifyReply
|
||||
) {
|
||||
const queryParams = req.query as PageQueryParams;
|
||||
|
||||
try {
|
||||
const paymentList = await listPayments(queryParams, req.user);
|
||||
return res.code(200).send(paymentList);
|
||||
} catch (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
46
src/payments/payment.route.ts
Normal file
46
src/payments/payment.route.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { FastifyInstance } from "fastify";
|
||||
import { getPaymentHandler, listPaymentHandler } from "./payment.controller";
|
||||
import { $payment } from "./payment.schema";
|
||||
|
||||
export async function paymentRoutes(fastify: FastifyInstance) {
|
||||
fastify.get(
|
||||
"/:paymentId",
|
||||
{
|
||||
schema: {
|
||||
params: {
|
||||
type: "object",
|
||||
properties: {
|
||||
paymentId: { type: "string" },
|
||||
},
|
||||
},
|
||||
},
|
||||
config: { requiredClaims: ["payment:read"] },
|
||||
preHandler: [fastify.authorize],
|
||||
},
|
||||
getPaymentHandler
|
||||
);
|
||||
|
||||
fastify.get(
|
||||
"/",
|
||||
{
|
||||
schema: {
|
||||
params: $payment("pageQueryParams"),
|
||||
},
|
||||
config: { requiredClaims: ["payment:read"] },
|
||||
preHandler: [fastify.authorize],
|
||||
},
|
||||
listPaymentHandler
|
||||
);
|
||||
|
||||
fastify.get(
|
||||
"/search",
|
||||
{
|
||||
schema: {
|
||||
params: $payment("pageQueryParams"),
|
||||
},
|
||||
config: { requiredClaims: ["payment:read"] },
|
||||
preHandler: [fastify.authorize],
|
||||
},
|
||||
listPaymentHandler
|
||||
);
|
||||
}
|
||||
43
src/payments/payment.schema.ts
Normal file
43
src/payments/payment.schema.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { buildJsonSchemas } from "fastify-zod";
|
||||
import mongoose from "mongoose";
|
||||
import { pageQueryParams } from "../pagination";
|
||||
|
||||
const paymentSchema = new mongoose.Schema({
|
||||
permitNumber: String,
|
||||
recordId: String,
|
||||
tenantId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
pid: {
|
||||
type: String,
|
||||
unique: true,
|
||||
},
|
||||
permitPid: String,
|
||||
county: Object,
|
||||
client: {
|
||||
type: mongoose.Types.ObjectId,
|
||||
ref: "organization",
|
||||
},
|
||||
clientData: Object,
|
||||
address: Object,
|
||||
permitLink: String,
|
||||
cardEnding: String,
|
||||
totalPaid: Number,
|
||||
receiptNo: String,
|
||||
fileId: String,
|
||||
paymentDate: Date,
|
||||
});
|
||||
|
||||
export const paymentModel = mongoose.model("payment", paymentSchema);
|
||||
|
||||
export const paymentFields = Object.keys(paymentSchema.paths).filter(
|
||||
(path) => path !== "__v"
|
||||
);
|
||||
|
||||
export const { schemas: paymentSchemas, $ref: $payment } = buildJsonSchemas(
|
||||
{
|
||||
pageQueryParams,
|
||||
},
|
||||
{ $id: "payment" }
|
||||
);
|
||||
94
src/payments/payments.service.ts
Normal file
94
src/payments/payments.service.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import mongoose from "mongoose";
|
||||
import { AuthenticatedUser } from "../auth";
|
||||
import { getFilterObject, getSortObject, PageQueryParams } from "../pagination";
|
||||
import { paymentFields, paymentModel } from "./payment.schema";
|
||||
|
||||
export async function getPayment(paymentId: string, user: AuthenticatedUser) {
|
||||
const paymentObj = await paymentModel.findOne({
|
||||
tenantId: user.tenantId,
|
||||
pid: paymentId,
|
||||
});
|
||||
|
||||
if (user.role === "client" && paymentObj.client.toString() !== user.orgId)
|
||||
return null;
|
||||
|
||||
return paymentObj;
|
||||
}
|
||||
|
||||
export async function listPayments(
|
||||
params: PageQueryParams,
|
||||
user: AuthenticatedUser
|
||||
) {
|
||||
const page = params.page || 1;
|
||||
const pageSize = params.pageSize || 10;
|
||||
const sortObj = getSortObject(params, paymentFields);
|
||||
const filterObj = getFilterObject(params) || [];
|
||||
|
||||
if (user.role == "client") {
|
||||
filterObj.push({ client: new mongoose.Types.ObjectId(user.orgId) });
|
||||
}
|
||||
|
||||
const pipeline: Array<any> = [
|
||||
{ $match: { $and: [{ tenantId: user.tenantId }, ...filterObj] } },
|
||||
];
|
||||
|
||||
if (params.searchToken) {
|
||||
const regex = new RegExp(params.searchToken, "i");
|
||||
|
||||
pipeline.push({
|
||||
$match: {
|
||||
$or: [
|
||||
{ permitNumber: { $regex: regex } },
|
||||
{ "address.full_address": { $regex: regex } },
|
||||
],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
pipeline.push(
|
||||
{
|
||||
$project: {
|
||||
_id: 1,
|
||||
permitNumber: 1,
|
||||
recordId: 1,
|
||||
tenantId: 1,
|
||||
pid: 1,
|
||||
permitPid: 1,
|
||||
county: 1,
|
||||
client: 1,
|
||||
clientData: 1,
|
||||
address: 1,
|
||||
permitLink: 1,
|
||||
cardEnding: 1,
|
||||
totalPaid: 1,
|
||||
receiptNo: 1,
|
||||
fileId: 1,
|
||||
paymentDate: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
$facet: {
|
||||
metadata: [{ $count: "count" }],
|
||||
data: [
|
||||
{ $sort: sortObj },
|
||||
{ $skip: (page - 1) * pageSize },
|
||||
{ $limit: pageSize },
|
||||
],
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const paymentsList = await paymentModel.aggregate(pipeline);
|
||||
|
||||
if (paymentsList[0].data.length === 0)
|
||||
return { permits: [], metadata: { count: 0, page, pageSize } };
|
||||
|
||||
return {
|
||||
payments: paymentsList[0]?.data,
|
||||
metadata: {
|
||||
count: paymentsList[0].metadata[0].count,
|
||||
page,
|
||||
pageSize,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import { mailProxyRoutes } from "./mailProxy/mailProxy.route";
|
||||
import { viewRoutes } from "./view/view.route";
|
||||
import { processedRoutes } from "./processed/processed.route";
|
||||
import { ctaskRoutes } from "./ctask/ctask.route";
|
||||
import { paymentRoutes } from "./payments/payment.route";
|
||||
|
||||
export default async function routes(fastify: FastifyInstance) {
|
||||
fastify.addHook("preHandler", authHandler);
|
||||
@@ -30,5 +31,6 @@ export default async function routes(fastify: FastifyInstance) {
|
||||
fastify.register(configRoutes, { prefix: "/config" });
|
||||
fastify.register(viewRoutes, { prefix: "/views" });
|
||||
fastify.register(processedRoutes, { prefix: "/processed" });
|
||||
fastify.register(paymentRoutes, { prefix: "/payments" });
|
||||
fastify.register(realTimeRoutes);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import { mailSchemas } from "./mailProxy/mailProxy.schema";
|
||||
import { viewSchemas } from "./view/view.schema";
|
||||
import { processedSchemas } from "./processed/processed.schema";
|
||||
import { cTaskSchemas } from "./ctask/ctask.schema";
|
||||
import { paymentSchemas } from "./payments/payment.schema";
|
||||
|
||||
const app = fastify({ logger: true, trustProxy: true });
|
||||
|
||||
@@ -57,6 +58,7 @@ for (const schema of [
|
||||
...mailSchemas,
|
||||
...viewSchemas,
|
||||
...processedSchemas,
|
||||
...paymentSchemas,
|
||||
]) {
|
||||
app.addSchema(schema);
|
||||
}
|
||||
|
||||
@@ -34,4 +34,5 @@ export type Claim =
|
||||
| "view:delete"
|
||||
| "note:read"
|
||||
| "note:write"
|
||||
| "note:delete";
|
||||
| "note:delete"
|
||||
| "payment:read";
|
||||
|
||||
@@ -36,6 +36,7 @@ export const rules: Record<
|
||||
"note:read",
|
||||
"note:write",
|
||||
"note:delete",
|
||||
"payment:read",
|
||||
],
|
||||
hiddenFields: {
|
||||
orgs: ["__v"],
|
||||
@@ -73,6 +74,7 @@ export const rules: Record<
|
||||
"note:read",
|
||||
"note:write",
|
||||
"note:delete",
|
||||
"payment:read",
|
||||
],
|
||||
hiddenFields: {
|
||||
orgs: ["__v"],
|
||||
|
||||
Reference in New Issue
Block a user