NotesWhat is notes.io?

Notes brand slogan

Notes - notes.io

using PRO.Application.Infrastructor.Dtos.Application.Contact.ContactDtos;
using PRO.Application.Infrastructor.Dtos.Application.Contact.ContactTradeTypeDtos;
using PRO.SharedKernel.Domain.Application.ContactDomain.Enums;
using PRO.SharedKernel.Infrastructure.DbProvider.EFCore.Aggregates;
using System.Linq;

namespace PRO.Application.Contact.Services.Application.Contact;
public class ContactService : IContactService
{
#region Constructor
private readonly IMapper _mapper;
private readonly IWorkContext _workContext;
private readonly IContactRepository _contactRepository;
private readonly IContactTagRepository _contactTagRepository;
private readonly IContactEmailRepository _contactEmailRepository;
private readonly IContactPhoneRepository _contactPhoneRepository;
private readonly IContactOtherRepository _contactOtherRepository;
private readonly IContactSearchRepository _contactSearchRepository;
private readonly IContactAddressRepository _contactAddressRepository;
private readonly IContactTradeTypeRepository _contactTradeTypeRepository;

public ContactService(
IMapper mapper,
IWorkContext workContext,
IContactRepository contactRepository,
IContactTagRepository contactTagRepository,
IContactOtherRepository contactOtherRepository,
IContactEmailRepository contactEmailRepository,
IContactPhoneRepository contactPhoneRepository,
IContactSearchRepository contactSearchRepository,
IContactAddressRepository contactAddressRepository,
IContactTradeTypeRepository contactTradeTypeRepository)
{
this._mapper = mapper;
this._workContext = workContext;
this._contactRepository = contactRepository;
this._contactTagRepository = contactTagRepository;
this._contactEmailRepository = contactEmailRepository;
this._contactPhoneRepository = contactPhoneRepository;
this._contactOtherRepository = contactOtherRepository;
this._contactSearchRepository = contactSearchRepository;
this._contactAddressRepository = contactAddressRepository;
this._contactTradeTypeRepository = contactTradeTypeRepository;
}
#endregion


#region Get
public Task<ContactDto> Get(int id)
{
return this.Get(id, _workContext.CurrentUser.AccountId);
}
public async Task<ContactDto> Get(int id, Guid accountId)
{
var contact = await _contactRepository.Table
.Where(x => x.AccountId == accountId && x.Id == id)
.ProjectTo<ContactDto>(this._mapper.ConfigurationProvider)
.FirstOrDefaultAsync();

if (contact == null)
throw new EntityNotFound(Messages.ContactNotFound);

return contact;
}
#endregion

#region GetAll
public async Task<PagingQuery<CD.Contact, ContactListDto>> GetAll(
int pageIndex,
int pageSize,
string? sort = null,
string? sortDirection = null,
string? search = null,
int? contactTypeId = null,
int[]? contactTradeTypeIds = null,
double? latitude = null,
double? longitude = null,
int? distance = null)
{
var contacts = _contactRepository.Table
.Include(x => x.ContactEmails)
.Include(x => x.ContactPhones)
.Include(x => x.ContactAddresses)
.Include(x => x.ContactTradeTypes)
.Include(x => x.ContactOthers)
.Include(x => x.ContactTags)
.WhereTenant(_workContext)
.Where(x => x.DeleteType == DeleteTypes.Active);

if (search != null)
{
var contactSearchedIds = this._contactSearchRepository.Table
.WhereTenant(_workContext)
.Where(s => s.Search.Contains(search))
.Select(s => s.Id)
.ToArray();
contacts = contacts.Where(x => contactSearchedIds.Contains(x.Id));
}

if (contactTypeId == 0)
{
contacts = contacts.Where(x => x.ContactTypeId == null);
}
else if (contactTypeId != null)
{
contacts = contacts.Where(x => x.ContactTypeId == contactTypeId);
}

if (latitude.HasValue && longitude.HasValue && distance.HasValue)
{
List<int> ids = await this._contactAddressRepository.Table.AsNoTracking()
.Where(s => s.Contact.AccountId == _workContext.CurrentUser.AccountId && 3959 * Math.Acos(Math.Cos(latitude.Value * (Math.PI / 180.0)) * Math.Cos(s.Latitude.GetValueOrDefault() * (Math.PI / 180.0)) * Math.Cos(s.Longitude.GetValueOrDefault() * (Math.PI / 180.0) - longitude.Value * (Math.PI / 180.0)) + Math.Sin(latitude.Value * (Math.PI / 180.0)) * Math.Sin(s.Latitude.GetValueOrDefault() * (Math.PI / 180.0))) <= distance.Value)
.Select(s => s.ContactId)
.Distinct()
.ToListAsync();
contacts = contacts.Where(s => ids.Contains(s.Id));
}

if (contactTradeTypeIds != null)
{
var filteredData = new List<int>();

foreach (CD.Contact contact in contacts)
{
var tradeTypes = contact.ContactTradeTypes
.Where(x => contactTradeTypeIds.Contains(x.TradeTypeId));

if (tradeTypes.Any())
{
filteredData.Add(contact.Id);
}
}
contacts = contacts.Where(x => filteredData.Contains(x.Id));
}

return await contacts
.AsQueryable()
.AsPaging<CD.Contact, ContactListDto>(_mapper, pageIndex, pageSize, sort, sortDirection);
}
#endregion

#region GetTrash
public async Task<PagingQuery<CD.Contact, ContactTrashDto>> GetTrash(
int pageIndex,
int pageSize,
string? sort = null,
string? sortDirection = null,
string? search = null,
int? contactTypeId = null,
int[]? contactTradeTypeIds = null,
double? latitude = null,
double? longitude = null,
int? distance = null)
{
var contacts = _contactRepository.Table
.Include(x => x.ContactEmails)
.Include(x => x.ContactPhones)
.Include(x => x.ContactAddresses)
.Include(x => x.ContactTradeTypes)
.Include(x => x.ContactOthers)
.Include(x => x.ContactTags)
.WhereTenant(_workContext)
.Where(x => x.DeleteType == DeleteTypes.Trash);

if (search != null)
{
var contactSearchedIds = this._contactSearchRepository.Table
.WhereTenant(_workContext)
.Where(s => s.Search.Contains(search))
.Select(s => s.Id)
.ToArray();
contacts = contacts.Where(x => contactSearchedIds.Contains(x.Id));
}

if (contactTypeId == 0)
{
contacts = contacts.Where(x => x.ContactTypeId == null);
}
else if (contactTypeId != null)
{
contacts = contacts.Where(x => x.ContactTypeId == contactTypeId);
}

if (latitude.HasValue && longitude.HasValue && distance.HasValue)
{
List<int> ids = await this._contactAddressRepository.Table.AsNoTracking()
.Where(s => s.Contact.AccountId == _workContext.CurrentUser.AccountId && 3959 * Math.Acos(Math.Cos(latitude.Value * (Math.PI / 180.0)) * Math.Cos(s.Latitude.GetValueOrDefault() * (Math.PI / 180.0)) * Math.Cos(s.Longitude.GetValueOrDefault() * (Math.PI / 180.0) - longitude.Value * (Math.PI / 180.0)) + Math.Sin(latitude.Value * (Math.PI / 180.0)) * Math.Sin(s.Latitude.GetValueOrDefault() * (Math.PI / 180.0))) <= distance.Value)
.Select(s => s.ContactId)
.Distinct()
.ToListAsync();
contacts = contacts.Where(s => ids.Contains(s.Id));
}

if (contactTradeTypeIds != null)
{
var filteredData = new List<int>();

foreach (CD.Contact contact in contacts)
{
var tradeTypes = contact.ContactTradeTypes
.Where(x => contactTradeTypeIds.Contains(x.TradeTypeId));

if (tradeTypes.Any())
{
filteredData.Add(contact.Id);
}
}
contacts = contacts.Where(x => filteredData.Contains(x.Id));
}

return await contacts
.AsQueryable()
.AsPaging<CD.Contact, ContactTrashDto>(_mapper, pageIndex, pageSize, sort, sortDirection);
}
#endregion

#region GetAllDuplicate
public async Task<IEnumerable<ContactDuplicateDto>> GetDuplicate()
{
var contacts = _contactRepository.Table
.Where(x => x.AccountId == _workContext.CurrentUser.AccountId &&
x.Dismissed == false &&
x.DeleteType == DeleteTypes.Active);

var duplicatedNames = await contacts
.GroupBy(x => x.FirstName + x.MiddleName + x.LastName)
.Select(x => new { FullName = x.Key, Count = x.Count() })
.Where(x => x.Count > 1)
.Select(x => x.FullName.ToLower())
.ToListAsync();

var result = new List<ContactDuplicateDto>();

if (duplicatedNames.Count == 0)
return result;

var duplicatedContacts = await contacts
.Where(x => duplicatedNames.Contains((x.FirstName + x.MiddleName + x.LastName).ToLower()))
.OrderByDescending(x => x.CreatedDate)
.Select(x => new ContactDuplicateDto
{
Id = x.Id,
FirstName = x.FirstName,
MiddleName = x.MiddleName,
LastName = x.LastName,
Phones = x.ContactPhones.Select(p => p.Phone),
Emails = x.ContactEmails.Select(p => p.Email)
})
.ToListAsync();


foreach (var duplicatedName in duplicatedNames)
{
var currentContacts = duplicatedContacts
.Where(x => (x.FirstName + x.MiddleName + x.LastName).ToLower() == duplicatedName)
.Select(x => new ContactDuplicateDto
{
Id = x.Id,
FirstName = x.FirstName,
MiddleName = x.MiddleName,
LastName = x.LastName,
Phones = x.Phones,
Emails = x.Emails
}).ToList();

var entity = currentContacts.First();
entity.DuplicateRecords = _mapper.Map<List<ContactDuplicateSubDto>>(
currentContacts.Skip(1).ToList());

result.Add(entity);
}
return result;

}
#endregion

#region GetCounts
public async Task<IEnumerable<ContactCountDto>> GetContactCounts(DeleteTypes deleteTypes)
{
var contactCounts = await _contactRepository.Table
.WhereTenant(_workContext)
.Where(x => x.DeleteType == deleteTypes)
.Select(s => s.ContactTypeId)
.GroupBy(s => s)
.Select(s => new ContactCountDto
{
ContactTypeId = s.Key,
Count = s.Count()
})
.ToListAsync();

return contactCounts;
}
#endregion

#region Create
public async Task<CD.Contact> Create(ContactCreateDto contactCreateDto)
{
var contact = CreateContactObject(contactCreateDto);
await _contactRepository.InsertAsync(contact);
return contact;
}

public CD.Contact CreateContactObject(ContactCreateDto contactCreateDto)
{

CD.Contact contact = new(
contactCreateDto.ContactTypeId,
contactCreateDto.FirstName,
contactCreateDto.MiddleName,
contactCreateDto.LastName,
contactCreateDto.Prefix,
contactCreateDto.Suffix,
contactCreateDto.NickName,
contactCreateDto.FileAs,
contactCreateDto.PhoneticFirst,
contactCreateDto.PhoneticMiddle,
contactCreateDto.PhoneticLast,
contactCreateDto.JobTitle,
contactCreateDto.Department,
contactCreateDto.CompanyName,
contactCreateDto.CompanyVisible,
contactCreateDto.BirthDate,
contactCreateDto.Notes,
contactCreateDto.ProfilePicture);

if (contactCreateDto.ContactTags != null)
contact.ContactTags.AddRange(contactCreateDto.ContactTags.Select(s => new CD.ContactTag(contact.Id, s.TagId)).ToList());

if (contactCreateDto.ContactEmails != null)
contact.ContactEmails.AddRange(contactCreateDto.ContactEmails.Select(s => new ContactEmail(contact.Id, s.Email, s.Label, s.Visible)).ToList());

if (contactCreateDto.ContactPhones != null)
contact.ContactPhones.AddRange(contactCreateDto.ContactPhones.Select(s => new ContactPhone(contact.Id, s.CountryId, s.Phone, s.Label, s.Visible)).ToList());

if (contactCreateDto.ContactAddresses != null)
contact.ContactAddresses.AddRange(contactCreateDto.ContactAddresses.Select(s => new ContactAddress(contact.Id, s.CountryId, s.StreetAddress, s.StreetAddressLine2, s.City, s.ProvinceId, s.ProvinceText, s.StateId, s.StateText, s.POBox, s.ZipCode, s.Latitude, s.Longitude, s.Label, s.Visible)).ToList());


if (contactCreateDto.ContactOthers != null)
contact.ContactOthers.AddRange(contactCreateDto.ContactOthers.Select(s => new ContactOther(contact.Id, s.ContactOtherTypeId, s.Value, s.Label)).ToList());

if (contactCreateDto.ContactTradeTypes != null)
contact.ContactTradeTypes.AddRange(contactCreateDto.ContactTradeTypes.Select(s => new ContactTradeType(contact.Id, s.TradeTypeId)).ToList());

contact.ContactSearch = new ContactSearch(
contact.Id,
contactCreateDto.FirstName,
contactCreateDto.MiddleName,
contactCreateDto.LastName,
contactCreateDto.CompanyName,
contactCreateDto.JobTitle,
contactCreateDto.Department,
contactCreateDto.ContactPhones == null ? null : contactCreateDto.ContactPhones.Select(s => s.Phone),
contactCreateDto.ContactEmails == null ? null : contactCreateDto.ContactEmails.Select(s => s.Email),
contactCreateDto.ContactAddresses == null ? null : contactCreateDto.ContactAddresses.Select(s => (s.StreetAddress ?? "") + " " + (s.StreetAddressLine2 ?? "") + " " + (s.City ?? "") + " " + (s.StateText ?? "") + " " + (s.ProvinceText ?? "") + " " + (s.ZipCode ?? "")),
contactCreateDto.ContactTags == null ? null : contactCreateDto.ContactTags.Select(s => s.TagName),
contactCreateDto.ContactTradeTypes == null ? null : contactCreateDto.ContactTradeTypes.Select(s => s.TradeTypeName));

return contact;

}
#endregion

#region Update
public async Task<CD.Contact> Update(ContactUpdateDto contactUpdateDto)
{
var contact = await _contactRepository.Table
.Include(i => i.ContactTags)
.Include(i => i.ContactPhones)
.Include(i => i.ContactEmails)
.Include(i => i.ContactOthers)
.Include(i => i.ContactSearch)
.Include(i => i.ContactAddresses)
.Include(i => i.ContactTradeTypes)
.FirstOrDefaultAsync(x => x.Id == contactUpdateDto.Id && x.AccountId == _workContext.CurrentUser.AccountId);

if (contact == null)
throw new EntityNotFound(Messages.ContactNotFound);

contact.Update(
contactUpdateDto.ContactTypeId,
contactUpdateDto.FirstName,
contactUpdateDto.MiddleName,
contactUpdateDto.LastName,
contactUpdateDto.Prefix,
contactUpdateDto.Suffix,
contactUpdateDto.NickName,
contactUpdateDto.FileAs,
contactUpdateDto.PhoneticFirst,
contactUpdateDto.PhoneticMiddle,
contactUpdateDto.PhoneticLast,
contactUpdateDto.JobTitle,
contactUpdateDto.Department,
contactUpdateDto.CompanyName,
contactUpdateDto.CompanyVisible,
contactUpdateDto.BirthDate,
contactUpdateDto.Notes,
contactUpdateDto.ProfilePicture);
await _contactRepository.UpdateAsync(contact);

//
// Update many relations
await CUDContactTags(contact, contactUpdateDto);
await CUDContactEmails(contact, contactUpdateDto);
await CUDContactPhones(contact, contactUpdateDto);
await CUDContactOthers(contact, contactUpdateDto);
await CUDContactAddresses(contact, contactUpdateDto);
await CUDContactTradeTypes(contact, contactUpdateDto);

//
// Update search
contact.ContactSearch.Update(
contactUpdateDto.FirstName,
contactUpdateDto.MiddleName,
contactUpdateDto.LastName,
contactUpdateDto.CompanyName,
contactUpdateDto.JobTitle,
contactUpdateDto.Department,
contactUpdateDto.ContactPhones == null ? null : contactUpdateDto.ContactPhones.Select(s => s.Phone),
contactUpdateDto.ContactEmails == null ? null : contactUpdateDto.ContactEmails.Select(s => s.Email),
contactUpdateDto.ContactAddresses == null ? null : contactUpdateDto.ContactAddresses.Select(s => (s.StreetAddress ?? "") + " " + (s.StreetAddressLine2 ?? "") + " " + (s.City ?? "") + " " + (s.StateText ?? "") + " " + (s.ProvinceText ?? "") + " " + (s.ZipCode ?? "")),
contactUpdateDto.ContactTags == null ? null : contactUpdateDto.ContactTags.Select(s => s.TagName),
contactUpdateDto.ContactTradeTypes == null ? null : contactUpdateDto.ContactTradeTypes.Select(s => s.TradeTypeName));

await _contactSearchRepository.UpdateAsync(contact.ContactSearch);

return contact;
}

#endregion

#region Delete
public async Task<CD.Contact> Delete(ContactDeleteDto request)
{
var contact = await _contactRepository.Table
.FirstOrDefaultAsync(x => x.Id == request.Id &&
x.AccountId == _workContext.CurrentUser.AccountId);

if (contact == null)
throw new EntityNotFound(Messages.ContactNotFound);

contact.Delete();
await _contactRepository.UpdateAsync(contact,
s => s.DeleteType,
s => s.DeletedDate,
s => s.DeletedReason);

return contact;
}
#endregion

#region DeleteBulk
public async Task<IEnumerable<CD.Contact>> DeleteBulk(ContactBulkDeleteDto contactBulkDeleteDto)
{
var contacts = await _contactRepository.Table
.Where(x => contactBulkDeleteDto.Ids.Contains(x.Id) && x.AccountId == _workContext.CurrentUser.AccountId)
.ToListAsync();

foreach (var contact in contacts)
contact.Delete();

await _contactRepository.UpdateRangeAsync(contacts,
s => s.DeleteType,
s => s.DeletedDate,
s => s.DeletedReason);

return contacts;
}
#endregion

#region Forever
public async Task<CD.Contact> Forever(ContactForeverDto request)
{
var contact = await _contactRepository.Table
.FirstOrDefaultAsync(x => x.Id == request.Id && x.AccountId == _workContext.CurrentUser.AccountId);

if (contact == null)
throw new EntityNotFound(Messages.ContactNotFound);

contact.DeleteForever();
await _contactRepository.UpdateAsync(contact,
s => s.DeleteType,
s => s.DeletedDate);

return contact;
}
#endregion

#region ForeverBulk
public async Task<IEnumerable<CD.Contact>> ForeverBulk(ContactBulkForeverDto contactBulkForeverDto)
{
var contacts = await _contactRepository.Table
.Where(x => contactBulkForeverDto.Ids.Contains(x.Id) && x.AccountId == _workContext.CurrentUser.AccountId)
.ToListAsync();

foreach (var contact in contacts)
contact.DeleteForever();

await _contactRepository.UpdateRangeAsync(contacts,
s => s.DeleteType,
s => s.DeletedDate);

return contacts;
}
#endregion

#region EmptyTrash
public async Task<IEnumerable<CD.Contact>> EmptyTrash()
{
var contacts = await this._contactRepository.Table
.AsNoTracking()
.Where(s => s.DeleteType == DeleteTypes.Trash &&
s.AccountId == this._workContext.CurrentUser.AccountId)
.ToListAsync();

foreach (var contact in contacts)
contact.DeleteForever();

await _contactRepository.UpdateRangeAsync(contacts,
s => s.DeleteType,
s => s.DeletedDate);

return contacts;
}
#endregion

#region Recover
public async Task<CD.Contact> Recover(ContactDeleteDto request)
{
var contact = await _contactRepository.Table
.FirstOrDefaultAsync(x => x.Id == request.Id && x.AccountId == _workContext.CurrentUser.AccountId);

if (contact == null)
throw new EntityNotFound(Messages.ContactNotFound);

contact.Recover();
await _contactRepository.UpdateAsync(contact,
s => s.DeleteType,
s => s.DeletedDate,
s => s.DeletedReason);

return contact;
}
#endregion

#region RecoverBulk
public async Task<IEnumerable<CD.Contact>> RecoverBulk(ContactBulkRecoverDto request)
{
var contacts = await _contactRepository.Table
.Where(x => request.Ids.Contains(x.Id) && x.AccountId == _workContext.CurrentUser.AccountId)
.ToListAsync();

foreach (var contact in contacts)
contact.Recover();

await _contactRepository.UpdateRangeAsync(contacts,
s => s.DeleteType,
s => s.DeletedDate,
s => s.DeletedReason);

return contacts;
}
#endregion

#region Dismiss
public async Task<IEnumerable<CD.Contact>> Dismiss(ContactDismissDto request)
{
var contacts = await _contactRepository.Table
.Where(x => request.Ids.Contains(x.Id) && x.AccountId == _workContext.CurrentUser.AccountId)
.ToListAsync();

contacts.ForEach(x => x.Dismiss());

await _contactRepository.UpdateRangeAsync(contacts,
s => s.Dismissed);

return contacts;
}

#endregion

#region Merge
public async Task<CD.Contact> Merge(MergeContactDto mergeContactDto)
{
CD.Contact? contactMergeTo = await _contactRepository.Table
.Include(x => x.ContactPhones)
.Include(x => x.ContactAddresses)
.Include(x => x.ContactEmails)
.FirstOrDefaultAsync(x => x.Id == mergeContactDto.MergeTo && x.AccountId == _workContext.CurrentUser.AccountId);

if (contactMergeTo == null)
throw new EntityNotFound(Messages.ContactNotFound);

var contacts = _contactRepository.Table
.Include(i => i.ContactPhones)
.Include(i => i.ContactEmails)
.Include(i => i.ContactAddresses)
.Where(x =>
x.AccountId == _workContext.CurrentUser.AccountId &&
mergeContactDto.MergeFrom.Contains(x.Id))
.ToList();

if (contacts.Count() == 0)
throw new EntityNotFound(Messages.ContactNotFound);

foreach (var current in contacts)
{
foreach (var phone in current.ContactPhones)
{
if (contactMergeTo.ContactPhones.Any(x => x.Phone == phone.Phone)) continue;

var contactPhone = new ContactPhone(
contactMergeTo.Id,
phone.CountryId,
phone.Phone,
phone.Label,
phone.Visible);
contactMergeTo.ContactPhones.Add(contactPhone);
await this._contactPhoneRepository.InsertAsync(contactPhone);
}

foreach (var email in current.ContactEmails)
{
if (contactMergeTo.ContactEmails.Any(x => x.Email != email.Email))
{
var contactEmail = new ContactEmail(
contactMergeTo.Id,
email.Email,
email.Label,
email.Visible);
contactMergeTo.ContactEmails.Add(contactEmail);
await this._contactEmailRepository.InsertAsync(contactEmail);
}
}

foreach (var address in current.ContactAddresses)
{
var contactAddress = new ContactAddress(
contactMergeTo.Id,
address.CountryId,
address.StreetAddress,
address.StreetAddressLine2,
address.City,
address.ProvinceId,
address.ProvinceText,
address.StateId,
address.StateText,
address.POBox,
address.ZipCode,
address.Latitude,
address.Longitude,
address.Label,
address.Visible);
contactMergeTo.ContactAddresses.Add(contactAddress);
await this._contactAddressRepository.InsertAsync(contactAddress);
}

//MERGE
current.Dismissed = true;
current.DeleteType = DeleteTypes.Forever;
contactMergeTo.Notes += $"nr{current.Notes}";
current.DeletedReason = ContactDeleteReason.MergedWithDuplicateContact.ToByte();
}

await _contactRepository.UpdateRangeAsync(contacts,
s => s.Notes,
s => s.Dismissed,
s => s.DeleteType,
s => s.DeletedReason);

return contactMergeTo;
}
#endregion

#region UpdateType
public async Task<IEnumerable<CD.Contact>> UpdateType(ContactUpdateTypeDto request)
{
var contacts = await _contactRepository.Table
.Include(s => s.ContactTradeTypes)
.Where(x => request.ContactIds.Contains(x.Id) && x.AccountId == _workContext.CurrentUser.AccountId).ToListAsync();

if (contacts == null || contacts.Count == 0)
throw new EntityNotFound(Messages.ContactNotFound);

foreach (var contact in contacts)
{
contact.ContactTypeId = request.ContactTypeId;

var entityIds = contact.ContactTradeTypes.Select(s => s.TradeTypeId).ToList();
var dtoIds = request.TradeTypeIds.ToList();
var creates = dtoIds.Where(s => !entityIds.Contains(s)).ToList();
var deletes = contact.ContactTradeTypes.Where(s => !dtoIds.Contains(s.TradeTypeId)).ToList();

//
// Create
var contactTradeTypes = creates.Select(s => new CD.ContactTradeType(contact.Id, s)).ToList();
contact.ContactTradeTypes.AddRange(contactTradeTypes);
await this._contactTradeTypeRepository.InsertRangeAsync(contactTradeTypes);

//
// Delete
contact.ContactTradeTypes.RemoveRange(deletes);
await this._contactTradeTypeRepository.DeleteRangeAsync(deletes);
}

await _contactRepository.UpdateRangeAsync(contacts,
s => s.ContactTypeId);

return contacts;

}
#endregion

#region Private Helpers

private async Task CUDContactTags(CD.Contact contact, ContactUpdateDto contactUpdateDto)
{
if (contactUpdateDto.ContactTags == null)
contactUpdateDto.ContactTags = new HashSet<ContactTagUpdateDto>();

var entityIds = contact.ContactTags.Select(s => s.TagId).ToList();
var dtoIds = contactUpdateDto.ContactTags.Select(s => s.TagId).ToList();
var creates = contactUpdateDto.ContactTags.Where(s => !entityIds.Contains(s.TagId)).ToList();
var deletes = contact.ContactTags.Where(s => !dtoIds.Contains(s.TagId)).ToList();

//
// Create
var contactTags = creates.Select(s => new CD.ContactTag(contact.Id, s.TagId)).ToList();
contact.ContactTags.AddRange(contactTags);
await this._contactTagRepository.InsertRangeAsync(contactTags);

//
// Delete
contact.ContactTags.RemoveRange(deletes);
await this._contactTagRepository.DeleteRangeAsync(deletes);
}
private async Task CUDContactEmails(CD.Contact contact, ContactUpdateDto contactUpdateDto)
{
if (contactUpdateDto.ContactEmails == null)
contactUpdateDto.ContactEmails = new HashSet<ContactEmailUpdateDto>();

var (creates, updates, deletes) =
contact.ContactEmails.CUDs<ContactEmail, ContactEmailUpdateDto, int>(
contactUpdateDto.ContactEmails, _mapper);

//
// Create
var contactEmails = creates.Select(s => new ContactEmail(contact.Id, s.Email, s.Label, s.Visible)).ToList();
contact.ContactEmails.AddRange(contactEmails);
await this._contactEmailRepository.InsertRangeAsync(contactEmails);

//
// Update
foreach (var contactEmail in updates)
{
var emailDto = contactUpdateDto.ContactEmails.First(s => s.Id == contactEmail.Id);
contactEmail.Update(emailDto.Email, emailDto.Label, emailDto.Visible);
}
await this._contactEmailRepository.UpdateRangeAsync(updates,
s => s.Email,
s => s.Label,
s => s.Visible);

//
// Delete
contact.ContactEmails.RemoveRange(deletes);
await this._contactEmailRepository.DeleteRangeAsync(deletes);
}
private async Task CUDContactPhones(CD.Contact contact, ContactUpdateDto contactUpdateDto)
{
if (contactUpdateDto.ContactPhones == null)
contactUpdateDto.ContactPhones = new HashSet<ContactPhoneUpdateDto>();

var (creates, updates, deletes) =
contact.ContactPhones.CUDs<ContactPhone, ContactPhoneUpdateDto, int>(
contactUpdateDto.ContactPhones, _mapper);

//
// Create
var contactPhones = creates.Select(s => new ContactPhone(contact.Id, s.CountryId, s.Phone, s.Label, s.Visible)).ToList();
contact.ContactPhones.AddRange(contactPhones);
await this._contactPhoneRepository.InsertRangeAsync(contactPhones);

//
// Update
foreach (var contactPhone in updates)
{
var phoneDto = contactUpdateDto.ContactPhones.First(s => s.Id == contactPhone.Id);
contactPhone.Update(phoneDto.CountryId, phoneDto.Phone, phoneDto.Label, phoneDto.Visible);
}
await this._contactPhoneRepository.UpdateRangeAsync(updates,
s => s.Phone,
s => s.Label,
s => s.Visible,
s => s.CountryId);

//
// Delete
contact.ContactPhones.RemoveRange(deletes);
await this._contactPhoneRepository.DeleteRangeAsync(deletes);
}
private async Task CUDContactOthers(CD.Contact contact, ContactUpdateDto contactUpdateDto)
{
if (contactUpdateDto.ContactOthers == null)
contactUpdateDto.ContactOthers = new HashSet<ContactOtherUpdateDto>();

var (creates, updates, deletes) =
contact.ContactOthers.CUDs<ContactOther, ContactOtherUpdateDto, int>(
contactUpdateDto.ContactOthers, _mapper);

//
// Create
var contactOthers = creates.Select(s => new ContactOther(contact.Id, s.ContactOtherTypeId, s.Value, s.Label)).ToList();
contact.ContactOthers.AddRange(contactOthers);
await this._contactOtherRepository.InsertRangeAsync(contactOthers);

//
// Update
foreach (var contactOther in updates)
{
var otherDto = contactUpdateDto.ContactOthers.First(s => s.Id == contactOther.Id);
contactOther.Update(otherDto.ContactOtherTypeId, otherDto.Value, otherDto.Label);
}
await this._contactOtherRepository.UpdateRangeAsync(updates,
s => s.Value,
s => s.Label,
s => s.ContactOtherTypeId);

//
// Delete
contact.ContactOthers.RemoveRange(deletes);
await this._contactOtherRepository.DeleteRangeAsync(deletes);
}
private async Task CUDContactAddresses(CD.Contact contact, ContactUpdateDto contactUpdateDto)
{
if (contactUpdateDto.ContactAddresses == null)
contactUpdateDto.ContactAddresses = new HashSet<ContactAddressUpdateDto>();

var (creates, updates, deletes) =
contact.ContactAddresses.CUDs<ContactAddress, ContactAddressUpdateDto, int>(
contactUpdateDto.ContactAddresses, _mapper);

//
// Create
var contactAddresses = creates.Select(s => new ContactAddress(
contact.Id,
s.CountryId,
s.StreetAddress,
s.StreetAddressLine2,
s.City,
s.ProvinceId,
s.ProvinceText,
s.StateId,
s.StateText,
s.POBox,
s.ZipCode,
s.Latitude,
s.Longitude,
s.Label,
s.Visible)).ToList();
contact.ContactAddresses.AddRange(contactAddresses);
await this._contactAddressRepository.InsertRangeAsync(contactAddresses);

//
// Update
foreach (var contactAddress in updates)
{
var addressDto = contactUpdateDto.ContactAddresses.First(s => s.Id == contactAddress.Id);
contactAddress.Update(
addressDto.CountryId,
addressDto.StreetAddress,
addressDto.StreetAddressLine2,
addressDto.City,
addressDto.ProvinceId,
addressDto.ProvinceText,
addressDto.StateId,
addressDto.StateText,
addressDto.POBox,
addressDto.ZipCode,
addressDto.Latitude,
addressDto.Longitude,
addressDto.Label,
addressDto.Visible);
}
await this._contactAddressRepository.UpdateRangeAsync(updates,
s => s.CountryId,
s => s.StreetAddress,
s => s.StreetAddressLine2,
s => s.City,
s => s.ProvinceId,
s => s.ProvinceText,
s => s.StateId,
s => s.StateText,
s => s.POBox,
s => s.ZipCode,
s => s.Latitude,
s => s.Longitude,
s => s.Label,
s => s.Visible);

//
// Delete
contact.ContactAddresses.RemoveRange(deletes);
await this._contactAddressRepository.DeleteRangeAsync(deletes);
}
private async Task CUDContactTradeTypes(CD.Contact contact, ContactUpdateDto contactUpdateDto)
{
if (contactUpdateDto.ContactTradeTypes == null)
contactUpdateDto.ContactTradeTypes = new HashSet<ContactTradeTypeUpdateDto>();

var entityIds = contact.ContactTradeTypes.Select(s => s.TradeTypeId).ToList();
var dtoIds = contactUpdateDto.ContactTradeTypes.Select(s => s.TradeTypeId).ToList();
var creates = contactUpdateDto.ContactTradeTypes.Where(s => !entityIds.Contains(s.TradeTypeId)).ToList();
var deletes = contact.ContactTradeTypes.Where(s => !dtoIds.Contains(s.TradeTypeId)).ToList();

//
// Create
var contactTradeTypes = creates.Select(s => new CD.ContactTradeType(contact.Id, s.TradeTypeId)).ToList();
contact.ContactTradeTypes.AddRange(contactTradeTypes);
await this._contactTradeTypeRepository.InsertRangeAsync(contactTradeTypes);

//
// Delete
contact.ContactTradeTypes.RemoveRange(deletes);
await this._contactTradeTypeRepository.DeleteRangeAsync(deletes);
}

#endregion
}


     
 
what is notes.io
 

Notes.io is a web-based application for taking notes. You can take your notes and share with others people. If you like taking long notes, notes.io is designed for you. To date, over 8,000,000,000 notes created and continuing...

With notes.io;

  • * You can take a note from anywhere and any device with internet connection.
  • * You can share the notes in social platforms (YouTube, Facebook, Twitter, instagram etc.).
  • * You can quickly share your contents without website, blog and e-mail.
  • * You don't need to create any Account to share a note. As you wish you can use quick, easy and best shortened notes with sms, websites, e-mail, or messaging services (WhatsApp, iMessage, Telegram, Signal).
  • * Notes.io has fabulous infrastructure design for a short link and allows you to share the note as an easy and understandable link.

Fast: Notes.io is built for speed and performance. You can take a notes quickly and browse your archive.

Easy: Notes.io doesn’t require installation. Just write and share note!

Short: Notes.io’s url just 8 character. You’ll get shorten link of your note when you want to share. (Ex: notes.io/q )

Free: Notes.io works for 12 years and has been free since the day it was started.


You immediately create your first note and start sharing with the ones you wish. If you want to contact us, you can use the following communication channels;


Email: [email protected]

Twitter: http://twitter.com/notesio

Instagram: http://instagram.com/notes.io

Facebook: http://facebook.com/notesio



Regards;
Notes.io Team

     
 
Shortened Note Link
 
 
Looding Image
 
     
 
Long File
 
 

For written notes was greater than 18KB Unable to shorten.

To be smaller than 18KB, please organize your notes, or sign in.