task-fic-display
This commit is contained in:
@@ -24,6 +24,10 @@ import {
|
||||
canAccessScopedCrmRecord
|
||||
} from '@/features/crm/security/server/service';
|
||||
import { generateNextDocumentCode } from '@/features/foundation/document-sequence/service';
|
||||
import {
|
||||
resolveBranchDisplays,
|
||||
resolveUserDisplays
|
||||
} from '@/features/foundation/display/server/display-resolver';
|
||||
import { getActiveOptionsByCategory } from '@/features/foundation/master-options/service';
|
||||
import { syncOpportunityPipelineStageFromQuotationStatus } from '@/features/crm/opportunities/server/service';
|
||||
import {
|
||||
@@ -130,12 +134,21 @@ function mapApprovedArtifactSummary(
|
||||
|
||||
function mapQuotationRecord(
|
||||
row: typeof crmQuotations.$inferSelect,
|
||||
options?: { approvedArtifact?: QuotationApprovedArtifactSummary | null }
|
||||
options?: {
|
||||
approvedArtifact?: QuotationApprovedArtifactSummary | null;
|
||||
branchName?: string | null;
|
||||
branchCode?: string | null;
|
||||
salesmanName?: string | null;
|
||||
createdByName?: string | null;
|
||||
updatedByName?: string | null;
|
||||
}
|
||||
): QuotationRecord {
|
||||
return {
|
||||
id: row.id,
|
||||
organizationId: row.organizationId,
|
||||
branchId: row.branchId,
|
||||
branchName: options?.branchName ?? null,
|
||||
branchCode: options?.branchCode ?? null,
|
||||
code: row.code,
|
||||
opportunityId: row.opportunityId,
|
||||
customerId: row.customerId,
|
||||
@@ -164,6 +177,7 @@ function mapQuotationRecord(
|
||||
isHotProject: row.isHotProject,
|
||||
competitor: row.competitor,
|
||||
salesmanId: row.salesmanId,
|
||||
salesmanName: options?.salesmanName ?? null,
|
||||
isSent: row.isSent,
|
||||
sentAt: row.sentAt?.toISOString() ?? null,
|
||||
sentVia: row.sentVia,
|
||||
@@ -185,7 +199,9 @@ function mapQuotationRecord(
|
||||
updatedAt: row.updatedAt.toISOString(),
|
||||
deletedAt: row.deletedAt?.toISOString() ?? null,
|
||||
createdBy: row.createdBy,
|
||||
updatedBy: row.updatedBy
|
||||
createdByName: options?.createdByName ?? null,
|
||||
updatedBy: row.updatedBy,
|
||||
updatedByName: options?.updatedByName ?? null
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1211,6 +1227,27 @@ export async function getQuotationDetail(
|
||||
accessContext?: QuotationAccessContext
|
||||
): Promise<QuotationRecord> {
|
||||
const quotation = await assertQuotationBelongsToOrganization(id, organizationId, accessContext);
|
||||
const [userDisplayMap, branchDisplayMap] = await Promise.all([
|
||||
resolveUserDisplays([
|
||||
quotation.salesmanId,
|
||||
quotation.createdBy,
|
||||
quotation.updatedBy
|
||||
]),
|
||||
resolveBranchDisplays({
|
||||
organizationId,
|
||||
branchIds: [quotation.branchId]
|
||||
})
|
||||
]);
|
||||
const branchDisplay = quotation.branchId ? (branchDisplayMap.get(quotation.branchId) ?? null) : null;
|
||||
const baseDisplayOptions = {
|
||||
branchName: branchDisplay?.name ?? null,
|
||||
branchCode: branchDisplay?.code ?? null,
|
||||
salesmanName: quotation.salesmanId
|
||||
? (userDisplayMap.get(quotation.salesmanId)?.displayName ?? null)
|
||||
: null,
|
||||
createdByName: userDisplayMap.get(quotation.createdBy)?.displayName ?? null,
|
||||
updatedByName: userDisplayMap.get(quotation.updatedBy)?.displayName ?? null
|
||||
};
|
||||
const approvedArtifactId =
|
||||
quotation.approvedArtifactId ??
|
||||
(quotation.approvedPdfUrl?.startsWith('artifact:')
|
||||
@@ -1218,7 +1255,7 @@ export async function getQuotationDetail(
|
||||
: null);
|
||||
|
||||
if (!approvedArtifactId) {
|
||||
return mapQuotationRecord(quotation);
|
||||
return mapQuotationRecord(quotation, baseDisplayOptions);
|
||||
}
|
||||
|
||||
const [artifact] = await db
|
||||
@@ -1237,19 +1274,15 @@ export async function getQuotationDetail(
|
||||
return mapQuotationRecord(quotation);
|
||||
}
|
||||
|
||||
const relatedUserIds = [artifact.generatedBy, artifact.lockedBy].filter(Boolean) as string[];
|
||||
const actorRows = relatedUserIds.length
|
||||
? await db
|
||||
.select({ id: users.id, name: users.name })
|
||||
.from(users)
|
||||
.where(inArray(users.id, relatedUserIds))
|
||||
: [];
|
||||
const actorMap = new Map(actorRows.map((row) => [row.id, row.name]));
|
||||
const artifactActorMap = await resolveUserDisplays([artifact.generatedBy, artifact.lockedBy]);
|
||||
|
||||
return mapQuotationRecord(quotation, {
|
||||
...baseDisplayOptions,
|
||||
approvedArtifact: mapApprovedArtifactSummary(artifact, {
|
||||
generatedByName: actorMap.get(artifact.generatedBy) ?? null,
|
||||
lockedByName: artifact.lockedBy ? (actorMap.get(artifact.lockedBy) ?? null) : null
|
||||
generatedByName: artifactActorMap.get(artifact.generatedBy)?.displayName ?? null,
|
||||
lockedByName: artifact.lockedBy
|
||||
? (artifactActorMap.get(artifact.lockedBy)?.displayName ?? null)
|
||||
: null
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user