Merge pull request #1083 from Tria-plc/freight_feature/usermanagement

Freight feature/usermanagement
This commit is contained in:
marshal
2026-08-03 01:40:20 +03:00
committed by GitHub
60 changed files with 2722 additions and 218 deletions

View File

@@ -15,8 +15,10 @@ import {
ApiProduces,
} from "@nestjs/swagger";
import { Response } from "express";
import { Public } from "@edr/api-common";
import { CurrentUser, Public } from "@edr/api-common";
import type { TCurrentUser } from "@tria-plc/api-common/modules/auth/types/current-user.type";
import { BookingStaff, BookingView } from "../../common/booking-guards";
import { UserTradeAccessService } from "../user-trade-access/user-trade-access.service";
import { FREIGHT_PERMS } from "../../seed/freight-permissions.registry";
import { PaymentService } from "./payment.service";
import { IntentStatusDto } from "./payments.dto";
@@ -24,7 +26,10 @@ import { IntentStatusDto } from "./payments.dto";
@ApiTags("Payment")
@Controller("payments")
export class PaymentController {
constructor(private readonly paymentService: PaymentService) { }
constructor(
private readonly paymentService: PaymentService,
private readonly userTradeAccessService: UserTradeAccessService,
) { }
// Customer-detail payments tab — same one-of rule as the bookings tab.
@Get("by-company/:companyId/customer-view")
@@ -52,18 +57,23 @@ export class PaymentController {
@ApiQuery({ name: "page", required: false })
@ApiQuery({ name: "pageSize", required: false })
async getAll(
@CurrentUser() user: TCurrentUser,
@Query("search") search?: string,
@Query("status") status?: string,
@Query("method") method?: string,
@Query("page") page?: string,
@Query("pageSize") pageSize?: string,
) {
// Per-user trade-direction scope, applied via the booking in ref_id.
const allowed =
await this.userTradeAccessService.resolveAllowedDirections(user);
return this.paymentService.getAll({
search,
status,
method,
page: page ? parseInt(page) : 1,
pageSize: pageSize ? parseInt(pageSize) : 10,
tradeDirections: allowed ?? undefined,
});
}

View File

@@ -13,6 +13,7 @@ import {
import { ServiceAuthGuard } from "../../common/guards/service-auth.guard";
import { BillingModule } from "../billing/billing.module";
import { UserTradeAccessModule } from "../user-trade-access/user-trade-access.module";
// import { FirstMileModule } from "../first-mile/first-mile.module";
// import { TrainSchedulingModule } from "../train-scheduling/train-scheduling.module";
import { PaymentRefundEntity } from "./entities/payment-refund.entity";
@@ -64,6 +65,7 @@ function rabbitMQImport(): DynamicModule[] {
timeout: Number(process.env.PAYMENT_API_HTTP_TIMEOUT_MS) || 60_000,
}),
ConfigModule,
UserTradeAccessModule,
forwardRef(() => BillingModule),
// forwardRef(() => TrainSchedulingModule),
// FirstMileModule,

View File

@@ -7,6 +7,7 @@ import {
Logger,
NotFoundException,
} from "@nestjs/common";
import { applyBookingRefDirectionScope } from "../user-trade-access/trade-scope.util";
import { PaymentEntity } from "./entities/payment.entity";
import { PaymentRepository } from "./payment.repository";
import { PaymentClientService } from "./payment-client.service";
@@ -110,6 +111,8 @@ export class PaymentService {
method?: string;
page?: number;
pageSize?: number;
/** Per-user trade-direction scope, applied via the booking in ref_id. */
tradeDirections?: string[];
}) {
const { search, status, method, page = 1, pageSize = 10 } = filters;
const skip = (page - 1) * pageSize;
@@ -128,6 +131,9 @@ export class PaymentService {
if (method) {
qb.andWhere("payment.method = :method", { method });
}
if (filters.tradeDirections) {
applyBookingRefDirectionScope(qb, "payment.ref_id", filters.tradeDirections);
}
const [items, total] = await qb
.orderBy("payment.createdAt", "DESC")