Adding registration date and multiple addresses for contacts and leads.
This commit is contained in:
@@ -12,3 +12,23 @@ export function toJsonCustomFields(
|
||||
): Prisma.InputJsonValue {
|
||||
return (value ?? {}) as Prisma.InputJsonValue;
|
||||
}
|
||||
|
||||
export function asAddresses(value: unknown): string[] {
|
||||
if (!Array.isArray(value)) return [];
|
||||
const out: string[] = [];
|
||||
for (const item of value) {
|
||||
const text = String(item ?? '').trim();
|
||||
if (text && !out.includes(text)) out.push(text);
|
||||
if (out.length >= 20) break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
export function toJsonAddresses(value?: string[] | null): Prisma.InputJsonValue {
|
||||
return asAddresses(value ?? []);
|
||||
}
|
||||
|
||||
/** Collect address-like cells from an excel row into a unique list. */
|
||||
export function collectAddresses(...parts: Array<string | undefined | null>): string[] {
|
||||
return asAddresses(parts.map((p) => (p ?? '').trim()).filter(Boolean));
|
||||
}
|
||||
|
||||
@@ -4,9 +4,13 @@ import { PERSON_MOOD_LABELS, PERSON_MOODS } from '@mento/shared';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import type { Actor } from '../common/record-scope';
|
||||
import { ownerWhere, resolveOwnerId } from '../common/record-scope';
|
||||
import {
|
||||
collectAddresses,
|
||||
} from '../common/custom-fields';
|
||||
import {
|
||||
formatJalaliDate,
|
||||
parseExcelMapping,
|
||||
parseJalaliDateTime,
|
||||
previewExcel,
|
||||
readMappedRows,
|
||||
writeXlsx,
|
||||
@@ -73,8 +77,17 @@ const PERSON_ALIASES: Record<string, string> = {
|
||||
گروهمشتری: 'group',
|
||||
آدرس: 'address',
|
||||
آدرس1: 'address',
|
||||
آدرساصلی: 'address',
|
||||
address: 'address',
|
||||
address2: 'address2',
|
||||
آدرس۲: 'address2',
|
||||
آدرس2: 'address2',
|
||||
آدرس_1: 'address2',
|
||||
آدرسدوم: 'address2',
|
||||
آدرسمنزل: 'homeAddress',
|
||||
آدرمنزل: 'homeAddress',
|
||||
آدرسخانه: 'homeAddress',
|
||||
homeaddress: 'homeAddress',
|
||||
کدپستی: 'postalCode',
|
||||
کدپستی1: 'postalCode',
|
||||
استانفیلدپیشفرض: 'province',
|
||||
@@ -93,8 +106,13 @@ const PERSON_ALIASES: Record<string, string> = {
|
||||
type: '_type',
|
||||
_type: '_type',
|
||||
آیدیاینستاگرام: 'instagram',
|
||||
اینستاگرام: 'instagram',
|
||||
پیجاینستاگرام: 'instagram',
|
||||
instagram: 'instagram',
|
||||
معرف: 'referrer',
|
||||
سایتهایمشتری: 'website',
|
||||
تاریخثبت: 'registeredAt',
|
||||
registeredat: 'registeredAt',
|
||||
شمارهفکس: 'fax',
|
||||
تلفن2: 'phone2',
|
||||
تلفنهایدیگرمشتری: 'otherPhones',
|
||||
@@ -128,6 +146,11 @@ const PERSON_FIELDS = [
|
||||
{ key: 'position', label: 'سمت' },
|
||||
{ key: 'companyName', label: 'شرکت' },
|
||||
{ key: 'ownerName', label: 'کارشناس فروش' },
|
||||
{ key: 'address', label: 'آدرس' },
|
||||
{ key: 'address2', label: 'آدرس ۲' },
|
||||
{ key: 'homeAddress', label: 'آدرس منزل' },
|
||||
{ key: 'instagram', label: 'اینستاگرام' },
|
||||
{ key: 'registeredAt', label: 'تاریخ ثبت' },
|
||||
{ key: 'notes', label: 'یادداشت' },
|
||||
{ key: 'mood', label: 'وضعیت مشتری' },
|
||||
];
|
||||
@@ -218,6 +241,7 @@ const CUSTOM_KEYS = [
|
||||
'province',
|
||||
'city',
|
||||
'address',
|
||||
'address2',
|
||||
'nationalId',
|
||||
'birthDate',
|
||||
'group',
|
||||
@@ -279,20 +303,20 @@ export class ContactsExcelService {
|
||||
birthDate: extra.birthDate ?? '',
|
||||
mood: extra.group || PERSON_MOOD_LABELS[p.mood || 'newcomer'],
|
||||
otherPhones: extra.otherPhones ?? '',
|
||||
address: extra.address ?? '',
|
||||
website: extra.website ?? '',
|
||||
address: p.addresses[0] ?? extra.address ?? '',
|
||||
website: p.website ?? extra.website ?? '',
|
||||
otherEmails: extra.otherEmails ?? '',
|
||||
position2: p.position ?? extra.position ?? '',
|
||||
city2: extra.city ?? '',
|
||||
code2: extra.customerCode ?? '',
|
||||
group2: extra.group ?? '',
|
||||
address2: extra.address ?? '',
|
||||
address2: p.addresses[1] ?? extra.address ?? '',
|
||||
phone2: extra.phone2 ?? p.phone ?? '',
|
||||
postalCode2: extra.postalCode ?? '',
|
||||
referrer: extra.referrer ?? '',
|
||||
homeAddress: extra.homeAddress ?? '',
|
||||
referrer: extra.referrer ?? p.referrer ?? '',
|
||||
homeAddress: p.addresses[2] ?? extra.homeAddress ?? '',
|
||||
birthDate2: extra.birthDate ?? '',
|
||||
instagram: extra.instagram ?? '',
|
||||
instagram: p.instagram ?? extra.instagram ?? '',
|
||||
group: extra.group ?? '',
|
||||
colleagueContact: extra.colleagueContact ?? '',
|
||||
previousCompany: extra.previousCompany ?? '',
|
||||
@@ -388,10 +412,33 @@ export class ContactsExcelService {
|
||||
|
||||
const customFields: Record<string, string> = {};
|
||||
for (const key of CUSTOM_KEYS) {
|
||||
if (
|
||||
key === 'address' ||
|
||||
key === 'address2' ||
|
||||
key === 'homeAddress' ||
|
||||
key === 'instagram' ||
|
||||
key === 'website'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
const value = row[key]?.trim();
|
||||
if (value) customFields[key] = value;
|
||||
}
|
||||
|
||||
const addresses = collectAddresses(
|
||||
row.address,
|
||||
row.address2,
|
||||
row.homeAddress,
|
||||
);
|
||||
const registeredAt =
|
||||
parseJalaliDateTime(row.registeredAt) ??
|
||||
(() => {
|
||||
const raw = row.registeredAt?.trim();
|
||||
if (!raw) return null;
|
||||
const d = new Date(raw);
|
||||
return Number.isNaN(d.getTime()) ? null : d;
|
||||
})();
|
||||
|
||||
try {
|
||||
await this.people.create(actor, {
|
||||
firstName: names.firstName,
|
||||
@@ -400,11 +447,15 @@ export class ContactsExcelService {
|
||||
phone: row.phone || row.phone2 || undefined,
|
||||
mobile: row.mobile || undefined,
|
||||
position: row.position || undefined,
|
||||
website: row.website || undefined,
|
||||
instagram: row.instagram || undefined,
|
||||
addresses,
|
||||
notes: row.notes || undefined,
|
||||
mood: parseMood(row.mood) ?? parseMood(row.group),
|
||||
companyId,
|
||||
ownerId: resolveOwnerId(actor, ownerId ?? null),
|
||||
customFields,
|
||||
registeredAt: registeredAt?.toISOString() ?? null,
|
||||
});
|
||||
result.created += 1;
|
||||
if (ownerMissing) {
|
||||
|
||||
@@ -181,11 +181,21 @@ export class CreatePersonDto {
|
||||
@MaxLength(300)
|
||||
website?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(200)
|
||||
instagram?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(120)
|
||||
referrer?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
@IsString({ each: true })
|
||||
addresses?: string[];
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(2000)
|
||||
@@ -213,6 +223,11 @@ export class CreatePersonDto {
|
||||
@ValidateIf((_, v) => v !== '' && v != null)
|
||||
@IsString()
|
||||
ownerId?: string | null;
|
||||
|
||||
/** فقط برای ایمپورت اکسل — تاریخ ثبت مبدأ */
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
registeredAt?: string | null;
|
||||
}
|
||||
|
||||
export class UpdatePersonDto {
|
||||
@@ -251,11 +266,21 @@ export class UpdatePersonDto {
|
||||
@MaxLength(300)
|
||||
website?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(200)
|
||||
instagram?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(120)
|
||||
referrer?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
@IsString({ each: true })
|
||||
addresses?: string[];
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(2000)
|
||||
|
||||
@@ -15,7 +15,9 @@ import { PrismaService } from '../prisma/prisma.service';
|
||||
import { CompaniesService } from './companies.service';
|
||||
import { emptyToNull, normalizeEmail, normalizePhone } from './normalize';
|
||||
import {
|
||||
asAddresses,
|
||||
asCustomFields,
|
||||
toJsonAddresses,
|
||||
toJsonCustomFields,
|
||||
} from '../common/custom-fields';
|
||||
import {
|
||||
@@ -47,7 +49,9 @@ type PersonRow = {
|
||||
mobile: string | null;
|
||||
position: string | null;
|
||||
website: string | null;
|
||||
instagram: string | null;
|
||||
referrer: string | null;
|
||||
addresses: unknown;
|
||||
notes: string | null;
|
||||
mood: PersonMood;
|
||||
tags: string[];
|
||||
@@ -138,6 +142,7 @@ export class PeopleService {
|
||||
await this.companies.ensureInOrg(actor.organizationId, companyId, actor);
|
||||
}
|
||||
|
||||
const registeredAt = dto.registeredAt ? new Date(dto.registeredAt) : null;
|
||||
const data: Prisma.PersonUncheckedCreateInput = {
|
||||
organizationId: actor.organizationId,
|
||||
firstName: (dto.firstName ?? '').trim(),
|
||||
@@ -147,13 +152,18 @@ export class PeopleService {
|
||||
mobile: normalizePhone(dto.mobile),
|
||||
position: emptyToNull(dto.position),
|
||||
website: emptyToNull(dto.website),
|
||||
instagram: emptyToNull(dto.instagram),
|
||||
referrer: emptyToNull(dto.referrer),
|
||||
addresses: toJsonAddresses(dto.addresses),
|
||||
notes: emptyToNull(dto.notes),
|
||||
mood: dto.mood ?? 'newcomer',
|
||||
tags: normalizeTags(dto.tags),
|
||||
companyId,
|
||||
ownerId: resolveOwnerId(actor, dto.ownerId),
|
||||
customFields: toJsonCustomFields(dto.customFields),
|
||||
...(registeredAt && !Number.isNaN(registeredAt.getTime())
|
||||
? { createdAt: registeredAt }
|
||||
: {}),
|
||||
};
|
||||
await this.assertNoDuplicate(actor.organizationId, data);
|
||||
|
||||
@@ -202,7 +212,9 @@ export class PeopleService {
|
||||
if ('mobile' in dto) data.mobile = normalizePhone(dto.mobile);
|
||||
if ('position' in dto) data.position = emptyToNull(dto.position);
|
||||
if ('website' in dto) data.website = emptyToNull(dto.website);
|
||||
if ('instagram' in dto) data.instagram = emptyToNull(dto.instagram);
|
||||
if ('referrer' in dto) data.referrer = emptyToNull(dto.referrer);
|
||||
if ('addresses' in dto) data.addresses = toJsonAddresses(dto.addresses);
|
||||
if ('notes' in dto) data.notes = emptyToNull(dto.notes);
|
||||
if (dto.mood !== undefined) data.mood = dto.mood;
|
||||
if ('tags' in dto) data.tags = normalizeTags(dto.tags);
|
||||
@@ -295,7 +307,18 @@ export class PeopleService {
|
||||
mobile: row.mobile,
|
||||
position: row.position,
|
||||
website: row.website,
|
||||
instagram: row.instagram,
|
||||
referrer: row.referrer,
|
||||
addresses: (() => {
|
||||
const fromCol = asAddresses(row.addresses);
|
||||
if (fromCol.length) return fromCol;
|
||||
const extra = asCustomFields(row.customFields);
|
||||
return asAddresses(
|
||||
[extra.address, extra.homeAddress, extra.address2]
|
||||
.map((v) => (typeof v === 'string' ? v : ''))
|
||||
.filter(Boolean),
|
||||
);
|
||||
})(),
|
||||
notes: row.notes,
|
||||
mood: row.mood,
|
||||
tags: row.tags ?? [],
|
||||
|
||||
@@ -21,6 +21,8 @@ export class CreateLeadDto {
|
||||
@IsOptional() @IsString() phone?: string;
|
||||
@IsOptional() @IsString() city?: string;
|
||||
@IsOptional() @IsString() region?: string;
|
||||
@IsOptional() @IsString() instagram?: string;
|
||||
@IsOptional() @IsArray() @IsString({ each: true }) addresses?: string[];
|
||||
@IsOptional() @IsString() trade?: string;
|
||||
@IsOptional() @IsString() source?: string;
|
||||
@IsOptional() @IsString() notes?: string;
|
||||
@@ -28,6 +30,8 @@ export class CreateLeadDto {
|
||||
@IsOptional() @IsString() stageId?: string;
|
||||
@IsOptional() @IsString() assigneeId?: string | null;
|
||||
@IsOptional() @IsString() nextFollowUpAt?: string | null;
|
||||
/** فقط برای ایمپورت اکسل — تاریخ ثبت مبدأ */
|
||||
@IsOptional() @IsString() registeredAt?: string | null;
|
||||
}
|
||||
|
||||
export class UpdateLeadDto {
|
||||
@@ -37,6 +41,8 @@ export class UpdateLeadDto {
|
||||
@IsOptional() @IsString() phone?: string | null;
|
||||
@IsOptional() @IsString() city?: string | null;
|
||||
@IsOptional() @IsString() region?: string | null;
|
||||
@IsOptional() @IsString() instagram?: string | null;
|
||||
@IsOptional() @IsArray() @IsString({ each: true }) addresses?: string[];
|
||||
@IsOptional() @IsString() trade?: string | null;
|
||||
@IsOptional() @IsString() source?: string | null;
|
||||
@IsOptional() @IsString() notes?: string | null;
|
||||
|
||||
@@ -5,6 +5,7 @@ import type { LeadImportJobDto } from '@mento/shared';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import {
|
||||
parseExcelMapping,
|
||||
parseJalaliDateTime,
|
||||
previewExcel,
|
||||
readMappedRows,
|
||||
type ExcelFieldOption,
|
||||
@@ -40,6 +41,23 @@ const LEAD_ALIASES: Record<string, string> = {
|
||||
region: 'region',
|
||||
منطقه: 'region',
|
||||
محله: 'region',
|
||||
address: 'address',
|
||||
آدرس: 'address',
|
||||
آدرساصلی: 'address',
|
||||
address2: 'address2',
|
||||
آدرس۲: 'address2',
|
||||
آدرس2: 'address2',
|
||||
آدرسدوم: 'address2',
|
||||
homeaddress: 'homeAddress',
|
||||
آدرسمنزل: 'homeAddress',
|
||||
آدرسخانه: 'homeAddress',
|
||||
instagram: 'instagram',
|
||||
اینستاگرام: 'instagram',
|
||||
پیجاینستاگرام: 'instagram',
|
||||
آیدیاینستاگرام: 'instagram',
|
||||
registeredat: 'registeredAt',
|
||||
تاریخثبت: 'registeredAt',
|
||||
تاریخثبتمشتری: 'registeredAt',
|
||||
trade: 'trade',
|
||||
صنف: 'trade',
|
||||
رسته: 'trade',
|
||||
@@ -58,6 +76,11 @@ const LEAD_FIELDS: ExcelFieldOption[] = [
|
||||
{ key: 'phone', label: 'تلفن' },
|
||||
{ key: 'city', label: 'شهر' },
|
||||
{ key: 'region', label: 'منطقه' },
|
||||
{ key: 'address', label: 'آدرس' },
|
||||
{ key: 'address2', label: 'آدرس ۲' },
|
||||
{ key: 'homeAddress', label: 'آدرس منزل' },
|
||||
{ key: 'instagram', label: 'اینستاگرام' },
|
||||
{ key: 'registeredAt', label: 'تاریخ ثبت' },
|
||||
{ key: 'trade', label: 'صنف' },
|
||||
{ key: 'source', label: 'منبع' },
|
||||
{ key: 'notes', label: 'توضیحات' },
|
||||
@@ -237,6 +260,19 @@ export class LeadsImportService {
|
||||
}
|
||||
return '';
|
||||
};
|
||||
const registeredRaw = get(
|
||||
'registeredAt',
|
||||
'تاریخ ثبت',
|
||||
'تاریخ ثبت مشتری',
|
||||
'registeredat',
|
||||
);
|
||||
const registeredAt =
|
||||
parseJalaliDateTime(registeredRaw)?.toISOString() ??
|
||||
(() => {
|
||||
if (!registeredRaw) return '';
|
||||
const d = new Date(registeredRaw);
|
||||
return Number.isNaN(d.getTime()) ? '' : d.toISOString();
|
||||
})();
|
||||
return {
|
||||
title: get('title', 'نام', 'نام فروشگاه', 'فروشگاه', 'shop', 'name'),
|
||||
contactName: get('contactName', 'مالک', 'مسئول', 'نام مالک', 'owner'),
|
||||
@@ -244,6 +280,11 @@ export class LeadsImportService {
|
||||
phone: get('phone', 'تلفن'),
|
||||
city: get('city', 'شهر'),
|
||||
region: get('region', 'منطقه', 'محله'),
|
||||
address: get('address', 'آدرس', 'آدرس اصلی'),
|
||||
address2: get('address2', 'آدرس ۲', 'آدرس2', 'آدرس دوم'),
|
||||
homeAddress: get('homeAddress', 'آدرس منزل', 'آدرس خانه'),
|
||||
instagram: get('instagram', 'اینستاگرام', 'پیج اینستاگرام', 'آی دی اینستاگرام'),
|
||||
registeredAt,
|
||||
trade: get('trade', 'صنف', 'رسته'),
|
||||
source: get('source', 'منبع', 'منبع لید'),
|
||||
notes: get('notes', 'توضیحات', 'یادداشت'),
|
||||
|
||||
@@ -20,6 +20,11 @@ import {
|
||||
type Actor,
|
||||
elevated,
|
||||
} from '../common/record-scope';
|
||||
import {
|
||||
asAddresses,
|
||||
collectAddresses,
|
||||
toJsonAddresses,
|
||||
} from '../common/custom-fields';
|
||||
import { emptyToNull, normalizePhone } from '../contacts/normalize';
|
||||
import { LocalFileStorage } from '../storage/local-file.storage';
|
||||
import { LeadStagesService } from './lead-stages.service';
|
||||
@@ -238,6 +243,8 @@ export class LeadsService {
|
||||
phone?: string | null;
|
||||
city?: string | null;
|
||||
region?: string | null;
|
||||
instagram?: string | null;
|
||||
addresses?: string[];
|
||||
trade?: string | null;
|
||||
source?: string | null;
|
||||
notes?: string | null;
|
||||
@@ -245,6 +252,7 @@ export class LeadsService {
|
||||
stageId?: string;
|
||||
assigneeId?: string | null;
|
||||
nextFollowUpAt?: string | null;
|
||||
registeredAt?: string | null;
|
||||
},
|
||||
): Promise<LeadDto> {
|
||||
await this.stages.ensureDefaults(actor.organizationId);
|
||||
@@ -271,6 +279,7 @@ export class LeadsService {
|
||||
assigneeId = actor.userId;
|
||||
}
|
||||
|
||||
const registeredAt = dto.registeredAt ? new Date(dto.registeredAt) : null;
|
||||
const row = await this.prisma.lead.create({
|
||||
data: {
|
||||
organizationId: actor.organizationId,
|
||||
@@ -280,6 +289,8 @@ export class LeadsService {
|
||||
phone: emptyToNull(dto.phone),
|
||||
city: emptyToNull(dto.city),
|
||||
region: emptyToNull(dto.region),
|
||||
instagram: emptyToNull(dto.instagram),
|
||||
addresses: toJsonAddresses(dto.addresses),
|
||||
trade: emptyToNull(dto.trade),
|
||||
source: emptyToNull(dto.source),
|
||||
notes: emptyToNull(dto.notes),
|
||||
@@ -287,6 +298,9 @@ export class LeadsService {
|
||||
dto.estimatedValue != null
|
||||
? new Prisma.Decimal(dto.estimatedValue)
|
||||
: null,
|
||||
...(registeredAt && !Number.isNaN(registeredAt.getTime())
|
||||
? { createdAt: registeredAt }
|
||||
: {}),
|
||||
stageId,
|
||||
assigneeId,
|
||||
createdById: actor.userId,
|
||||
@@ -351,6 +365,12 @@ export class LeadsService {
|
||||
...(dto.region !== undefined
|
||||
? { region: emptyToNull(dto.region as string) }
|
||||
: {}),
|
||||
...(dto.instagram !== undefined
|
||||
? { instagram: emptyToNull(dto.instagram as string) }
|
||||
: {}),
|
||||
...(dto.addresses !== undefined
|
||||
? { addresses: toJsonAddresses(dto.addresses) }
|
||||
: {}),
|
||||
...(dto.trade !== undefined
|
||||
? { trade: emptyToNull(dto.trade as string) }
|
||||
: {}),
|
||||
@@ -717,6 +737,8 @@ export class LeadsService {
|
||||
lastName,
|
||||
mobile: lead.mobile,
|
||||
phone: lead.phone,
|
||||
instagram: lead.instagram,
|
||||
addresses: toJsonAddresses(asAddresses(lead.addresses)),
|
||||
notes: [
|
||||
lead.notes,
|
||||
lead.city ? `شهر: ${lead.city}` : null,
|
||||
@@ -727,6 +749,7 @@ export class LeadsService {
|
||||
.filter(Boolean)
|
||||
.join('\n'),
|
||||
ownerId: lead.assigneeId ?? actor.userId,
|
||||
createdAt: lead.createdAt,
|
||||
},
|
||||
});
|
||||
createdPerson = true;
|
||||
@@ -884,6 +907,11 @@ export class LeadsService {
|
||||
phone?: string;
|
||||
city?: string;
|
||||
region?: string;
|
||||
address?: string;
|
||||
address2?: string;
|
||||
homeAddress?: string;
|
||||
instagram?: string;
|
||||
registeredAt?: string;
|
||||
trade?: string;
|
||||
source?: string;
|
||||
notes?: string;
|
||||
@@ -910,6 +938,7 @@ export class LeadsService {
|
||||
if (existingPerson) return 'duplicate';
|
||||
|
||||
try {
|
||||
const registeredAt = row.registeredAt ? new Date(row.registeredAt) : null;
|
||||
const lead = await this.prisma.lead.create({
|
||||
data: {
|
||||
organizationId,
|
||||
@@ -919,11 +948,18 @@ export class LeadsService {
|
||||
phone: emptyToNull(row.phone),
|
||||
city: emptyToNull(row.city),
|
||||
region: emptyToNull(row.region),
|
||||
instagram: emptyToNull(row.instagram),
|
||||
addresses: toJsonAddresses(
|
||||
collectAddresses(row.address, row.address2, row.homeAddress),
|
||||
),
|
||||
trade: emptyToNull(row.trade),
|
||||
source: emptyToNull(row.source) ?? 'ایمپورت اکسل',
|
||||
notes: emptyToNull(row.notes),
|
||||
stageId: defaultStageId,
|
||||
createdById,
|
||||
...(registeredAt && !Number.isNaN(registeredAt.getTime())
|
||||
? { createdAt: registeredAt }
|
||||
: {}),
|
||||
},
|
||||
});
|
||||
await this.prisma.leadEvent.create({
|
||||
@@ -990,6 +1026,8 @@ export class LeadsService {
|
||||
phone: row.phone,
|
||||
city: row.city,
|
||||
region: row.region,
|
||||
instagram: row.instagram,
|
||||
addresses: asAddresses(row.addresses),
|
||||
trade: row.trade,
|
||||
source: row.source,
|
||||
notes: row.notes,
|
||||
|
||||
Reference in New Issue
Block a user