145 lines
4.5 KiB
TypeScript
145 lines
4.5 KiB
TypeScript
import { Body, Controller, Get, Post, Query, UseGuards } from '@nestjs/common';
|
|
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
|
import { TenantWalletService } from './tenant-wallet.service';
|
|
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
|
|
import { RolesGuard } from '../auth/guards/roles.guard';
|
|
import { Roles } from '../auth/decorators/roles.decorator';
|
|
import { CurrentUser, AuthUser } from '../auth/decorators/current-user.decorator';
|
|
|
|
/**
|
|
* محفظة المستأجر — يقرأها **أدمن المستأجر** لا السوبر-أدمن (docs/24).
|
|
* النطاق من التوكن دائماً: `user.tenantId`، فلا يمكن لأدمن مستأجر قراءة
|
|
* أرقام مستأجر آخر بتمرير معرّف في الطلب.
|
|
*/
|
|
@ApiTags('tenant-wallet')
|
|
@ApiBearerAuth()
|
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
|
@Roles('admin')
|
|
@Controller('admin/wallet')
|
|
export class TenantWalletController {
|
|
constructor(private readonly wallet: TenantWalletService) {}
|
|
|
|
/** الأرباح القابلة للسحب مقابل الأمانات المحتفَظ بها. */
|
|
@Get('summary')
|
|
summary(@CurrentUser() user: AuthUser, @Query('currency') currency?: string) {
|
|
return this.wallet.summary(user.tenantId, currency || 'JOD');
|
|
}
|
|
|
|
/** من أين جاء الإيراد: شحن سائقين · عمولات · رسوم. */
|
|
@Get('revenue-by-reason')
|
|
byReason(
|
|
@CurrentUser() user: AuthUser,
|
|
@Query('days') days?: string,
|
|
@Query('currency') currency?: string,
|
|
) {
|
|
const n = Number(days);
|
|
return this.wallet.revenueByReason(
|
|
user.tenantId,
|
|
Number.isFinite(n) && n > 0 ? Math.min(n, 365) : 30,
|
|
currency || 'JOD',
|
|
);
|
|
}
|
|
|
|
/** كشف حساب تفصيلي للدفتر. book يمكن أن يكون 'revenue' أو 'pending' */
|
|
@Get('statement')
|
|
statement(
|
|
@CurrentUser() user: AuthUser,
|
|
@Query('book') book: 'revenue' | 'pending',
|
|
@Query('currency') currency?: string,
|
|
@Query('limit') limit?: string,
|
|
@Query('offset') offset?: string,
|
|
) {
|
|
return this.wallet.statement(
|
|
book || 'revenue',
|
|
user.tenantId,
|
|
currency || 'JOD',
|
|
limit ? parseInt(limit, 10) : 100,
|
|
offset ? parseInt(offset, 10) : 0,
|
|
);
|
|
}
|
|
|
|
/** سحب أرباح المستأجر (من دفتر الإيرادات حصراً) */
|
|
@Post('withdraw')
|
|
withdraw(
|
|
@CurrentUser() user: AuthUser,
|
|
@Body() body: { amount: number; currency?: string },
|
|
) {
|
|
return this.wallet.withdraw(
|
|
user.tenantId,
|
|
Number(body.amount),
|
|
body.currency || 'JOD',
|
|
);
|
|
}
|
|
|
|
// ─── تقارير المستأجر (P4) ───────────────────────────────────────
|
|
|
|
/** إيراد حسب مزوّد الدفع (cash / cliq / syriatel / mtn / ...). */
|
|
@Get('report/by-provider')
|
|
reportByProvider(
|
|
@CurrentUser() user: AuthUser,
|
|
@Query('days') days?: string,
|
|
) {
|
|
const n = Number(days);
|
|
return this.wallet.revenueByProvider(
|
|
user.tenantId,
|
|
Number.isFinite(n) && n > 0 ? Math.min(n, 365) : 30,
|
|
);
|
|
}
|
|
|
|
/** إيراد يومي — سلسلة زمنية. */
|
|
@Get('report/by-day')
|
|
reportByDay(
|
|
@CurrentUser() user: AuthUser,
|
|
@Query('days') days?: string,
|
|
@Query('currency') currency?: string,
|
|
) {
|
|
const n = Number(days);
|
|
return this.wallet.revenueByDay(
|
|
user.tenantId,
|
|
Number.isFinite(n) && n > 0 ? Math.min(n, 365) : 30,
|
|
currency || 'JOD',
|
|
);
|
|
}
|
|
|
|
/** ملخّص الرحلات المالي (GMV + عمولة + خصومات). */
|
|
@Get('report/trips')
|
|
reportTrips(
|
|
@CurrentUser() user: AuthUser,
|
|
@Query('days') days?: string,
|
|
) {
|
|
const n = Number(days);
|
|
return this.wallet.tripRevenueSummary(
|
|
user.tenantId,
|
|
Number.isFinite(n) && n > 0 ? Math.min(n, 365) : 30,
|
|
);
|
|
}
|
|
|
|
/** ملخّص سحوبات السائقين. */
|
|
@Get('report/payouts')
|
|
reportPayouts(
|
|
@CurrentUser() user: AuthUser,
|
|
@Query('days') days?: string,
|
|
) {
|
|
const n = Number(days);
|
|
return this.wallet.payoutSummary(
|
|
user.tenantId,
|
|
Number.isFinite(n) && n > 0 ? Math.min(n, 365) : 30,
|
|
);
|
|
}
|
|
|
|
/** التقرير الشامل — يجمع كل شيء في طلب واحد. */
|
|
@Get('report/full')
|
|
reportFull(
|
|
@CurrentUser() user: AuthUser,
|
|
@Query('days') days?: string,
|
|
@Query('currency') currency?: string,
|
|
) {
|
|
const n = Number(days);
|
|
return this.wallet.fullReport(
|
|
user.tenantId,
|
|
Number.isFinite(n) && n > 0 ? Math.min(n, 365) : 30,
|
|
currency || 'JOD',
|
|
);
|
|
}
|
|
}
|