fix pluggin bug 2
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
export const PLUGIN_STORE_DURATIONS = [30, 90, 180, 360] as const;
|
||||
export const PLUGIN_STORE_DURATIONS = [30, 90, 180, 360, 0] as const;
|
||||
|
||||
export type PluginStoreDuration = (typeof PLUGIN_STORE_DURATIONS)[number];
|
||||
|
||||
@@ -90,13 +90,23 @@ export const PLUGIN_CATALOG_SEED: Array<{
|
||||
},
|
||||
];
|
||||
|
||||
export function daysToPlanMonths(days: number): 1 | 3 | 6 | 12 {
|
||||
export function daysToPlanMonths(days: number): 0 | 1 | 3 | 6 | 12 {
|
||||
if (days === 0) return 0;
|
||||
if (days === 90) return 3;
|
||||
if (days === 180) return 6;
|
||||
if (days === 360) return 12;
|
||||
return 1;
|
||||
}
|
||||
|
||||
export function pluginStoreDurationLabel(days: number): string {
|
||||
if (Number(days) === 0) return 'یکبار پرداخت';
|
||||
if (days === 30) return '۳۰ روزه';
|
||||
if (days === 90) return '۹۰ روزه';
|
||||
if (days === 180) return '۱۸۰ روزه';
|
||||
if (days === 360) return '۳۶۰ روزه';
|
||||
return `${days} روزه`;
|
||||
}
|
||||
|
||||
export function inferSettingKeyFromName(name: string): string | null {
|
||||
const n = String(name || '').trim();
|
||||
if (!n) return null;
|
||||
|
||||
@@ -38,6 +38,7 @@ import {
|
||||
inferSettingKeyFromName,
|
||||
PLUGIN_CATALOG_SEED,
|
||||
PLUGIN_STORE_DURATIONS,
|
||||
pluginStoreDurationLabel,
|
||||
} from './plugin-catalog.seed';
|
||||
import {
|
||||
ApprovePurchaseDto,
|
||||
@@ -380,6 +381,7 @@ export class PluginStoreService implements OnModuleInit, OnModuleDestroy {
|
||||
}
|
||||
|
||||
const months = daysToPlanMonths(req.durationDays);
|
||||
const oneTime = req.durationDays === 0;
|
||||
const existing = await this.prisma.pluginSubscription.findFirst({
|
||||
where: {
|
||||
tenantId: req.tenantId,
|
||||
@@ -393,10 +395,12 @@ export class PluginStoreService implements OnModuleInit, OnModuleDestroy {
|
||||
existing?.expiresAt && existing.expiresAt.getTime() > now.getTime()
|
||||
? existing.expiresAt
|
||||
: now;
|
||||
const expiresAt =
|
||||
existing?.expiresAt && existing.expiresAt.getTime() > now.getTime()
|
||||
const expiresAt = oneTime
|
||||
? null
|
||||
: existing?.expiresAt && existing.expiresAt.getTime() > now.getTime()
|
||||
? addIranMonths(from, months)
|
||||
: addIranPlanExpiry(now, months);
|
||||
const chargeExpiresAt = expiresAt ?? new Date('9999-12-31T00:00:00.000Z');
|
||||
|
||||
const plugin = existing
|
||||
? await this.prisma.pluginSubscription.update({
|
||||
@@ -410,7 +414,7 @@ export class PluginStoreService implements OnModuleInit, OnModuleDestroy {
|
||||
chargedAt: now,
|
||||
expiresAt,
|
||||
isActive: true,
|
||||
autoCutOnExpiry: dto.autoCutOnExpiry,
|
||||
autoCutOnExpiry: oneTime ? false : dto.autoCutOnExpiry,
|
||||
lastAlertDate: null,
|
||||
alertMarks: Prisma.DbNull,
|
||||
},
|
||||
@@ -426,7 +430,7 @@ export class PluginStoreService implements OnModuleInit, OnModuleDestroy {
|
||||
chargedAt: now,
|
||||
expiresAt,
|
||||
isActive: true,
|
||||
autoCutOnExpiry: dto.autoCutOnExpiry,
|
||||
autoCutOnExpiry: oneTime ? false : dto.autoCutOnExpiry,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -436,7 +440,7 @@ export class PluginStoreService implements OnModuleInit, OnModuleDestroy {
|
||||
chargedAt: now,
|
||||
planMonths: months,
|
||||
priceRials: req.finalPriceRials,
|
||||
expiresAt,
|
||||
expiresAt: chargeExpiresAt,
|
||||
note: 'خرید از فروشگاه',
|
||||
createdById: userId,
|
||||
},
|
||||
@@ -460,10 +464,13 @@ export class PluginStoreService implements OnModuleInit, OnModuleDestroy {
|
||||
entityId: id,
|
||||
tenantId: req.tenantId,
|
||||
userId,
|
||||
after: { settingKey: req.catalogItem.settingKey, expiresAt: expiresAt.toISOString() } as Prisma.InputJsonValue,
|
||||
after: {
|
||||
settingKey: req.catalogItem.settingKey,
|
||||
expiresAt: expiresAt?.toISOString() ?? null,
|
||||
} as Prisma.InputJsonValue,
|
||||
});
|
||||
|
||||
return { ok: true, expiresAt: expiresAt.toISOString() };
|
||||
return { ok: true, expiresAt: expiresAt?.toISOString() ?? null };
|
||||
}
|
||||
|
||||
async rejectRequest(id: string, userId?: string) {
|
||||
@@ -544,12 +551,14 @@ export class PluginStoreService implements OnModuleInit, OnModuleDestroy {
|
||||
.sort((a, b) => (b.expiresAt?.getTime() || 0) - (a.expiresAt?.getTime() || 0))[0];
|
||||
const daysLeft = sub?.expiresAt ? iranDaysUntil(sub.expiresAt) : null;
|
||||
const hasPending = pendingIds.has(item.id);
|
||||
const lifetime = Boolean(sub?.isActive && !sub.expiresAt);
|
||||
const lockedByDays =
|
||||
sub?.isActive &&
|
||||
lifetime ||
|
||||
(sub?.isActive &&
|
||||
sub.expiresAt &&
|
||||
sub.expiresAt.getTime() > now &&
|
||||
daysLeft != null &&
|
||||
daysLeft > 3;
|
||||
daysLeft > 3);
|
||||
return {
|
||||
id: item.id,
|
||||
settingKey: item.settingKey,
|
||||
@@ -640,6 +649,9 @@ export class PluginStoreService implements OnModuleInit, OnModuleDestroy {
|
||||
where: { tenantId, settingKey: item.settingKey, isActive: true },
|
||||
orderBy: { expiresAt: 'desc' },
|
||||
});
|
||||
if (sub?.isActive && !sub.expiresAt) {
|
||||
throw new ConflictException('این افزونه یکبار پرداخت شده و فعال است');
|
||||
}
|
||||
if (sub?.expiresAt && sub.expiresAt.getTime() > Date.now()) {
|
||||
const daysLeft = iranDaysUntil(sub.expiresAt);
|
||||
if (daysLeft > 3) {
|
||||
@@ -663,7 +675,7 @@ export class PluginStoreService implements OnModuleInit, OnModuleDestroy {
|
||||
});
|
||||
|
||||
this.notify.notifyAdmins(
|
||||
`درخواست افزونه: «${created.catalogItem.titleFa}» ${dto.durationDays}روزه برای «${created.tenant.nameFa}» (${created.tenant.domain}) — ${price.finalPriceRials.toLocaleString('fa-IR')} ریال`,
|
||||
`درخواست افزونه: «${created.catalogItem.titleFa}» ${pluginStoreDurationLabel(dto.durationDays)} برای «${created.tenant.nameFa}» (${created.tenant.domain}) — ${price.finalPriceRials.toLocaleString('fa-IR')} ریال`,
|
||||
);
|
||||
|
||||
return this.toRequestRow({
|
||||
|
||||
Reference in New Issue
Block a user