Files
edr-platform/apps/edr-freight-api/src/modules/payment/payment.repository.ts
2026-06-23 06:45:29 +00:00

116 lines
4.1 KiB
TypeScript

import { Injectable } from "@nestjs/common";
import { DataSource, FindOptionsWhere, QueryDeepPartialEntity, QueryRunner, Repository } from "typeorm";
import { PaymentEntity } from "./entities/payment.entity";
@Injectable()
export class PaymentRepository {
private readonly paymentRepo: Repository<PaymentEntity>;
constructor(private readonly dataSource: DataSource) {
this.paymentRepo = this.dataSource.getRepository(PaymentEntity)
}
async createTr(qr: QueryRunner, data: Pick<PaymentEntity, "amount" | "method" | "currency" | "type" | "refId" | "merchantOrderId" | "rawInitiation" | "clientAction" | "expiresAt" | "reason">): Promise<PaymentEntity> {
const payment = qr.manager.create(PaymentEntity, data)
return qr.manager.save(payment)
}
async create(data: Pick<PaymentEntity, "amount" | "method" | "currency" | "type" | "refId" | "merchantOrderId" | "rawInitiation" | "clientAction" | "expiresAt" | "reason">): Promise<PaymentEntity> {
const payment = this.paymentRepo.create(data)
return this.paymentRepo.save(payment)
}
findOneBy(options: FindOptionsWhere<PaymentEntity> | FindOptionsWhere<PaymentEntity>[]): Promise<PaymentEntity | null> {
return this.paymentRepo.findOneBy(options);
}
update(where: FindOptionsWhere<PaymentEntity>, data: QueryDeepPartialEntity<PaymentEntity>) {
return this.paymentRepo.update(where, data)
}
getActivePaymentByRefIdAndMethod(refId: string, method: PaymentEntity["method"]) {
return this.paymentRepo
.createQueryBuilder('payment')
.where('payment.method = :method', { method })
.andWhere('payment.refId = :refId', { refId })
.andWhere('payment.status IN (:...statuses)', {
statuses: ['action-required'],
})
.andWhere('payment.expiresAt > :now', { now: new Date() })
.getOne();
}
getActivePaymentByOrderIdAndMethod(orderId: string, method: PaymentEntity["method"]) {
return this.paymentRepo
.createQueryBuilder('payment')
.where('payment.method = :method', { method })
.andWhere('payment.merchantOrderId = :orderId', { orderId })
.andWhere('payment.status IN (:...statuses)', {
statuses: ['action-required'],
})
.andWhere('payment.expiresAt > :now', { now: new Date() })
.getOne();
}
createQueryBuilder(alias: string) {
return this.paymentRepo.createQueryBuilder(alias);
}
async findByCompanyId(companyId: string): Promise<{
id: string;
merchantOrderId: string;
bookingReference: string;
amount: number;
currency: string;
method: string;
status: string;
paidAt: Date | null;
createdAt: Date;
}[]> {
const rows: {
id: string;
merchant_order_id: string;
booking_reference: string;
amount: number;
currency: string;
method: string;
status: string;
paid_at: Date | null;
created_at: Date;
}[] = await this.dataSource.query(
`SELECT p.id,
p.merchant_order_id,
b.reference AS booking_reference,
p.amount,
p.currency,
p.method,
p.status,
p.paid_at,
p.created_at
FROM freight.payments p
JOIN freight.bookings b ON b.id = p.ref_id
WHERE b.company_id = $1
AND p.deleted_at IS NULL
AND b.deleted_at IS NULL
ORDER BY p.created_at DESC`,
[companyId],
);
return rows.map((r) => ({
id: r.id,
merchantOrderId: r.merchant_order_id,
bookingReference: r.booking_reference,
amount: Number(r.amount),
currency: r.currency,
method: r.method,
status: r.status,
paidAt: r.paid_at,
createdAt: r.created_at,
}));
}
}