|
|
|
|
@@ -8,6 +8,8 @@ import type {
|
|
|
|
|
CrmCustomerChildDto,
|
|
|
|
|
CrmRecordDetailDto,
|
|
|
|
|
CrmRecordInput,
|
|
|
|
|
CrmLifecycleStage,
|
|
|
|
|
CrmRecordRollupsDto,
|
|
|
|
|
CrmRecordStatus,
|
|
|
|
|
CrmRecordSummaryDto,
|
|
|
|
|
} from "@mrp/shared/dist/crm/types.js";
|
|
|
|
|
@@ -25,6 +27,11 @@ function mapSummary(record: Customer | Vendor): CrmRecordSummaryDto {
|
|
|
|
|
state: record.state,
|
|
|
|
|
country: record.country,
|
|
|
|
|
status: record.status as CrmRecordStatus,
|
|
|
|
|
lifecycleStage: record.lifecycleStage as CrmLifecycleStage,
|
|
|
|
|
preferredAccount: record.preferredAccount,
|
|
|
|
|
strategicAccount: record.strategicAccount,
|
|
|
|
|
requiresApproval: record.requiresApproval,
|
|
|
|
|
blockedAccount: record.blockedAccount,
|
|
|
|
|
updatedAt: record.updatedAt.toISOString(),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
@@ -43,6 +50,12 @@ function mapDetail(record: Customer | Vendor): CrmRecordDetailDto {
|
|
|
|
|
|
|
|
|
|
type CustomerSummaryRecord = Customer & {
|
|
|
|
|
parentCustomer: Pick<Customer, "id" | "name"> | null;
|
|
|
|
|
_count: {
|
|
|
|
|
contactEntries: number;
|
|
|
|
|
contacts: number;
|
|
|
|
|
childCustomers: number;
|
|
|
|
|
};
|
|
|
|
|
contactEntries: Array<Pick<ContactEntryWithAuthor, "contactAt">>;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
type CustomerDetailedRecord = Customer & {
|
|
|
|
|
@@ -57,6 +70,14 @@ type VendorDetailedRecord = Vendor & {
|
|
|
|
|
contacts: ContactRecord[];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
type VendorSummaryRecord = Vendor & {
|
|
|
|
|
_count: {
|
|
|
|
|
contactEntries: number;
|
|
|
|
|
contacts: number;
|
|
|
|
|
};
|
|
|
|
|
contactEntries: Array<Pick<ContactEntryWithAuthor, "contactAt">>;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
type ContactRecord = {
|
|
|
|
|
id: string;
|
|
|
|
|
fullName: string;
|
|
|
|
|
@@ -75,16 +96,39 @@ function mapCustomerChild(record: Pick<Customer, "id" | "name" | "status">): Crm
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function mapCustomerSummary(record: CustomerSummaryRecord): CrmRecordSummaryDto {
|
|
|
|
|
function mapRollups(input: {
|
|
|
|
|
lastContactAt?: Date | null;
|
|
|
|
|
contactHistoryCount: number;
|
|
|
|
|
contactCount: number;
|
|
|
|
|
attachmentCount: number;
|
|
|
|
|
childCustomerCount?: number;
|
|
|
|
|
}): CrmRecordRollupsDto {
|
|
|
|
|
return {
|
|
|
|
|
lastContactAt: input.lastContactAt ? input.lastContactAt.toISOString() : null,
|
|
|
|
|
contactHistoryCount: input.contactHistoryCount,
|
|
|
|
|
contactCount: input.contactCount,
|
|
|
|
|
attachmentCount: input.attachmentCount,
|
|
|
|
|
childCustomerCount: input.childCustomerCount,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function mapCustomerSummary(record: CustomerSummaryRecord, attachmentCount: number): CrmRecordSummaryDto {
|
|
|
|
|
return {
|
|
|
|
|
...mapSummary(record),
|
|
|
|
|
isReseller: record.isReseller,
|
|
|
|
|
parentCustomerId: record.parentCustomer?.id ?? null,
|
|
|
|
|
parentCustomerName: record.parentCustomer?.name ?? null,
|
|
|
|
|
rollups: mapRollups({
|
|
|
|
|
lastContactAt: record.contactEntries[0]?.contactAt ?? null,
|
|
|
|
|
contactHistoryCount: record._count.contactEntries,
|
|
|
|
|
contactCount: record._count.contacts,
|
|
|
|
|
attachmentCount,
|
|
|
|
|
childCustomerCount: record._count.childCustomers,
|
|
|
|
|
}),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function mapCustomerDetail(record: CustomerDetailedRecord): CrmRecordDetailDto {
|
|
|
|
|
function mapCustomerDetail(record: CustomerDetailedRecord, attachmentCount: number): CrmRecordDetailDto {
|
|
|
|
|
return {
|
|
|
|
|
...mapDetailedRecord(record),
|
|
|
|
|
isReseller: record.isReseller,
|
|
|
|
|
@@ -96,7 +140,19 @@ function mapCustomerDetail(record: CustomerDetailedRecord): CrmRecordDetailDto {
|
|
|
|
|
currencyCode: record.currencyCode,
|
|
|
|
|
taxExempt: record.taxExempt,
|
|
|
|
|
creditHold: record.creditHold,
|
|
|
|
|
lifecycleStage: record.lifecycleStage as CrmLifecycleStage,
|
|
|
|
|
preferredAccount: record.preferredAccount,
|
|
|
|
|
strategicAccount: record.strategicAccount,
|
|
|
|
|
requiresApproval: record.requiresApproval,
|
|
|
|
|
blockedAccount: record.blockedAccount,
|
|
|
|
|
contacts: record.contacts.map(mapCrmContact),
|
|
|
|
|
rollups: mapRollups({
|
|
|
|
|
lastContactAt: record.contactEntries[0]?.contactAt ?? null,
|
|
|
|
|
contactHistoryCount: record.contactEntries.length,
|
|
|
|
|
contactCount: record.contacts.length,
|
|
|
|
|
attachmentCount,
|
|
|
|
|
childCustomerCount: record.childCustomers.length,
|
|
|
|
|
}),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -112,14 +168,37 @@ function mapCrmContact(record: ContactRecord): CrmContactDto {
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function mapVendorDetail(record: VendorDetailedRecord): CrmRecordDetailDto {
|
|
|
|
|
function mapVendorSummary(record: VendorSummaryRecord, attachmentCount: number): CrmRecordSummaryDto {
|
|
|
|
|
return {
|
|
|
|
|
...mapSummary(record),
|
|
|
|
|
rollups: mapRollups({
|
|
|
|
|
lastContactAt: record.contactEntries[0]?.contactAt ?? null,
|
|
|
|
|
contactHistoryCount: record._count.contactEntries,
|
|
|
|
|
contactCount: record._count.contacts,
|
|
|
|
|
attachmentCount,
|
|
|
|
|
}),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function mapVendorDetail(record: VendorDetailedRecord, attachmentCount: number): CrmRecordDetailDto {
|
|
|
|
|
return {
|
|
|
|
|
...mapDetailedRecord(record),
|
|
|
|
|
paymentTerms: record.paymentTerms,
|
|
|
|
|
currencyCode: record.currencyCode,
|
|
|
|
|
taxExempt: record.taxExempt,
|
|
|
|
|
creditHold: record.creditHold,
|
|
|
|
|
lifecycleStage: record.lifecycleStage as CrmLifecycleStage,
|
|
|
|
|
preferredAccount: record.preferredAccount,
|
|
|
|
|
strategicAccount: record.strategicAccount,
|
|
|
|
|
requiresApproval: record.requiresApproval,
|
|
|
|
|
blockedAccount: record.blockedAccount,
|
|
|
|
|
contacts: record.contacts.map(mapCrmContact),
|
|
|
|
|
rollups: mapRollups({
|
|
|
|
|
lastContactAt: record.contactEntries[0]?.contactAt ?? null,
|
|
|
|
|
contactHistoryCount: record.contactEntries.length,
|
|
|
|
|
contactCount: record.contacts.length,
|
|
|
|
|
attachmentCount,
|
|
|
|
|
}),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -177,15 +256,50 @@ function mapDetailedRecord(record: DetailedRecord): CrmRecordDetailDto {
|
|
|
|
|
interface CrmListFilters {
|
|
|
|
|
query?: string;
|
|
|
|
|
status?: CrmRecordStatus;
|
|
|
|
|
lifecycleStage?: CrmLifecycleStage;
|
|
|
|
|
state?: string;
|
|
|
|
|
flag?: "PREFERRED" | "STRATEGIC" | "REQUIRES_APPROVAL" | "BLOCKED";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function getAttachmentCountMap(ownerType: string, ownerIds: string[]) {
|
|
|
|
|
if (ownerIds.length === 0) {
|
|
|
|
|
return new Map<string, number>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const groupedAttachments = await prisma.fileAttachment.groupBy({
|
|
|
|
|
by: ["ownerId"],
|
|
|
|
|
where: {
|
|
|
|
|
ownerType,
|
|
|
|
|
ownerId: {
|
|
|
|
|
in: ownerIds,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
_count: {
|
|
|
|
|
_all: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return new Map(groupedAttachments.map((entry) => [entry.ownerId, entry._count._all]));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function buildWhereClause(filters: CrmListFilters) {
|
|
|
|
|
const trimmedQuery = filters.query?.trim();
|
|
|
|
|
const trimmedState = filters.state?.trim();
|
|
|
|
|
const flagFilter =
|
|
|
|
|
filters.flag === "PREFERRED"
|
|
|
|
|
? { preferredAccount: true }
|
|
|
|
|
: filters.flag === "STRATEGIC"
|
|
|
|
|
? { strategicAccount: true }
|
|
|
|
|
: filters.flag === "REQUIRES_APPROVAL"
|
|
|
|
|
? { requiresApproval: true }
|
|
|
|
|
: filters.flag === "BLOCKED"
|
|
|
|
|
? { blockedAccount: true }
|
|
|
|
|
: {};
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
...(filters.status ? { status: filters.status } : {}),
|
|
|
|
|
...(filters.lifecycleStage ? { lifecycleStage: filters.lifecycleStage } : {}),
|
|
|
|
|
...flagFilter,
|
|
|
|
|
...(trimmedState ? { state: { contains: trimmedState } } : {}),
|
|
|
|
|
...(trimmedQuery
|
|
|
|
|
? {
|
|
|
|
|
@@ -213,11 +327,28 @@ export async function listCustomers(filters: CrmListFilters = {}) {
|
|
|
|
|
name: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
contactEntries: {
|
|
|
|
|
select: {
|
|
|
|
|
contactAt: true,
|
|
|
|
|
},
|
|
|
|
|
orderBy: {
|
|
|
|
|
contactAt: "desc",
|
|
|
|
|
},
|
|
|
|
|
take: 1,
|
|
|
|
|
},
|
|
|
|
|
_count: {
|
|
|
|
|
select: {
|
|
|
|
|
contactEntries: true,
|
|
|
|
|
contacts: true,
|
|
|
|
|
childCustomers: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
orderBy: { name: "asc" },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return customers.map(mapCustomerSummary);
|
|
|
|
|
const attachmentCountMap = await getAttachmentCountMap("crm-customer", customers.map((customer) => customer.id));
|
|
|
|
|
return customers.map((customer) => mapCustomerSummary(customer, attachmentCountMap.get(customer.id) ?? 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function getCustomerById(customerId: string) {
|
|
|
|
|
@@ -252,7 +383,18 @@ export async function getCustomerById(customerId: string) {
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return customer ? mapCustomerDetail(customer) : null;
|
|
|
|
|
if (!customer) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const attachmentCount = await prisma.fileAttachment.count({
|
|
|
|
|
where: {
|
|
|
|
|
ownerType: "crm-customer",
|
|
|
|
|
ownerId: customerId,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return mapCustomerDetail(customer, attachmentCount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function createCustomer(payload: CrmRecordInput) {
|
|
|
|
|
@@ -279,6 +421,7 @@ export async function createCustomer(payload: CrmRecordInput) {
|
|
|
|
|
country: payload.country,
|
|
|
|
|
status: payload.status,
|
|
|
|
|
notes: payload.notes,
|
|
|
|
|
lifecycleStage: payload.lifecycleStage ?? "ACTIVE",
|
|
|
|
|
isReseller: payload.isReseller ?? false,
|
|
|
|
|
resellerDiscountPercent: payload.resellerDiscountPercent ?? 0,
|
|
|
|
|
parentCustomerId: payload.parentCustomerId ?? null,
|
|
|
|
|
@@ -286,6 +429,10 @@ export async function createCustomer(payload: CrmRecordInput) {
|
|
|
|
|
currencyCode: payload.currencyCode ?? "USD",
|
|
|
|
|
taxExempt: payload.taxExempt ?? false,
|
|
|
|
|
creditHold: payload.creditHold ?? false,
|
|
|
|
|
preferredAccount: payload.preferredAccount ?? false,
|
|
|
|
|
strategicAccount: payload.strategicAccount ?? false,
|
|
|
|
|
requiresApproval: payload.requiresApproval ?? false,
|
|
|
|
|
blockedAccount: payload.blockedAccount ?? false,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
@@ -300,7 +447,19 @@ export async function createCustomer(payload: CrmRecordInput) {
|
|
|
|
|
currencyCode: customer.currencyCode,
|
|
|
|
|
taxExempt: customer.taxExempt,
|
|
|
|
|
creditHold: customer.creditHold,
|
|
|
|
|
lifecycleStage: customer.lifecycleStage as CrmLifecycleStage,
|
|
|
|
|
preferredAccount: customer.preferredAccount,
|
|
|
|
|
strategicAccount: customer.strategicAccount,
|
|
|
|
|
requiresApproval: customer.requiresApproval,
|
|
|
|
|
blockedAccount: customer.blockedAccount,
|
|
|
|
|
contacts: [],
|
|
|
|
|
rollups: mapRollups({
|
|
|
|
|
lastContactAt: null,
|
|
|
|
|
contactHistoryCount: 0,
|
|
|
|
|
contactCount: 0,
|
|
|
|
|
attachmentCount: 0,
|
|
|
|
|
childCustomerCount: 0,
|
|
|
|
|
}),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -341,6 +500,7 @@ export async function updateCustomer(customerId: string, payload: CrmRecordInput
|
|
|
|
|
country: payload.country,
|
|
|
|
|
status: payload.status,
|
|
|
|
|
notes: payload.notes,
|
|
|
|
|
lifecycleStage: payload.lifecycleStage ?? "ACTIVE",
|
|
|
|
|
isReseller: payload.isReseller ?? false,
|
|
|
|
|
resellerDiscountPercent: payload.resellerDiscountPercent ?? 0,
|
|
|
|
|
parentCustomerId: payload.parentCustomerId ?? null,
|
|
|
|
|
@@ -348,6 +508,10 @@ export async function updateCustomer(customerId: string, payload: CrmRecordInput
|
|
|
|
|
currencyCode: payload.currencyCode ?? "USD",
|
|
|
|
|
taxExempt: payload.taxExempt ?? false,
|
|
|
|
|
creditHold: payload.creditHold ?? false,
|
|
|
|
|
preferredAccount: payload.preferredAccount ?? false,
|
|
|
|
|
strategicAccount: payload.strategicAccount ?? false,
|
|
|
|
|
requiresApproval: payload.requiresApproval ?? false,
|
|
|
|
|
blockedAccount: payload.blockedAccount ?? false,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
@@ -362,17 +526,47 @@ export async function updateCustomer(customerId: string, payload: CrmRecordInput
|
|
|
|
|
currencyCode: customer.currencyCode,
|
|
|
|
|
taxExempt: customer.taxExempt,
|
|
|
|
|
creditHold: customer.creditHold,
|
|
|
|
|
lifecycleStage: customer.lifecycleStage as CrmLifecycleStage,
|
|
|
|
|
preferredAccount: customer.preferredAccount,
|
|
|
|
|
strategicAccount: customer.strategicAccount,
|
|
|
|
|
requiresApproval: customer.requiresApproval,
|
|
|
|
|
blockedAccount: customer.blockedAccount,
|
|
|
|
|
contacts: [],
|
|
|
|
|
rollups: mapRollups({
|
|
|
|
|
lastContactAt: null,
|
|
|
|
|
contactHistoryCount: 0,
|
|
|
|
|
contactCount: 0,
|
|
|
|
|
attachmentCount: 0,
|
|
|
|
|
childCustomerCount: 0,
|
|
|
|
|
}),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function listVendors(filters: CrmListFilters = {}) {
|
|
|
|
|
const vendors = await prisma.vendor.findMany({
|
|
|
|
|
where: buildWhereClause(filters),
|
|
|
|
|
include: {
|
|
|
|
|
contactEntries: {
|
|
|
|
|
select: {
|
|
|
|
|
contactAt: true,
|
|
|
|
|
},
|
|
|
|
|
orderBy: {
|
|
|
|
|
contactAt: "desc",
|
|
|
|
|
},
|
|
|
|
|
take: 1,
|
|
|
|
|
},
|
|
|
|
|
_count: {
|
|
|
|
|
select: {
|
|
|
|
|
contactEntries: true,
|
|
|
|
|
contacts: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
orderBy: { name: "asc" },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return vendors.map(mapSummary);
|
|
|
|
|
const attachmentCountMap = await getAttachmentCountMap("crm-vendor", vendors.map((vendor) => vendor.id));
|
|
|
|
|
return vendors.map((vendor) => mapVendorSummary(vendor, attachmentCountMap.get(vendor.id) ?? 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function listCustomerHierarchyOptions(excludeCustomerId?: string) {
|
|
|
|
|
@@ -422,7 +616,18 @@ export async function getVendorById(vendorId: string) {
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return vendor ? mapVendorDetail(vendor) : null;
|
|
|
|
|
if (!vendor) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const attachmentCount = await prisma.fileAttachment.count({
|
|
|
|
|
where: {
|
|
|
|
|
ownerType: "crm-vendor",
|
|
|
|
|
ownerId: vendorId,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return mapVendorDetail(vendor, attachmentCount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function createVendor(payload: CrmRecordInput) {
|
|
|
|
|
@@ -438,11 +643,16 @@ export async function createVendor(payload: CrmRecordInput) {
|
|
|
|
|
postalCode: payload.postalCode,
|
|
|
|
|
country: payload.country,
|
|
|
|
|
status: payload.status,
|
|
|
|
|
lifecycleStage: payload.lifecycleStage ?? "ACTIVE",
|
|
|
|
|
notes: payload.notes,
|
|
|
|
|
paymentTerms: payload.paymentTerms ?? null,
|
|
|
|
|
currencyCode: payload.currencyCode ?? "USD",
|
|
|
|
|
taxExempt: payload.taxExempt ?? false,
|
|
|
|
|
creditHold: payload.creditHold ?? false,
|
|
|
|
|
preferredAccount: payload.preferredAccount ?? false,
|
|
|
|
|
strategicAccount: payload.strategicAccount ?? false,
|
|
|
|
|
requiresApproval: payload.requiresApproval ?? false,
|
|
|
|
|
blockedAccount: payload.blockedAccount ?? false,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
@@ -452,7 +662,18 @@ export async function createVendor(payload: CrmRecordInput) {
|
|
|
|
|
currencyCode: vendor.currencyCode,
|
|
|
|
|
taxExempt: vendor.taxExempt,
|
|
|
|
|
creditHold: vendor.creditHold,
|
|
|
|
|
lifecycleStage: vendor.lifecycleStage as CrmLifecycleStage,
|
|
|
|
|
preferredAccount: vendor.preferredAccount,
|
|
|
|
|
strategicAccount: vendor.strategicAccount,
|
|
|
|
|
requiresApproval: vendor.requiresApproval,
|
|
|
|
|
blockedAccount: vendor.blockedAccount,
|
|
|
|
|
contacts: [],
|
|
|
|
|
rollups: mapRollups({
|
|
|
|
|
lastContactAt: null,
|
|
|
|
|
contactHistoryCount: 0,
|
|
|
|
|
contactCount: 0,
|
|
|
|
|
attachmentCount: 0,
|
|
|
|
|
}),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -478,11 +699,16 @@ export async function updateVendor(vendorId: string, payload: CrmRecordInput) {
|
|
|
|
|
postalCode: payload.postalCode,
|
|
|
|
|
country: payload.country,
|
|
|
|
|
status: payload.status,
|
|
|
|
|
lifecycleStage: payload.lifecycleStage ?? "ACTIVE",
|
|
|
|
|
notes: payload.notes,
|
|
|
|
|
paymentTerms: payload.paymentTerms ?? null,
|
|
|
|
|
currencyCode: payload.currencyCode ?? "USD",
|
|
|
|
|
taxExempt: payload.taxExempt ?? false,
|
|
|
|
|
creditHold: payload.creditHold ?? false,
|
|
|
|
|
preferredAccount: payload.preferredAccount ?? false,
|
|
|
|
|
strategicAccount: payload.strategicAccount ?? false,
|
|
|
|
|
requiresApproval: payload.requiresApproval ?? false,
|
|
|
|
|
blockedAccount: payload.blockedAccount ?? false,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
@@ -492,7 +718,18 @@ export async function updateVendor(vendorId: string, payload: CrmRecordInput) {
|
|
|
|
|
currencyCode: vendor.currencyCode,
|
|
|
|
|
taxExempt: vendor.taxExempt,
|
|
|
|
|
creditHold: vendor.creditHold,
|
|
|
|
|
lifecycleStage: vendor.lifecycleStage as CrmLifecycleStage,
|
|
|
|
|
preferredAccount: vendor.preferredAccount,
|
|
|
|
|
strategicAccount: vendor.strategicAccount,
|
|
|
|
|
requiresApproval: vendor.requiresApproval,
|
|
|
|
|
blockedAccount: vendor.blockedAccount,
|
|
|
|
|
contacts: [],
|
|
|
|
|
rollups: mapRollups({
|
|
|
|
|
lastContactAt: null,
|
|
|
|
|
contactHistoryCount: 0,
|
|
|
|
|
contactCount: 0,
|
|
|
|
|
attachmentCount: 0,
|
|
|
|
|
}),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|