feat: add channel report batch briefs
This commit is contained in:
@@ -74,8 +74,6 @@ export class SmsSignatureService {
|
||||
) {}
|
||||
async listSignatures(queryOrTenantId?: string | SignatureListQuery, summaryOnly = false) {
|
||||
const query = typeof queryOrTenantId === 'string' ? { tenantId: queryOrTenantId } : (queryOrTenantId ?? {});
|
||||
const signatureSort =
|
||||
query.signatureSort === 'asc' || query.signatureSort === 'desc' ? query.signatureSort : undefined;
|
||||
const signatures = await this.prisma.smsSignature.findMany({
|
||||
where: {
|
||||
id: query.signatureId,
|
||||
@@ -159,7 +157,7 @@ export class SmsSignatureService {
|
||||
select: { reportType: true, materialVersion: true, snapshot: true },
|
||||
},
|
||||
},
|
||||
orderBy: signatureSort ? [{ name: signatureSort }, { id: 'asc' }] : { createdAt: 'desc' },
|
||||
orderBy: { createdAt: 'desc' },
|
||||
...(query.page && query.pageSize
|
||||
? {
|
||||
skip: (query.page - 1) * query.pageSize,
|
||||
@@ -442,11 +440,97 @@ export class SmsSignatureService {
|
||||
]
|
||||
: undefined,
|
||||
};
|
||||
const [items, total] = await Promise.all([
|
||||
const [items, total, pendingReportDetailTotal] = await Promise.all([
|
||||
this.listSignatures({ ...query, page, pageSize }, true),
|
||||
this.prisma.smsSignature.count({ where }),
|
||||
this.countPendingReportDetails(where),
|
||||
]);
|
||||
return { items, total, page, pageSize };
|
||||
return { items, total, page, pageSize, pendingReportDetailTotal };
|
||||
}
|
||||
|
||||
private async countPendingReportDetails(where: Prisma.SmsSignatureWhereInput) {
|
||||
const signatures = await this.prisma.smsSignature.findMany({
|
||||
where: { AND: [where, { auditStatus: 'approved', pendingReport: true }] },
|
||||
select: {
|
||||
id: true,
|
||||
applicationId: true,
|
||||
materialVersion: true,
|
||||
application: { select: { status: true } },
|
||||
reportTasks: {
|
||||
where: { reportType: 'signature' },
|
||||
select: { channelId: true, carrier: true, status: true, approvalScope: true },
|
||||
},
|
||||
reportBatchItems: {
|
||||
where: { reportType: 'signature', batch: { status: { in: ['completed', 'partial_failed'] } } },
|
||||
select: { materialVersion: true, snapshot: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
const applicationIds = [
|
||||
...new Set(signatures.map((signature) => signature.applicationId).filter((id): id is string => Boolean(id))),
|
||||
];
|
||||
const routes = applicationIds.length
|
||||
? await this.prisma.channelRouteRule.findMany({
|
||||
where: { applicationId: { in: applicationIds }, status: 'active' },
|
||||
select: {
|
||||
applicationId: true,
|
||||
group: {
|
||||
select: {
|
||||
status: true,
|
||||
items: {
|
||||
select: {
|
||||
channel: { select: { id: true, carrier: true, carriers: true, status: true } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
: [];
|
||||
let total = 0;
|
||||
for (const signature of signatures) {
|
||||
if (!signature.applicationId || signature.application?.status !== 'active') continue;
|
||||
const generatedTargets = new Set<string>();
|
||||
for (const item of signature.reportBatchItems.filter(
|
||||
(entry) => entry.materialVersion === signature.materialVersion,
|
||||
)) {
|
||||
const businessKeys = isRecord(item.snapshot) ? item.snapshot.businessKeys : undefined;
|
||||
if (!Array.isArray(businessKeys)) continue;
|
||||
for (const value of businessKeys) {
|
||||
const match = typeof value === 'string' ? value.match(/:channel:([^:]+):carrier:([^:]+)$/) : null;
|
||||
if (!match) continue;
|
||||
for (const carrier of match[2].split(',').map((entry) => entry.trim()).filter(Boolean))
|
||||
generatedTargets.add(`${match[1]}:${carrier}`);
|
||||
}
|
||||
}
|
||||
const channels = [
|
||||
...new Map(
|
||||
routes
|
||||
.filter((route) => route.applicationId === signature.applicationId && route.group?.status === 'active')
|
||||
.flatMap((route) => route.group!.items.map((item) => item.channel))
|
||||
.filter((channel) => channel.status === 'active')
|
||||
.map((channel) => [channel.id, channel]),
|
||||
).values(),
|
||||
];
|
||||
for (const channel of channels) {
|
||||
for (const carrier of normalizeChannelCarriers(channel.carriers, channel.carrier)) {
|
||||
const task =
|
||||
signature.reportTasks.find(
|
||||
(candidate) => candidate.channelId === channel.id && candidate.carrier === carrier,
|
||||
) ??
|
||||
signature.reportTasks.find(
|
||||
(candidate) =>
|
||||
candidate.channelId === channel.id &&
|
||||
candidate.carrier === null &&
|
||||
candidate.approvalScope === 'legacy_channel',
|
||||
);
|
||||
if (task?.status === 'abandoned') continue;
|
||||
if (generatedTargets.has(`${channel.id}:${carrier}`) || generatedTargets.has(`${channel.id}:legacy`)) continue;
|
||||
total += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
async getSignature(id: string) {
|
||||
|
||||
Reference in New Issue
Block a user